From b8f273c9b66e1a75b221fcf412fba09b337ab3d5 Mon Sep 17 00:00:00 2001 From: Markus Koch Date: Fri, 8 Nov 2024 16:06:04 +0100 Subject: [PATCH] fpga: bench: Add bench to run larger programs from external RAM --- fpga/hdl/bench/bench_top_zephyr.vhd | 181 ++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 fpga/hdl/bench/bench_top_zephyr.vhd diff --git a/fpga/hdl/bench/bench_top_zephyr.vhd b/fpga/hdl/bench/bench_top_zephyr.vhd new file mode 100644 index 0000000..84d37e4 --- /dev/null +++ b/fpga/hdl/bench/bench_top_zephyr.vhd @@ -0,0 +1,181 @@ +-- -------------------------------------------------------------------------- -- +-- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs -- +-- -------------------------------------------------------------------------- -- +-- Inspection-only test bench to run a larger memory image from external RAM. +-- -------------------------------------------------------------------------- -- +-- 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_zephyr is + generic( + runner_cfg : string := runner_cfg_default + ); +end entity bench_top_zephyr; + +architecture RTL of bench_top_zephyr 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); + +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( + SIZE => 8 * 1024 * 1024, + --MEMFILE => "../sw/demo/decrypt-1.vhex", + 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); + variable print_time : boolean := true; + procedure print(text : character) is + variable lb : line; + begin + write(lb, text); + write(output, lb.all); + flush(output); + end procedure print; + 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; + if print_time then + write(output, "{" & time'image(now) & "} "); + print_time := false; + end if; + print(character'val(to_integer(unsigned(d)))); + if character'val(to_integer(unsigned(d))) = LF then + print_time := true; + end if; + --report "UART RX: " & character'val(to_integer(unsigned(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); + + report "Waiting for internal reset to be complete..."; + wait for 10 us; + report "Starting tests..."; + + while test_suite loop + if run("run_program") then + uart_rx <= '1'; + wait for (1 sec / UART_BAUD) * 10; + + report ("Jumping to external RAM..."); + -- 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"00"); + + report ("This is a manual test. Add wait statement here and watch the output..."); + wait for 0 ns; + report ("Stopping test."); + end if; + end loop; + test_runner_cleanup(runner); + end process test; + + test_runner_watchdog(runner, 1000 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;