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