bench: Move HWITL tests to own top level / test bench file
This commit is contained in:
parent
82d4e6808b
commit
fd721ae24f
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,3 +9,4 @@ cocotb/sim_build
|
||||
cocotb/wave.ghw
|
||||
|
||||
cocotb/cocotb_top_mac_test
|
||||
cocotb/cocotb_top_hwitl
|
||||
|
77
cocotb/cocotb_top_hwitl.vhd
Normal file
77
cocotb/cocotb_top_hwitl.vhd
Normal file
@ -0,0 +1,77 @@
|
||||
-- -------------------------------------------------------------------------- --
|
||||
-- TRASHERNET - A Trashy Ethernet Stack for FPGAs --
|
||||
-- -------------------------------------------------------------------------- --
|
||||
-- cocotb_top_hwitl.vhd : Test bench for cocotb HW-in-the-loop tests
|
||||
-- -------------------------------------------------------------------------- --
|
||||
-- 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;
|
||||
|
||||
entity cocotb_top_hwitl is
|
||||
end entity cocotb_top_hwitl;
|
||||
|
||||
architecture bench of cocotb_top_hwitl is
|
||||
-- DUT signals
|
||||
signal clk : std_logic;
|
||||
signal rst_n : std_logic;
|
||||
signal rx_p : std_logic;
|
||||
signal tx_p : std_logic;
|
||||
signal tx_n : std_logic;
|
||||
signal led_n : std_logic_vector(7 downto 0);
|
||||
signal button_n : std_logic_vector(3 downto 0);
|
||||
signal debug_data : std_logic_vector(7 downto 0);
|
||||
|
||||
-- Generic test bench
|
||||
signal bench_ready : std_logic := '0';
|
||||
begin
|
||||
top_mac_test_inst : entity top_hwitl (mac) -- TODO: I haven't managed to get configurations working with cocotb yet, so changing this line changes the test case :(
|
||||
port map(
|
||||
clk => clk,
|
||||
rst_n => rst_n,
|
||||
rx_p => rx_p,
|
||||
tx_p => tx_p,
|
||||
tx_n => tx_n,
|
||||
led_n => led_n,
|
||||
button_n => button_n,
|
||||
debug_data => debug_data
|
||||
);
|
||||
|
||||
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;
|
||||
|
||||
rstsim : process is
|
||||
begin
|
||||
rst_n <= '0';
|
||||
wait for 400 ns;
|
||||
rst_n <= '1';
|
||||
wait for 100 ns;
|
||||
wait until rising_edge(clk);
|
||||
bench_ready <= '1';
|
||||
wait;
|
||||
end process rstsim;
|
||||
|
||||
cocovc_eth_inst : entity work.cocovc_eth
|
||||
port map(
|
||||
rx_p => tx_p,
|
||||
rx_n => tx_n,
|
||||
tx_p => rx_p,
|
||||
tx_n => open
|
||||
);
|
||||
|
||||
button_n <= (others => '1');
|
||||
|
||||
end architecture bench;
|
@ -2,4 +2,4 @@
|
||||
|
||||
echo Hardware in the loop test
|
||||
|
||||
make TOPLEVEL=cocotb_top_mac_test MODULE=hw_itl
|
||||
make TOPLEVEL=cocotb_top_hwitl MODULE=hw_itl
|
||||
|
205
design/top_hwitl.vhd
Normal file
205
design/top_hwitl.vhd
Normal file
@ -0,0 +1,205 @@
|
||||
-- -------------------------------------------------------------------------- --
|
||||
-- TRASHERNET - A Trashy Ethernet Stack for FPGAs --
|
||||
-- -------------------------------------------------------------------------- --
|
||||
-- top_hwitl.vhd: Top level design for hardware-in-the-loop tests
|
||||
--
|
||||
-- Target: Simulation
|
||||
-- -------------------------------------------------------------------------- --
|
||||
-- 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;
|
||||
|
||||
use ieee.math_real.all;
|
||||
|
||||
library trashernet;
|
||||
use trashernet.trashernet_pkg.all;
|
||||
|
||||
entity top_hwitl is
|
||||
port(
|
||||
clk : in std_logic;
|
||||
rst_n : in std_logic;
|
||||
rx_p : in std_logic;
|
||||
tx_p : out std_logic;
|
||||
tx_n : out std_logic;
|
||||
led_n : out std_logic_vector(7 downto 0);
|
||||
button_n : in std_logic_vector(3 downto 0);
|
||||
debug_data : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end entity top_hwitl;
|
||||
|
||||
architecture mac of top_hwitl is
|
||||
component pll0
|
||||
port(
|
||||
CLK : in std_logic;
|
||||
CLKOP : out std_logic;
|
||||
LOCK : out std_logic
|
||||
);
|
||||
end component pll0;
|
||||
|
||||
constant F_CLK : integer := 50000000;
|
||||
constant F_CLK_PHY : integer := 140000000;
|
||||
|
||||
constant LED_BLINK : boolean_vector(led_n'range) := (
|
||||
6 downto 2 => true,
|
||||
others => false
|
||||
);
|
||||
|
||||
constant ETH_CONFIG : configuration_t := (
|
||||
mac_address => (x"00", x"ff", x"ff", x"11", x"22", x"33")
|
||||
);
|
||||
|
||||
signal rst : std_logic;
|
||||
signal clk_phy : std_logic;
|
||||
signal phy_pll_lock : std_logic;
|
||||
|
||||
signal led_sig : std_logic_vector(led_n'range);
|
||||
|
||||
signal phy_out : phy_out_t;
|
||||
signal phy_in : phy_in_t;
|
||||
|
||||
signal mac_out : mac_out_t;
|
||||
signal mac_in : mac_in_t;
|
||||
|
||||
type status_t is (IDLE, TX);
|
||||
signal state : status_t;
|
||||
constant BYTE_CNT_MAX : integer := 100;
|
||||
signal byte_cnt : integer range 0 to BYTE_CNT_MAX;
|
||||
|
||||
signal button_n_sync : std_logic_vector(button_n'range);
|
||||
signal button : std_logic_vector(button_n'range);
|
||||
|
||||
constant TMO_MAX : integer := integer(round((real(F_CLK) * 0.25))) - 1;
|
||||
signal tmo : integer range 0 to TMO_MAX;
|
||||
begin
|
||||
trashernet_mac_inst : entity trashernet.trashernet_mac
|
||||
port map(
|
||||
clk => clk,
|
||||
rst => rst,
|
||||
phy_out => phy_out,
|
||||
phy_in => phy_in,
|
||||
mac_out => mac_out,
|
||||
mac_in => mac_in
|
||||
);
|
||||
|
||||
pll0_inst : pll0
|
||||
port map(
|
||||
CLK => clk,
|
||||
CLKOP => clk_phy,
|
||||
LOCK => phy_pll_lock
|
||||
);
|
||||
|
||||
trashernet_phy_cdc_inst : entity trashernet.trashernet_phy_cdc
|
||||
generic map(
|
||||
F_CLK => F_CLK,
|
||||
F_CLK_PHY => F_CLK_PHY
|
||||
)
|
||||
port map(
|
||||
clk => clk,
|
||||
phy_clk => clk_phy,
|
||||
rst => rst,
|
||||
phy_out => phy_out,
|
||||
phy_in => phy_in,
|
||||
rx_p => rx_p,
|
||||
tx_p => tx_p,
|
||||
tx_n => tx_n
|
||||
);
|
||||
|
||||
reset_sync : process(clk, rst_n) is
|
||||
begin
|
||||
if (rst_n = '0') then
|
||||
rst <= '1';
|
||||
elsif (rising_edge(clk)) then
|
||||
rst <= '0';
|
||||
end if;
|
||||
end process reset_sync;
|
||||
|
||||
ledcon_inst : entity work.ledcon
|
||||
generic map(
|
||||
F_CLK => F_CLK,
|
||||
BLINK => LED_BLINK
|
||||
)
|
||||
port map(
|
||||
clk => clk,
|
||||
rst => rst,
|
||||
sig => led_sig,
|
||||
led_n => led_n
|
||||
);
|
||||
|
||||
led_sig <= (
|
||||
0 => phy_pll_lock,
|
||||
1 => phy_out.carrier_detect,
|
||||
2 => phy_out.rx_active,
|
||||
3 => phy_out.rx_error,
|
||||
4 => mac_out.rx_mac_crc_ok,
|
||||
5 => mac_out.rx_mac_crc_error,
|
||||
6 => mac_out.tx_active,
|
||||
7 => '0'
|
||||
);
|
||||
|
||||
synchronizer_inst : entity trashernet.synchronizer
|
||||
generic map(
|
||||
SIZE => 2
|
||||
)
|
||||
port map(
|
||||
clk => clk,
|
||||
rst => rst,
|
||||
data_in => button_n(0),
|
||||
data_out => button_n_sync(0)
|
||||
);
|
||||
|
||||
button <= not button_n_sync;
|
||||
|
||||
receiver : process(clk, rst) is
|
||||
begin
|
||||
if rst then
|
||||
state <= IDLE;
|
||||
mac_in.tx_mac_data_en <= '0';
|
||||
tmo <= 0;
|
||||
elsif rising_edge(clk) then
|
||||
if (tmo /= 0) then
|
||||
tmo <= tmo - 1;
|
||||
end if;
|
||||
case state is
|
||||
when IDLE =>
|
||||
if mac_out.rx_mac_crc_ok then
|
||||
if (mac_out.rx_header.mac_destination = ETH_CONFIG.mac_address) then -- Note: We won't respond to broadcasts!
|
||||
state <= TX;
|
||||
byte_cnt <= BYTE_CNT_MAX;
|
||||
mac_in.tx_header.mac_destination <= mac_out.rx_header.mac_source;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if (tmo = 0) or (button(0) = '1') then
|
||||
state <= TX;
|
||||
byte_cnt <= BYTE_CNT_MAX;
|
||||
mac_in.tx_header.mac_destination <= (others => x"FF");
|
||||
end if;
|
||||
when TX =>
|
||||
tmo <= TMO_MAX;
|
||||
mac_in.tx_header.mac_ethertype <= (x"00", std_logic_vector(to_unsigned(BYTE_CNT_MAX, 8)));
|
||||
mac_in.tx_mac_data_en <= '1';
|
||||
mac_in.tx_mac_data <= std_logic_vector(to_unsigned(byte_cnt, 8));
|
||||
if mac_out.tx_mac_data_ack then
|
||||
if byte_cnt = 1 then
|
||||
mac_in.tx_mac_data_en <= '0';
|
||||
state <= IDLE;
|
||||
else
|
||||
byte_cnt <= byte_cnt - 1;
|
||||
end if;
|
||||
end if;
|
||||
end case;
|
||||
|
||||
end if;
|
||||
end process receiver;
|
||||
|
||||
mac_in.tx_header.mac_source <= ETH_CONFIG.mac_address;
|
||||
|
||||
debug_data(0) <= tx_p;
|
||||
debug_data(1) <= tx_n;
|
||||
|
||||
end architecture mac;
|
Loading…
Reference in New Issue
Block a user