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 tb is
end entity;

architecture bench of tb is
	constant CLK_PERIOD : time := 10 ns;
    
	signal stop : boolean := false;
    
	signal clk : std_logic;
	signal res_n : std_logic := '0';

	signal address : std_logic_vector(0 downto 0) := "0";
	signal write : std_logic := '0';
	signal read : std_logic := '0';
    
	signal writedata : std_logic_vector(31 downto 0);
	signal readdata : std_logic_vector(31 downto 0);

	type test_vector_t is array (0 to 9) of std_logic_vector(31 downto 0);

	constant test_vector : test_vector_t := (
		x"00010000", -- one * one
		x"fff842ab", -- one * x
		x"ffe2859a", -- one * y
		x"001e3999", -- one * z
		x"003be6ac", -- x * x
		x"00e425f0", -- x * y
		x"ff161241", -- x * z
		x"0364f5a1", -- y * y
		x"fc85062d", -- y * z
		x"03918cd1"  -- z * z
	);

    begin
	avalon_mm_sqrt_inst : entity work.avalon_mm_sqrt
	port map (
	    clk       => clk,
	    res_n     => res_n,
	    address   => address,
	    write     => write,
	    read      => read,
	    writedata => writedata,
	    readdata  => readdata
	);
    
	stimulus : process
	begin
		res_n <= '0';
		write <= '0';
		writedata <= x"00000000";
		wait for 100 ns;
		wait until rising_edge(clk);
		res_n <= '1';
                wait until rising_edge(clk);
                read <= '0';
                address <= "0";
                for i in 0 to (test_vector'length / 2) - 1 loop
                        write <= '1';
                        writedata <= test_vector(2*i);
                        wait until rising_edge(clk);
                        writedata <= test_vector(2*i+1);
                        wait until rising_edge(clk);
                        write <= '0';
                        wait for 2*CLK_PERIOD;
                        read <= '1';
                        wait until readdata <= x"00000001";
                        address <= "1";
                        wait until rising_edge(clk);
                        address <= "0";
                        wait until readdata <= x"00000001";
                        address <= "1";
                        wait until rising_edge(clk);
                        read <= '0';
                        address <= "0";
                end loop;
		wait until rising_edge(clk);
                wait for 256*CLK_PERIOD;
		stop <= true;
		wait;
	end process;
    
	generate_clk : process
	begin
		while not stop loop
			clk <= '1', '0' after CLK_PERIOD / 2;
			wait for CLK_PERIOD;
		end loop;
		wait;
	end process;
    
    end architecture;
    
