Logic N位加法器/减法器VHDL

Logic N位加法器/减法器VHDL,logic,vhdl,Logic,Vhdl,您好,我正在尝试用VHDL实现一个N位加法器/减法器,但由于某些原因,我无法让它正常工作,我似乎无法找到问题所在 加法器工作正常,但减法器不工作,我无法真正看到问题所在,因为我检查了表达式,它是正确的,但当我模拟时,减法部分似乎根本不工作 下面是我如何实现溢出检测和饱和控制: LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; entity ripple_adder_subtracter_saturate is generic (WIDTH : INT

您好,我正在尝试用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;

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

首先,在位加法器中,过程灵敏度列表缺失
b_sub
,它将在
b
之后有一个事件增量周期。您可能最终会对最后一个
b_sub
值进行操作,如果您想要合成该值,该值还具有推断锁存器(
b_sub
未在else下分配)

还请注意,
add_sub
通过反转位加法器
b
位,有效地补充了顶层
b

要通过将顶层
b
的两个补码相加来完成减法,需要一个
+1
通过进位来完成。为了保持使用顶级
cin
的能力,您只需在
add\u sub='0'
时将
cin
的值反转到
cell\u 0
。这允许您链接
WIDTH
WIDTH操作数的操作

涟漪\u加法器\u减法器\u饱和

signal o_flow : STD_LOGIC;                             -- internal overflow ...

signal cin_add_sub: std_logic;                         -- added

begin

    cin_add_sub <= not add_sub xor cin;                -- added
您可以在位加法器中添加单独的语句或进程,以在当前进程中,在
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;
位加法器的架构foo是 信号b_信号:标准逻辑; 开始
b_sig无模拟试验台,无预期输出,无用于比较的实际输出。如果你有这些,你可能会看到从哪里开始寻找…我有一个测试台和一个do文件,想让我把它们发布在这里和我的波形到哪里?我以为它会占用太多的东西,但我肯定会发布它们。当它开始测试减法部分时,它在750ns时失败,所以我相信全加器/减法器有问题,但我找不到任何问题。。。因此,这可能是我的nBitadder设计中的其他东西,但我似乎也找不到它可能是什么,我已经尝试了一段时间,因此非常感谢您的帮助。除非这是为了任务,我认为您最好使用
numeric\u std
包和
+
/
-
运算符来实现这种函数。这个设计可能适合于一个相当简单的过程。是的,我见过这种实现,但这是一个任务,所以这是我们应该做的方法。非常感谢您的帮助和提醒,它现在可以工作了。我做了您建议的更改并运行了模拟,但无法使其工作。。。所以在我的头撞到墙上几个小时后,我重新启动了模拟软件,它工作了。。。再次感谢!您的测试台未设置为连续模拟,它应该完成,或者您应该从模拟时间0重新启动它。
-- 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
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: bitAdder port map(a(0), b(0), cin_add_sub, add_sub, temp_sum(0), carry(0));
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;