Vivado 2016.3记录的约束阵列不受约束std_logic_vector

问题描述:

我尝试来合成一些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; 

所以这意味着与无约束阵列的记录阵列实际上是支持的,但直接约束语法是没有的。

任何想法如何更精细地定义它?尽管这不是什么大不了的定义是这样的*..不过我不会介意,以避免它,它看起来有点哈克......

感谢 布鲁诺

+0

不知道崩溃,但它看起来像你的'in_axis_in'和'out_axis_in'端口应该有类型'axis_in_vector'而不''axis_in'。要么,要么删除这些端口上的范围限制。 –

+1

是的。它包含错误。首先模拟它并修复它们。从缺少的库/使用条款开始,然后是包中缺少的约束条件。编译包:'ghdl -a axi_pkg.vhd axi_pkg.vhd:6:9:无约束数组类型的元素声明“std_logic_vector”是不允许的,第一个问题很明显。 –

+1

嗨布鲁诺,正如其他人所说,有错误需要修复。我不喜欢唱片中的不受约束的领域,但似乎它在2008年是合法的(我学到了一些东西)。但是,使用它有点费劲:[https://www.edaplayground.com/x/5Gd3](https://www.edaplayground.com/x/5Gd3)。接下来的问题是你想让'tuser'字段的宽度相同。我想不出你会怎么做。我想知道通用软件包是否可能是更好的方法,假设你可以综合它们。 –

与赛灵思SR我们是来工作期望的行为的例子,所以我将它发布在Vivado以及ModelSim/Edaplayground中。

-- 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; 

package axi_pkg is 
    type axis_downstream is record 
     tdata : std_logic_vector; 
     tvalid : std_logic; 
     tlast : std_logic; 
     tuser : std_logic_vector; 
    end record; 

    type axis_upstream is record 
     tready : std_logic; 
    end record; 

    type axis_downstream_vector is array (natural range <>) of axis_downstream; 
    type axis_upstream_vector is array (natural range <>) of axis_upstream; 
end package; 


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; 

    signal axis_downstream : axis_downstream_vector(SIZE-1 downto 0)(tdata(DATA_W-1 downto 0), 
                    tuser(DATA_W/8-1 downto 0)); 
    signal axis_upstream : axis_upstream_vector(SIZE-1 downto 0); 
begin 
    assert axis_downstream'length = SIZE 
     report "SIZE is not correct" 
    severity failure; 

    assert axis_downstream(0).tdata'length = DATA_W 
     report "TDATA width is not correct" 
    severity failure; 

    assert axis_downstream(0).tuser'length = (DATA_W/8) 
     report "TUSER width is not correct" 
    severity failure; 

end architecture; 

问题是,并非所有文件在Vivado中都标记为2008年(我的错)。但我发布这个最小的例子,以便它很好地适合这个问题。 也Edaplayground链接:https://www.edaplayground.com/x/3sKr