VHDL:' X'加法器

时间:2015-06-23 15:51:18

标签: vhdl

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

所以,有两个名为A和B的寄存器,两个名为As的位和Bs在A和B中有符号位,一个XOR门用于在减法中产生B的2补码,最后结果应存储在名为AVF

的寄存器中的A和As(值和符号)和溢出位

这是一个简单的图表:

enter image description here

模式= 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;

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;

试验台:

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;

当我运行测试平台时,结果值填充了&#39; X&#39; :

enter image description here

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

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

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

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

谢谢......

1 个答案:

答案 0 :(得分:4)

文件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; 

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

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

最后,如果合成,您的第二个进程将生成锁存器。锁存器是已知的存储器元件,当使用不当时会断开电路。它们是电路行为与模拟不匹配的主要原因,应予以删除。只要在组合过程中分配的信号未在过程的每个路径中分配,就会出现锁存器。这意味着每次评估流程时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'