Commit 24b84fb3 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski Committed by Maciej Lipinski

wr_streamers: added timeout feature to fixed_latency_ts_match

parent 1cf6b932
......@@ -14,11 +14,12 @@ entity fixed_latency_ts_match is
clk_i : in std_logic;
rst_n_i : in std_logic;
arm_i : in std_logic;
arm_i : in std_logic;
ts_tai_i : in std_logic_vector(39 downto 0);
ts_cycles_i : in std_logic_vector(27 downto 0);
ts_latency_i : in std_logic_vector(27 downto 0);
ts_timeout_i : in std_logic_vector(27 downto 0);
-- Time valid flag
tm_time_valid_i : in std_logic := '0';
......@@ -29,9 +30,9 @@ entity fixed_latency_ts_match is
-- Fractional part of the second (in clk_ref_i cycles)
tm_cycles_i : in std_logic_vector(27 downto 0) := x"0000000";
match_o : out std_logic;
late_o : out std_logic
late_o : out std_logic;
timeout_o : out std_logic
);
......@@ -58,27 +59,36 @@ architecture rtl of fixed_latency_ts_match is
signal ts_adjusted_cycles : unsigned(28 downto 0);
signal ts_adjusted_tai : unsigned(39 downto 0);
signal ts_timeout_cycles : unsigned(28 downto 0);
signal ts_timeout_tai : unsigned(39 downto 0);
signal tm_cycles_scaled : unsigned(28 downto 0);
signal ts_latency_scaled : unsigned(28 downto 0);
signal ts_timeout_scaled : unsigned(28 downto 0);
signal tm_cycles_scaled_d : unsigned(28 downto 0);
signal ts_latency_scaled_d : unsigned(28 downto 0);
signal ts_adjusted_d : unsigned(28 downto 0);
signal tm_cycles_scaled_d : unsigned(28 downto 0);
signal tm_tai_d : unsigned(39 downto 0);
signal match, late : std_logic;
signal match, late, timeout : std_logic;
signal state : t_state;
signal trig : std_logic;
signal ts_adj_next_cycle, roll_lo, roll_hi : std_logic;
signal wait_cnt : unsigned(23 downto 0);
attribute mark_debug : string;
attribute mark_debug of ts_adjusted_d : signal is "TRUE";
attribute mark_debug of tm_cycles_scaled_d : signal is "TRUE";
attribute mark_debug of ts_latency_scaled_d : signal is "TRUE";
attribute mark_debug of state : signal is "TRUE";
attribute mark_debug of match : signal is "TRUE";
attribute mark_debug of late : signal is "TRUE";
attribute mark_debug of ts_adjusted_cycles : signal is "TRUE";
attribute mark_debug of ts_adjusted_tai : signal is "TRUE";
attribute mark_debug of ts_timeout_cycles : signal is "TRUE";
attribute mark_debug of ts_timeout_tai : signal is "TRUE";
attribute mark_debug of tm_cycles_scaled_d : signal is "TRUE";
attribute mark_debug of tm_tai_d : signal is "TRUE";
attribute mark_debug of state : signal is "TRUE";
attribute mark_debug of match : signal is "TRUE";
attribute mark_debug of late : signal is "TRUE";
attribute mark_debug of timeout : signal is "TRUE";
attribute mark_debug of trig : signal is "TRUE";
begin
......@@ -86,14 +96,13 @@ begin
process(clk_i)
begin
if rising_edge(clk_i) then
ts_adjusted_d <= ts_adjusted_cycles;
tm_cycles_scaled_d <= tm_cycles_scaled;
ts_latency_scaled_d <= ts_latency_scaled;
tm_cycles_scaled_d <= tm_cycles_scaled;
tm_tai_d <= unsigned(tm_tai_i);
end if;
end process;
process(tm_cycles_i, ts_latency_i)
process(tm_cycles_i, ts_latency_i, ts_timeout_i)
begin
if g_clk_ref_rate = 62500000 then
tm_cycles_scaled <= unsigned(tm_cycles_i & '0');
......@@ -107,6 +116,32 @@ begin
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wait_cnt <= (others => '0');
trig <= '0';
else
case State is
when IDLE =>
wait_cnt <= (others => '0');
trig <= '0';
when others =>
wait_cnt <= wait_cnt + 1;
if wait_cnt = 3000 then
trig <= '1';
end if;
end case;
end if;
end if;
end process;
process(clk_i)
begin
......@@ -122,11 +157,16 @@ begin
when IDLE =>
match <= '0';
late <= '0';
timeout <= '0';
if arm_i = '1' then
ts_adjusted_cycles <= resize(unsigned(ts_cycles_i) + unsigned(ts_latency_i), 29);
ts_adjusted_cycles <= resize(unsigned(ts_cycles_i) + unsigned(ts_latency_scaled), 29);
ts_adjusted_tai <= resize(unsigned(ts_tai_i), 40);
State <= WRAP_ADJ_TS;
ts_timeout_cycles <= resize(unsigned(ts_cycles_i) + unsigned(ts_timeout_scaled), 29);
ts_timeout_tai <= resize(unsigned(ts_tai_i), 40);
State <= WRAP_ADJ_TS;
end if;
when WRAP_ADJ_TS =>
......@@ -137,6 +177,11 @@ begin
ts_adjusted_tai <= ts_adjusted_tai + 1;
end if;
if ts_timeout_cycles >= f_cycles_counter_range then
ts_timeout_cycles <= ts_timeout_cycles - f_cycles_counter_range;
ts_timeout_tai <= ts_timeout_tai + 1;
end if;
State <= CHECK_LATE;
when CHECK_LATE =>
......@@ -147,10 +192,10 @@ begin
end if;
if ts_adjusted_tai < unsigned(tm_tai_i) then
if ts_adjusted_tai < tm_tai_d then
late <= '1';
State <= IDLE;
elsif ts_adjusted_tai = unsigned(tm_tai_i) and ts_adjusted_cycles <= tm_cycles_scaled then
elsif ts_adjusted_tai = tm_tai_d and ts_adjusted_cycles <= tm_cycles_scaled_d then
late <= '1';
State <= IDLE;
else
......@@ -158,7 +203,15 @@ begin
end if;
when WAIT_TRIG =>
if ts_adjusted_cycles = tm_cycles_scaled and ts_adjusted_tai = unsigned(tm_tai_i) then
if tm_tai_d > ts_timeout_tai or
(ts_timeout_tai = tm_tai_d and tm_cycles_scaled_d > ts_timeout_cycles) then
timeout <= '1';
State <= IDLE;
end if;
if ts_adjusted_cycles = tm_cycles_scaled_d and ts_adjusted_tai = tm_tai_d then
match <= '1';
State <= IDLE;
end if;
......@@ -170,5 +223,6 @@ begin
match_o <= match;
late_o <= late;
timeout_o <= timeout;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.gencores_pkg.all;
entity ts_restore_tai is
generic
(
g_tm_sample_period : integer := 20;
g_clk_ref_rate : integer;
g_simulation : integer := 0;
g_sim_cycle_counter_range : integer := 125000000
);
port (
clk_sys_i : in std_logic;
clk_ref_i : in std_logic;
rst_n_i : in std_logic;
-- Timing I/F, clk_ref_i clock domain
tm_time_valid_i : in std_logic;
tm_tai_i : in std_logic_vector(39 downto 0);
tm_cycles_i : in std_logic_vector(27 downto 0);
-- Timestamp I/F, clk_sys_i clock domain
ts_valid_i : in std_logic;
ts_cycles_i : in std_logic_vector(27 downto 0);
ts_valid_o : out std_logic;
ts_cycles_o : out std_logic_vector(27 downto 0);
ts_error_o : out std_logic;
ts_tai_o : out std_logic_vector(39 downto 0)
);
end entity;
architecture rtl of ts_restore_tai is
signal tm_cycles_sys, tm_cycles_ref, tm_cycles_ref_d : std_logic_vector(27 downto 0);
signal tm_tai_sys, tm_tai_ref, tm_tai_ref_d : std_logic_vector(39 downto 0);
signal tm_valid_sys, tm_valid_ref, tm_valid_ref_d : std_logic;
signal tm_sample_cnt : unsigned(5 downto 0);
signal tm_sample_p_ref : std_logic;
signal tm_sample_p_sys : std_logic;
impure function f_cycles_counter_range return integer is
begin
if g_simulation = 1 then
if g_clk_ref_rate = 62500000 then
return 2*g_sim_cycle_counter_range;
else
return g_sim_cycle_counter_range;
end if;
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 rst_n_ref : std_logic;
begin
U_SyncReset_to_RefClk : gc_sync_ffs
port map (
clk_i => clk_ref_i,
rst_n_i => '1',
data_i => rst_n_i,
synced_o => rst_n_ref);
p_sample_tm_ref : process(clk_ref_i)
begin
if rising_edge(clk_ref_i) then
if rst_n_ref = '0' then
tm_sample_p_ref <= '0';
tm_sample_cnt <= (others => '0');
else
tm_cycles_ref <= tm_cycles_ref_d;
tm_tai_ref <= tm_tai_ref_d;
tm_valid_ref <= tm_valid_ref_d;
if tm_sample_cnt = g_tm_sample_period-1 then
tm_sample_p_ref <= '1';
tm_cycles_ref_d <= tm_cycles_i;
tm_tai_ref_d <= tm_tai_i;
tm_valid_ref_d <= tm_time_valid_i;
tm_sample_cnt <= (others => '0');
else
tm_sample_p_ref <= '0';
tm_sample_cnt <= tm_sample_cnt + 1;
end if;
end if;
end if;
end process;
U_Sync_Sample_Pulse : gc_pulse_synchronizer2
port map (
clk_in_i => clk_ref_i,
rst_in_n_i => rst_n_ref,
clk_out_i => clk_sys_i,
rst_out_n_i => rst_n_i,
d_ready_o => open,
d_p_i => tm_sample_p_ref,
q_p_o => tm_sample_p_sys);
p_sample_tm_sys : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
tm_valid_sys <= '0';
elsif tm_sample_p_sys = '1' then
tm_tai_sys <= tm_tai_ref;
tm_cycles_sys <= tm_cycles_ref;
tm_valid_sys <= tm_valid_ref;
end if;
end if;
end process;
p_process : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
ts_valid_o <= '0';
else
if ts_valid_i = '1' then
if unsigned(ts_cycles_i) > c_rollover_threshold_hi and unsigned(tm_cycles_sys) < c_rollover_threshold_lo then
ts_tai_o <= std_logic_vector(unsigned(tm_tai_sys) - 1);
else
ts_tai_o <= tm_tai_sys;
end if;
ts_cycles_o <= ts_cycles_i;
ts_error_o <= not tm_valid_sys;
ts_valid_o <= '1';
else
ts_valid_o <= '0';
end if;
end if;
end if;
end process;
end rtl;
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