Commit 4539e36f authored by Maciej Lipinski's avatar Maciej Lipinski Committed by Grzegorz Daniluk

[streamers/review] added generic that allows to use RX-only or TX-only

streamer.

- when instantiating wr_transmission (top streamers), it is now possible
  to define that only RX or only TX or both (RX and TX) streamers are used.
  this is to save resources and still use all the other goodies added to
  the streamers and also wrpc/wr-cores (this configuration will be
  propagated to the top of board entity in the next commit. So, the
  user can still use the board (and even ref-design) and instantiate
  only reception (or tranmission) to save resources
- the statistics entity is now split into 3 entities (top, rx, tx)
parent aa20995c
......@@ -8,5 +8,9 @@ files = ["streamers_pkg.vhd",
"gc_escape_detector.vhd",
"dropping_buffer.vhd",
"wr_transmission_wbgen2_pkg.vhd",
"xwr_transmission.vhd",
"wr_transmission_wb.vhd"]
"xwr_transmission.vhd",
"wr_transmission_wb.vhd",
"streamers_priv_pkg.vhd",
"xtx_streamers_stats.vhd",
"xrx_streamers_stats.vhd"
]
......@@ -5,6 +5,7 @@ use work.wrcore_pkg.all;
use work.wishbone_pkg.all; -- needed for t_wishbone_slave_in, etc
package streamers_pkg is
type t_streamers_op_mode is (RX_ONLY, TX_ONLY, TX_AND_RX);
-----------------------------------------------------------------------------------------
-- Transmission parameters (tx)
-----------------------------------------------------------------------------------------
......@@ -152,6 +153,7 @@ package streamers_pkg is
component xrtx_streamers_stats is
generic (
g_streamers_op_mode : t_streamers_op_mode := TX_AND_RX;
g_cnt_width : integer := 32;
g_acc_width : integer := 64
);
......@@ -192,6 +194,7 @@ package streamers_pkg is
component xwr_transmission is
generic (
g_streamers_op_mode : t_streamers_op_mode := TX_AND_RX;
--tx/rx
g_tx_streamer_params : t_tx_streamer_params := c_tx_streamer_params_defaut;
g_rx_streamer_params : t_rx_streamer_params := c_rx_streamer_params_defaut;
......
-------------------------------------------------------------------------------
-- Title : WR Streamers Private Packages
-- Project : WR Streamers
-------------------------------------------------------------------------------
-- File : streamers_priv_pkg.vhd
-- Author : Maciej Lipinski
-- Company : CERN
-- Platform : FPGA-generics
-- Standard : VHDL
-- Created : 2017-04-20
-------------------------------------------------------------------------------
-- Description:
-- Private package of streamers: all the components/functions used only by
-- streamers, not useful by users/applications
-------------------------------------------------------------------------------
--
-- Copyright (c) 2017 CERN/BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.wishbone_pkg.all; -- needed for t_wishbone_slave_in, etc
package streamers_priv_pkg is
component xtx_streamers_stats is
generic (
g_cnt_width : integer := 32);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
sent_frame_i : in std_logic;
reset_stats_i : in std_logic;
snapshot_ena_i : in std_logic := '0';
sent_frame_cnt_o : out std_logic_vector(g_cnt_width-1 downto 0));
end component;
component xrx_streamers_stats is
generic (
g_cnt_width : integer := 32;
g_acc_width : integer := 64);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
rcvd_frame_i : in std_logic;
lost_block_i : in std_logic;
lost_frame_i : in std_logic;
lost_frames_cnt_i : in std_logic_vector(14 downto 0);
rcvd_latency_i : in std_logic_vector(27 downto 0);
rcvd_latency_valid_i : in std_logic;
tm_time_valid_i : in std_logic;
snapshot_ena_i : in std_logic := '0';
reset_stats_i : in std_logic;
rcvd_frame_cnt_o : out std_logic_vector(g_cnt_width-1 downto 0);
lost_frame_cnt_o : out std_logic_vector(g_cnt_width-1 downto 0);
lost_block_cnt_o : out std_logic_vector(g_cnt_width-1 downto 0);
latency_cnt_o : out std_logic_vector(g_cnt_width-1 downto 0);
latency_acc_overflow_o : out std_logic;
latency_acc_o : out std_logic_vector(g_acc_width-1 downto 0);
latency_max_o : out std_logic_vector(27 downto 0);
latency_min_o : out std_logic_vector(27 downto 0));
end component;
end streamers_priv_pkg;
\ No newline at end of file
......@@ -47,11 +47,15 @@ use work.wishbone_pkg.all; -- needed for t_wishbone_slave_in, etc
use work.streamers_pkg.all; -- needed for streamers
use work.wr_fabric_pkg.all; -- neede for :t_wrf_source_in, etc
use work.wrcore_pkg.all; -- needed for t_generic_word_array
-- use work.wr_transmission_wbgen2_pkg.all;
use work.streamers_priv_pkg.all;
entity xrtx_streamers_stats is
generic (
-- Indicates whether this module instantiates both streamers (rx and tx) or only one
-- of them. An application that only receives or only transmits might want to use
-- RX_ONLY or TX_ONLY mode to save resources.
g_streamers_op_mode : t_streamers_op_mode := TX_AND_RX;
-- Width of frame counters
g_cnt_width : integer := 32; -- minimum 15 bits, max 32
g_acc_width : integer := 64 -- max value 64
......@@ -98,7 +102,7 @@ entity xrtx_streamers_stats is
);
end xrtx_streamers_stats;
architecture rtl of xrtx_streamers_stats is
component pulse_stamper
......@@ -216,69 +220,6 @@ begin
reset_time_tai_o <= reset_time_tai;
reset_time_cycles_o <= reset_time_cycles;
-------------------------------------------------------------------------------------------
-- frame/block statistics, i.e. lost, sent, received
-------------------------------------------------------------------------------------------
-- process that counts stuff: receved/send/lost frames
p_cnts: process(clk_i)
begin
if rising_edge(clk_i) then
if (rst_n_i = '0' or reset_stats = '1') then
sent_frame_cnt <= (others => '0');
rcvd_frame_cnt <= (others => '0');
lost_frame_cnt <= (others => '0');
lost_block_cnt <= (others => '0');
else
-- count sent frames
if(sent_frame_i = '1') then
sent_frame_cnt <= sent_frame_cnt + 1;
end if;
-- count received frames
if(rcvd_frame_i = '1') then
rcvd_frame_cnt <= rcvd_frame_cnt + 1;
end if;
-- count lost frames
if(lost_frame_i = '1') then
lost_frame_cnt <= lost_frame_cnt + resize(unsigned(lost_frames_cnt_i),lost_frame_cnt'length);
end if;
-- count lost blocks
if(lost_block_i = '1') then
lost_block_cnt <= lost_block_cnt + 1;
end if;
end if;
end if;
end process;
-------------------------------------------------------------------------------------------
-- latency statistics
-------------------------------------------------------------------------------------------
p_latency_stats: process(clk_i)
begin
if rising_edge(clk_i) then
if (rst_n_i = '0' or reset_stats = '1') then
latency_max <= (others => '0');
latency_min <= (others => '1');
latency_acc <= (others => '0');
latency_cnt <= (others => '0');
latency_acc_overflow <= '0';
else
if(rcvd_latency_valid_i = '1' and tm_time_valid_i = '1') then
if(latency_max < rcvd_latency_i) then
latency_max <= rcvd_latency_i;
end if;
if(latency_min > rcvd_latency_i) then
latency_min <= rcvd_latency_i;
end if;
if(latency_acc(g_acc_width) ='1') then
latency_acc_overflow <= '1';
end if;
latency_cnt <= latency_cnt + 1;
latency_acc <= latency_acc + resize(unsigned(rcvd_latency_i),latency_acc'length);
end if;
end if;
end if;
end process;
-------------------------------------------------------------------------------------------
-- snapshot
-------------------------------------------------------------------------------------------
......@@ -288,61 +229,61 @@ begin
-------------------------------------------------------------------------------------------
snapshot_ena <= snapshot_ena_i or snapshot_remote_ena;
-- snapshot
p_stats_snapshot: process(clk_i)
begin
if rising_edge(clk_i) then
if (rst_n_i = '0') then
snapshot_ena_d1 <= '0';
sent_frame_cnt_d1 <= (others=>'0');
rcvd_frame_cnt_d1 <= (others=>'0');
lost_frame_cnt_d1 <= (others=>'0');
lost_block_cnt_d1 <= (others=>'0');
latency_cnt_d1 <= (others=>'0');
latency_max_d1 <= (others=>'0');
latency_min_d1 <= (others=>'0');
latency_acc_d1 <= (others=>'0');
latency_acc_overflow_d1 <= '0';
else
if(snapshot_ena = '1' and snapshot_ena_d1 = '0') then
sent_frame_cnt_d1 <= sent_frame_cnt;
rcvd_frame_cnt_d1 <= rcvd_frame_cnt;
lost_frame_cnt_d1 <= lost_frame_cnt;
lost_block_cnt_d1 <= lost_block_cnt;
latency_cnt_d1 <= latency_cnt;
latency_max_d1 <= latency_max;
latency_min_d1 <= latency_min;
latency_acc_d1 <= latency_acc;
latency_acc_overflow_d1 <= latency_acc_overflow;
end if;
snapshot_ena_d1 <= snapshot_ena;
end if;
end if;
end process;
-------------------------------------------------------------------------------------------
-- snapshot or current value
-------------------------------------------------------------------------------------------
sent_frame_cnt_out <= std_logic_vector(sent_frame_cnt_d1) when (snapshot_ena_d1 = '1') else
std_logic_vector(sent_frame_cnt);
rcvd_frame_cnt_out <= std_logic_vector(rcvd_frame_cnt_d1) when (snapshot_ena_d1 = '1') else
std_logic_vector(rcvd_frame_cnt);
lost_frame_cnt_out <= std_logic_vector(lost_frame_cnt_d1) when (snapshot_ena_d1 = '1') else
std_logic_vector(lost_frame_cnt);
lost_block_cnt_out <= std_logic_vector(lost_block_cnt_d1) when (snapshot_ena_d1 = '1') else
std_logic_vector(lost_block_cnt);
latency_max_out <= latency_max_d1 when (snapshot_ena_d1 = '1') else
latency_max;
latency_min_out <= latency_min_d1 when (snapshot_ena_d1 = '1') else
latency_min;
latency_acc_out <= std_logic_vector(latency_acc_d1(g_acc_width-1 downto 0)) when (snapshot_ena_d1 = '1') else
std_logic_vector(latency_acc(g_acc_width-1 downto 0));
latency_cnt_out <= std_logic_vector(latency_cnt_d1) when (snapshot_ena_d1 = '1') else
std_logic_vector(latency_cnt);
latency_acc_overflow_out <= latency_acc_overflow_d1 when (snapshot_ena_d1 = '1') else
latency_acc_overflow;
gen_tx_stats: if(g_streamers_op_mode=TX_ONLY OR g_streamers_op_mode=TX_AND_RX) generate
U_TX_STATS: xtx_streamers_stats
generic map (
g_cnt_width => g_cnt_width
)
port map(
clk_i => clk_i,
rst_n_i => rst_n_i,
sent_frame_i => sent_frame_i,
reset_stats_i => reset_stats,
snapshot_ena_i => snapshot_ena,
sent_frame_cnt_o => sent_frame_cnt_out);
end generate gen_tx_stats;
gen_not_tx_stats: if(g_streamers_op_mode=RX_ONLY) generate
sent_frame_cnt_out <= (others => '0');
end generate gen_not_tx_stats;
gen_rx_stats: if(g_streamers_op_mode=RX_ONLY OR g_streamers_op_mode=TX_AND_RX) generate
U_RX_STATS: xrx_streamers_stats
generic map(
g_cnt_width => g_cnt_width,
g_acc_width => g_acc_width
)
port map(
clk_i => clk_i,
rst_n_i => rst_n_i,
rcvd_frame_i => rcvd_frame_i,
lost_block_i => lost_block_i,
lost_frame_i => lost_frame_i,
lost_frames_cnt_i => lost_frames_cnt_i,
rcvd_latency_i => rcvd_latency_i,
rcvd_latency_valid_i => rcvd_latency_valid_i,
tm_time_valid_i => tm_time_valid_i,
snapshot_ena_i => snapshot_ena,
reset_stats_i => reset_stats,
rcvd_frame_cnt_o => rcvd_frame_cnt_out,
lost_frame_cnt_o => lost_frame_cnt_out,
lost_block_cnt_o => lost_block_cnt_out,
latency_cnt_o => latency_cnt_out,
latency_acc_overflow_o => latency_acc_overflow_out,
latency_acc_o => latency_acc_out,
latency_max_o => latency_max_out,
latency_min_o => latency_min_out);
end generate gen_rx_stats;
gen_not_rx_stats: if(g_streamers_op_mode=TX_ONLY) generate
rcvd_frame_cnt_out <= (others => '0');
lost_frame_cnt_out <= (others => '0');
lost_block_cnt_out <= (others => '0');
latency_cnt_out <= (others => '0');
latency_acc_overflow_out <= '0';
latency_acc_out <= (others => '0');
latency_max_out <= (others => '0');
latency_min_out <= (others => '0');
end generate gen_not_rx_stats;
-------------------------------------------------------------------------------------------
-- wishbone local output
-------------------------------------------------------------------------------------------
......
-------------------------------------------------------------------------------
-- Title : WR Recpetion Streamers statistics
-- Project : White Rabbit Streamers
-------------------------------------------------------------------------------
-- File : xrx_streamers_stats.vhd
-- Author : Maciej Lipinski
-- Company : CERN
-- Created : 2017-04-19
-- Platform : FPGA-generics
-- Standard : VHDL
-------------------------------------------------------------------------------
-- Description:
--
-------------------------------------------------------------------------------
--
-- Copyright (c) 2016 CERN/BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
---------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library work;
use work.wishbone_pkg.all; -- needed for t_wishbone_slave_in, etc
use work.streamers_pkg.all; -- needed for streamers
use work.wr_fabric_pkg.all; -- neede for :t_wrf_source_in, etc
use work.wrcore_pkg.all; -- needed for t_generic_word_array
-- use work.wr_transmission_wbgen2_pkg.all;
entity xrx_streamers_stats is
generic (
-- Width of frame counters
g_cnt_width : integer := 32; -- minimum 15 bits, max 32
g_acc_width : integer := 64 -- max value 64
);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
-- input signals from streamers
rcvd_frame_i : in std_logic;
lost_block_i : in std_logic;
lost_frame_i : in std_logic;
lost_frames_cnt_i : in std_logic_vector(14 downto 0);
rcvd_latency_i : in std_logic_vector(27 downto 0);
rcvd_latency_valid_i : in std_logic;
tm_time_valid_i : in std_logic;
snapshot_ena_i : in std_logic := '0';
reset_stats_i : in std_logic;
----------------------- statistics ----------------------------------------
-- output statistics: tx/rx counters
rcvd_frame_cnt_o : out std_logic_vector(g_cnt_width-1 downto 0);
lost_frame_cnt_o : out std_logic_vector(g_cnt_width-1 downto 0);
lost_block_cnt_o : out std_logic_vector(g_cnt_width-1 downto 0);
-- output statistics: latency
latency_cnt_o : out std_logic_vector(g_cnt_width-1 downto 0);
latency_acc_overflow_o : out std_logic;
latency_acc_o : out std_logic_vector(g_acc_width-1 downto 0);
latency_max_o : out std_logic_vector(27 downto 0);
latency_min_o : out std_logic_vector(27 downto 0)
);
end xrx_streamers_stats;
architecture rtl of xrx_streamers_stats is
signal rcvd_frame_cnt : unsigned(g_cnt_width-1 downto 0);
signal lost_frame_cnt : unsigned(g_cnt_width-1 downto 0);
signal lost_block_cnt : unsigned(g_cnt_width-1 downto 0);
signal latency_cnt : unsigned(g_cnt_width-1 downto 0);
signal latency_max : std_logic_vector(27 downto 0);
signal latency_min : std_logic_vector(27 downto 0);
signal latency_acc : unsigned(g_acc_width-1+1 downto 0);
signal latency_acc_overflow: std_logic;
-- snaphsot
signal rcvd_frame_cnt_d1 : unsigned(g_cnt_width-1 downto 0);
signal lost_frame_cnt_d1 : unsigned(g_cnt_width-1 downto 0);
signal lost_block_cnt_d1 : unsigned(g_cnt_width-1 downto 0);
signal latency_cnt_d1 : unsigned(g_cnt_width-1 downto 0);
signal latency_max_d1 : std_logic_vector(27 downto 0);
signal latency_min_d1 : std_logic_vector(27 downto 0);
signal latency_acc_d1 : unsigned(g_acc_width-1+1 downto 0);
signal latency_acc_overflow_d1: std_logic;
signal snapshot_ena_d1 : std_logic;
begin
-------------------------------------------------------------------------------------------
-- frame/block statistics, i.e. lost, sent, received
-------------------------------------------------------------------------------------------
-- process that counts stuff: receved/lost frames
p_cnts: process(clk_i)
begin
if rising_edge(clk_i) then
if (rst_n_i = '0' or reset_stats_i = '1') then
rcvd_frame_cnt <= (others => '0');
lost_frame_cnt <= (others => '0');
lost_block_cnt <= (others => '0');
else
-- count received frames
if(rcvd_frame_i = '1') then
rcvd_frame_cnt <= rcvd_frame_cnt + 1;
end if;
-- count lost frames
if(lost_frame_i = '1') then
lost_frame_cnt <= lost_frame_cnt + resize(unsigned(lost_frames_cnt_i),lost_frame_cnt'length);
end if;
-- count lost blocks
if(lost_block_i = '1') then
lost_block_cnt <= lost_block_cnt + 1;
end if;
end if;
end if;
end process;
-------------------------------------------------------------------------------------------
-- latency statistics
-------------------------------------------------------------------------------------------
p_latency_stats: process(clk_i)
begin
if rising_edge(clk_i) then
if (rst_n_i = '0' or reset_stats_i = '1') then
latency_max <= (others => '0');
latency_min <= (others => '1');
latency_acc <= (others => '0');
latency_cnt <= (others => '0');
latency_acc_overflow <= '0';
else
if(rcvd_latency_valid_i = '1' and tm_time_valid_i = '1') then
if(latency_max < rcvd_latency_i) then
latency_max <= rcvd_latency_i;
end if;
if(latency_min > rcvd_latency_i) then
latency_min <= rcvd_latency_i;
end if;
if(latency_acc(g_acc_width) ='1') then
latency_acc_overflow <= '1';
end if;
latency_cnt <= latency_cnt + 1;
latency_acc <= latency_acc + resize(unsigned(rcvd_latency_i),latency_acc'length);
end if;
end if;
end if;
end process;
-------------------------------------------------------------------------------------------
-- snapshot
-------------------------------------------------------------------------------------------
-- snapshot is used to expose to user coherent value, so that the count for accumulated
-- latency is coherent with the accumulated latency and the average can be accurately
-- calculated
-------------------------------------------------------------------------------------------
-- snapshot
p_stats_snapshot: process(clk_i)
begin
if rising_edge(clk_i) then
if (rst_n_i = '0') then
snapshot_ena_d1 <= '0';
rcvd_frame_cnt_d1 <= (others=>'0');
lost_frame_cnt_d1 <= (others=>'0');
lost_block_cnt_d1 <= (others=>'0');
latency_cnt_d1 <= (others=>'0');
latency_max_d1 <= (others=>'0');
latency_min_d1 <= (others=>'0');
latency_acc_d1 <= (others=>'0');
latency_acc_overflow_d1 <= '0';
else
if(snapshot_ena_i = '1' and snapshot_ena_d1 = '0') then
rcvd_frame_cnt_d1 <= rcvd_frame_cnt;
lost_frame_cnt_d1 <= lost_frame_cnt;
lost_block_cnt_d1 <= lost_block_cnt;
latency_cnt_d1 <= latency_cnt;
latency_max_d1 <= latency_max;
latency_min_d1 <= latency_min;
latency_acc_d1 <= latency_acc;
latency_acc_overflow_d1 <= latency_acc_overflow;
end if;
snapshot_ena_d1 <= snapshot_ena_i;
end if;
end if;
end process;
-------------------------------------------------------------------------------------------
-- snapshot or current value
-------------------------------------------------------------------------------------------
rcvd_frame_cnt_o <= std_logic_vector(rcvd_frame_cnt_d1) when (snapshot_ena_d1 = '1') else
std_logic_vector(rcvd_frame_cnt);
lost_frame_cnt_o <= std_logic_vector(lost_frame_cnt_d1) when (snapshot_ena_d1 = '1') else
std_logic_vector(lost_frame_cnt);
lost_block_cnt_o <= std_logic_vector(lost_block_cnt_d1) when (snapshot_ena_d1 = '1') else
std_logic_vector(lost_block_cnt);
latency_max_o <= latency_max_d1 when (snapshot_ena_d1 = '1') else
latency_max;
latency_min_o <= latency_min_d1 when (snapshot_ena_d1 = '1') else
latency_min;
latency_acc_o <= std_logic_vector(latency_acc_d1(g_acc_width-1 downto 0)) when (snapshot_ena_d1 = '1') else
std_logic_vector(latency_acc(g_acc_width-1 downto 0));
latency_cnt_o <= std_logic_vector(latency_cnt_d1) when (snapshot_ena_d1 = '1') else
std_logic_vector(latency_cnt);
latency_acc_overflow_o <= latency_acc_overflow_d1 when (snapshot_ena_d1 = '1') else
latency_acc_overflow;
end rtl;
\ No newline at end of file
-------------------------------------------------------------------------------
-- Title : WR tx Streamers statistics
-- Project : White Rabbit Streamers
-------------------------------------------------------------------------------
-- File : xrtx_streamers_stats.vhd
-- Author : Maciej Lipinski
-- Company : CERN
-- Created : 2017-04-19
-- Platform : FPGA-generics
-- Standard : VHDL
-------------------------------------------------------------------------------
-- Description:
--
-------------------------------------------------------------------------------
--
-- Copyright (c) 2017 CERN/BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library work;
use work.wishbone_pkg.all; -- needed for t_wishbone_slave_in, etc
use work.streamers_pkg.all; -- needed for streamers
use work.wr_fabric_pkg.all; -- neede for :t_wrf_source_in, etc
use work.wrcore_pkg.all; -- needed for t_generic_word_array
-- use work.wr_transmission_wbgen2_pkg.all;
entity xtx_streamers_stats is
generic (
-- Width of frame counters
g_cnt_width : integer := 32 -- minimum 15 bits, max 32
);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
-- input signals from streamers
sent_frame_i : in std_logic;
-- statistic control
reset_stats_i : in std_logic;
snapshot_ena_i : in std_logic := '0';
----------------------- statistics ----------------------------------------
-- output statistics: tx/rx counters
sent_frame_cnt_o : out std_logic_vector(g_cnt_width-1 downto 0)
);
end xtx_streamers_stats;
architecture rtl of xtx_streamers_stats is
signal sent_frame_cnt : unsigned(g_cnt_width-1 downto 0);
signal sent_frame_cnt_d1 : unsigned(g_cnt_width-1 downto 0);
signal snapshot_ena_d1 : std_logic;
begin
-------------------------------------------------------------------------------------------
-- frame/block statistics, i.e. lost, sent, received
-------------------------------------------------------------------------------------------
-- process that counts stuff: receved/send/lost frames
p_cnts: process(clk_i)
begin
if rising_edge(clk_i) then
if (rst_n_i = '0' or reset_stats_i = '1') then
sent_frame_cnt <= (others => '0');
else
-- count sent frames
if(sent_frame_i = '1') then
sent_frame_cnt <= sent_frame_cnt + 1;
end if;
end if;
end if;
end process;
-------------------------------------------------------------------------------------------
-- snapshot
-------------------------------------------------------------------------------------------
-- snapshot is used to expose to user coherent value, so that the count for accumulated
-- latency is coherent with the accumulated latency and the average can be accurately
-- calculated
-------------------------------------------------------------------------------------------
p_stats_snapshot: process(clk_i)
begin
if rising_edge(clk_i) then
if (rst_n_i = '0') then
snapshot_ena_d1 <= '0';
sent_frame_cnt_d1 <= (others=>'0');
else
if(snapshot_ena_i = '1' and snapshot_ena_d1 = '0') then
sent_frame_cnt_d1 <= sent_frame_cnt;
end if;
snapshot_ena_d1 <= snapshot_ena_i;
end if;
end if;
end process;
-------------------------------------------------------------------------------------------
-- snapshot or current value
-------------------------------------------------------------------------------------------
sent_frame_cnt_o <= std_logic_vector(sent_frame_cnt_d1) when (snapshot_ena_d1 = '1') else
std_logic_vector(sent_frame_cnt);
end rtl;
\ No newline at end of file
......@@ -58,6 +58,10 @@ use work.wr_transmission_wbgen2_pkg.all;
entity xwr_transmission is
generic (
-- Indicates whether this module instantiates both streamers (rx and tx) or only one
-- of them. An application that only receives or only transmits might want to use
-- RX_ONLY or TX_ONLY mode to save resources.
g_streamers_op_mode : t_streamers_op_mode := TX_AND_RX;
-----------------------------------------------------------------------------------------
-- Transmission/reception parameters
-----------------------------------------------------------------------------------------
......@@ -210,16 +214,18 @@ architecture rtl of xwr_transmission is
signal rx_data : std_logic_vector(g_rx_streamer_params.data_width-1 downto 0);
signal wb_regs_slave_in : t_wishbone_slave_in;
signal wb_regs_slave_out : t_wishbone_slave_out;
signal rx_latency_valid : std_logic;
signal rx_latency : std_logic_vector(27 downto 0);
signal rx_lost_frames : std_logic;
signal rx_lost_blocks : std_logic;
signal rx_frame : std_logic;
signal tx_frame : std_logic;
signal reset_time_tai : std_logic_vector(39 downto 0);
signal latency_acc : std_logic_vector(63 downto 0);
signal rx_valid : std_logic;
signal rx_latency_valid : std_logic;
signal rx_latency : std_logic_vector(27 downto 0);
signal rx_lost_frames : std_logic;
signal rx_lost_frames_cnt : std_logic_vector(14 downto 0);
signal rx_lost_blocks : std_logic;
signal rx_frame : std_logic;
signal tx_cfg_mac_local : std_logic_vector(47 downto 0);
signal tx_cfg_mac_target : std_logic_vector(47 downto 0);
signal tx_cfg_ethertype : std_logic_vector(15 downto 0);
......@@ -247,73 +253,98 @@ architecture rtl of xwr_transmission is
begin
U_TX: xtx_streamer
generic map(
g_data_width => g_tx_streamer_params.data_width,
g_tx_buffer_size => g_tx_streamer_params.buffer_size,
g_tx_threshold => g_tx_streamer_params.threshold,
g_tx_max_words_per_frame => g_tx_streamer_params.max_words_per_frame,
g_tx_timeout => g_tx_streamer_params.timeout,
g_escape_code_disable => g_tx_streamer_params.escape_code_disable)
port map(
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
src_i => src_i,
src_o => src_o,
clk_ref_i => clk_ref_i,
tm_time_valid_i => tm_time_valid_i,
tm_tai_i => tm_tai_i,
tm_cycles_i => tm_cycles_i,
tx_data_i => tx_data_i,
tx_valid_i => tx_valid_i,
tx_dreq_o => tx_dreq_o,
tx_last_p1_i => tx_last_p1_i,
tx_flush_p1_i => tx_flush_p1_i,
tx_reset_seq_i => from_wb.sscr1_rst_seq_id_o,
tx_frame_p1_o => tx_frame,
cfg_mac_local_i => tx_cfg_mac_local_i,
cfg_mac_target_i => tx_cfg_mac_target_i,
cfg_ethertype_i => tx_cfg_ethertype_i);
U_RX: xrx_streamer
generic map(
g_data_width => g_rx_streamer_params.data_width,
g_buffer_size => g_rx_streamer_params.buffer_size,
g_escape_code_disable => g_rx_streamer_params.escape_code_disable,
g_expected_words_number => g_rx_streamer_params.expected_words_number
)
port map(
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
snk_i => snk_i,
snk_o => snk_o,
clk_ref_i => clk_ref_i,
tm_time_valid_i => tm_time_valid_i,
tm_tai_i => tm_tai_i,
tm_cycles_i => tm_cycles_i,
rx_first_p1_o => rx_first_p1_o,
rx_last_p1_o => rx_last_p1_o,
rx_data_o => rx_data,
rx_valid_o => rx_valid,
rx_dreq_i => rx_dreq_i,
rx_lost_p1_o => rx_lost_blocks,
rx_lost_frames_p1_o => rx_lost_frames,
rx_lost_frames_cnt_o => rx_lost_frames_cnt,
rx_latency_o => rx_latency,
rx_latency_valid_o => rx_latency_valid,
rx_frame_p1_o => rx_frame,
cfg_mac_local_i => rx_cfg_mac_local_i,
cfg_mac_remote_i => rx_cfg_mac_remote_i,
cfg_ethertype_i => rx_cfg_ethertype_i,
cfg_accept_broadcasts_i => rx_cfg_accept_broadcasts_i,
cfg_filter_remote_i => rx_cfg_filter_remote,
cfg_fixed_latency_i => rx_cfg_fixed_latency);
rx_data_o <= rx_data;
rx_valid_o <= rx_valid;
-------------------------------------------------------------------------------------------
-- transmission
-------------------------------------------------------------------------------------------
gen_tx: if(g_streamers_op_mode=TX_ONLY OR g_streamers_op_mode=TX_AND_RX) generate
U_TX: xtx_streamer
generic map(
g_data_width => g_tx_streamer_params.data_width,
g_tx_buffer_size => g_tx_streamer_params.buffer_size,
g_tx_threshold => g_tx_streamer_params.threshold,
g_tx_max_words_per_frame => g_tx_streamer_params.max_words_per_frame,
g_tx_timeout => g_tx_streamer_params.timeout,
g_escape_code_disable => g_tx_streamer_params.escape_code_disable)
port map(
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
src_i => src_i,
src_o => src_o,
clk_ref_i => clk_ref_i,
tm_time_valid_i => tm_time_valid_i,
tm_tai_i => tm_tai_i,
tm_cycles_i => tm_cycles_i,
tx_data_i => tx_data_i,
tx_valid_i => tx_valid_i,
tx_dreq_o => tx_dreq_o,
tx_last_p1_i => tx_last_p1_i,
tx_flush_p1_i => tx_flush_p1_i,
tx_reset_seq_i => from_wb.sscr1_rst_seq_id_o,
tx_frame_p1_o => tx_frame,
cfg_mac_local_i => tx_cfg_mac_local_i,
cfg_mac_target_i => tx_cfg_mac_target_i,
cfg_ethertype_i => tx_cfg_ethertype_i);
end generate gen_tx;
gen_not_tx: if(g_streamers_op_mode=RX_ONLY) generate
src_o <= c_dummy_snk_in;
tx_dreq_o <= '0';
tx_frame <= '0';
end generate gen_not_tx;
-------------------------------------------------------------------------------------------
-- reception
-------------------------------------------------------------------------------------------
gen_rx: if(g_streamers_op_mode=RX_ONLY OR g_streamers_op_mode=TX_AND_RX) generate
U_RX: xrx_streamer
generic map(
g_data_width => g_rx_streamer_params.data_width,
g_buffer_size => g_rx_streamer_params.buffer_size,
g_escape_code_disable => g_rx_streamer_params.escape_code_disable,
g_expected_words_number => g_rx_streamer_params.expected_words_number
)
port map(
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
snk_i => snk_i,
snk_o => snk_o,
clk_ref_i => clk_ref_i,
tm_time_valid_i => tm_time_valid_i,
tm_tai_i => tm_tai_i,
tm_cycles_i => tm_cycles_i,
rx_first_p1_o => rx_first_p1_o,
rx_last_p1_o => rx_last_p1_o,
rx_data_o => rx_data,
rx_valid_o => rx_valid,
rx_dreq_i => rx_dreq_i,
rx_lost_p1_o => rx_lost_blocks,
rx_lost_frames_p1_o => rx_lost_frames,
rx_lost_frames_cnt_o => rx_lost_frames_cnt,
rx_latency_o => rx_latency,
rx_latency_valid_o => rx_latency_valid,
rx_frame_p1_o => rx_frame,
cfg_mac_local_i => rx_cfg_mac_local_i,
cfg_mac_remote_i => rx_cfg_mac_remote_i,
cfg_ethertype_i => rx_cfg_ethertype_i,
cfg_accept_broadcasts_i => rx_cfg_accept_broadcasts_i,
cfg_filter_remote_i => rx_cfg_filter_remote,
cfg_fixed_latency_i => rx_cfg_fixed_latency);
end generate gen_rx;
gen_not_rx: if(g_streamers_op_mode=TX_ONLY) generate
snk_o <= c_dummy_src_in;
rx_first_p1_o <= '0';
rx_last_p1_o <= '0';
rx_data <= (others => '0');
rx_valid <= '0';
end generate gen_not_rx;
-------------------------------------------------------------------------------------------
-- statistics for both
-------------------------------------------------------------------------------------------
-- statistics are useful only for
U_STATS: xrtx_streamers_stats
generic map(
g_streamers_op_mode => g_streamers_op_mode,
g_cnt_width => g_stats_cnt_width,
g_acc_width => g_stats_acc_width
)
......@@ -352,6 +383,8 @@ begin
to_wb.rx_stat5_rx_latency_acc_lsb_i <= latency_acc(31 downto 0);
to_wb.rx_stat6_rx_latency_acc_msb_i <= latency_acc(63 downto 32);
rx_data_o <= rx_data;
rx_valid_o <= rx_valid;
U_WB_ADAPTER : wb_slave_adapter
generic map (
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment