【问题标题】:Change VHDL testbench and 32bit-ALU with clock to one without将带时钟的 VHDL 测试台和 32 位 ALU 更改为不带时钟的
【发布时间】:2014-10-08 09:12:40
【问题描述】:

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

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,但是如何使用测试台对其进行测试?

【问题讨论】:

    标签: vhdl xilinx mips32 alu xilinx-ise


    【解决方案1】:

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

    所以从 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 信号由刺激过程控制,以保护当 进行检查,以避免在启动或其他 特殊情况。

    【讨论】:

      【解决方案2】:
           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;
      

      【讨论】:

        【解决方案3】:

        最后我得到了这个:

        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;
        

        这是模拟的结果:

        【讨论】:

          猜你喜欢
          • 2015-08-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-28
          • 1970-01-01
          相关资源
          最近更新 更多