首页 文章

N位加法器/减法器VHDL

提问于
浏览
0

您好我正在尝试在VHDL中实现N位加法器/减法器,但由于某些原因我无法正常工作,我似乎无法找到问题所在 .

加法器正在工作,但减法器不是,我不能真正看到问题是什么,因为我检查了表达式并且它是正确的,但是当我模拟它时,似乎减法部分不起作用一点都不...

以下是我使用溢出检测和饱和度控制的实现方式:

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时它应该做additon等 . 这就是全加器/减法器的样子:

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

1 回答

  • 1

    如果不运行您的测试平台,则在未标记的加法器进程中会出现一些错误 .

    第一,在bitAdder中,过程灵敏度列表缺少 b_sub ,在 b 之后将有一个事件一个增量循环 . 您最终可能会在最后一个 b_sub 值上运行,如果要合成它,也会有一个推断锁存器( b_sub 未在其他情况下分配) .

    另请注意,通过反转bitAdder b 位, add_sub 有效地补充了顶级 b .

    要通过添加顶级 b 的两个补码来完成减法,您需要通过进位来完成 + 1 . 为了保留使用顶级 cin 的能力,您可以简单地将 cin 的值反转为 cell_0 add_sub = '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中添加单独的语句或进程,以便在 add_sub = '0' 时反转 b 并消除当前进程中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; 终止 . 额外的等待使你可以或多或少地统一显示所有测试的波形 . )

    检查波形转储显示减法获得正确的值 . 我没有验证其余的断言 .

相关问题