VHDL 中的可综合多维数组

Sou*_*mya 7 arrays vhdl multidimensional-array

我需要使用多维数组来表示我的设计中的矩阵。我已经尝试了两个可用的选项:

  1. 声明数组数组

    type t11 is array (0 to c1_r2) of std_logic_vector(31 downto 0);
    type t1 is array (0 to r1) of t11; --r1*c1_r2 matrix
    
    Run Code Online (Sandbox Code Playgroud)
  2. 多维数组。

    type matrix  is array (natural range <>, natural range <>)
                   of std_logic_vector(31 downto 0);
    
    Run Code Online (Sandbox Code Playgroud)

但是,在这两种情况下,我在 xilinx 中的后期综合模拟都给了我错误“切片名称仅允许在一维数组上使用”。在可综合 vhdl 设计中使用多维数组的正确方法是什么?欢迎任何意见。

我正在使用 Xilinx ISE 附带的 XST 合成器。我正在索引 i 和 j,因为我的矩阵维度是 m * n * 32。

我在实体中的净 a_in

    a_in: in  matrix (0 to size - 1, 0 to size - 1);
Run Code Online (Sandbox Code Playgroud)

被修改为

    a_in : in STD_LOGIC_VECTOR3 ( 1 downto 0 , 1 downto 0 , 31 downto 0 );
Run Code Online (Sandbox Code Playgroud)

在我的程序中,我从矩阵中访问 k 和 m 的两个生成语句中的值,如下所示:

    add_instx: add 
            port map (
                a => a_in(k,m),
                b => b_in(k,m),
                clk => clk,
                sclr => clr,
                ce => start,
                result => temp_out(k,m),
                rdy => add_over(k,m)
            );
Run Code Online (Sandbox Code Playgroud)

我对 a_in 的测试台输入给出为

    a_in <= (("00111111100000000000000000000000", "00000000000000000000000000000000"),("00000000000000000000000000000000", "00111111100000000000000000000000"));
Run Code Online (Sandbox Code Playgroud)

我的综合生成了以下类型的警告:Xst:387 - 连接到网络的 KEEP 属性可能会阻碍时序优化。您可以通过删除此属性获得更好的结果。但是,我没有设置任何保留属性,我不确定在哪里查找此属性。请帮忙!非常感谢。

我很抱歉没有添加完整的代码。请在下面找到代码和包。

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.NUMERIC_STD.ALL;
    use work.mat_pak.all;


    entity newproj is
        generic ( size:  natural := 2 );
        port ( 
            clk:                in  std_logic;
            clr:                in  std_logic;
            start:              in  std_logic;
            a_in:               in  matrix (0 to size - 1, 0 to size - 1);
            b_in:               in  matrix (0 to size - 1, 0 to size - 1);
            aplusb:             out matrix (0 to size - 1, 0 to size - 1);
            parallel_add_done:  out std_logic);
    end newproj;

    architecture Behavioral of newproj is
    COMPONENT add --This is a 32 bit floating point add IP core
      PORT (
        a : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
        b : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
        clk : IN STD_LOGIC;
         sclr : IN STD_LOGIC;
         ce : IN STD_LOGIC;
        result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
         rdy: OUT STD_LOGIC
      );
    END COMPONENT;

        signal temp_out: matrix (0 to size - 1, 0 to size - 1) :=  (others => (others => (others => '0')));  
        signal add_over: bmatrix (0 to size - 1, 0 to size - 1) := (others => (others => '0'));  

    begin

        g0: 
            for k in  0 to mat_dim generate 
            g0x: 
                for m in 0 to mat_dim generate
                add_instx: add 
                    port map (
                        a => a_in(k,m),
                        b => b_in(k,m),
                        clk => clk,
                        sclr => clr,
                        ce => start,
                        result => temp_out(k,m),
                        rdy => add_over(k,m)
                    );
            end generate;   
        end generate;

        aplusb <= temp_out;

         p1_add:
        process (add_over)
            variable check_all_done: std_logic;
        begin
            check_all_done := '1';
            for k in 0 to mat_dim loop
                for m in 0 to mat_dim loop
                    check_all_done := check_all_done and add_over(k)(m);
                end loop;
            end loop;
            parallel_add_done <= check_all_done;
        end process;

    end Behavioral;
