N 位 Adder/Subtractor VHDL
N-bit Adder/Subtractor VHDL
你好,我正在尝试在 VHDL 中实现 N 位 adder/subtractor,但由于某种原因我无法正常工作,而且我似乎无法找到问题所在。
加法器正常工作,但减法器不工作,我无法真正看出问题所在,因为我已经检查了表达式并且它是正确的,但是当我模拟时它看起来像是减法部分根本不工作...
下面是我的溢出检测和饱和控制的实现方式:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
entity ripple_adder_subtracter_saturate is
generic (WIDTH : INTEGER := 8);
port (a : IN STD_LOGIC_VECTOR(WIDTH-1 downto 0);
b : IN STD_LOGIC_VECTOR(WIDTH-1 downto 0);
cin : IN STD_LOGIC := '0';
saturate : IN STD_LOGIC := '0';
add_sub : IN STD_LOGIC := '1';
y : OUT STD_LOGIC_VECTOR(WIDTH-1 downto 0);
cout : OUT STD_LOGIC;
overflow : OUT STD_LOGIC);
end ripple_adder_subtracter_saturate;
ARCHITECTURE behavior OF ripple_adder_subtracter_saturate is
component bitAdder is
port(a : IN STD_LOGIC;
b : IN STD_LOGIC;
cin : IN STD_LOGIC;
add_sub : IN STD_LOGIC;
y : OUT STD_LOGIC;
cout : OUT STD_LOGIC);
end component;
signal carry : STD_LOGIC_VECTOR (WIDTH-1 downto 0); -- hold the carry outs from the adders
signal temp_sum : STD_LOGIC_VECTOR (WIDTH-1 downto 0);
signal o_flow : STD_LOGIC; -- internal overflow signal so I can read it in the process
begin
cell_0: bitAdder port map(a(0), b(0), cin, add_sub, temp_sum(0), carry(0));
G: FOR i IN 1 TO WIDTH-1 GENERATE
cell_i: bitAdder port map(a(i), b(i), carry(i-1), add_sub, temp_sum(i), carry(i));
end GENERATE;
o_flow <= carry(WIDTH-1) XOR carry(WIDTH-2);
overflow <= o_flow;
cout <= carry(WIDTH-1);
process(saturate, temp_sum, carry, o_flow)
begin
if (saturate = '1' AND o_flow = '1') then
if (carry(WIDTH-1) = '0') then
y <= (WIDTH-1 => '0', others => '1');
else
y <= (WIDTH-1 => '1', others => '0');
end if;
else
y <= temp_sum;
end if;
end process;
end behavior;
信号add_sub=0时做减法,为1时做加法等。
这是完整的 adder/subtractor 的样子:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY bitAdder IS
PORT (a: IN STD_LOGIC;
b: IN STD_LOGIC;
cin: IN STD_LOGIC;
add_sub : IN STD_LOGIC;
y: OUT STD_LOGIC;
cout: OUT STD_LOGIC);
END bitAdder;
ARCHITECTURE behavior OF bitAdder IS
signal b_sub : STD_LOGIC := '1';
BEGIN
process(a, b, cin, add_sub)
begin
if (add_sub = '0') then
b_sub <= (not b);
y <= (a XOR b_sub) XOR cin;
cout <= (a AND b_sub) OR (b_sub AND cin) OR (a AND cin);
else
y <= (a XOR b) XOR cin;
cout <= (a AND b) OR (b AND cin) or (a AND cin);
end if;
end process;
END behavior;
你能看出我可能做错了什么吗?我已经用头撞墙好几个小时了,但没有成功。所以任何类型的指针都会有所帮助!
这是它应该通过的测试平台:
-----------------------------------
-- testbench type 3 for --
-- ripple carry adder/subtracter --
-- with overflow signal --
-- and saturation logic --
-- for generic vector --
-----------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY ripple_adder_subtracter_saturate_tb3 IS
GENERIC (WIDTH:INTEGER:=8);
PORT(test_OK:OUT STD_LOGIC);
END ripple_adder_subtracter_saturate_tb3;
ARCHITECTURE arch_ripple_adder_subtracter_saturate_tb3 OF
ripple_adder_subtracter_saturate_tb3 IS
COMPONENT ripple_adder_subtracter_saturate IS
GENERIC (WIDTH:INTEGER:=8);
PORT(a:IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
b:IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
add_sub:IN STD_LOGIC;
saturate:IN STD_LOGIC;
y:OUT STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
overflow:OUT STD_LOGIC);
END COMPONENT ripple_adder_subtracter_saturate;
SIGNAL a_tb_signal:STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
SIGNAL b_tb_signal:STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
SIGNAL y_tb_signal:STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
SIGNAL add_sub_tb_signal:STD_LOGIC;
SIGNAL saturate_tb_signal:STD_LOGIC;
SIGNAL overflow_tb_signal:STD_LOGIC;
BEGIN
ripple_adder_subtracter_saturate_comp:
COMPONENT ripple_adder_subtracter_saturate
PORT MAP(a=>a_tb_signal,
b=>b_tb_signal,
add_sub=>add_sub_tb_signal,
saturate=>saturate_tb_signal,
y=>y_tb_signal,
overflow=>overflow_tb_signal);
saturate_tb_signal<='0', -- overflow
'1' AFTER 1400 ns; -- saturate
add_sub_tb_signal<='1', -- add
'0' AFTER 700 ns, -- sub
'1' AFTER 1400 ns, -- add
'0' AFTER 2100 ns; -- sub
a_tb_signal<="00000000", -- 0
"01010101" AFTER 100 ns, -- 85
"11100101" AFTER 300 ns, -- -27
"00000000" AFTER 700 ns, -- 0
"01010101" AFTER 800 ns, -- 85
"11100101" AFTER 1000 ns, -- -27
"00000000" AFTER 1400 ns, -- 0
"01010101" AFTER 1500 ns, -- 85
"11100101" AFTER 1700 ns, -- -27
"00000000" AFTER 2100 ns, -- 0
"01010101" AFTER 2200 ns, -- 85
"11100101" AFTER 2400 ns; -- -27
b_tb_signal<="00000000", -- 0
"00011101" AFTER 100 ns, -- 29
"00111000" AFTER 200 ns, -- 56
"00000110" AFTER 400 ns, -- 6
"11001000" AFTER 500 ns, -- -56
"10010111" AFTER 600 ns, -- -105
"00000000" AFTER 700 ns, -- 0
"00011101" AFTER 800 ns, -- 29
"11001000" AFTER 900 ns, -- -56
"00111000" AFTER 1000 ns, -- 56
"00000110" AFTER 1100 ns, -- 6
"11001000" AFTER 1200 ns, -- -56
"01101001" AFTER 1300 ns, -- 105
"00000000" AFTER 1400 ns, -- 0
"00011101" AFTER 1500 ns, -- 29
"00111000" AFTER 1600 ns, -- 56
"00000110" AFTER 1800 ns, -- 6
"11001000" AFTER 1900 ns, -- -56
"10010111" AFTER 2000 ns, -- -105
"00000000" AFTER 2100 ns, -- 0
"00011101" AFTER 2200 ns, -- 29
"11001000" AFTER 2300 ns, -- -56
"00111000" AFTER 2400 ns, -- 56
"00000110" AFTER 2500 ns, -- 6
"11001000" AFTER 2600 ns, -- -56
"01101001" AFTER 2700 ns; -- 105
test_proc:
PROCESS
BEGIN
--overflow
--addition
WAIT FOR 50 ns; -- 50 ns 0+0=0 (00000000)
ASSERT (y_tb_signal="00000000")
REPORT "Error for 0+0=0=00000000"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when 0+0=0=00000000"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 150 ns 85+29=114 (01110010)
ASSERT (y_tb_signal="01110010")
REPORT "Error for 85+29=114=01110010"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when 85+29=114=01110010"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 250 ns 85+56=141->-115 (10001101)
ASSERT (y_tb_signal="10001101")
REPORT "Error for 85+56=141->-115=10001101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='1')
REPORT "Error in overflow bit when 85+56=141->-115=10001101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 350 ns -27+56=29 (00011101)
ASSERT (y_tb_signal="00011101")
REPORT "Error for -27+56=29=00011101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27+56=29=00011101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 450 ns -27+6=-21 (11101011)
ASSERT (y_tb_signal="11101011")
REPORT "Error for -27+6=-21=11101011"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27+6=-21=11101011"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 550 ns -27-56=-83 (10101101)
ASSERT (y_tb_signal="10101101")
REPORT "Error for -27-56=-83=10101101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27-56=-83=10101101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 650 ns -27-105=-132->124 (01111100)
ASSERT (y_tb_signal="01111100")
REPORT "Error for -27-105=-132->124=01111100"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='1')
REPORT "Error in overflow bit when -27-105=-132->124=01111100"
SEVERITY ERROR;
--subtraction
WAIT FOR 100 ns; -- 750 ns 0-0=0 (00000000)
ASSERT (y_tb_signal="00000000")
REPORT "Error for 0-0=0=00000000"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when 0-0=0=00000000"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 850 ns 85-29=56 (00111000)
ASSERT (y_tb_signal="00111000")
REPORT "Error for 85-29=56=00111000"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when 85-29=56=00111000"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 950 ns 85-(-56)=141->-115 (10001101)
ASSERT (y_tb_signal="10001101")
REPORT "Error for 85-(-56)=141->-115=10001101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='1')
REPORT "Error in overflow bit when 85-(-56)=141->-115=10001101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1050 ns -27-56=-83 (10101101)
ASSERT (y_tb_signal="10101101")
REPORT "Error for -27-56=-83=10101101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27-56=-83=10101101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1150 ns -27-6=-33 (11011111)
ASSERT (y_tb_signal="11011111")
REPORT "Error for -27-6=-33=11011111"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27-6=-33=11011111"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1250 ns -27-(-56)=29 (00011101)
ASSERT (y_tb_signal="00011101")
REPORT "Error for -27-(-56)=29=00011101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27-(-56)=29=00011101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1350 ns -27-105=-132->124 (01111100)
ASSERT (y_tb_signal="01111100")
REPORT "Error for -27-105=-132->124=01111100"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='1')
REPORT "Error in overflow bit when -27-105=-132->124=01111100"
SEVERITY ERROR;
--saturate
--addition
WAIT FOR 100 ns; -- 1450 ns 0+0=0 (00000000)
ASSERT (y_tb_signal="00000000")
REPORT "Error for 0+0=0=00000000"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when 0+0=0=00000000"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1550 ns 85+29=114 (01110010)
ASSERT (y_tb_signal="01110010")
REPORT "Error for 85+29=114=01110010"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when 85+29=114=01110010"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1650 ns 85+56=141->127 (01111111)
ASSERT (y_tb_signal="01111111")
REPORT "Error for 85+56=141->127=10001101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='1')
REPORT "Error in overflow bit when 85+56=141->127=10001101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1750 ns -27+56=29 (00011101)
ASSERT (y_tb_signal="00011101")
REPORT "Error for -27+56=29=00011101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27+56=29=00011101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1850 ns -27+6=-21 (11101011)
ASSERT (y_tb_signal="11101011")
REPORT "Error for -27+6=-21=11101011"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27+6=-21=11101011"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1950 ns -27-56=-83 (10101101)
ASSERT (y_tb_signal="10101101")
REPORT "Error for -27-56=-83=10101101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27-56=-83=10101101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 2050 ns -27-105=-132->-128 (10000000)
ASSERT (y_tb_signal="10000000")
REPORT "Error for -27-105=-132->-128=01111100"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='1')
REPORT "Error in overflow bit when -27-105=-132->-127=10000000"
SEVERITY ERROR;
--subtraction
WAIT FOR 100 ns; -- 2150 ns 0-0=0 (00000000)
ASSERT (y_tb_signal="00000000")
REPORT "Error for 0-0=0=00000000"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when 0-0=0=00000000"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 2250 ns 85-29=56 (00111000)
ASSERT (y_tb_signal="00111000")
REPORT "Error for 85-29=56=00111000"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when 85-29=56=00111000"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 2350 ns 85-(-56)=141->127 (01111111)
ASSERT (y_tb_signal="01111111")
REPORT "Error for 85-(-56)=141->127=01111111"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='1')
REPORT "Error in overflow bit when 85-(-56)=141->127=01111111"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 2450 ns -27-56=-83 (10101101)
ASSERT (y_tb_signal="10101101")
REPORT "Error for -27-56=-83=10101101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27-56=-83=10101101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 2550 ns -27-6=-33 (11011111)
ASSERT (y_tb_signal="11011111")
REPORT "Error for -27-6=-33=11011111"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27-6=-33=11011111"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 2650 ns -27-(-56)=29 (00011101)
ASSERT (y_tb_signal="00011101")
REPORT "Error for -27-(-56)=29=00011101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27-(-56)=29=00011101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 2750 ns -27-105=-132->-128 (10000000)
ASSERT (y_tb_signal="10000000")
REPORT "Error for -27-105=-132->-128=10000000"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='1')
REPORT "Error in overflow bit when -27-105=-132->-128=10000000"
SEVERITY ERROR;
END PROCESS test_proc;
END arch_ripple_adder_subtracter_saturate_tb3;
和 .do 文件:
-- ripple_adder_saturate_tb3.do
restart -f -nowave
view signals wave
add wave saturate_tb_signal a_tb_signal b_tb_signal y_tb_signal
add wave -radix signed a_tb_signal b_tb_signal y_tb_signal
add wave -radix unsigned y_tb_signal
add wave overflow_tb_signal
run 1380ns
在没有 运行 测试台的情况下,未标记的加法器进程中有几处错误。
首先,在 bitAdder 中缺少进程敏感性列表 b_sub
,它将在 b
之后有一个事件增量周期。您最终可能会在最后一个 b_sub
值上进行操作,如果您想要合成它,它也有一个推断的锁存器(b_sub
未在 else 下分配)。
另请注意,add_sub
通过反转 bitAdder b
位有效地补充了顶层 b
。
要通过添加顶层 b
的二进制补码来完成减法,您需要 + 1
通过进位完成。要保留使用顶层 cin
的能力,您可以简单地将 cin
的值在 add_sub = '0'
时传递给 cell_0
。这允许您链接 WIDTH
宽度操作数的操作。
在ripple_adder_subtracter_saturate
中:
signal o_flow : STD_LOGIC; -- internal overflow ...
signal cin_add_sub: std_logic; -- added
begin
cin_add_sub <= not add_sub xor cin; -- added
并在 cell_0
实例化中用 cin_add_sub
替换 cin
:
cell_0: bitAdder port map(a(0), b(0), cin_add_sub, add_sub, temp_sum(0), carry(0));
您可以在 bitAdder 中添加一个单独的语句或进程来反转 b
when add_sub = '0'
并删除当前进程中 if 语句中的 else。
类似于:
architecture foo of bitAdder is
signal b_sig: std_logic;
begin
b_sig <= not b when add_sub = '0' else
b; -- b_sig <= not add_sub xor b;
y <= a xor b_sig xor cin;
cout <= (a and b_sig) or
(b_sig and cin) or
(a and cin);
end architecture;
同样,您可以将整个二进制补码运算移动到设计顶层。
我进行了上述更改,您的设计没有产生任何断言违规。 (只要你不让它 运行 足够长的时间让带有断言语句的过程结束,它应该被说 wait 49 ns; wait;
终止。额外的等待所以你可以或多或少地显示波形对所有测试统一。)
检查波形转储显示减法得到正确的值。我没有验证其余的断言。
你好,我正在尝试在 VHDL 中实现 N 位 adder/subtractor,但由于某种原因我无法正常工作,而且我似乎无法找到问题所在。
加法器正常工作,但减法器不工作,我无法真正看出问题所在,因为我已经检查了表达式并且它是正确的,但是当我模拟时它看起来像是减法部分根本不工作...
下面是我的溢出检测和饱和控制的实现方式:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
entity ripple_adder_subtracter_saturate is
generic (WIDTH : INTEGER := 8);
port (a : IN STD_LOGIC_VECTOR(WIDTH-1 downto 0);
b : IN STD_LOGIC_VECTOR(WIDTH-1 downto 0);
cin : IN STD_LOGIC := '0';
saturate : IN STD_LOGIC := '0';
add_sub : IN STD_LOGIC := '1';
y : OUT STD_LOGIC_VECTOR(WIDTH-1 downto 0);
cout : OUT STD_LOGIC;
overflow : OUT STD_LOGIC);
end ripple_adder_subtracter_saturate;
ARCHITECTURE behavior OF ripple_adder_subtracter_saturate is
component bitAdder is
port(a : IN STD_LOGIC;
b : IN STD_LOGIC;
cin : IN STD_LOGIC;
add_sub : IN STD_LOGIC;
y : OUT STD_LOGIC;
cout : OUT STD_LOGIC);
end component;
signal carry : STD_LOGIC_VECTOR (WIDTH-1 downto 0); -- hold the carry outs from the adders
signal temp_sum : STD_LOGIC_VECTOR (WIDTH-1 downto 0);
signal o_flow : STD_LOGIC; -- internal overflow signal so I can read it in the process
begin
cell_0: bitAdder port map(a(0), b(0), cin, add_sub, temp_sum(0), carry(0));
G: FOR i IN 1 TO WIDTH-1 GENERATE
cell_i: bitAdder port map(a(i), b(i), carry(i-1), add_sub, temp_sum(i), carry(i));
end GENERATE;
o_flow <= carry(WIDTH-1) XOR carry(WIDTH-2);
overflow <= o_flow;
cout <= carry(WIDTH-1);
process(saturate, temp_sum, carry, o_flow)
begin
if (saturate = '1' AND o_flow = '1') then
if (carry(WIDTH-1) = '0') then
y <= (WIDTH-1 => '0', others => '1');
else
y <= (WIDTH-1 => '1', others => '0');
end if;
else
y <= temp_sum;
end if;
end process;
end behavior;
信号add_sub=0时做减法,为1时做加法等。 这是完整的 adder/subtractor 的样子:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY bitAdder IS
PORT (a: IN STD_LOGIC;
b: IN STD_LOGIC;
cin: IN STD_LOGIC;
add_sub : IN STD_LOGIC;
y: OUT STD_LOGIC;
cout: OUT STD_LOGIC);
END bitAdder;
ARCHITECTURE behavior OF bitAdder IS
signal b_sub : STD_LOGIC := '1';
BEGIN
process(a, b, cin, add_sub)
begin
if (add_sub = '0') then
b_sub <= (not b);
y <= (a XOR b_sub) XOR cin;
cout <= (a AND b_sub) OR (b_sub AND cin) OR (a AND cin);
else
y <= (a XOR b) XOR cin;
cout <= (a AND b) OR (b AND cin) or (a AND cin);
end if;
end process;
END behavior;
你能看出我可能做错了什么吗?我已经用头撞墙好几个小时了,但没有成功。所以任何类型的指针都会有所帮助!
这是它应该通过的测试平台:
-----------------------------------
-- testbench type 3 for --
-- ripple carry adder/subtracter --
-- with overflow signal --
-- and saturation logic --
-- for generic vector --
-----------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY ripple_adder_subtracter_saturate_tb3 IS
GENERIC (WIDTH:INTEGER:=8);
PORT(test_OK:OUT STD_LOGIC);
END ripple_adder_subtracter_saturate_tb3;
ARCHITECTURE arch_ripple_adder_subtracter_saturate_tb3 OF
ripple_adder_subtracter_saturate_tb3 IS
COMPONENT ripple_adder_subtracter_saturate IS
GENERIC (WIDTH:INTEGER:=8);
PORT(a:IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
b:IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
add_sub:IN STD_LOGIC;
saturate:IN STD_LOGIC;
y:OUT STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
overflow:OUT STD_LOGIC);
END COMPONENT ripple_adder_subtracter_saturate;
SIGNAL a_tb_signal:STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
SIGNAL b_tb_signal:STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
SIGNAL y_tb_signal:STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
SIGNAL add_sub_tb_signal:STD_LOGIC;
SIGNAL saturate_tb_signal:STD_LOGIC;
SIGNAL overflow_tb_signal:STD_LOGIC;
BEGIN
ripple_adder_subtracter_saturate_comp:
COMPONENT ripple_adder_subtracter_saturate
PORT MAP(a=>a_tb_signal,
b=>b_tb_signal,
add_sub=>add_sub_tb_signal,
saturate=>saturate_tb_signal,
y=>y_tb_signal,
overflow=>overflow_tb_signal);
saturate_tb_signal<='0', -- overflow
'1' AFTER 1400 ns; -- saturate
add_sub_tb_signal<='1', -- add
'0' AFTER 700 ns, -- sub
'1' AFTER 1400 ns, -- add
'0' AFTER 2100 ns; -- sub
a_tb_signal<="00000000", -- 0
"01010101" AFTER 100 ns, -- 85
"11100101" AFTER 300 ns, -- -27
"00000000" AFTER 700 ns, -- 0
"01010101" AFTER 800 ns, -- 85
"11100101" AFTER 1000 ns, -- -27
"00000000" AFTER 1400 ns, -- 0
"01010101" AFTER 1500 ns, -- 85
"11100101" AFTER 1700 ns, -- -27
"00000000" AFTER 2100 ns, -- 0
"01010101" AFTER 2200 ns, -- 85
"11100101" AFTER 2400 ns; -- -27
b_tb_signal<="00000000", -- 0
"00011101" AFTER 100 ns, -- 29
"00111000" AFTER 200 ns, -- 56
"00000110" AFTER 400 ns, -- 6
"11001000" AFTER 500 ns, -- -56
"10010111" AFTER 600 ns, -- -105
"00000000" AFTER 700 ns, -- 0
"00011101" AFTER 800 ns, -- 29
"11001000" AFTER 900 ns, -- -56
"00111000" AFTER 1000 ns, -- 56
"00000110" AFTER 1100 ns, -- 6
"11001000" AFTER 1200 ns, -- -56
"01101001" AFTER 1300 ns, -- 105
"00000000" AFTER 1400 ns, -- 0
"00011101" AFTER 1500 ns, -- 29
"00111000" AFTER 1600 ns, -- 56
"00000110" AFTER 1800 ns, -- 6
"11001000" AFTER 1900 ns, -- -56
"10010111" AFTER 2000 ns, -- -105
"00000000" AFTER 2100 ns, -- 0
"00011101" AFTER 2200 ns, -- 29
"11001000" AFTER 2300 ns, -- -56
"00111000" AFTER 2400 ns, -- 56
"00000110" AFTER 2500 ns, -- 6
"11001000" AFTER 2600 ns, -- -56
"01101001" AFTER 2700 ns; -- 105
test_proc:
PROCESS
BEGIN
--overflow
--addition
WAIT FOR 50 ns; -- 50 ns 0+0=0 (00000000)
ASSERT (y_tb_signal="00000000")
REPORT "Error for 0+0=0=00000000"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when 0+0=0=00000000"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 150 ns 85+29=114 (01110010)
ASSERT (y_tb_signal="01110010")
REPORT "Error for 85+29=114=01110010"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when 85+29=114=01110010"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 250 ns 85+56=141->-115 (10001101)
ASSERT (y_tb_signal="10001101")
REPORT "Error for 85+56=141->-115=10001101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='1')
REPORT "Error in overflow bit when 85+56=141->-115=10001101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 350 ns -27+56=29 (00011101)
ASSERT (y_tb_signal="00011101")
REPORT "Error for -27+56=29=00011101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27+56=29=00011101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 450 ns -27+6=-21 (11101011)
ASSERT (y_tb_signal="11101011")
REPORT "Error for -27+6=-21=11101011"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27+6=-21=11101011"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 550 ns -27-56=-83 (10101101)
ASSERT (y_tb_signal="10101101")
REPORT "Error for -27-56=-83=10101101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27-56=-83=10101101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 650 ns -27-105=-132->124 (01111100)
ASSERT (y_tb_signal="01111100")
REPORT "Error for -27-105=-132->124=01111100"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='1')
REPORT "Error in overflow bit when -27-105=-132->124=01111100"
SEVERITY ERROR;
--subtraction
WAIT FOR 100 ns; -- 750 ns 0-0=0 (00000000)
ASSERT (y_tb_signal="00000000")
REPORT "Error for 0-0=0=00000000"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when 0-0=0=00000000"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 850 ns 85-29=56 (00111000)
ASSERT (y_tb_signal="00111000")
REPORT "Error for 85-29=56=00111000"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when 85-29=56=00111000"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 950 ns 85-(-56)=141->-115 (10001101)
ASSERT (y_tb_signal="10001101")
REPORT "Error for 85-(-56)=141->-115=10001101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='1')
REPORT "Error in overflow bit when 85-(-56)=141->-115=10001101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1050 ns -27-56=-83 (10101101)
ASSERT (y_tb_signal="10101101")
REPORT "Error for -27-56=-83=10101101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27-56=-83=10101101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1150 ns -27-6=-33 (11011111)
ASSERT (y_tb_signal="11011111")
REPORT "Error for -27-6=-33=11011111"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27-6=-33=11011111"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1250 ns -27-(-56)=29 (00011101)
ASSERT (y_tb_signal="00011101")
REPORT "Error for -27-(-56)=29=00011101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27-(-56)=29=00011101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1350 ns -27-105=-132->124 (01111100)
ASSERT (y_tb_signal="01111100")
REPORT "Error for -27-105=-132->124=01111100"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='1')
REPORT "Error in overflow bit when -27-105=-132->124=01111100"
SEVERITY ERROR;
--saturate
--addition
WAIT FOR 100 ns; -- 1450 ns 0+0=0 (00000000)
ASSERT (y_tb_signal="00000000")
REPORT "Error for 0+0=0=00000000"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when 0+0=0=00000000"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1550 ns 85+29=114 (01110010)
ASSERT (y_tb_signal="01110010")
REPORT "Error for 85+29=114=01110010"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when 85+29=114=01110010"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1650 ns 85+56=141->127 (01111111)
ASSERT (y_tb_signal="01111111")
REPORT "Error for 85+56=141->127=10001101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='1')
REPORT "Error in overflow bit when 85+56=141->127=10001101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1750 ns -27+56=29 (00011101)
ASSERT (y_tb_signal="00011101")
REPORT "Error for -27+56=29=00011101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27+56=29=00011101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1850 ns -27+6=-21 (11101011)
ASSERT (y_tb_signal="11101011")
REPORT "Error for -27+6=-21=11101011"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27+6=-21=11101011"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 1950 ns -27-56=-83 (10101101)
ASSERT (y_tb_signal="10101101")
REPORT "Error for -27-56=-83=10101101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27-56=-83=10101101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 2050 ns -27-105=-132->-128 (10000000)
ASSERT (y_tb_signal="10000000")
REPORT "Error for -27-105=-132->-128=01111100"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='1')
REPORT "Error in overflow bit when -27-105=-132->-127=10000000"
SEVERITY ERROR;
--subtraction
WAIT FOR 100 ns; -- 2150 ns 0-0=0 (00000000)
ASSERT (y_tb_signal="00000000")
REPORT "Error for 0-0=0=00000000"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when 0-0=0=00000000"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 2250 ns 85-29=56 (00111000)
ASSERT (y_tb_signal="00111000")
REPORT "Error for 85-29=56=00111000"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when 85-29=56=00111000"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 2350 ns 85-(-56)=141->127 (01111111)
ASSERT (y_tb_signal="01111111")
REPORT "Error for 85-(-56)=141->127=01111111"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='1')
REPORT "Error in overflow bit when 85-(-56)=141->127=01111111"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 2450 ns -27-56=-83 (10101101)
ASSERT (y_tb_signal="10101101")
REPORT "Error for -27-56=-83=10101101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27-56=-83=10101101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 2550 ns -27-6=-33 (11011111)
ASSERT (y_tb_signal="11011111")
REPORT "Error for -27-6=-33=11011111"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27-6=-33=11011111"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 2650 ns -27-(-56)=29 (00011101)
ASSERT (y_tb_signal="00011101")
REPORT "Error for -27-(-56)=29=00011101"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='0')
REPORT "Error in overflow bit when -27-(-56)=29=00011101"
SEVERITY ERROR;
WAIT FOR 100 ns; -- 2750 ns -27-105=-132->-128 (10000000)
ASSERT (y_tb_signal="10000000")
REPORT "Error for -27-105=-132->-128=10000000"
SEVERITY ERROR;
ASSERT (overflow_tb_signal='1')
REPORT "Error in overflow bit when -27-105=-132->-128=10000000"
SEVERITY ERROR;
END PROCESS test_proc;
END arch_ripple_adder_subtracter_saturate_tb3;
和 .do 文件:
-- ripple_adder_saturate_tb3.do
restart -f -nowave
view signals wave
add wave saturate_tb_signal a_tb_signal b_tb_signal y_tb_signal
add wave -radix signed a_tb_signal b_tb_signal y_tb_signal
add wave -radix unsigned y_tb_signal
add wave overflow_tb_signal
run 1380ns
在没有 运行 测试台的情况下,未标记的加法器进程中有几处错误。
首先,在 bitAdder 中缺少进程敏感性列表 b_sub
,它将在 b
之后有一个事件增量周期。您最终可能会在最后一个 b_sub
值上进行操作,如果您想要合成它,它也有一个推断的锁存器(b_sub
未在 else 下分配)。
另请注意,add_sub
通过反转 bitAdder b
位有效地补充了顶层 b
。
要通过添加顶层 b
的二进制补码来完成减法,您需要 + 1
通过进位完成。要保留使用顶层 cin
的能力,您可以简单地将 cin
的值在 add_sub = '0'
时传递给 cell_0
。这允许您链接 WIDTH
宽度操作数的操作。
在ripple_adder_subtracter_saturate
中:
signal o_flow : STD_LOGIC; -- internal overflow ...
signal cin_add_sub: std_logic; -- added
begin
cin_add_sub <= not add_sub xor cin; -- added
并在 cell_0
实例化中用 cin_add_sub
替换 cin
:
cell_0: bitAdder port map(a(0), b(0), cin_add_sub, add_sub, temp_sum(0), carry(0));
您可以在 bitAdder 中添加一个单独的语句或进程来反转 b
when add_sub = '0'
并删除当前进程中 if 语句中的 else。
类似于:
architecture foo of bitAdder is
signal b_sig: std_logic;
begin
b_sig <= not b when add_sub = '0' else
b; -- b_sig <= not add_sub xor b;
y <= a xor b_sig xor cin;
cout <= (a and b_sig) or
(b_sig and cin) or
(a and cin);
end architecture;
同样,您可以将整个二进制补码运算移动到设计顶层。
我进行了上述更改,您的设计没有产生任何断言违规。 (只要你不让它 运行 足够长的时间让带有断言语句的过程结束,它应该被说 wait 49 ns; wait;
终止。额外的等待所以你可以或多或少地显示波形对所有测试统一。)
检查波形转储显示减法得到正确的值。我没有验证其余的断言。