我嘗試來合成一些VHDL 2008代碼Vivado 2016.3(同樣的情況在2016.4)Vivado 2016.3記錄的約束陣列不受約束std_logic_vector
的想法是能夠有不受約束的陣列中的記錄,並在同時有無限制的這些記錄數組。
相關代碼:
(axi_pkg.vhd)
-- axi_pkg.vhd
-- Author: Bruno Kremel (CERN BE-RF-FB)
-- Date: 2016-01-23
-- Description: AXI4 Package
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.misc_pkg.all;
package axi_pkg is
type axis_in is record
tdata : std_logic_vector;
tvalid : std_logic;
tlast : std_logic;
tuser : std_logic_vector;
end record;
type axis_out is record
tready : std_logic;
end record;
type axis_in_vector is array (natural range <>) of axis_in;
type axis_out_vector is array (natural range <>) of axis_out;
end package;
(axis_reg.vhd)
-- axis_reg.vhd
-- Author: Bruno Kremel (CERN BE-RF-FB)
-- Date: 2016-11-22
-- Description: AXI4 Stream register
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.misc_pkg.all;
use work.axi_pkg.all;
entity axis_reg is
generic (
DATA_TYPE : string := "signed"
);
port (
aresetn : in std_logic;
aclk : in std_logic;
-- Input stream
in_axis_in : in axis_in;
in_axis_out : out axis_out;
-- Output stream
out_axis_in : out axis_in;
out_axis_out : in axis_out
);
end entity axis_reg;
architecture basic of axis_reg is
constant OUT_DATA_W :natural := out_axis_in.tdata'length;
constant IN_DATA_W :natural := in_axis_in.tdata'length;
signal in_tdata_conv : std_logic_vector(OUT_DATA_W-1 downto 0);
signal in_tuser_conv : std_logic_vector(OUT_DATA_W/8-1 downto 0);
signal in_tdata_shd : std_logic_vector(IN_DATA_W-1 downto 0);
signal in_tuser_shd : std_logic_vector(IN_DATA_W/8-1 downto 0);
begin
gen_signed: if DATA_TYPE = "signed" generate
in_tdata_conv <= std_logic_vector(resize(signed(in_tdata_shd), OUT_DATA_W));
in_tuser_conv <= std_logic_vector(resize(signed(in_tuser_shd), OUT_DATA_W/8));
end generate;
gen_unsigned: if DATA_TYPE = "unsigned" generate
in_tdata_conv <= std_logic_vector(resize(unsigned(in_tdata_shd), OUT_DATA_W));
in_tuser_conv <= std_logic_vector(resize(unsigned(in_tuser_shd), OUT_DATA_W/8));
end generate;
reg_ctrl_inst : entity work.axis_reg_ctrl
port map (
aresetn => aresetn,
aclk => aclk,
next_tdata => in_tdata_conv,
next_tuser => in_tuser_conv,
next_update => open,
in_tvalid => in_axis_in.tvalid,
in_tready => in_axis_out.tready,
in_tlast => in_axis_in.tlast,
out_tdata => out_axis_in.tdata,
out_tvalid => out_axis_in.tvalid,
out_tready => out_axis_out.tready,
out_tlast => out_axis_in.tlast,
out_tuser => out_axis_in.tuser
);
end architecture;
(test_entity.vhd)
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.axi_pkg.all;
entity test_entity is
port (
aresetn : std_logic;
aclk : std_logic;
-- Input stream
in_axis_in : in axis_in_vector;
in_axis_out : out axis_out_vector;
-- Output stream
out_axis_in : out axis_in_vector;
out_axis_out : in axis_out_vector
);
end entity;
architecture test of test_entity is
begin
gen_reg : for i in 0 to in_axis_in'length-1 generate
begin
reg_i : entity work.axis_reg
generic map (
DATA_TYPE => "signed"
)
port map (aresetn => aresetn,
aclk => aclk,
in_axis_in => in_axis_in(i),
in_axis_out => in_axis_out(i),
out_axis_in => out_axis_in(i),
out_axis_out => out_axis_out(i));
end generate;
end architecture;
最後test_entity_top .vhd這基本上是缺點用於合成的尺寸:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.axi_pkg.all;
entity test_entity_top is
end entity;
architecture test of test_entity_top is
constant SIZE : natural := 10;
constant DATA_W : natural := 16;
signal test_axis_in : axis_in(tdata(DATA_W-1 downto 0),
tuser(DATA_W/8-1 downto 0));
signal test_axis_out : axis_out;
signal in_axis_in : axis_in_vector(SIZE-1 downto 0)(tdata(DATA_W-1 downto 0),
tuser(DATA_W/8-1 downto 0));
signal in_axis_out : axis_out_vector(SIZE-1 downto 0);
signal out_axis_in : axis_in_vector(SIZE-1 downto 0)(tdata(DATA_W-1 downto 0),
tuser(DATA_W/8-1 downto 0));
signal out_axis_out : axis_out_vector(SIZE-1 downto 0);
signal aresetn : std_logic;
signal aclk : std_logic;
begin
tst : entity work.test_entity
port map (aresetn => aresetn,
aclk => aclk,
in_axis_in => in_axis_in,
in_axis_out => in_axis_out,
out_axis_in => out_axis_in,
out_axis_out => out_axis_out
);
end architecture;
這一切都很好地編譯在ModelSim中。但Vivado不願意sythesise吧...因爲這個錯誤:
ERROR: [Synth 8-2190] illegal syntax for subtype indication [/home/bkremel/test_vivado/test_entity_top.vhd:15]
ERROR: [Synth 8-2235] indexed name prefix type axis_in_vector expects 1 dimensions [/home/bkremel/test_vivado/test_entity_top.vhd:15]
ERROR: [Synth 8-2190] illegal syntax for subtype indication [/home/bkremel/test_vivado/test_entity_top.vhd:18]
ERROR: [Synth 8-2235] indexed name prefix type axis_in_vector expects 1 dimensions [/home/bkremel/test_vivado/test_entity_top.vhd:18]
ERROR: [Synth 8-1031] in_axis_in is not declared [/home/bkremel/test_vivado/test_entity_top.vhd:28]
ERROR: [Synth 8-1031] out_axis_in is not declared [/home/bkremel/test_vivado/test_entity_top.vhd:30]
ERROR: [Synth 8-1568] actual of formal out port out_axis_in cannot be an expression [/home/bkremel/test_vivado/test_entity_top.vhd:30]
INFO: [Synth 8-2810] unit test ignored due to previous errors [/home/bkremel/test_vivado/test_entity_top.vhd:9]
這表明它實際上接受記錄約束的語法:
signal test_axis_in : axis_in(tdata(DATA_W-1 downto 0),
tuser(DATA_W/8-1 downto 0));
雖然它不喜歡:
signal in_axis_in : axis_in_vector(SIZE-1 downto 0)(tdata(DATA_W-1 downto 0),
tuser(DATA_W/8-1 downto 0));
你會建議使用無約束數組和記錄的intead嗎?
問題是,我的設計經常改變流的位大小。所以使用通用包將是相當不雅的(特別是這個寄存器是一個很好的例子,當在一個文件中你有不同大小的數據總線)
到目前爲止,我已經使用一個維的SLV不使用功能/程序與手工索引記錄,但是這是相當混亂,以保持...
我還添加相關代碼https://www.edaplayground.com/x/eiC edaplayground例如(證明它在模擬器中工作)...
編輯:
有趣的是,它實際上合成,如果我下面:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.axi_pkg.all;
entity test_entity_top is
end entity;
architecture test of test_entity_top is
constant SIZE : natural := 4;
constant DATA_W : natural := 16;
subtype axis_in_constr is axis_in(tdata(DATA_W-1 downto 0),
tuser(DATA_W/8-1 downto 0));
subtype axis_out_constr is axis_out;
signal ch0, ch1, ch2, ch3 : axis_in_constr;
signal out0, out1, out2, out3 : axis_in_constr;
signal in_axis_in : axis_in_vector := (ch0, ch1, ch2, ch3);
signal out_axis_in : axis_in_vector := (out0, out1, out2, out3);
signal in_axis_out : axis_out_vector(SIZE-1 downto 0);
signal out_axis_out : axis_out_vector(SIZE-1 downto 0);
signal aresetn : std_logic;
signal aclk : std_logic;
begin
tst : entity work.test_entity
port map (aresetn => aresetn,
aclk => aclk,
in_axis_in => in_axis_in,
in_axis_out => in_axis_out,
out_axis_in => out_axis_in,
out_axis_out => out_axis_out
);
end architecture;
所以這意味着與無約束陣列的記錄陣列實際上是支持的,但直接約束語法是沒有的。
任何想法如何更精細地定義它?儘管這不是什麼大不了的定義是這樣的頂級..不過我不會介意,以避免它,它看起來有點哈克......
感謝 布魯諾
不知道崩潰,但它看起來像你的'in_axis_in'和'out_axis_in'端口應該有類型'axis_in_vector'而不''axis_in'。要麼,要麼刪除這些端口上的範圍限制。 –
是的。它包含錯誤。首先模擬它並修復它們。從缺少的庫/使用條款開始,然後是包中缺少的約束條件。編譯包:'ghdl -a axi_pkg.vhd axi_pkg.vhd:6:9:無約束數組類型的元素聲明「std_logic_vector」是不允許的,第一個問題很明顯。 –
嗨布魯諾,正如其他人所說,有錯誤需要修復。我不喜歡唱片中的不受約束的領域,但似乎它在2008年是合法的(我學到了一些東西)。但是,使用它有點費勁:[https://www.edaplayground.com/x/5Gd3](https://www.edaplayground.com/x/5Gd3)。接下來的問題是你想讓'tuser'字段的寬度相同。我想不出你會怎麼做。我想知道通用軟件包是否可能是更好的方法,假設你可以綜合它們。 –