【问题标题】:VHDL : False Results in 4-Bit Adder and SubtractorVHDL:4 位加法器和减法器中的错误结果
【发布时间】:2015-05-26 13:54:29
【问题描述】:

我想用 VHDL 制作一个 4 位加法器和减法器 我创建了 1 位全加器、异或门(用于减法)和一个 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;

在我的主要代码中,我使用了那些(比如测试台!):

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;

主要场景是对该算法进行建模:

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

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

有一个问题:

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

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

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

编辑

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

谢谢...

【问题讨论】:

    标签: logic vhdl digital-logic


    【解决方案1】:

    您的测试平台add_and_sub 没有分配给它的ab,它们的默认值都是'U'。

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

    查看 std_logic_1164 包正文中的 not_tableor_tableand_tablexor_table

    还要成为Minimal, Complete, and Verifiable example,您的读者既需要预期结果,也需要实际结果。

    如果您实际上是在模拟测试台,我希望它不会消耗模拟时间,并且在初始化期间经过一定数量的增量周期后会显示 sume 塞满“U”。

    我没有亲自修改您的测试台以确定您的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;
    

    我们得到:

    (可点击)

    我们发现我们在 ab 上收到了一个事件,但 sum 没有改变。

    而原因在过程中的case语句中就很明显了。 mode的默认值为'U',case语句有01和:

       when others =>  
        --   
      end case;  
    

    而其他选择导致mode 中没有新值。

    为什么没有任何工作可以通过阅读包 std_logic_1164、xor_table、a​​nd_table 或 or_table 的主体源来发现。使用mode = 'U',您所有的组合输出都将是“U”。

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

    signal mode : std_logic := '0';
    

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

    (可点击)

    这是过程中的一个问题:

     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 看起来应该可以工作。问题似乎都在测试台上。

    【讨论】:

    • 谢谢,我忘了说我正在使用 ModelSim,我使用它的模拟来测试我的代码,首先我强制 "A" 、 "B" 和 "Mode" 的值,然后运行它以获得result 和 wave ,但是对于 sum 值 result 是不正确的,正如你所说我的过程有问题; “那么你如何解决这个难题?有两种可能”:可以举个例子吗?
    • 我知道我应该为每个算法序列设置一个控制单元;例如,每个序列都用一个组件和一个控制位完成,但我不知道该怎么做!
    【解决方案2】:

    我做了一些改变

    我做了一个 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 和测试台上

    我多次更改 ALU 并测试了很多方法,但总是有些事情出错!

    如果您想对该算法进行编码,您将创建哪些单元,或者您将创建什么?!你将如何编码?!

    感谢您的帮助...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多