Commit 5919c662 authored by Maciej Lipinski's avatar Maciej Lipinski

[wr streamers]: added to rx the possiblity to provide fixed-latency parameter.

this new feature allows to day the instant at which the data is outputed
from the rx streamer. this delay is measured from the instant the streamer's
frame was transmitted. Effectively, the network becomes a fixed-latency
medium
parent 56e068f9
......@@ -65,7 +65,8 @@ package streamers_pkg is
cfg_mac_local_i : in std_logic_vector(47 downto 0) := x"000000000000";
cfg_mac_remote_i : in std_logic_vector(47 downto 0) := x"000000000000";
cfg_ethertype_i : in std_logic_vector(15 downto 0) := x"dbff";
cfg_accept_broadcasts_i : in std_logic := '1');
cfg_accept_broadcasts_i : in std_logic := '1';
cfg_fixed_latency_i : in std_logic_vector(27 downto 0) := x"0000000");
end component;
constant c_STREAMERS_ARR_SIZE_OUT : integer := 14;
......
......@@ -115,7 +115,7 @@ entity xrx_streamer is
rx_latency_o : out std_logic_vector(27 downto 0);
-- 1 when the latency on rx_latency_o is valid.
rx_latency_valid_o : out std_logic;
-- received streamer frame (counts all frames, corrupted and not)
-- received streamer frame (counts all frames, corrupted and not)
rx_frame_p1_o : out std_logic;
-- MAC address
......@@ -124,7 +124,8 @@ entity xrx_streamer is
cfg_ethertype_i : in std_logic_vector(15 downto 0) := x"dbff";
-- 1: accept all broadcast packets
-- 0: accept only unicasts
cfg_accept_broadcasts_i : in std_logic := '1'
cfg_accept_broadcasts_i : in std_logic := '1';
cfg_fixed_latency_i : in std_logic_vector(27 downto 0) := x"0000000"
);
end xrx_streamer;
......@@ -237,6 +238,20 @@ architecture rtl of xrx_streamer is
signal is_frame_seq_id : std_logic;
signal word_count : unsigned(11 downto 0);
signal sync_seq_no : std_logic;
-- fixed latency signals
type t_rx_delay_state is (DELAY, ALLOW);
signal timestamped : std_logic;
signal delay_cnt : std_logic_vector(27 downto 0);
signal fixed_latency_zero : std_logic_vector(27 downto 0);
signal fixed_latency_cnt : std_logic_vector(27 downto 0);
signal rx_dreq_mask : std_logic;
signal rx_latency : std_logic_vector(27 downto 0);
signal rx_latency_stored : std_logic_vector(27 downto 0);
signal rx_latency_valid : std_logic;
signal delay_state : t_rx_delay_state;
signal rx_dreq : std_logic;
begin -- rtl
rst <= not rst_n_i;
......@@ -317,7 +332,7 @@ begin -- rtl
d_valid_i => fifo_dvalid,
d_o => fifo_dout,
d_valid_o => rx_valid_o,
d_req_i => rx_dreq_i);
d_req_i => rx_dreq);
fifo_din(g_data_width+1) <= fifo_sync;
fifo_din(g_data_width) <= fifo_last or
......@@ -339,6 +354,65 @@ begin -- rtl
tm_cycles_i => tm_cycles_i,
tag_cycles_o => rx_tag_cycles);
-------------------------------------------------------------------------------------------
-- fixed latency implementation
-------------------------------------------------------------------------------------------
-- mask rx_dreq to prevent reception
rx_dreq <= rx_dreq_i and rx_dreq_mask;
-- produce a pulse when SOF is timestamped, this pulse starts counter in clk_sys clock
-- domain
U_sync_with_clk : gc_sync_ffs
port map (
clk_i => clk_sys_i,
rst_n_i => rst_n_i,
data_i => fsm_in.sof,
synced_o => timestamped);
-- count delay after reception of frame
p_delay_cnt : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' or timestamped = '1' then
delay_cnt <= (others=>'0');
else
delay_cnt <= std_logic_vector(unsigned(delay_cnt) + 1);
end if;
end if;
end process;
fixed_latency_zero <= (others => '0');
fixed_latency_cnt <= std_logic_vector(unsigned(delay_cnt) + unsigned(rx_latency_stored));
-- introduce fixed latency, if configured to do so
p_fixed_latency_fsm : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' or cfg_fixed_latency_i = fixed_latency_zero then
delay_state <= ALLOW;
rx_latency_stored <= (others=>'0');
rx_dreq_mask <= '1';
else
case delay_state is
when ALLOW =>
if(rx_latency_valid ='1') then
rx_dreq_mask <= '0';
rx_latency_stored <= rx_latency;
delay_state <= DELAY;
end if;
when DELAY =>
if(fixed_latency_cnt >= cfg_fixed_latency_i) then
rx_dreq_mask <= '1';
delay_state <= ALLOW;
end if;
end case;
end if;
end if;
end process;
-------------------------------------------------------------------------------------------
-- end of fixed latency implementation
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
p_fsm : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
......@@ -355,7 +429,6 @@ begin -- rtl
got_next_subframe <= '0';
fifo_sync <= '0';
fifo_last <= '0';
rx_latency_valid_o <= '0';
tx_tag_valid <= '0';
ser_count <= (others => '0');
word_count <= (others => '0');
......@@ -363,6 +436,8 @@ begin -- rtl
rx_frame_p1_o <= '0';
rx_lost_frames_cnt_o <= (others => '0');
frames_lost <= '0';
rx_latency <= (others=>'0');
rx_latency_valid <= '0';
else
case state is
when IDLE =>
......@@ -378,12 +453,13 @@ begin -- rtl
fifo_sync <='0';
fifo_last <= '0';
word_count <= (others => '0');
rx_latency_valid_o <= '0';
tx_tag_valid <= '0';
rx_frame_p1_o <= '0';
rx_lost_frames_cnt_o <= (others => '0');
frames_lost <= '0';
blocks_lost <= '0';
rx_latency <= (others=>'0');
rx_latency_valid <= '0';
if(fsm_in.sof = '1') then
state <= HEADER;
......@@ -457,15 +533,15 @@ begin -- rtl
word_count <= word_count + 1; -- count words, increment in advance
got_next_subframe <= '1';
if(tx_tag_valid = '1') then
rx_latency_valid_o <= '1';
rx_latency_valid <= '1';
if(unsigned(tx_tag_cycles) > unsigned(rx_tag_cycles)) then
rx_latency_o <= std_logic_vector(unsigned(rx_tag_cycles) - unsigned(tx_tag_cycles) + to_unsigned(125000000, 28));
rx_latency <= std_logic_vector(unsigned(rx_tag_cycles) - unsigned(tx_tag_cycles) + to_unsigned(125000000, 28));
else
rx_latency_o <= std_logic_vector(unsigned(rx_tag_cycles) - unsigned(tx_tag_cycles));
rx_latency <= std_logic_vector(unsigned(rx_tag_cycles) - unsigned(tx_tag_cycles));
end if;
tx_tag_valid <= '0';
else
rx_latency_valid_o <= '0';
rx_latency_valid <= '0';
end if;
if(std_logic_vector(seq_no) /= fsm_in.data(14 downto 0)) then
......@@ -510,7 +586,7 @@ begin -- rtl
when PAYLOAD =>
frames_lost <= '0';
rx_lost_frames_cnt_o <= (others => '0');
rx_latency_valid_o <= '0';
rx_latency_valid <= '0';
fifo_sync <= got_next_subframe;
if(fsm_in.eof = '1') then
......@@ -635,7 +711,8 @@ begin -- rtl
rx_lost_p1_o <= frames_lost or blocks_lost;
rx_lost_blocks_p1_o <= blocks_lost;
rx_lost_frames_p1_o <= frames_lost;
rx_latency_o <= rx_latency;
rx_latency_valid_o <= rx_latency_valid;
crc_restart <= '1' when (state = FRAME_SEQ_ID or (is_escape = '1' and fsm_in.data(15) = '1')) else not rst_n_i;
end rtl;
......@@ -346,7 +346,8 @@ begin
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_accept_broadcasts_i => rx_cfg_accept_broadcasts_i,
cfg_fixed_latency_i => x"00000dc");
rx_data_o <= rx_data;
rx_valid_o <= rx_valid;
......
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