Измените тестовый стенд VHDL и 32-битный ALU с часами на один без

Я написал эту VHDL-программу для 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, но как я могу проверить его с помощью тестового стенда?


person kimliv    schedule 08.10.2014    source источник


Ответы (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 управляется процессом стимулов, чтобы защититься, когда должна быть сделана проверка, чтобы избежать ложных ошибок при запуске или других особых условиях.

person Morten Zilmer    schedule 08.10.2014

В итоге я получил это:

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;

Вот результат моделирования:

введите здесь описание изображения

person kimliv    schedule 08.10.2014