-- 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; use ieee.std_logic_textio.all; library std; use std.textio.all; entity testbench is end testbench; architecture behavior of testbench is component alu generic( OPERAND_WIDTH : integer ); port( 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: alu generic map ( OPERAND_WIDTH => OPERAND_WIDTH ) port map( 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; max_op <= (others => '1'); max_operand <= (others => '1'); -- input generation process input : process(rst, clk) variable op1_in, op2_in: std_logic_vector(OPERAND_WIDTH-1 downto 0); variable opcode_in: std_logic_vector(2 downto 0); variable linein, oplinein: line; file input: text is "input.txt"; file opcode_input: text is "opcode.txt"; begin if rst = '1' then opcode <= (others => '0'); operand1 <= (others => '0'); operand2 <= (others => '0'); elsif clk'event and clk = '1' then if opcode = max_op then done <= '1'; elsif (not endfile(input)) then readline(input, linein); read(linein, op1_in); read(linein, op2_in); operand2 <= op2_in; if not( op1_in = operand1 ) then if operand1 = max_operand then readline(opcode_input, oplinein); read(oplinein, opcode_in); opcode <= opcode_in; end if; operand1 <= op1_in; end if; else done <= '1'; -- can't go on without input 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(2) = '1' then -- arithmetic opcodes case opcode(1 downto 0) is when ADD => assert(result = std_logic_vector(unsigned(operand1) + unsigned(operand2))) report "Incorrect result adding" severity error; when SUB => assert(result = std_logic_vector(unsigned(operand1) - unsigned(operand2))) report "Incorrect result subtracting" severity error; when MUL => assert(result = truncate(std_logic_vector(unsigned(operand1) * unsigned(operand2)), OPERAND_WIDTH)) report "Incorrect result multiplying" severity error; when NEG => assert(result = std_logic_vector(0 - unsigned(operand1))) 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(1 downto 0) is when opAND => assert(result = (operand1 and operand2)) report "Incorrect result ANDing" severity error; when opOR => assert(result = (operand1 or operand2)) report "Incorrect result ORing" severity error; when opXOR => assert(result = (operand1 xor operand2)) report "Incorrect result XORing" severity error; when opNEG => assert(result = (not operand1)) 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;