222 lines
4.6 KiB
VHDL
222 lines
4.6 KiB
VHDL
|
-- -------------------------------------------------------------------------- --
|
||
|
-- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs --
|
||
|
-- -------------------------------------------------------------------------- --
|
||
|
-- TODO
|
||
|
-- -------------------------------------------------------------------------- --
|
||
|
-- Author : Markus Koch <markus@notsyncing.net>
|
||
|
-- 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;
|
||
|
use std.textio.all;
|
||
|
|
||
|
library device_models;
|
||
|
|
||
|
entity bench_top_manual is
|
||
|
end entity bench_top_manual;
|
||
|
|
||
|
architecture bench of bench_top_manual is
|
||
|
constant UART_BAUD : real := 38400.0;
|
||
|
|
||
|
signal clk : std_logic;
|
||
|
signal rst_n_a : std_logic;
|
||
|
|
||
|
signal uart_txd : std_logic;
|
||
|
signal uart_rxd : std_logic;
|
||
|
|
||
|
signal psram_ce_n : std_logic;
|
||
|
signal psram_sclk : std_logic;
|
||
|
signal psram_sio : std_logic_vector(3 downto 0);
|
||
|
|
||
|
signal rx_p : std_logic := '0';
|
||
|
signal rx_n : std_logic := '1';
|
||
|
signal tx_p : std_logic_vector(3 downto 0);
|
||
|
signal tx_n : std_logic_vector(3 downto 0);
|
||
|
|
||
|
procedure print(text : string) is
|
||
|
variable lb : line;
|
||
|
begin
|
||
|
write(lb, text);
|
||
|
writeline(output, lb);
|
||
|
end procedure print;
|
||
|
|
||
|
procedure print(text : character) is
|
||
|
variable lb : line;
|
||
|
begin
|
||
|
write(lb, text);
|
||
|
write(output, lb.all);
|
||
|
flush(output);
|
||
|
end procedure print;
|
||
|
begin
|
||
|
clock_driver : process
|
||
|
constant period : time := 1 sec / 48000000;
|
||
|
begin
|
||
|
clk <= '0';
|
||
|
wait for period / 2;
|
||
|
clk <= '1';
|
||
|
wait for period / 2;
|
||
|
end process clock_driver;
|
||
|
|
||
|
reset_gen : process is
|
||
|
begin
|
||
|
rst_n_a <= '0';
|
||
|
wait for 40 ns;
|
||
|
rst_n_a <= '1';
|
||
|
wait;
|
||
|
end process reset_gen;
|
||
|
|
||
|
top_inst : entity design.top
|
||
|
port map(
|
||
|
clk_12m => clk,
|
||
|
uart_tx => uart_txd,
|
||
|
uart_rx => uart_rxd,
|
||
|
eth_rx_p => rx_p,
|
||
|
eth_rx_n => rx_n,
|
||
|
eth_tx_p => tx_p,
|
||
|
eth_tx_n => tx_n,
|
||
|
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
|
||
|
);
|
||
|
|
||
|
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_txd);
|
||
|
wait for 0.5 * DELAY;
|
||
|
for i in 0 to 7 loop
|
||
|
wait for DELAY;
|
||
|
d(i) := uart_txd;
|
||
|
end loop;
|
||
|
wait for 1.0 * DELAY;
|
||
|
print(character'val(to_integer(unsigned(d))));
|
||
|
end process uart_decoder;
|
||
|
|
||
|
loader : process is
|
||
|
procedure uart_tx(d : std_logic_vector(7 downto 0)) is
|
||
|
constant DELAY : time := (1 sec / UART_BAUD);
|
||
|
begin
|
||
|
uart_rxd <= '0';
|
||
|
wait for DELAY;
|
||
|
for i in d'low to d'high loop
|
||
|
uart_rxd <= d(i);
|
||
|
wait for DELAY;
|
||
|
end loop;
|
||
|
uart_rxd <= '1';
|
||
|
wait for DELAY;
|
||
|
end procedure uart_tx;
|
||
|
|
||
|
begin
|
||
|
uart_rxd <= '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");
|
||
|
|
||
|
print("RX Data: ");
|
||
|
wait for (1 sec / UART_BAUD) * 10 * 5;
|
||
|
print("");
|
||
|
|
||
|
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");
|
||
|
|
||
|
print("RX Data: ");
|
||
|
wait for (1 sec / UART_BAUD) * 10 * 5;
|
||
|
print("");
|
||
|
|
||
|
wait for 400 us;
|
||
|
|
||
|
report "Done.";
|
||
|
|
||
|
std.env.stop;
|
||
|
wait;
|
||
|
|
||
|
end process loader;
|
||
|
|
||
|
end architecture bench;
|
||
|
|
||
|
-- Commands to test on real HW
|
||
|
-- ---------------------------
|
||
|
-- Dump boot ROM : 02 00 00 00 00 00 00 00 FF
|
||
|
-- Write four bytes to RAM : 01 40 00 00 00 00 00 00 04 01 02 03 04
|
||
|
-- Dump these four bytes : 02 40 00 00 00 00 00 00 04
|