Run Code Online (Sandbox Code Playgroud)

这里使用的包是:

    library IEEE;
    use IEEE.STD_LOGIC_1164.all;
    use IEEE.NUMERIC_STD.ALL;


    package mat_pak is

        CONSTANT mat_dim : natural := 2;

        type matrix  is array (natural range <>, natural range <>)
                   of std_logic_vector(31 downto 0);
        type bmatrix is array (natural range <>, natural range <>) 
                   of std_logic;                      


    end mat_pak;
Run Code Online (Sandbox Code Playgroud)

综合后仿真模型文件在排序和数据类型方面自行修改了实体。实体如下所示:

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    library UNISIM;
    use UNISIM.VCOMPONENTS.ALL;
    use UNISIM.VPKG.ALL;

    entity newproj is
      port (
        clk : in STD_LOGIC := 'X'; 
        clr : in STD_LOGIC := 'X'; 
        start : in STD_LOGIC := 'X'; 
        parallel_add_done : out STD_LOGIC; 
        a_in : in STD_LOGIC_VECTOR3 ( 1 downto 0 , 1 downto 0 , 31 downto 0 ); 
        b_in : in STD_LOGIC_VECTOR3 ( 1 downto 0 , 1 downto 0 , 31 downto 0 ); 
        aplusb : out STD_LOGIC_VECTOR3 ( 1 downto 0 , 1 downto 0 , 31 downto 0 ) 
      );
    end newproj;
Run Code Online (Sandbox Code Playgroud)

Pae*_*els 8

您的第一个数组不是多维数组,而是 2 次嵌套的一维数组。

你的例子:

type t11 is array (0 to c1_r2) of std_logic_vector(31 downto 0);
type t1 is array (0 to r1) of t11;
Run Code Online (Sandbox Code Playgroud)

这个定义更明确:

subtype t_dim1 is std_logic_vector(31 downto 0);
type t_dim1_vector is array(natural range <>) of t_dim1;
subtype t_dim2 is t_dim1_vector(0 to c1_r2);
type t_dim3_vector is array(natural range <>) of t_dim2;
subtype t_dim3 is t_dim3_vector(0 to r1);
Run Code Online (Sandbox Code Playgroud)

您可以通过索引每个维度来访问此结构:

signal matrix3 : t_dim3;
signal matrix2 : t_dim2;
signal matrix1 : t_dim1;
signal slv : std_logic_vector(31 downto 0);
signal sl : std_logic;

matrix2 <= matrix3(i);
matrix1 <= matrix2(j);
matrix1 <= matrix3(i)(j);
slv <= matrix3(i)(j);
sl <= matrix3(i)(j)(k);
Run Code Online (Sandbox Code Playgroud)

您还可以对每个维度进行切片:

signal matrix3 : t_dim3;
signal slice3 : t_dim3_vector(0 to 3);
signal slice2 : t_dim2_vector(0 to 3);
signal slv : std_logic_vector(7 downto 0);

slice3 <= matrix3(4 to 7);
slice2 <= matrix3(i)(2 to 5);
slice2 <= slice3(i)(2 to 5);
slv <= matrix3(i)(j)(15 downto 8);
Run Code Online (Sandbox Code Playgroud)

你的第二个例子:

type matrix is array (natural range <>, natural range <>) of std_logic_vector(31 downto 0);
Run Code Online (Sandbox Code Playgroud)

这是一个带有嵌套一维数组的二维数组。可以按如下方式访问此结构:

signal mat : matrix(0 to r1, p to c1_r2);
signal slv : std_logic_vector(31 downto 0);
signal sl : std_logic;

slv <= mat(i, j);
sl <= mat(i, j)(k);
Run Code Online (Sandbox Code Playgroud)

由于 VHDL-2008 切片也允许在多维数组中使用。在 VHDL-2008 之前,您必须为这项工作使用函数。

查看我的PoC.vectors包,了解如何处理一维和多维数组。