【问题标题】:VHDL : 'X' value in result of AdderVHDL:加法器结果中的“X”值
【发布时间】:2015-06-24 00:46:49
【问题描述】:

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

所以,有两个名为 A 和 B 的寄存器,名为 As 和 Bs 的两个位具有 A 和 B 中值的符号位,一个 XOR Gate 用于在减法中对 B 进行 2 补码,最终结果应存储在A and As ( value and 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;

算术:

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;

测试台:

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;

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

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

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

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

我应该怎么做才能对上面的图表进行编码?

谢谢...

【问题讨论】:

  • 向 Wave 窗口添加一些有趣的内部信号,看看它们在做什么。从 Jonathan 指向的 ALU 信号开始。看看 Xes 是从哪里来的,试试他的建议,看看它们是否会消失。使用内部信号进行调试是一项重要的开发技能。

标签: vhdl


【解决方案1】:

您在 alu.vhd 文件中的信号 Sum_ALUTemp_CsTemp_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; 

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

此外,您应该知道语句wait for 30 ns; 是不可综合的。合成器可能会失败或只是忽略等待语句。如果您的目标是模拟路由延迟,那么您的使用是可以的,否则如果您的目标是综合,您应该更改逻辑。

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

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

    CASE Mode_ALU IS

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

【讨论】:

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