首页 文章

VHDL:4位加法器和减法器中的错误结果

提问于
浏览
0

我想用VHDL制作一个4位加法器和减法器我创建了1位全加器,XOR门(用于减法)和一个4位加法器,如下所示:

全加法器:

LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY FullAdder_1_Bit IS
  PORT(
    X, Y : IN STD_LOGIC;
    CIn  : IN STD_LOGIC;
    Sum  : OUT STD_LOGIC;
    COut : OUT STD_LOGIC
  );
END FullAdder_1_Bit;

ARCHITECTURE Behavier OF FullAdder_1_Bit IS
BEGIN
  Sum <= X XOR Y XOR CIn;
  COut <= (X AND Y) OR (X AND CIn) OR (Y AND CIn);
END Behavier;

异或门:

LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY XORGate IS
  PORT(
    X1, X2 : IN STD_LOGIC;
    Y : OUT STD_LOGIC
  );  
END XORGate;

ARCHITECTURE Declare OF XORGate IS
BEGIN  
 Y <= X1 XOR X2;
END Declare;

4位加法器:

LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY Adder_4_Bit IS
  PORT(
    A, B : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
    Mode : IN STD_LOGIC;
    Sum  : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
    COut : OUT STD_LOGIC
  );  
END Adder_4_Bit;

ARCHITECTURE Structure OF Adder_4_Bit IS
COMPONENT FullAdder_1_Bit IS
  PORT(
    X, Y : IN STD_LOGIC;
    CIn  : IN STD_LOGIC;
    Sum  : OUT STD_LOGIC;
    COut : OUT STD_LOGIC
  );
END COMPONENT;

COMPONENT XORGate IS
  PORT(
    X1, X2 : IN STD_LOGIC;
    Y : OUT STD_LOGIC
  );  
END COMPONENT;

SIGNAL COut_Temp : STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL XB : STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN  
  B_0 : XORGate PORT MAP(Mode, B(0), XB(0));
  B_1 : XORGate PORT MAP(Mode, B(1), XB(1));
  B_2 : XORGate PORT MAP(Mode, B(2), XB(2));
  B_3 : XORGate PORT MAP(Mode, B(3), XB(3));

  SUM_0 : FullAdder_1_Bit
  PORT MAP (A(0), XB(0), Mode, Sum(0), COut_Temp(0));

  SUM_1 : FullAdder_1_Bit
  PORT MAP (A(1), XB(1), COut_Temp(0), Sum(1), COut_Temp(1));

  SUM_2 : FullAdder_1_Bit
  PORT MAP (A(2), XB(2), COut_Temp(1), Sum(2), COut_Temp(2));

  SUM_3 : FullAdder_1_Bit
  PORT MAP (A(3), XB(3), COut_Temp(2), Sum(3), COut);  
END;

在我的主要代码中,我使用过那些(比如Test-Bench!):

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.ALL;

ENTITY Add_AND_Sub IS

END Add_AND_Sub;

ARCHITECTURE Declare OF Add_AND_Sub IS
COMPONENT Adder_4_Bit IS
  PORT(
    A, B : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
    Mode : IN STD_LOGIC;
    Sum  : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
    COut : OUT STD_LOGIC
  );  
END COMPONENT;

SIGNAL A, B : STD_LOGIC_VECTOR(4 DOWNTO 0);
SIGNAL Mode : STD_LOGIC;
SIGNAL As, Bs, E, AVF : STD_LOGIC;
SIGNAL XA, XB, Sum : STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN 

 Add : Adder_4_Bit
 PORT MAP(XA, XB, Mode, Sum, E);

 PROCESS(A, B, Mode)
 BEGIN
  As <= A(4);
  Bs <= B(4);

  XA <= A(3 DOWNTO 0);
  XB <= B(3 DOWNTO 0);  

  CASE Mode IS
   WHEN '0' =>
     IF ((As XOR Bs) = '1') THEN                   
       Mode <= '1';
       XA <= Sum;       
       AVF <= '0';
       IF (E = '1') THEN
         IF (XA = "0000") THEN
           As <= '0';
         END IF;
       ELSE           
         XA <= (NOT XA) + "0001";
         As <= NOT As;
       END IF; 
     ELSE
       XA <= Sum;
     END IF;   

   WHEN '1' =>
     IF ((As XOR Bs) = '1') THEN              
       Mode <= '0';       
       XA <= Sum;       
       AVF <= E;        
     ELSE       
       AVF <= '0';
       XA <= Sum;
       IF (E = '1') THEN
         IF (XA = "0000") THEN
           As <= '0';
         END IF;
       ELSE
         XA <= (NOT XA) + "0001";
         As <= NOT As;
       END IF;      
     END IF;
   WHEN Others =>  
    --   
  END CASE;          
 END PROCESS; 

