-- VHDL Test Bench Created from source file alu_struct.vhd -- 09:40:21 06/16/2003 -- -- Notes: -- This testbench has been automatically generated using types std_logic and -- std_logic_vector for the ports of the unit under test. Xilinx recommends -- that these types always be used for the top-level I/O of a design in order -- to guarantee that the testbench will bind correctly to the post-implementation -- simulation model. -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity testbench is end testbench; architecture behavior of testbench is component datapath generic( OPERAND_WIDTH : integer ); port( clk : in std_logic; rst : in std_logic; opcode : in std_logic_vector(2 downto 0); operand1 : in std_logic_vector(OPERAND_WIDTH-1 downto 0); operand2 : in std_logic_vector(OPERAND_WIDTH-1 downto 0); result : out std_logic_vector(OPERAND_WIDTH-1 downto 0) ); end component; -- truncate a vector down to "length" least-significant bits. function truncate(vec: std_logic_vector; length: integer) return std_logic_vector is begin return vec(length-1 downto 0); end function truncate; constant clk_period: time := 5 ns; constant OPERAND_WIDTH : integer := 3; -- declare math opcode constants constant ADD : std_logic_vector(1 downto 0) := "00"; constant SUB : std_logic_vector(1 downto 0) := "01"; constant MUL : std_logic_vector(1 downto 0) := "10"; constant NEG : std_logic_vector(1 downto 0) := "11"; -- declare logical opcode constants constant opAND : std_logic_vector(1 downto 0) := "00"; constant opOR : std_logic_vector(1 downto 0) := "01"; constant opXOR : std_logic_vector(1 downto 0) := "10"; constant opNEG : std_logic_vector(1 downto 0) := "11"; signal clk : std_logic; signal rst : std_logic; signal opcode : std_logic_vector(2 downto 0); signal operand1 : std_logic_vector(OPERAND_WIDTH-1 downto 0); signal operand2 : std_logic_vector(OPERAND_WIDTH-1 downto 0); -- buffers to take pipeline delay through ALU into account signal opcode_r : std_logic_vector(2 downto 0); signal operand1_r : std_logic_vector(OPERAND_WIDTH-1 downto 0); signal operand2_r : std_logic_vector(OPERAND_WIDTH-1 downto 0); signal result : std_logic_vector(OPERAND_WIDTH-1 downto 0); signal done : std_logic := '0'; signal max_operand : std_logic_vector(OPERAND_WIDTH-1 downto 0); signal max_op : std_logic_vector(2 downto 0); begin uut: datapath generic map ( OPERAND_WIDTH => OPERAND_WIDTH ) port map( clk => clk, rst => rst, opcode => opcode, operand1 => operand1, operand2 => operand2, result => result ); -- the clock, which we'll use to step through input values clk <= '0' when rst = '1' else not clk after clk_period when (done = '0') else '0'; -- generate an initial reset pulse rst <= '1', '0' after clk_period; -- indicate that the simulation is done. This happens when we've checked all inputs. done <= '1' after clk_period when (opcode_r = max_op) and (operand1_r = max_operand) and (operand2_r = max_operand) else '0'; max_op <= (others => '1'); --max_operand(OPERAND_WIDTH-1) <= '0'; --max_operand(OPERAND_WIDTH-2 downto 0) <= (others => '1'); max_operand <= (others => '1'); -- input generation process input : process(rst, clk) begin if rst = '1' then opcode <= (others => '0'); operand1 <= (others => '0'); operand2 <= (others => '0'); elsif clk'event and clk = '1' then opcode_r <= opcode; operand1_r <= operand1; operand2_r <= operand2; operand2 <= std_logic_vector(unsigned(operand2) + 1); if operand2 = max_operand then operand2 <= (others => '0'); operand1 <= std_logic_vector(unsigned(operand1) + 1); if operand1 = max_operand then operand1 <= (others => '0'); opcode <= std_logic_vector(unsigned(opcode) + 1); end if; end if; end if; end process input; -- verification process verify : process(rst, clk) begin if clk'event and clk = '0' then if now > 0 ps then if opcode_r(2) = '1' then -- arithmetic opcodes case opcode_r(1 downto 0) is when ADD => assert(result = std_logic_vector(unsigned(operand1_r) + unsigned(operand2_r))) report "Incorrect result adding" severity error; when SUB => assert(result = std_logic_vector(unsigned(operand1_r) - unsigned(operand2_r))) report "Incorrect result subtracting" severity error; when MUL => assert(result = truncate(std_logic_vector(unsigned(operand1_r) * unsigned(operand2_r)), OPERAND_WIDTH)) report "Incorrect result multiplying" severity error; when NEG => assert(result = std_logic_vector(0 - unsigned(operand1_r))) report "Incorrect result negating" severity error; when others => assert(false) report "simulation error: invalid math opcode!" severity failure; end case; else -- logic opcodes case opcode_r(1 downto 0) is when opAND => assert(result = (operand1_r and operand2_r)) report "Incorrect result ANDing" severity error; when opOR => assert(result = (operand1_r or operand2_r)) report "Incorrect result ORing" severity error; when opXOR => assert(result = (operand1_r xor operand2_r)) report "Incorrect result XORing" severity error; when opNEG => assert(result = (not operand1_r)) report "Incorrect result taking logical negation" severity error; when others => assert(false) report "simulation error: invalid math opcode!" severity failure; end case; end if; end if; end if; end process verify; -- *** End Test Bench - User Defined Section *** end;