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