END Declare;

主要方案是对此算法进行建模:

Add_Sub_Algorithm

但现在我想在XA和As中输出

  • 我应该使用算法中显示的寄存器,例如"E"和"AVF"

有一个问题:

我们知道端口映射是连续连接的,所以当我改变模式值时,结果(总和)必须改变,是真的吗?!

我已经尝试过这段代码,但我无法在XA中获得输出,并且sum值没有True结果,我知道我的主代码(Process)存在一些问题,但我无法找到问题

请检查代码并告诉我出了什么问题!

Edit

我使用ModelSim及其模拟测试我的代码,首先强制“A”,“B”和“模式”的值然后运行以获得结果和波

谢谢 ...

2 回答

  • 1

    你的测试平台 add_and_sub 没有对它进行任务 ab ,它们是're default values are all ' U.

    当您对 adder_4_bit 的输入未定义时,您期望什么?

    查看std_logic_1164包体内的 not_tableor_tableand_tablexor_table .

    也是一个Minimal, Complete, and Verifiable example您的读者需要预期和实际结果 .

    如果你希望它不消耗模拟时间,并且在初始化期间显示 sume chock满'U' s之后的一些delta周期 .

    我没有亲自修改你的测试平台以确定你的 adder_4_bit 是否有效,但是如果你提供有效的刺激,你可以调试它 . 消耗模拟时间并使用不同的输入值会很有帮助 .

    将监控进程添加到 add_and_sub

    MONITOR:
         process (sum)
             function to_string(inp: std_logic_vector) return string is
                 variable image_str: string (1 to inp'length);
                 alias input_str:  std_logic_vector (1 to inp'length) is inp;
             begin
                 for i in input_str'range loop
                     image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
                 end loop;
                 -- report "image_str = " & image_str;
                 return image_str;
             end;
         begin
             report "sum = " & to_string(sum);
         end process;
    

    得到:

    fourbitadder.vhdl:174:10:@ 0ms :(报告说明):sum = uuuu

    sum 上的一个事件 .

    添加一个进程以在 a 和'b`上引发事件:

    STIMULUS:
         process
         begin
             a <= "00000" after 10 ns;
             b <= "00000" after 10 ns;
             wait for 20 ns;
             wait;
         end process;
    

    我们得到:

    add_and_sub.png
    (可点击)

    我们发现我们在 ab 上发生了一个事件,但_2585233没有改变 .

    原因在于流程中的案例陈述 . mode的默认值是'U',case语句可以选择 01 和:

    when others =>  
        --   
      end case;
    

    其他选择导致 mode 没有新的 Value .

    通过读取包std_logic_1164,xor_table,and_table,or_table的正文来源,可以发现无效的原因 . 使用 mode = 'U' 所有组合输出将为'U' .

    要解决此问题,您可以为在测试平台中声明它的 mode 分配一个默认值:

    signal mode : std_logic := '0';
    

    mode 定义为导致某些操作的有效选择,我们注意到 xa 现在从未定义导致相同的问题:

    enter image description here
    (可点击)

    这是一个过程中的问题:

    process(a, b, mode)
     begin
      as <= a(4);
      bs <= b(4);
    
      xa <= a(3 downto 0);
      xb <= b(3 downto 0);  
    
      case mode is
       when '0' =>
         if ((as xor bs) = '1') then                   
           mode <= '1';
           xa <= sum;       
           avf <= '0';
           if (e = '1') then
             if (xa = "0000") then
               as <= '0';
             end if;
           else           
             xa <= std_logic_vector(unsigned(not xa) + unsigned'("0001"));
             as <= not as;
           end if; 
         else
           xa <= sum;
         end if;   
    
       when '1' =>
         if ((as xor bs) = '1') then              
           mode <= '0';       
           xa <= sum;       
           avf <= e;        
         else       
           avf <= '0';
           xa <= sum;
           if (e = '1') then
             if (xa = "0000") then
               as <= '0';
             end if;
           else
             xa <= std_logic_vector(unsigned(not xa) + unsigned'("0001"));
             as <= not as;
           end if;      
         end if;
       when others =>  
        --   
      end case;
    

    请注意,有三个地方分配了 xa ,它们之间没有模拟时间 . 任何模拟时间只有一个投影输出波形值 . 稍后在同一过程中的赋值将导致分配后一个值,在本例中为 sum ,这都是'U' .

    那么你如何解决这个难题呢?有两种可能性 . 首先,您无法尝试进行算法激励生成,使用不同值的连续赋值之间的等待语句明确地将输入分配给 add . 您还可以在现有过程中对同一信号的连续分配之间插入延迟,这需要大量重写 .

    从积极的方面来说, adder_4_bitfull_adder_1bit 看起来应该有效 . 问题似乎都在测试平台中 .

  • -1

    我做了一些改变

    我做了一个ALU单位:

    LIBRARY ieee;
    USE ieee.std_logic_1164.all;
    USE ieee.numeric_std.all;
    USE ieee.std_logic_unsigned.ALL;
    
    ENTITY ALU IS
      PORT(
        --Clk  : IN STD_LOGIC;
        A, B : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
        Sel  : IN STD_LOGIC;
        AOut : OUT STD_LOGIC_VECTOR(4 DOWNTO 0);
        AsO  : OUT STD_LOGIC
      );  
    END ALU;
    
    ARCHITECTURE Declare OF ALU IS
    COMPONENT Adder_4_Bit IS
      PORT(
        A, B : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
        Mode : IN STD_LOGIC;
        Sum  : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
        COut : OUT STD_LOGIC
      );  
    END COMPONENT;
    
    SIGNAL As, Bs, E, AVF : STD_LOGIC;
    SIGNAL XA, XB, Sum : STD_LOGIC_VECTOR(3 DOWNTO 0);
    SIGNAL Mode : STD_LOGIC;
    
    BEGIN  
    
     Add : Adder_4_Bit
     PORT MAP(XA, XB, Mode, Sum, E);  
    
     PROCESS
     BEGIN
    
     As <= A(4);
     Bs <= B(4);
    
     XA <= A(3 DOWNTO 0);
     XB <= B(3 DOWNTO 0);  
    
      CASE Sel IS
       WHEN '0' =>
         IF ((As XOR Bs) = '1') THEN                  
           Mode <= '1';              
           AVF <= '0';
           WAIT ON Sum;
           IF (E = '1') THEN
             IF (Sum = "0000") THEN
               As <= '0';
             END IF;
           ELSE          
             Sum <= (NOT Sum) + "0001";
             As <= NOT As;
           END IF;
         ELSE
           Mode <= '0';
           WAIT ON Sum;
         END IF;
    
         AOut <= Sum;
         AsO  <= As;  
    
       WHEN '1' =>
         IF ((As XOR Bs) = '1') THEN              
           Mode <= '0';
           WAIT ON Sum;                    
           AVF <= E;        
         ELSE      
           Mode <= '1';
           WAIT ON Sum;
           AVF <= '0';
           IF (E = '1') THEN
             IF (Sum = "0000") THEN
               As <= '0';
             END IF;
           ELSE
             Sum <= (NOT Sum) + "0001";
             As <= NOT As;
           END IF;      
         END IF;
         AOut <= Sum;
         AsO  <= As;
       WHEN Others =>  
        --  
      END CASE;
    
     END PROCESS;
    
    END Declare;
    

    和这样的测试台:

    LIBRARY ieee;
    USE ieee.std_logic_1164.all;
    USE ieee.numeric_std.all;
    USE ieee.std_logic_unsigned.ALL;
    
    ENTITY ALU_Test_Bench IS
    
    END ALU_Test_Bench;
    
    ARCHITECTURE Declare OF ALU_Test_Bench IS
    COMPONENT ALU IS
      PORT(
        --Clk  : IN STD_LOGIC;
        A, B : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
        Sel  : IN STD_LOGIC;
        AOut : OUT STD_LOGIC_VECTOR(4 DOWNTO 0);
        AsO  : OUT STD_LOGIC
      );  
    END COMPONENT;
    
    SIGNAL Xs, S : STD_LOGIC;
    SIGNAL X, Y, O : STD_LOGIC_VECTOR(4 DOWNTO 0);
    
    BEGIN
    
      ALU_PM : ALU PORT MAP(X, Y, S, O, Xs);
    
      Main_Process : PROCESS
      BEGIN      
       WAIT FOR 100 ns;  
       X <= "00010";
       Y <= "11011";
    
       S <= '0';
       WAIT FOR 30 ns;
       S <= '1';
       WAIT FOR 30 ns;
    
       WAIT FOR 100 ns;  
       X <= "01110";
       Y <= "10011";
    
       S <= '0';
       WAIT FOR 30 ns;
       S <= '1';
       WAIT FOR 30 ns;
    
       WAIT FOR 100 ns;  
       X <= "10011";
       Y <= "11111";
    
       S <= '0';
       WAIT FOR 30 ns;
       S <= '1';
       WAIT FOR 30 ns;
    
      END PROCESS;
    
    END Declare;
    

    正如我所说,我想模拟我在第一篇文章中发布的算法

    有一些问题......

    例如,当我模拟并运行测试台时,O和Xs中没有输出值!

    我知道问题出在ALU和Test Bench

    我多次改变ALU并测试了许多方法,但有时出现了一些问题!

    如果你想编码那个算法,你将创建哪些单位,或者你将创建什么?你将如何编码呢?

    谢谢你的帮助 ...

相关问题