0

我编写了这个 VHDL 程序 vor 一个 ALU 及其正在工作的测试平台:

ALU 代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity ALU_CLK is
port(   Clk : in std_logic; --clock signal
        InRegA,InRegB : in signed(31 downto 0); --input operands
        InOp : in unsigned(2 downto 0); --Operation to be performed
        OutReg : out signed(31 downto 0);  --output of ALU
        OutZero : out std_logic
        );
end ALU_CLK;

architecture Behavioral of ALU_CLK is

signal Reg1,Reg2,Reg3 : signed(31 downto 0) := (others => '0');

begin

Reg1 <= INregA;
Reg2 <= InRegB;
OutReg <= Reg3;
process(Clk)
    variable temp: signed(31 downto 0);
begin
 if(rising_edge(Clk)) then
      case InOp is
            when "010" => 
                 temp := Reg1 + Reg2;    --addition
            when "000" => 
                 temp := Reg1 and Reg2;  --AND gate  
            when "001" => 
                 temp := Reg1 or Reg2;   --OR gate                 
            when others =>
                 NULL;
      end case;   
             if temp  = (31 downto 0=>'0') then
                OutZero <= '1';
                else
                OutZero <= '0';
            end if;
            Reg3 <= temp;
   end if; 
end process;    
end Behavioral; 

测试台代码:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

ENTITY tb IS
END tb;

ARCHITECTURE ALU_CLK OF tb IS 

   signal Clk : std_logic := '0';
   signal A,B,R : signed(31 downto 0) := (others => '0');
   signal Op : unsigned(2 downto 0) := (others => '0');
   signal zero :  std_logic :='0';
   constant Clk_period : time := 10 ns;

BEGIN
   uut: entity work.ALU_CLK PORT MAP (
          Clk => Clk,
          InRegA => A,
          InRegB => B,
          InOp => Op,
          OutReg => R,
          OutZero => zero
        );

   Clk_process :process
   begin
        Clk <= '0';
        wait for Clk_period/2;
        Clk <= '1';
        wait for Clk_period/2;
   end process;

   -- Stimulus process
   stim_proc: process
   begin        
      wait for Clk_period*1;
          --test normal operations
        A  <= "00000000000000000000000000010011"; --19 in decimal
        B  <= "00000000000000000000000000001100"; --12 in decimal
        Op <= "000";  wait for Clk_period; --Bitwise and A and B
        Op <= "001";  wait for Clk_period; --Bitwise or B from A.
        Op <= "010";  wait for Clk_period; --addition A nad B  
      wait;
   end process;   
END;

为了稍微缩短代码清单,我没有发布 ALU 所做的所有操作。我可以管理它以将 ALU 更改为没有 clk 的 ALU,但是如何使用测试台对其进行测试?

4

3 回答 3

2

即使在没有时钟的模块的测试台上,最好有一个时钟来为测试事件计时,并更容易以波形查看测试进度。

因此,从 ALU 中移除时钟后,测试台进程​​可以控制刺激并执行以下检查:

