From 3c4a0f5e68672486a53b242cec7267cf83e59f1d Mon Sep 17 00:00:00 2001 From: Daniel van der Schuur <schuur@astron.nl> Date: Wed, 12 Oct 2016 13:27:00 +0000 Subject: [PATCH] -Added counters; -Added tb_end output; -Removed clk input; -Added statistics check @ tb_end; -Added timeout. --- libraries/io/eth/src/vhdl/eth_statistics.vhd | 146 ++++++++++++------- 1 file changed, 97 insertions(+), 49 deletions(-) diff --git a/libraries/io/eth/src/vhdl/eth_statistics.vhd b/libraries/io/eth/src/vhdl/eth_statistics.vhd index 39c93d010c..1e350b7cd3 100644 --- a/libraries/io/eth/src/vhdl/eth_statistics.vhd +++ b/libraries/io/eth/src/vhdl/eth_statistics.vhd @@ -22,15 +22,7 @@ -- Author: -- . Daniel van der Schuur -- Purpose: --- . Provide Ethernet statistics from serial input --- Description: --- . The packets on the serial input are disassembled (header stripped) and --- the following statistics are provided: --- . Entity outputs: --- . Packet count --- . Packet length --- . Transcript window output: --- . Packet header field names&values +-- . Provide a generic Ethernet output checking stage for simulation. LIBRARY IEEE, common_lib, work, technology_lib, dp_lib, tech_tse_lib; USE IEEE.STD_LOGIC_1164.ALL; @@ -43,22 +35,52 @@ USE tech_tse_lib.tech_tse_pkg.ALL; USE technology_lib.technology_select_pkg.ALL; ENTITY eth_statistics IS + GENERIC ( + g_runtime_nof_packets : NATURAL; -- Run the test bench for nof_packets before asserting tb_end + g_runtime_timeout : TIME; -- Report Failure if g_runtime_nof_packets is not reached before this time + g_check_nof_valid : BOOLEAN := FALSE; -- True enables valid count checking at tb_end. Reports Failure in case of mismatch. + g_check_nof_valid_ref : NATURAL := 0 -- . Specify reference valid count here + ); PORT ( - eth_clk : IN STD_LOGIC; eth_serial_in : IN STD_LOGIC; - - pkt_cnt : OUT NATURAL; - pkt_len : OUT NATURAL + tb_end : OUT STD_LOGIC -- To be used to stop test-bench generated clocks ); END eth_statistics; ARCHITECTURE str OF eth_statistics IS - SIGNAL tech_tse_rx_src_out : t_dp_sosi; + CONSTANT c_eth_clk_freq_mhz : NATURAL := 125; + CONSTANT c_eth_word_w : NATURAL := 32; + CONSTANT c_eth_clk_period : TIME := 8 ns; + + SIGNAL eth_clk : STD_LOGIC := '0'; + SIGNAL eth_rst : STD_LOGIC; + + SIGNAL tech_tse_rx_src_out : t_dp_sosi; + + SIGNAL packet_count : NATURAL := 0; + SIGNAL valid_count : NATURAL := 0; + SIGNAL cycle_count : NATURAL := 0; + SIGNAL i_tb_end : STD_LOGIC; + SIGNAL timeout : STD_LOGIC; + + SIGNAL nxt_packet_count : NATURAL := 0; + SIGNAL nxt_valid_count : NATURAL := 0; + SIGNAL nxt_cycle_count : NATURAL := 0; + SIGNAL nxt_tb_end : STD_LOGIC; + + SIGNAL data_rate_mbps : NATURAL; -- Data rate in Mbps (natural is only 32b so bps is not possible). BEGIN + ------------------------------------------------------------------------------ + -- We're generating a clock locally; it happens to be in sync with the 125Mz + -- transmitter clock that is generated from 25MHz by a PLL. + ------------------------------------------------------------------------------ + eth_clk <= NOT eth_clk OR i_tb_end AFTER c_eth_clk_period/2; + eth_rst <= '1', '0' AFTER c_eth_clk_period*8; + ------------------------------------------------------------------------------ -- Use tech_tse with internal simulation model as Ethernet receiver ------------------------------------------------------------------------------ @@ -92,42 +114,68 @@ BEGIN ); ------------------------------------------------------------------------------ - -- Use 2 BSN monitors: - -- . Monitor A captures the number of SOPs per test interval; - -- . Monitor B captures the number of valid words per packet. + -- Counters ------------------------------------------------------------------------------ --- u_mon : ENTITY work.dp_bsn_monitor --- GENERIC MAP ( --- g_sync_timeout => g_sync_timeout, --- g_error_bi => g_error_bi, --- g_log_first_bsn => g_log_first_bsn --- ) --- PORT MAP ( --- rst => dp_rst, --- clk => dp_clk, --- --- -- ST interface --- in_siso => in_siso_arr(i), --- in_sosi => in_sosi_arr(i), --- sync_in => sync_in, --- --- -- MM interface --- -- . control --- mon_evt => mon_evt_arr(i), --- mon_sync => OPEN, --- mon_sync_timeout => mon_sync_timeout_arr(i), --- -- . siso --- mon_ready_stable => mon_ready_stable_arr(i), --- mon_xon_stable => mon_xon_stable_arr(i), --- -- . sosi --- mon_bsn_at_sync => mon_bsn_at_sync_arr(i), --- mon_nof_sop => mon_nof_sop_arr(i), --- mon_nof_err => mon_nof_err_arr(i), --- mon_nof_valid => mon_nof_valid_arr(i), --- --- mon_bsn_first => mon_bsn_first_arr(i), --- mon_bsn_first_cycle_cnt => mon_bsn_first_cycle_cnt_arr(i) --- ); + nxt_packet_count <= packet_count+1 WHEN tech_tse_rx_src_out.sop='1' ELSE packet_count; + nxt_valid_count <= valid_count+1 WHEN tech_tse_rx_src_out.valid='1'ELSE valid_count; + nxt_cycle_count <= cycle_count+1 WHEN packet_count>0 OR (packet_count=0 AND tech_tse_rx_src_out.sop='1') ELSE cycle_count; + + ------------------------------------------------------------------------------ + -- Assert timeout after user specified time + -- . Note: Using AFTER [time] results in the simulation actually running up to + -- the runtime. This is okay as tb_end='1' makes sure no signals are + -- changing anymore so this does not take extra sim time. + ------------------------------------------------------------------------------ + timeout <= '0', '1' AFTER g_runtime_timeout; + ------------------------------------------------------------------------------ + -- Assert tb_end if we've seen g_runtime_nof_packets packets + ------------------------------------------------------------------------------ + nxt_tb_end <= '1' WHEN packet_count>g_runtime_nof_packets OR (packet_count=g_runtime_nof_packets AND tech_tse_rx_src_out.sop='1') ELSE '0'; + tb_end <= i_tb_end; + + ------------------------------------------------------------------------------ + -- Derive some interesting statistics + ------------------------------------------------------------------------------ + p_tb_end_calc: PROCESS(nxt_tb_end, timeout) + BEGIN + IF nxt_tb_end='1' AND timeout='0' THEN --Don't calc anything if a timeout occured + IF falling_edge(eth_clk) THEN + data_rate_mbps <= c_eth_clk_freq_mhz * c_eth_word_w * valid_count / cycle_count; + END IF; + END IF; + END PROCESS; + + ------------------------------------------------------------------------------ + -- On tb_end; do the checks defined in the generics + ------------------------------------------------------------------------------ + p_tb_end_check: PROCESS(nxt_tb_end, timeout) + BEGIN + IF timeout='1' AND nxt_tb_end='0' THEN + REPORT "[eth_statistics] Timeout occured!" SEVERITY FAILURE; + ELSIF nxt_tb_end='1' THEN + IF falling_edge(eth_clk) THEN + IF (g_check_nof_valid=TRUE AND valid_count/=g_check_nof_valid_ref) THEN REPORT "[eth_statistics] Valid count does not match reference" SEVERITY FAILURE; END IF; + END IF; + END IF; + END PROCESS; + + ------------------------------------------------------------------------------ + -- Registers + ------------------------------------------------------------------------------ + p_eth_clk: PROCESS(eth_clk, eth_rst) + BEGIN + IF eth_rst='1' THEN + packet_count <= 0; + valid_count <= 0; + cycle_count <= 0; + i_tb_end <= '0'; + ELSIF(rising_edge(eth_clk)) THEN + packet_count <= nxt_packet_count; + valid_count <= nxt_valid_count; + cycle_count <= nxt_cycle_count; + i_tb_end <= nxt_tb_end; + END IF; + END PROCESS; END str; -- GitLab