Vivado 2016.3无约束std_logic_vector的无约束记录数组

时间:2017-01-23 14:38:13

标签: vhdl fpga xilinx vivado

我正在尝试在Vivado 2016.3中合成一些VHDL 2008代码(2016年的情况相同)。

这个想法是能够在记录中拥有无约束的数组,同时拥有这些记录的无约束数组。

相关代码:

(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不愿意将它合成......有了这个错误:

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

您建议使用无约束数组和记录的内容吗?

问题是我的设计经常改变流的位大小。所以使用通用包将是非常不优雅的(特别是这个寄存器是一个很好的例子,当在一个文件中你有不同大小的数据总线的总线)

到目前为止,我已经使用了一维没有记录的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;

这意味着实际上支持具有无约束数组的记录数组,但直接约束语法不支持。

任何想法如何更精细地定义它?虽然定义这样的顶级水平并不是什么大不了的事情。但我还是不介意避免它,它看起来有点hacky ......

由于 布鲁诺

1 个答案:

答案 0 :(得分:0)

使用Xilinx 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