-- -------------------------------------------------------------------------- -- -- 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; use std.textio.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; library osvvm; context osvvm.osvvmContext; use osvvm.ScoreboardPkg_slv.all; entity bench_top_neorv32_wb is generic( runner_cfg : string := runner_cfg_default ); end entity bench_top_neorv32_wb; architecture RTL of bench_top_neorv32_wb is constant UART_BAUD : integer := 250000; signal clk_in : std_logic; signal uart_tx : std_logic; signal uart_rx : std_logic; signal eth_rx_p : std_logic; signal eth_tx_p : std_logic_vector(3 downto 0); signal eth_tx_n : std_logic_vector(3 downto 0); signal eth_led_green_n : std_logic; signal eth_led_orange_n : std_logic; signal led_user : std_logic; signal psram_ce_n : std_logic; signal psram_sclk : std_logic; signal psram_sio : std_logic_vector(3 downto 0); signal flash_ce_n : std_logic; signal flash_sclk : std_logic; signal flash_sio : std_logic_vector(3 downto 0); signal pmod : std_logic_vector(7 downto 0); signal SB : ScoreboardIDType; begin top_inst : entity design.top generic map( F_IN => 50000000, F_CLK => 25000000, F_CLK_PHY => 50000000, UART_BAUD => UART_BAUD, CPU => "neorv32" ) port map( clk_in => clk_in, uart_tx => uart_tx, uart_rx => uart_rx, eth_rx_p => eth_rx_p, eth_tx_p => eth_tx_p, eth_tx_n => eth_tx_n, eth_led_green_n => eth_led_green_n, eth_led_orange_n => eth_led_orange_n, led_user => led_user, psram_ce_n => psram_ce_n, psram_sclk => psram_sclk, psram_sio => psram_sio, flash_ce_n => flash_ce_n, flash_sclk => flash_sclk, flash_sio => flash_sio, pmod => pmod ); aps6404l_inst : entity device_models.aps6404l generic map( LOG_EN => false ) port map( ce_n => psram_ce_n, sclk => psram_sclk, sio => psram_sio ); uart_decoder : process is constant DELAY : time := (1 sec / UART_BAUD); variable d : std_logic_vector(7 downto 0); begin wait until falling_edge(uart_tx); wait for 0.5 * DELAY; for i in 0 to 7 loop wait for DELAY; d(i) := uart_tx; end loop; wait for 1.0 * DELAY; Check(SB, d); end process uart_decoder; test : process is procedure uart_tx(d : std_logic_vector(7 downto 0)) is constant DELAY : time := (1 sec / UART_BAUD); begin uart_rx <= '0'; wait for DELAY; for i in d'low to d'high loop uart_rx <= d(i); wait for DELAY; end loop; uart_rx <= '1'; wait for DELAY; end procedure uart_tx; begin test_runner_setup(runner, runner_cfg); SB <= NewID("UART RX"); report "Waiting for internal reset to be complete..."; wait for 10 us; report "Starting tests..."; while test_suite loop if run("bootloader") then uart_rx <= '1'; wait for (1 sec / UART_BAUD) * 10; report ("Writing ABCD+jalr0 to RAM..."); -- WRITE uart_tx(x"01"); -- to RAM uart_tx(x"40"); uart_tx(x"00"); uart_tx(x"00"); uart_tx(x"00"); -- 8 bytes uart_tx(x"00"); uart_tx(x"00"); uart_tx(x"00"); uart_tx(x"08"); -- with this data ("ABCD", jalr zero) uart_tx(x"41"); uart_tx(x"42"); uart_tx(x"43"); uart_tx(x"44"); uart_tx(x"e7"); uart_tx(x"00"); uart_tx(x"00"); uart_tx(x"00"); report ("Reading back from RAM..."); -- READ uart_tx(x"02"); -- from RAM uart_tx(x"40"); uart_tx(x"00"); uart_tx(x"00"); uart_tx(x"00"); -- 4 bytes ("ABCD") uart_tx(x"00"); uart_tx(x"00"); uart_tx(x"00"); uart_tx(x"04"); Push(SB, x"41"); Push(SB, x"42"); Push(SB, x"43"); Push(SB, x"44"); wait for (1 sec / UART_BAUD) * 10 * 5; report ("Jumping to RAM+4..."); -- JUMP uart_tx(x"03"); -- to RAM (+4, jalr zero) uart_tx(x"40"); uart_tx(x"00"); uart_tx(x"00"); uart_tx(x"04"); -- The program will jump back to the loader, so we should be able to read again wait for 100 us; report ("Reading from RAM again..."); -- READ uart_tx(x"02"); -- from RAM uart_tx(x"40"); uart_tx(x"00"); uart_tx(x"00"); uart_tx(x"00"); -- 4 bytes uart_tx(x"00"); uart_tx(x"00"); uart_tx(x"00"); uart_tx(x"04"); Push(SB, x"41"); Push(SB, x"42"); Push(SB, x"43"); Push(SB, x"44"); wait for (1 sec / UART_BAUD) * 10 * 5; assert ScoreboardEmpty(SB) report "UART RX Scoreboard not empty at end of test!" severity error; end if; end loop; test_runner_cleanup(runner); end process test; test_runner_watchdog(runner, 50 ms); clock_driver : process constant period : time := 20 ns; begin clk_in <= '0'; wait for period / 2; clk_in <= '1'; wait for period - (period / 2); end process clock_driver; end architecture RTL;