Commit ef003dbd authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

wr_streamers: fixed timestamp wraparound detection in fixed latency mode

parent 0bce050d
......@@ -12,7 +12,9 @@ entity fixed_latency_delay is
g_data_width : integer;
g_buffer_size : integer;
g_use_ref_clock_for_data : integer;
g_clk_ref_rate : integer
g_clk_ref_rate : integer;
g_simulation : integer := 0;
g_sim_cycle_counter_range : integer := 125000000
);
port(
rst_n_i : in std_logic;
......@@ -55,8 +57,6 @@ architecture rtl of fixed_latency_delay is
signal State : t_state;
signal clk_data : std_logic;
signal rst_n_data : std_logic;
signal rst_n_ref : std_logic;
signal wr_full : std_logic;
constant c_datapath_width : integer := g_data_width + 2 + 28 + 1;
......@@ -177,7 +177,7 @@ begin
when TS_WAIT_MATCH =>
if delay_miss = '1' or delay_match = '1' then
if fifo_last = '1' then
if fifo_last = '1' and fifo_empty = '0' then
state <= TS_SETUP_MATCH;
else
state <= SEND;
......@@ -192,8 +192,10 @@ begin
else
state <= TS_SETUP_MATCH;
end if;
elsif fifo_empty = '1' then
state <= IDLE;
end if;
end case;
end if;
end if;
......@@ -202,7 +204,9 @@ begin
U_Compare : entity work.fixed_latency_ts_match
generic map (
g_clk_ref_rate => g_clk_ref_rate)
g_clk_ref_rate => g_clk_ref_rate,
g_sim_cycle_counter_range => g_sim_cycle_counter_range,
g_simulation => g_simulation)
port map (
clk_i => clk_ref_i,
rst_n_i => rst_n_ref,
......
......@@ -4,7 +4,11 @@ use ieee.numeric_std.all;
entity fixed_latency_ts_match is
generic
(g_clk_ref_rate : integer);
(g_clk_ref_rate : integer;
g_simulation : integer := 0;
g_sim_cycle_counter_range : integer := 125000000
);
port
(
clk_i : in std_logic;
......@@ -32,11 +36,21 @@ end entity;
architecture rtl of fixed_latency_ts_match is
constant c_unwrap_threshold : integer := 62500000;
impure function f_cycles_counter_range return integer is
begin
if g_simulation = 1 then
return g_sim_cycle_counter_range;
else
return 125000000;
end if;
end function;
constant c_rollover_threshold_lo : integer := f_cycles_counter_range / 4;
constant c_rollover_threshold_hi : integer := f_cycles_counter_range * 3 / 4;
signal ts_adjusted : unsigned(28 downto 0);
signal target_cycles : unsigned(28 downto 0);
signal delta : signed(28 downto 0);
signal arm_d : std_logic_vector(2 downto 0);
signal armed : std_logic;
......@@ -64,6 +78,7 @@ begin
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
armed <= '0';
arm_d <= (others => '0');
miss_o <= '0';
else
......@@ -73,17 +88,19 @@ begin
match_o <= '0';
miss_o <= '0';
ts_adjusted <= resize(unsigned(ts_origin_i) + unsigned(ts_latency_i), 29);
delta <= signed('0'&ts_origin_i) + signed('0'&ts_latency_i) - signed('0'&tm_cycles_i);
end if;
if delta < -c_unwrap_threshold or delta > c_unwrap_threshold then
ts_adjusted <= ts_adjusted + 125000000;
target_cycles <= tm_cycles_scaled + 125000000;
if ts_adjusted < c_rollover_threshold_lo and tm_cycles_scaled > c_rollover_threshold_hi then
target_cycles <= tm_cycles_scaled + f_cycles_counter_range;
if arm_d(0) = '1' then
ts_adjusted <= ts_adjusted + f_cycles_counter_range;
end if;
else
target_cycles <= tm_cycles_scaled;
end if;
if (arm_d(1) = '1') then
if ts_adjusted < target_cycles then
miss_o <= '1';
......@@ -92,7 +109,7 @@ begin
end if;
end if;
if armed = '1' and ts_adjusted = target_cycles then
if armed = '1' and ts_adjusted = tm_cycles_scaled then
match_o <= '1';
armed <= '0';
else
......
......@@ -78,6 +78,10 @@ entity xrx_streamer is
-- in the future, more frequences might be supported..
g_clk_ref_rate : integer := 125000000;
g_simulation : integer := 0;
g_sim_cycle_counter_range : integer := 125000000;
g_use_ref_clock_for_data : integer := 0
);
......@@ -277,78 +281,32 @@ begin -- rtl
g_data_width => g_data_width,
g_buffer_size => 32,
g_use_ref_clock_for_data => g_use_ref_clock_for_data,
g_clk_ref_rate => g_clk_ref_rate)
g_clk_ref_rate => g_clk_ref_rate,
g_sim_cycle_counter_range => g_sim_cycle_counter_range,
g_simulation => g_simulation)
port map (
rst_n_i => rst_n_i,
clk_sys_i => clk_sys_i,
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,
d_data_i => fifo_data,
d_last_i => fifo_last_int,
d_sync_i => fifo_sync,
d_target_ts_en_i => fifo_target_ts_en,
d_target_ts_i => std_logic_vector(fifo_target_ts),
d_valid_i => fifo_dvalid,
d_drop_i => fifo_drop,
d_accept_i => fifo_accept_d0,
d_req_o => fsm_in.dreq,
rx_first_p1_o => rx_first_p1_o,
rx_last_p1_o => rx_last_p1_o,
rx_data_o => rx_data_o,
rx_valid_o => rx_valid_o,
rx_dreq_i => rx_dreq_i,
rst_n_i => rst_n_i,
clk_sys_i => clk_sys_i,
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,
d_data_i => fifo_data,
d_last_i => fifo_last_int,
d_sync_i => fifo_sync,
d_target_ts_en_i => fifo_target_ts_en,
d_target_ts_i => std_logic_vector(fifo_target_ts),
d_valid_i => fifo_dvalid,
d_drop_i => fifo_drop,
d_accept_i => fifo_accept_d0,
d_req_o => fsm_in.dreq,
rx_first_p1_o => rx_first_p1_o,
rx_last_p1_o => rx_last_p1_o,
rx_data_o => rx_data_o,
rx_valid_o => rx_valid_o,
rx_dreq_i => rx_dreq_i,
rx_streamer_cfg_i => rx_streamer_cfg_i);
-- 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' then
-- delay_state <= DISABLED;
-- rx_latency_stored <= (others => '0');
-- rx_dreq_allow <= '1';
-- delay_cnt <= c_timestamper_delay;
-- else
-- case delay_state is
-- when DISABLED =>
-- if unsigned(rx_streamer_cfg_i.fixed_latency) /= c_fixed_latency_zero then
-- delay_state <= ALLOW;
-- end if;
-- rx_latency_stored <= (others => '0');
-- delay_cnt <= c_timestamper_delay;
-- rx_dreq_allow <= '1';
-- when ALLOW =>
-- if unsigned(rx_streamer_cfg_i.fixed_latency) = c_fixed_latency_zero then
-- delay_state <= DISABLED;
-- elsif(rx_latency_valid = '1') then
-- rx_dreq_allow <= '0';
-- rx_latency_stored <= rx_latency;
-- delay_state <= DELAY;
-- end if;
-- if(timestamped = '1') then
-- if(rx_tag_valid= '1') then
-- delay_cnt <= c_timestamper_delay;
-- else
-- delay_cnt <= delay_cnt + 2;
-- end if;
-- when DELAY =>
-- if unsigned(rx_streamer_cfg_i.fixed_latency) <= delay_cnt + rx_latency_stored then
-- rx_latency_stored <= (others => '0');
-- rx_dreq_allow <= '1';
-- delay_state <= ALLOW;
-- else
-- delay_cnt <= delay_cnt + 2;
-- end if;
-- end case;
-- end if;
-- end if;
-- end process;
-------------------------------------------------------------------------------------------
-- end of fixed latency implementation
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
p_fsm : process(clk_sys_i)
begin
......@@ -500,12 +458,12 @@ begin -- rtl
fifo_target_ts <= unsigned(tx_tag_cycles);
if(tx_tag_valid = '1' and unsigned(rx_streamer_cfg_i.fixed_latency) /= 0) then
fifo_target_ts_en <= '1';
end if;
-- latency measurement
if(tx_tag_valid = '1' and rx_tag_valid_stored = '1') then
rx_latency_valid <= '1';
......@@ -542,7 +500,7 @@ begin -- rtl
if fifo_dvalid = '1' then
fifo_target_ts_en <= '0';
end if;
fifo_drop <= '0';
fifo_accept <= '0';
ser_count <= (others => '0');
......@@ -568,7 +526,7 @@ begin -- rtl
if fifo_dvalid = '1' then
fifo_target_ts_en <= '0';
end if;
frames_lost <= '0';
rx_lost_frames_cnt_o <= (others => '0');
rx_latency_valid <= '0';
......@@ -602,10 +560,10 @@ begin -- rtl
state <= PAYLOAD;
fifo_accept <= crc_match; --_latched;
fifo_drop <= not crc_match; --_latched;
fifo_dvalid <= pending_write and not fifo_dvalid;
fifo_accept <= crc_match; --_latched;
fifo_drop <= not crc_match; --_latched;
fifo_dvalid <= pending_write and not fifo_dvalid;
pending_write <= '0';
elsif fsm_in.data = x"0bad" then
......@@ -645,8 +603,8 @@ begin -- rtl
fifo_data(g_data_width-16-1 downto 0) <= pack_data(g_data_width-16-1 downto 0);
fifo_data(g_data_width-1 downto g_data_width-16) <= fsm_in.data;
fifo_dvalid <= '0';
pending_write <= '1';
pending_write <= '1';
end if;
if(word_count = g_expected_words_number) then
state <= EOF;
......
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