0

我想用 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;

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

Add_Sub_Algorithm

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

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

有一个问题:

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

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

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

编辑

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

谢谢 ...

4

2 回答 2

1

您的测试台add_and_sub没有对其进行任何分配,a并且b它们的默认值都是“U”。

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

查看 std_logic_1164 包主体中的not_tableor_table和。 and_tablexor_table

还要成为一个最小、完整和可验证的示例,您的读者需要预期和实际结果。

如果您实际上是在模拟测试台,我希望它不会消耗模拟时间,并且在初始化显示期间经过一定数量的增量周期后会sum充满e“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

添加一个进程以在和“b”上引发事件a

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

我们得到:

add_and_sub.png (可点击)

我们发现我们得到了一个事件absum没有改变。

其原因在过程中的案例陈述中显而易见。mode 的默认值为 'U',case 语句可以选择0,1和:

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

于 2015-05-26T21:34:31.010 回答
0

我做了一些改变

我做了一个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 并测试了很多方法,但总是有些事情出错!

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

感谢您的帮助 ...

于 2015-06-14T16:38:23.247 回答