对软件包中VHDL泛型的查询

对软件包中VHDL泛型的查询,vhdl,Vhdl,我已经编写了一个简单的VHDL代码来添加两个包含32位浮点数的矩阵。矩阵尺寸已在包中定义。目前,我在vhdl代码中指定矩阵维度,并使用包中相应的类型。然而,我想在设计中使用generic来处理不同维度的矩阵。为此,我必须以某种方式使用包中定义的正确类型。我该怎么做呢? 我当前的VHDL代码如下 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; use work.mat_pak.all; entity new

我已经编写了一个简单的VHDL代码来添加两个包含32位浮点数的矩阵。矩阵尺寸已在包中定义。目前,我在vhdl代码中指定矩阵维度,并使用包中相应的类型。然而,我想在设计中使用generic来处理不同维度的矩阵。为此,我必须以某种方式使用包中定义的正确类型。我该怎么做呢? 我当前的VHDL代码如下

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

entity newproj is
    Port ( clk : in  STD_LOGIC;
           clr : in  STD_LOGIC;
           start : in  STD_LOGIC;
           A_in : in  t2;
           B_in : in  t2;
           AplusB : out  t2;
           parallel_add_done : out  STD_LOGIC);
end newproj;

architecture Behavioral of newproj is
COMPONENT add
  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: t2 := (others=>(others=>(others=>'0')));
signal add_over: t2bit:=(others=>(others=>'0'));
signal check_all_done,init_val: std_logic:='0';
begin
    init_val <= '1';
    g0: for k in 0 to 1 generate
                g1: for m in 0 to 1 generate
                            add_instx: add port map(A_in(k)(m), B_in(k)(m),     clk, clr, start, temp_out(k)(m), add_over(k)(m));
                end generate;   
        end generate;

        g2: for k in 0 to 1 generate
                g3: for m in 0 to 1 generate
                        check_all_done <= add_over(k)(m) and init_val;
                end generate;   
        end generate;

        p1_add:process(check_all_done,temp_out)
        begin
            AplusB <= temp_out;
            parallel_add_done <= check_all_done;            
        end process;

end Behavioral;

欢迎提出任何建议。谢谢。

我不太确定是否能完全理解,但我还是会尽力回答;)

可以像这样使用无约束数组:

package mat_pak is
  type matrix is array(natural range <>, natural range <>) of std_logic_vector(31 downto 0);
end package mat_pack;

entity newproj is
Generic ( size : natural );
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;
包装材料是
类型矩阵是std_逻辑_向量(31到0)的数组(自然范围,自然范围);
端包装材料包装;
实体newproj是
通用(尺寸:天然);
端口(时钟:在标准逻辑中;
clr:标准逻辑中;
启动:在标准逻辑中;
A_in:在矩阵中(0到大小-1,0到大小-1);
B_in:在矩阵中(0到大小-1,0到大小-1);
APLUBS:输出矩阵(0到大小-1,0到大小-1);
并行添加完成:输出标准逻辑);
结束新项目;

您的设计存在一些逻辑问题

首先,对于一个设计可以容忍的子层次结构,有一些最大数量的端口,你有192个“位”的矩阵输入和输出。你真的认为这个数字应该是可配置的吗

在某一点上,它将只适合于非常大的FPGA设备,不久之后也不适合那里

想象一些操作在
add
parallel_add_done
中使用可变数量的时钟,表示当
aplub
数据由所有实例化
add
组件贡献的矩阵数组元素组成时,单个
rdy
信号被and在一起。如果
add
s都花费了相同的时间,则您可以从其中任何一个获取
rdy
(如果您不是那么确定,则无法使用,
add
中有寄存器)

嵌套的generate语句都分配add_over(k,m)和
init_val
(这是
1
的合成常数)之间的AND的结果。将(k.m)位相加的效果(这在VHDL中不起作用,在合成中也可能无法实现)

注:我还展示了二维数组的正确索引方法

使用Jonathan的调整矩阵大小的方法:

library ieee;
use ieee.std_logic_1164.all;

package mat_pak is

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

library ieee;
use ieee.std_logic_1164.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 entity newproj;

architecture behavioral of newproj is
    component add
        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 size - 1 generate 
g0x: 
        for m in 0 to size - 1 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 size - 1 loop
            for m in 0 to size -1 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 architecture behavioral;
ieee库;
使用ieee.std_logic_1164.all;
包裹mat_pak是
类型矩阵为数组(自然范围,自然范围)
标准逻辑向量(31到0);
B矩阵类型为数组(自然范围,自然范围)
标准逻辑;
终端包mat_-pak;
图书馆ieee;
使用ieee.std_logic_1164.all;
使用work.mat_pak.all;
实体newproj是
通用(尺寸:自然:=2);
港口(
clk:标准逻辑中;
clr:标准逻辑中;
启动:在标准逻辑中;
a_in:in矩阵(0到大小-1,0到大小-1);
b_in:在矩阵中(0到大小-1,0到大小-1);
APLUBS:输出矩阵(0到大小-1,0到大小-1);
并行添加完成:输出标准逻辑
);
最终实体新建项目;
newproj的架构是
组件添加
港口(
a:标准逻辑向量(31到0);
b:标准逻辑向量(31到0);
clk:标准逻辑中;
sclr:标准逻辑中;
ce:标准逻辑;
结果:输出标准逻辑向量(31到0);
rdy:输出标准逻辑
);
端部元件;
信号温度输出:矩阵(0到大小-1,0到大小-1)
:=(其他=>(其他=>(其他=>“0”));
信号叠加:bmatrix(0到大小-1,0到大小-1)
:=(其他=>(其他=>“0”);
开始
g0:
对于大小为-1的0中的k,生成
g0x:
对于0中的m,生成大小为-1的
添加说明:添加
港口地图(
a=>a_in(k,m),
b=>b_in(k,m),
时钟=>clk,
sclr=>clr,
ce=>开始,
结果=>temp_out(k,m),
rdy=>在(k,m)上加上
);
终端生成;
终端生成;

APLUBS你好David Koontz,非常感谢您的投入和替代解决方案。矩阵加法是较大代码的一部分。在最高级别,输入和输出的数量将在Virtex 6提供的388个绑定IOB的范围内。因此,我希望有这么多输入端口(本例中为100个)是安全的。如果它仍然不可接受且不可合成,我将不得不寻找其他方法来获得相同的功能。再次感谢您的帮助。您好Jonathan Drolet,非常感谢您建议使用无约束数组。我从你的投入中学到了一些新的非常有用的东西。再次感谢。
library ieee;
use ieee.std_logic_1164.all;

package mat_pak is

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

library ieee;
use ieee.std_logic_1164.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 entity newproj;

architecture behavioral of newproj is
    component add
        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 size - 1 generate 
g0x: 
        for m in 0 to size - 1 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 size - 1 loop
            for m in 0 to size -1 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 architecture behavioral;