尊重 sharth 关于您确实打算在 Adder4 中实例化 N 个 Adder1 的机会的好答案:
ARCHITECTURE imp OF Adder4 IS
COMPONENT Adder1
PORT(
a, b, cIn : in STD_LOGIC;
sum, cOut : out STD_LOGIC);
END COMPONENT;
SIGNAL carry_sig: std_logic_vector(N-1 DOWNTO 0);
signal carry_in: std_logic_vector(N-1 DOWNTO 0);
BEGIN
-- What to write here?
carry_in <= ((carry_sig(N-2 downto 0)) &'0');
Adders:
for i in 0 to N-1 generate
begin
ADD1:
Adder1 port map (
a => a(i),
b => b(i),
cIn => carry_in(i),
sum => sum(i),
cOut => carry_sig(i)
);
end generate;
Carry_Out:
cOut <= carry_sig(N-1);
END imp;
ARCHITECTURE gen OF Adder4 IS
COMPONENT Adder1
PORT(
a, b, cIn : in STD_LOGIC;
sum, cOut : out STD_LOGIC);
END COMPONENT;
SIGNAL carry_sig: std_logic_vector(N-1 DOWNTO 0);
BEGIN
-- What to write here?
Adders:
for i in 0 to N-1 generate
ADD0:
if i = 0 generate
Add1:
Adder1 port map (
a => a(i),
b => b(i),
cIn => '0',
sum => sum(i),
cOut => carry_sig(i)
);
end generate;
ADDN:
if i /= 0 generate
Add1:
Adder1 port map (
a => a(i),
b => b(i),
cIn => carry_sig(i-1),
sum => sum(i),
cOut => carry_sig(i)
);
end generate;
end generate;
Carry_Out:
cOut <= carry_sig(N-1);
END architecture;
我自己更喜欢第一个架构(imp),需要第二个 std_logic_vector 用于进位输入,但大大简化了任何生成构造。两者之间的层次结构有所不同,第一个更易于阅读。
第一个架构 (imp) 还展示了如何手动实例化 Adder1 四次,消除了 generate 构造并将所有 (i) 范围表达式替换为它们各自的 Adder1 实例范围表达式 ((0),(1),(2),(3) ), 分别)。
手动实例化的 adder1 看起来像:
-- Note in this case you'd likely declare all the std_logic_vector with
-- ranges (3 downto 0)
SIGNAL carry_sig: std_logic_vector(3 DOWNTO 0);
signal carry_in: std_logic_vector(3 downto 0);
BEGIN
-- What to write here?
carry_in <= ((carry_sig(2 downto 0)) &'0');
ADD0:
Adder1 port map (
a => a(0),
b => b(0),
cIn => carry_in(0),
sum => sum(0),
cOut => carry_sig(0)
);
...
ADD3:
Adder1 port map (
a => a(3),
b => b(3),
cIn => carry_in(3),
sum => sum(3),
cOut => carry_sig(3)
);
cOut <= carry_sig(3); -- or connect directly to cOut in ADD3 above
使用 carry_sig 的附加进位向量向上调整,最低有效进位进位为“0”,使其易于编写。如果进位信号和进位信号分别命名,则实现进位前瞻方法也更容易阅读。
一个测试台也可以容纳一个宽度 N Adder4:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity adder4_tb is
constant N: natural := 4;
end entity;
architecture tb of adder4_tb is
signal a,b,sum: std_logic_vector (N-1 downto 0);
signal carryout: std_logic;
begin
DUT: entity work.Adder4
generic map (N => N) -- associates formal N with actual N (a constant)
port map (
a => a,
b => b,
sum => sum,
cOut => carryout
);
STIMULUS:
process
variable i,j: integer;
begin
for i in 0 to N*N-1 loop
for j in 0 to N*N-1 loop
a <= std_logic_vector(to_unsigned(i,N));
b <= std_logic_vector(to_unsigned(j,N));
wait for 10 ns; -- so we can view waveform display
end loop;
end loop;
wait; -- end the simulation
end process;
end architecture;
所有这些都没有考虑进位树延迟时间,后者可能会受到实施或使用快速进位电路(例如进位前瞻)的影响。
这给了我们一个看起来像这样的模拟:
或者为了更仔细地查看:
当使用基于生成语句的架构时,如果您更改了 N 的声明,您将拥有一个加法器,它将以 N 指定的可变宽度进行合成和模拟,直到纹波进位不再适用于输入数据速率(10 ns 在目前的测试台)。
请注意,通用 N 形式与测试台中声明的实际 N 的通用映射关联意味着在这种情况下,测试台中声明的 N 也设置了 Adder4 中的宽度 N。