Commit 12fecf86 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski Committed by Maciej Lipinski

wr_streamers: fixed timestamp wraparound detection in fixed latency mode

parent 946d409a
...@@ -12,7 +12,9 @@ entity fixed_latency_delay is ...@@ -12,7 +12,9 @@ entity fixed_latency_delay is
g_data_width : integer; g_data_width : integer;
g_buffer_size : integer; g_buffer_size : integer;
g_use_ref_clock_for_data : 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( port(
rst_n_i : in std_logic; rst_n_i : in std_logic;
...@@ -54,9 +56,7 @@ architecture rtl of fixed_latency_delay is ...@@ -54,9 +56,7 @@ architecture rtl of fixed_latency_delay is
type t_state is (IDLE, TS_SETUP_MATCH, TS_WAIT_MATCH, SEND); type t_state is (IDLE, TS_SETUP_MATCH, TS_WAIT_MATCH, SEND);
signal State: t_state; signal State: t_state;
signal clk_data : std_logic;
signal rst_n_data : std_logic;
signal rst_n_ref : std_logic; signal rst_n_ref : std_logic;
signal wr_full : std_logic; signal wr_full : std_logic;
constant c_datapath_width : integer := g_data_width + 2 + 28 + 1; constant c_datapath_width : integer := g_data_width + 2 + 28 + 1;
...@@ -175,7 +175,7 @@ begin ...@@ -175,7 +175,7 @@ begin
when TS_WAIT_MATCH => when TS_WAIT_MATCH =>
if delay_miss = '1' or delay_match = '1' then 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; state <= TS_SETUP_MATCH;
else else
state <= SEND; state <= SEND;
...@@ -190,7 +190,8 @@ begin ...@@ -190,7 +190,8 @@ begin
else else
state <= TS_SETUP_MATCH; state <= TS_SETUP_MATCH;
end if; end if;
elsif fifo_empty = '1' then
state <= IDLE;
end if; end if;
end case; end case;
end if; end if;
...@@ -200,7 +201,9 @@ begin ...@@ -200,7 +201,9 @@ begin
U_Compare: entity work.fixed_latency_ts_match U_Compare: entity work.fixed_latency_ts_match
generic map ( 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 ( port map (
clk_i => clk_ref_i, clk_i => clk_ref_i,
rst_n_i => rst_n_ref, rst_n_i => rst_n_ref,
......
...@@ -4,7 +4,11 @@ use ieee.numeric_std.all; ...@@ -4,7 +4,11 @@ use ieee.numeric_std.all;
entity fixed_latency_ts_match is entity fixed_latency_ts_match is
generic generic
(g_clk_ref_rate : integer); (g_clk_ref_rate : integer;
g_simulation : integer := 0;
g_sim_cycle_counter_range : integer := 125000000
);
port port
( (
clk_i : in std_logic; clk_i : in std_logic;
...@@ -32,11 +36,21 @@ end entity; ...@@ -32,11 +36,21 @@ end entity;
architecture rtl of fixed_latency_ts_match is 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 ts_adjusted : unsigned(28 downto 0);
signal target_cycles : 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 arm_d : std_logic_vector(2 downto 0);
signal armed : std_logic; signal armed : std_logic;
...@@ -64,6 +78,7 @@ begin ...@@ -64,6 +78,7 @@ begin
begin begin
if rising_edge(clk_i) then if rising_edge(clk_i) then
if rst_n_i = '0' then if rst_n_i = '0' then
armed <= '0';
arm_d <= (others => '0'); arm_d <= (others => '0');
miss_o <= '0'; miss_o <= '0';
else else
...@@ -73,17 +88,19 @@ begin ...@@ -73,17 +88,19 @@ begin
match_o <= '0'; match_o <= '0';
miss_o <= '0'; miss_o <= '0';
ts_adjusted <= resize(unsigned(ts_origin_i) + unsigned(ts_latency_i), 29); 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; end if;
if delta < -c_unwrap_threshold or delta > c_unwrap_threshold then if ts_adjusted < c_rollover_threshold_lo and tm_cycles_scaled > c_rollover_threshold_hi then
ts_adjusted <= ts_adjusted + 125000000; target_cycles <= tm_cycles_scaled + f_cycles_counter_range;
target_cycles <= tm_cycles_scaled + 125000000; if arm_d(0) = '1' then
ts_adjusted <= ts_adjusted + f_cycles_counter_range;
end if;
else else
target_cycles <= tm_cycles_scaled; target_cycles <= tm_cycles_scaled;
end if; end if;
if (arm_d(1) = '1') then if (arm_d(1) = '1') then
if ts_adjusted < target_cycles then if ts_adjusted < target_cycles then
miss_o <= '1'; miss_o <= '1';
...@@ -92,7 +109,7 @@ begin ...@@ -92,7 +109,7 @@ begin
end if; end if;
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'; match_o <= '1';
armed <= '0'; armed <= '0';
else else
......
...@@ -275,7 +275,9 @@ begin -- rtl ...@@ -275,7 +275,9 @@ begin -- rtl
g_data_width => g_data_width, g_data_width => g_data_width,
g_buffer_size => 32, g_buffer_size => 32,
g_use_ref_clock_for_data => g_use_ref_clock_for_data, 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 ( port map (
rst_n_i => rst_n_i, rst_n_i => rst_n_i,
clk_sys_i => clk_sys_i, clk_sys_i => clk_sys_i,
......
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