-- Combined stimuli and check process
process is
begin
  ...
  -- === 2 + 2 test ===
  -- Stimuli control
  wait until rising_edge(clk);
  InRegA <= to_signed(2, InRegA'length);
  InRegB <= to_signed(2, InRegA'length);
  InOp   <= "010";  -- Add
  -- Output check
  wait until falling_edge(clk);
  assert OutReg = InRegA + InRegB;
  assert (OutZero = '1') = (OutReg = 0);
  ...
end process;

为了简化检查部分,可以将其移至单独的流程,并可以根据操作进行检查,例如:

-- Check process
process (clk) is
begin
  if falling_edge(clk) then
    if check then
      -- OutReg check
      case InOp is
        when "010"  => assert OutReg = InRegA + InRegB;      -- Add
        when "000"  => assert OutReg = (InRegA and InRegB);  -- And
        when "001"  => assert OutReg = (InRegA or InRegB);   -- Or
        when others => report "Unsupported operation" severity ERROR;
      end case;
      -- OutZero check
      assert (OutZero = '1') = (OutReg = 0);
    end if;
  end if;
end process;

check信号由刺激过程控制,以保护何时进行检查,以避免在启动或其他特殊情况下出现错误错误。

于 2014-10-08T09:39:29.970 回答
1
     library IEEE;
     use IEEE.STD_LOGIC_1164.ALL;
     use IEEE.STD_LOGIC_ARITH.ALL;
     use IEEE.STD_LOGIC_UNSIGNED.ALL;
     entity alu32bit is
     port(en:in STD_LOGIC;
          opc:in STD_LOGIC_VECTOR(3 downto 0);
          a_in,b_in:in STD_LOGIC_VECTOR(31 downto 0);
          y_op:out STD_LOGIC_VECTOR(31 downto 0));
     end alu32 bit;

     architecture Behavioral of alu32 bit is
     begin
      Process(en,a_in,b_in,opc)
     begin
     if(en='1')then
     when "0001"=>y_op<=a_in+b_in;
     when "0010"=>y_op<=a_in-b_in;
     when "0011"=>y_op<=not a_in;
     when "0100"=>y_op<=a_in and b_in;
     when "0101"=>y_op<=a_in or b_in;
     when "0110"=>y_op<=a_in nand b_in;
     when "0111"=>y_op<=a_in xor b_in;
     when others=>null;
     end case;
     else
     y_op<="ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
     end if;
     end process;
     end Behavioral;
于 2015-03-26T13:53:50.503 回答
0

最后我得到了这个:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity ALU_32 is
port(  
        InRegA,InRegB : in signed(31 downto 0); --input operands
        InOp : in unsigned(2 downto 0); --Operation to be performed
        OutReg : out signed(31 downto 0);  --output of ALU
          OutZero : out std_logic
        );
end ALU_32;

architecture Behavioral of ALU_32 is

--temporary signal declaration.
signal Reg1,Reg2,Reg3 : signed(31 downto 0) := (others => '0');

begin

Reg1 <= InRegA;
Reg2 <= InRegB;
OutReg <= Reg3;

process(InOp, InRegA, inRegB)
    variable temp: signed(31 downto 0);
begin
      case InOp is
            when "010" => 
                 temp := Reg1 + Reg2;    --addition
            when "110" => 
                 temp := Reg1 - Reg2;    --subtraction
            when "000" => 
                 temp := Reg1 and Reg2;  --AND gate  
            when "001" => 
                 temp := Reg1 or Reg2;   --OR gate               
            when "100" => 
                 temp := Reg1 nor Reg2;  --NOR gate    
            when "011" => 
                 temp := Reg1 xor Reg2;  --XOR gate   
            when "101" => 
                 temp := not Reg1;       --NOT gate
            when "111" => 
                 if Reg1 < Reg2 then     --SLT (set on less than) gate
                     temp   := (others => '1');
                     else
                     temp   := (others => '0');
                 end if;
            when others =>
                 NULL;
      end case; 

             if temp  = (31 downto 0=>'0') then
                OutZero <= '1';
                else
                OutZero <= '0';
            end if;
            Reg3 <= temp;

end process;    

end Behavioral;

工作测试台是:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

ENTITY tb2 IS
END tb2;

ARCHITECTURE ALU_32 OF tb2 IS 


    COMPONENT ALU_32
    PORT(
         InRegA : IN  signed(31 downto 0);
         InRegB : IN  signed(31 downto 0);
         InOp : IN  unsigned(2 downto 0);
         OutReg : OUT  signed(31 downto 0);
         OutZero : OUT  std_logic
        );
    END COMPONENT;


   --Inputs
   signal InRegA : signed(31 downto 0) := (others => '0');
   signal InRegB : signed(31 downto 0) := (others => '0');
   signal InOp : unsigned(2 downto 0) := (others => '0');

    --Outputs
   signal OutReg : signed(31 downto 0);
   signal OutZero : std_logic;
   -- No clocks detected in port list. Replace <clock> below with 
   -- appropriate port name 

   --constant <InOp>_period : time := 10 ns;

BEGIN

   -- Instantiate the Unit Under Test (UUT)
   uut: ALU_32 PORT MAP (
          InRegA => InRegA,
          InRegB => InRegB,
          InOp => InOp,
          OutReg => OutReg,
          OutZero => OutZero
        );

   -- Stimulus process
   stim_proc: process
   begin        
      -- hold reset state for 100 ns.
      wait for 100 ns;  

      -- insert stimulus here 
        --test normal operations
        InRegA  <= "00000000000000000000000000010011"; --19 in decimal
        InRegB  <= "00000000000000000000000000001100"; --12 in decimal
        InOp <= "000";  wait for 100  ns;    --Bitwise and A and B
        InOp <= "001";  wait for 100  ns;    --Bitwise or B from A.
        InOp <= "010";  wait for 100  ns;    --addition A nad B
        InOp <= "100";  wait for 100  ns;    --Bitwise NOR of A and B
        InOp <= "011";  wait for 100  ns;    --Bitwise XOR of A and B
        InOp <= "110";  wait for 100  ns;    --substract A and B
        InOp <= "101";  wait for 100  ns;    --Bitwise NOT of A
        InOp <= "111";  wait for 100  ns;    --Bitwise SLT of A and B
        -- test SLT the other way around
        InRegB  <= "00000000000000000000000000010011"; --19 in decimal
        InRegA  <= "00000000000000000000000000001100"; --12 in decimal
        InOp <= "111";  wait for 100  ns;    --Bitwise SLT of A and B
        -- test Branch equal  that substraction is 0 and zero is 1
        InRegA  <= "00000000000000000000000000001011"; --11 in decimal
        InRegB  <= "00000000000000000000000000001011"; --11 in decimal
        InOp <= "110";  wait for 100  ns;    --substract A and B

      wait;
   end process;
END;

这是模拟的结果:

在此处输入图像描述

于 2014-10-08T09:54:09.890 回答