-- -------------------------------------------------------------------------- -- -- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs -- -- -------------------------------------------------------------------------- -- -- VUnit test bench for the aps6404l Wishbone IF -- -------------------------------------------------------------------------- -- -- Author : Markus Koch -- Contributors : None -- License : Mozilla Public License (MPL) Version 2 -- -------------------------------------------------------------------------- -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library design; use design.all; library generics; use generics.wishbone_pkg.all; library device_models; use device_models.all; library vunit_lib; context vunit_lib.vunit_context; entity bench_aps6404l_wb is generic( runner_cfg : string := runner_cfg_default ); end entity bench_aps6404l_wb; architecture RTL of bench_aps6404l_wb is signal wbi_o : wishbone_slave_out; signal wbi_i : wishbone_slave_in; signal wb_o : wishbone_slave_out; signal wb_i : wishbone_slave_in; signal clk : std_logic; signal rst : std_logic; signal psram_ce_n : std_logic; signal psram_sclk : std_logic; signal psram_sio : std_logic_vector(3 downto 0); begin aps6404l_wb_inst : entity design.aps6404l_wb port map( clk => clk, rst => rst, wbi_o => wbi_o, wbi_i => wbi_i, wb_o => wb_o, wb_i => wb_i, psram_ce_n => psram_ce_n, psram_sclk => psram_sclk, psram_sio => psram_sio ); aps6404l_inst : entity device_models.aps6404l port map( ce_n => psram_ce_n, sclk => psram_sclk, sio => psram_sio ); test : process is procedure bus_write( signal master_o : out wishbone_master_out; signal master_i : in wishbone_master_in; constant address : in wishbone_address; constant data : in wishbone_data ) is begin info("Writing to address 0x" & to_hstring(address)); master_o.we <= '1'; master_o.adr <= address; master_o.dat <= data; master_o.sel <= (others => '1'); master_o.cyc <= '1'; master_o.stb <= '1'; loop wait until rising_edge(clk); exit when master_i.ack = '1'; end loop; master_o.cyc <= '0'; master_o.stb <= '0'; end procedure bus_write; procedure bus_read( signal master_o : out wishbone_master_out; signal master_i : in wishbone_master_in; constant address : in wishbone_address; variable data : out wishbone_data ) is begin info("Reading from address 0x" & to_hstring(address)); master_o.we <= '0'; master_o.adr <= address; master_o.sel <= (others => '1'); master_o.cyc <= '1'; master_o.stb <= '1'; loop wait until rising_edge(clk); exit when master_i.ack = '1'; end loop; data := master_i.dat; master_o.cyc <= '0'; master_o.stb <= '0'; end procedure bus_read; procedure readcheck(signal master_o : out wishbone_master_out; signal master_i : in wishbone_master_in; constant address : in wishbone_address; constant expected : in wishbone_data) is variable data : wishbone_data; variable time_start : time; begin time_start := now; bus_read(wbi_i, wbi_o, address, data); info("Read data: 0x" & to_hstring(data) & " after " & time'image(now - time_start)); check(data = expected, "Data readback incorrect."); end procedure readcheck; variable data : wishbone_data; begin test_runner_setup(runner, runner_cfg); wbi_i.sel <= (others => '1'); wbi_i.cyc <= '0'; wbi_i.stb <= '0'; wb_i.cyc <= '0'; wb_i.stb <= '0'; while test_suite loop info("Resetting DUT"); rst <= '1'; wait for 30 ns; rst <= '0'; if run("data") then bus_write(wb_i, wb_o, x"00000000", x"12345678"); bus_read(wb_i, wb_o, x"00000000", data); info("Read data: 0x" & to_hstring(data)); check(data = x"12345678", "Data readback incorrect."); wait for 500 ns; elsif run("instruction") then bus_write(wb_i, wb_o, x"00000000", x"11223344"); bus_write(wb_i, wb_o, x"00000004", x"55667788"); bus_write(wb_i, wb_o, x"00000008", x"99aabbcc"); bus_write(wb_i, wb_o, x"0000000c", x"ddeeff00"); wait for 1 us; readcheck(wbi_i, wbi_o, x"00000000", x"11223344"); wait for 1 us; readcheck(wbi_i, wbi_o, x"00000004", x"55667788"); wait for 1 us; readcheck(wbi_i, wbi_o, x"00000008", x"99aabbcc"); wait for 1 us; readcheck(wbi_i, wbi_o, x"0000000c", x"ddeeff00"); wait for 1 us; end if; end loop; test_runner_cleanup(runner); end process test; test_runner_watchdog(runner, 1 ms); clock_driver : process constant period : time := 20 ns; begin clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2; end process clock_driver; end architecture RTL;