VHDL:加法器结果中的“ X”值

G3n*_*Man 0 vhdl

我创建了一个4位加法器,现在我想添加和将sub 2寄存器作为符号幅度值

因此,有两个名为A和B的寄存器,两个名为As和B的位在A和B中具有值的符号位,一个用于对B进行2补码减法的XOR门,最终结果应存储在A和As中(value和Sign)和名为AVF的寄存器中的溢出位

这是一个简单的图:

在此处输入图片说明

模式= 1 =>子; Mod = 0 =>添加

我写了这个代码:

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;
    FSum  : 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;
Run Code Online (Sandbox Code Playgroud)

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;
    C : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
    D : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
    Cs : IN STD_LOGIC;
    Ds : IN STD_LOGIC;
    Mode_ALU : IN STD_LOGIC;
    Sum_ALU : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
    AVF : 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 E, Temp_Cs, Temp_Ds : STD_LOGIC;
SIGNAL Temp_S : STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN   

 Add : Adder_4_Bit PORT MAP(C, D, Mode_ALU, Temp_S, E);   

-- Sum_ALU <= Temp_S;
-- Temp_Cs <= Cs;
-- Temp_Ds <= Ds;

 PROCESS
 BEGIN
  WAIT FOR 30 ns;

  Sum_ALU <= Temp_S;
  Temp_Cs <= Cs;
  Temp_Ds <= Ds;
 END PROCESS; 

 PROCESS(C, D, Cs, Ds, Mode_ALU)
 BEGIN   

  CASE Mode_ALU IS
   WHEN '0' =>
     IF ((Cs XOR Ds) = '1') THEN                                
       AVF <= '0';
       IF (E = '1') THEN
         IF (Temp_S = "0000") THEN
           Temp_Cs <= '0';
         END IF;
       ELSE           
         Sum_ALU <= (NOT Temp_S) + "0001";
         Temp_Cs <= NOT Cs;
       END IF;
     ELSE
       AVF <= E;
     END IF;

   WHEN '1' =>
     IF ((Cs XOR Ds) = '1') THEN                                  
       AVF <= E;        
     ELSE       
       AVF <= '0';
       IF (E = '1') THEN
         IF (Temp_S = "0000") THEN
           Temp_Cs <= '0';
         END IF;
       ELSE
         Sum_ALU <= (NOT Temp_S) + "0001";
         Temp_Cs <= NOT Cs;
       END IF;      
     END IF;

   WHEN Others =>  
    --   
  END CASE;

 END PROCESS; 

END Declare;
Run Code Online (Sandbox Code Playgroud)

试验台 :

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;
    C : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
    D : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
    Cs : IN STD_LOGIC;
    Ds : IN STD_LOGIC;
    Mode_ALU : IN STD_LOGIC;
    Sum_ALU : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
    AVF : OUT STD_LOGIC    
  ); 
END COMPONENT;

SIGNAL Xs, Ys, M, Av : STD_LOGIC;
SIGNAL X, Y, O : STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN

  ALU_PM : ALU PORT MAP(X, Y, Xs, Ys, M, O, Av);

  Mode_Process : PROCESS
  BEGIN
  M <= '1';
  WAIT FOR 10 ns;

  M <= '0';
  WAIT FOR 10 ns;

  END PROCESS;

  Calc_Process : PROCESS
  BEGIN       

   X <= "0010";
   Y <= "1011";
   Xs <= '0';
   Ys <= '1';
   WAIT FOR 20 ns;

   X <= "0110";
   Y <= "0011";
   Xs <= '1';
   Ys <= '1'; 
   WAIT FOR 20 ns; 

   X <= "0010";
   Y <= "1011";
   Xs <= '0';
   Ys <= '1';
   WAIT FOR 20 ns; 

  END PROCESS;

END Declare;
Run Code Online (Sandbox Code Playgroud)

当我运行测试平台时,结果值填充为'X':

在此处输入图片说明

我知道问题出在ALU中,但是我找不到问题。

我测试过4位加法器没有问题。

另一个问题是结果的calc符号位,我写的过程正确吗?

我应该怎么做才能编码上面的图?

谢谢 ...

Jon*_*let 5

您有信号的多个驱动器Sum_ALUTemp_CsTemp_Ds在文件alu.vhd。

PROCESS
BEGIN
 WAIT FOR 30 ns;

 Sum_ALU <= Temp_S;
 Temp_Cs <= Cs;
 Temp_Ds <= Ds;
END PROCESS; 

PROCESS(C, D, Cs, Ds, Mode_ALU)
BEGIN   

 CASE Mode_ALU IS
  WHEN '0' =>
    IF ((Cs XOR Ds) = '1') THEN                                
      AVF <= '0';
      IF (E = '1') THEN
        IF (Temp_S = "0000") THEN
          Temp_Cs <= '0';
        END IF;
      ELSE           
        Sum_ALU <= (NOT Temp_S) + "0001";
        Temp_Cs <= NOT Cs;
      END IF;
    ELSE
      AVF <= E;
    END IF;

  WHEN '1' =>
    IF ((Cs XOR Ds) = '1') THEN                                  
      AVF <= E;        
    ELSE       
      AVF <= '0';
      IF (E = '1') THEN
        IF (Temp_S = "0000") THEN
          Temp_Cs <= '0';
        END IF;
      ELSE
        Sum_ALU <= (NOT Temp_S) + "0001";
        Temp_Cs <= NOT Cs;
      END IF;      
    END IF;

  WHEN Others =>  
   --   
 END CASE;

END PROCESS; 
Run Code Online (Sandbox Code Playgroud)

每当您在多个过程中分配信号时(如此处所做的那样),就会产生多个驱动程序。如果驱动程序不同意该值(例如,一个驱动器为“ 1”,另一个驱动器为“ 0”),则结果不确定(“ X”)。您将必须自行解决问题,因为我不确定什么是正确的行为。但是,如果删除第一个过程,则模拟中不会出现未定义的信号。

此外,您应注意该语句wait for 30 ns;不可综合。合成器可能会失败,或者只是忽略wait语句。如果您的目标是模拟路由延迟,则您的用法很好,否则,如果目标是综合,则应更改逻辑。

最后,您的第二个过程将在合成后生成闩锁。锁存器是一种存储元件,使用不当会破坏电路。它们是电路行为与仿真不匹配的主要原因,应将其删除。只要您在组合过程中分配的信号没有在过程的每个路径中分配,就会出现闩锁。这意味着Temp_Cs并且Sum_ALU每次评估过程时都需要分配一个任务(AVF按原样进行);每个if都必须有一个else,并且必须分配所有信号。一种简单的处理方法是在过程开始时提供默认值,以便每个信号都有一个分配。如果在过程评估中多次分配信号,则只有最后一次分配才有效。例如:

PROCESS(C, D, Cs, Ds, Mode_ALU)
BEGIN
    Temp_Cs <= Cs;
    Sum_ALU <= Temp_S;

    CASE Mode_ALU IS
Run Code Online (Sandbox Code Playgroud)

虽然others没有必要在案例分支中进行分配,但是我还是建议您这样做。例如,您可以分配所有信号'X'