【问题标题】:Vivado 2016.3 unconstrained array of record with unconstrained std_logic_vectorVivado 2016.3 不受约束的记录数组,具有不受约束的 std_logic_vector
【发布时间】:2017-01-27 16:17:22
【问题描述】:

我正在尝试在 Vivado 2016.3 中合成一些 VHDL 2008 代码(2016.4 也是同样的情况)

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

相关代码:

(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...

谢谢 布鲁诺

【问题讨论】:

  • 不确定是否会发生崩溃,但您的in_axis_inout_axis_in 端口的类型应该是axis_in_vector 而不是axis_in。要么这样,要么删除这些端口上的范围限制。
  • 是的。它包含错误。首先模拟它并修复它们。从缺少的 library/use 子句开始,然后是包中缺少的约束。编译包:`ghdl -a axi_pkg.vhd axi_pkg.vhd:6:9: element declaration of unconstrained array type "std_logic_vector" is not allowed`第一个问题很清楚。
  • 您好 Bruno,正如其他人所说,存在需要修复的错误。我不喜欢记录中不受约束的字段,但似乎在 2008 年是合法的(我学到了一些东西)。不过,使用起来有点繁琐:https://www.edaplayground.com/x/5Gd3。下一个问题是您试图使tuser 字段具有相同的宽度。我想不出你会怎么做。我想知道通用包是否可能是一种更好的方法,假设你可以合成它们。
  • 我已经根据您的建议纠正了我的问题。现在它完全不受约束,可以说是相当优雅..它在 ModelSim 中工作,如原始问题中所述......但 Vivado 似乎无论如何都拒绝它......@BrianDrummond 记录中的不受约束的数组是 2008 年的功能......根据应该支持 Vivado 文档...
  • 确实为 VHDL-2008 编译消除了不受约束的矢量错误,我很抱歉。但是留下axi_pkg.vhd:9:41: prefix must denote an array object or type,前缀是tdata。这是一个数组,但我不确定它在end record 之前是否可见,端口列表中的类似用法不会。如果 VHDL 在从 Ada 简化时没有放弃区分记录,这将是微不足道的......

标签: vhdl fpga xilinx vivado


【解决方案1】:

借助 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2016-10-15
    • 2019-07-10
    • 1970-01-01
    • 2019-01-04
    • 1970-01-01
    相关资源
    最近更新 更多