Commit ddf3f87e authored by Tomasz Wlostowski's avatar Tomasz Wlostowski Committed by Maciej Lipinski

wr_streamers: async data path option for Tx streamer [wip]

added gc_async_counter_diff to general-cores, thus
updating the submodules
parent 23991f9b
Subproject commit 4e5f7badf0b72f51bdb01c63fcdc6d69afb4b750 Subproject commit e071a1065e0db20983a6f44f818c1a0111431b6d
...@@ -12,5 +12,8 @@ files = ["streamers_pkg.vhd", ...@@ -12,5 +12,8 @@ files = ["streamers_pkg.vhd",
"wr_streamers_wb.vhd", "wr_streamers_wb.vhd",
"streamers_priv_pkg.vhd", "streamers_priv_pkg.vhd",
"xtx_streamers_stats.vhd", "xtx_streamers_stats.vhd",
"xrx_streamers_stats.vhd" "xrx_streamers_stats.vhd",
] "fixed_latency_delay.vhd",
"fixed_latency_ts_match.vhd",
"fifo_showahead_adapter.vhd"
];
library ieee;
use ieee.std_logic_1164.all;
entity fifo_showahead_adapter is
generic (
g_width : integer);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
fifo_q_i : in std_logic_vector(g_width-1 downto 0);
fifo_empty_i : in std_logic;
fifo_rd_o : out std_logic;
q_o : out std_logic_vector(g_width-1 downto 0);
valid_o : out std_logic;
rd_i : in std_logic
);
end fifo_showahead_adapter;
architecture rtl of fifo_showahead_adapter is
signal rd, rd_d : std_logic;
signal valid_int : std_logic;
begin
process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
rd_d <= '0';
valid_int <= '0';
else
rd_d <= rd;
if rd = '1' then
valid_int <= '1';
elsif rd_i = '1' then
valid_int <= not fifo_empty_i;
end if;
end if;
end if;
end process;
rd <= not fifo_empty_i when valid_int = '0' else rd_i and not fifo_empty_i;
q_o <= fifo_q_i;
fifo_rd_o <= rd;
valid_o <= valid_int;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.gencores_pkg.all;
use work.genram_pkg.all;
use work.streamers_priv_pkg.all;
use work.streamers_pkg.all;
entity fixed_latency_delay is
generic(
g_data_width : integer;
g_buffer_size : integer;
g_use_ref_clock_for_data : integer;
g_clk_ref_rate : integer
);
port(
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
clk_ref_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);
-- input i/f (dropping buffer)
d_data_i : in std_logic_vector(g_data_width-1 downto 0);
d_last_i : in std_logic;
d_sync_i : in std_logic;
d_target_ts_en_i : in std_logic;
d_target_ts_i : in std_logic_vector(27 downto 0);
d_valid_i : in std_logic;
d_drop_i : in std_logic;
d_accept_i : in std_logic;
d_req_o : out std_logic;
-- output data path (clk_ref_i/clk_sys_i clock domain for
-- g_use_ref_clock_for_data = 1/0 respectively)
rx_first_p1_o : out std_logic;
rx_last_p1_o : out std_logic;
rx_data_o : out std_logic_vector(g_data_width-1 downto 0);
rx_valid_o : out std_logic;
rx_dreq_i : in std_logic;
rx_streamer_cfg_i : in t_rx_streamer_cfg
);
end entity;
architecture rtl of fixed_latency_delay is
type t_state is (IDLE, WAIT_TS_MATCH, SEND);
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;
signal fifo_rd : std_logic;
signal dbuf_d : std_logic_vector(c_datapath_width-1 downto 0);
signal dbuf_q : std_logic_vector(c_datapath_width-1 downto 0);
signal fifo_d : std_logic_vector(c_datapath_width-1 downto 0);
signal fifo_q : std_logic_vector(c_datapath_width-1 downto 0);
signal dbuf_q_valid : std_logic;
signal dbuf_req : std_logic;
signal fifo_q_int : std_logic_vector(c_datapath_width-1 downto 0);
signal fifo_rd_int, fifo_empty_int, fifo_q_valid : std_logic;
signal fifo_data : std_logic_vector(g_data_width-1 downto 0);
signal fifo_sync, fifo_last, fifo_target_ts_en : std_logic;
signal fifo_target_ts : std_logic_vector(27 downto 0);
signal fifo_we : std_logic;
signal delay_arm : std_logic;
signal delay_match : std_logic;
signal delay_miss : 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);
clk_data <= clk_sys_i when g_use_ref_clock_for_data = 0 else clk_ref_i;
rst_n_data <= rst_n_i when g_use_ref_clock_for_data = 0 else rst_n_ref;
dbuf_d(g_data_width-1 downto 0) <= d_data_i;
dbuf_d(g_data_width) <= d_last_i;
dbuf_d(g_data_width+1) <= d_sync_i;
dbuf_d(g_data_width+2) <= d_target_ts_en_i;
dbuf_d(g_data_width+3+27 downto g_data_width+3) <= d_target_ts_i;
U_DropBuffer : entity work.dropping_buffer
generic map (
g_size => g_buffer_size,
g_data_width => c_datapath_width)
port map (
clk_i => clk_sys_i,
rst_n_i => rst_n_i,
d_i => dbuf_d,
d_req_o => d_req_o,
d_drop_i => d_drop_i,
d_accept_i => d_accept_i,
d_valid_i => d_valid_i,
d_o => dbuf_q,
d_valid_o => dbuf_q_valid,
d_req_i => dbuf_req);
dbuf_req <= not wr_full;
fifo_we <= dbuf_q_valid and not wr_full;
U_ClockSyncFifo : generic_async_fifo
generic map (
g_data_width => c_datapath_width,
g_size => 16,
g_show_ahead => false)
port map (
rst_n_i => rst_n_i,
clk_wr_i => clk_sys_i,
d_i => dbuf_q,
we_i => dbuf_q_valid,
wr_full_o => wr_full,
clk_rd_i => clk_data,
q_o => fifo_q_int,
rd_i => fifo_rd_int,
rd_empty_o => fifo_empty_int);
U_ShowaheadForFIFO : entity work.fifo_showahead_adapter
generic map (
g_width => c_datapath_width)
port map (
clk_i => clk_data,
rst_n_i => rst_n_data,
fifo_q_i => fifo_q_int,
fifo_empty_i => fifo_empty_int,
fifo_rd_o => fifo_rd_int,
q_o => fifo_q,
valid_o => fifo_q_valid,
rd_i => fifo_rd);
process(clk_data)
begin
if rising_edge(clk_data) then
if rst_n_data = '0' then
state <= IDLE;
else
case state is
when IDLE =>
if fifo_q_valid = '1' then
if fifo_target_ts_en = '1' then
state <= WAIT_TS_MATCH;
else
state <= SEND;
end if;
end if;
when WAIT_TS_MATCH =>
if delay_miss = '1' then
state <= IDLE;
elsif delay_match = '1' then
state <= SEND;
end if;
when SEND =>
if fifo_last = '1' then
state <= IDLE;
end if;
end case;
end if;
end if;
end process;
U_Compare: entity work.fixed_latency_ts_match
generic map (
g_clk_ref_rate => g_clk_ref_rate)
port map (
clk_i => clk_ref_i,
rst_n_i => rst_n_ref,
arm_i => delay_arm,
ts_origin_i => fifo_target_ts,
ts_latency_i => rx_streamer_cfg_i.fixed_latency,
tm_time_valid_i => tm_time_valid_i,
tm_tai_i => tm_tai_i,
tm_cycles_i => tm_cycles_i,
match_o => delay_match,
miss_o => delay_miss);
process(state, rx_dreq_i, delay_match, fifo_target_ts_en, fifo_q_valid)
begin
case state is
when IDLE =>
fifo_rd <= fifo_q_valid and rx_dreq_i and not fifo_target_ts_en;
delay_arm <= fifo_q_valid and fifo_target_ts_en;
rx_valid_o <= fifo_q_valid and not fifo_target_ts_en;
rx_first_p1_o <= fifo_sync and not fifo_target_ts_en;
rx_last_p1_o <= fifo_last and not fifo_target_ts_en;
when WAIT_TS_MATCH =>
fifo_rd <= '0';
delay_arm <= '0';
rx_valid_o <= '0';
rx_first_p1_o <= '0';
rx_last_p1_o <= '0';
when SEND =>
fifo_rd <= rx_dreq_i;
delay_arm <= '0';
rx_first_p1_o <= fifo_sync;
rx_last_p1_o <= fifo_last;
rx_valid_o <= fifo_q_valid;
end case;
end process;
fifo_data <= fifo_q(g_data_width-1 downto 0);
fifo_last <= fifo_q(g_data_width);
fifo_sync <= fifo_q(g_data_width+1);
fifo_target_ts_en <= fifo_q(g_data_width+2);
fifo_target_ts <= fifo_q(g_data_width + 3 + 27 downto g_data_width + 3);
rx_data_o <= fifo_data;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity fixed_latency_ts_match is
generic
(g_clk_ref_rate : integer);
port
(
clk_i : in std_logic;
rst_n_i : in std_logic;
arm_i : in std_logic;
ts_origin_i : in std_logic_vector(27 downto 0);
ts_latency_i : in std_logic_vector(27 downto 0);
-- Time valid flag
tm_time_valid_i : in std_logic := '0';
-- TAI seconds
tm_tai_i : in std_logic_vector(39 downto 0) := x"0000000000";
-- 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;
miss_o : out std_logic
);
end entity;
architecture rtl of fixed_latency_ts_match is
constant c_unwrap_threshold : integer := 62500000;
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;
signal tm_cycles_scaled : unsigned(28 downto 0);
begin
process(tm_cycles_i)
begin
if g_clk_ref_rate = 62500000 then
tm_cycles_scaled <= unsigned(tm_cycles_i & '0');
elsif g_clk_ref_rate = 125000000 then
tm_cycles_scaled <= unsigned('0' & tm_cycles_i);
else
report "Unsupported g_clk_ref_rate (62.5 / 125 MHz)" severity failure;
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
arm_d <= (others => '0');
miss_o <= '0';
else
arm_d <= arm_d(1 downto 0) & arm_i;
if arm_i = '1' then
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;
else
target_cycles <= tm_cycles_scaled;
end if;
if (arm_d(1) = '1') then
if ts_adjusted < target_cycles then
miss_o <= '1';
else
armed <= '1';
end if;
end if;
if armed = '1' and ts_adjusted = target_cycles then
match_o <= '1';
armed <= '0';
else
match_o <= '0';
end if;
end if;
end if;
end process;
end rtl;
...@@ -184,13 +184,14 @@ package streamers_pkg is ...@@ -184,13 +184,14 @@ package streamers_pkg is
g_escape_code_disable : boolean := FALSE; g_escape_code_disable : boolean := FALSE;
g_simulation : integer := 0; g_simulation : integer := 0;
g_sim_startup_cnt : integer := 6250;--100us g_sim_startup_cnt : integer := 6250;--100us
g_clk_ref_rate : integer := 125000000); g_clk_ref_rate : integer := 125000000;
g_use_ref_clock_for_data : integer := 0);
port ( port (
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
clk_ref_i : in std_logic := '0';
rst_n_i : in std_logic; rst_n_i : in std_logic;
src_i : in t_wrf_source_in; src_i : in t_wrf_source_in;
src_o : out t_wrf_source_out; src_o : out t_wrf_source_out;
clk_ref_i : in std_logic := '0';
tm_time_valid_i : in std_logic := '0'; tm_time_valid_i : in std_logic := '0';
tm_tai_i : in std_logic_vector(39 downto 0) := x"0000000000"; tm_tai_i : in std_logic_vector(39 downto 0) := x"0000000000";
tm_cycles_i : in std_logic_vector(27 downto 0) := x"0000000"; tm_cycles_i : in std_logic_vector(27 downto 0) := x"0000000";
...@@ -294,7 +295,8 @@ package streamers_pkg is ...@@ -294,7 +295,8 @@ package streamers_pkg is
-- WB i/f -- WB i/f
g_slave_mode : t_wishbone_interface_mode := CLASSIC; g_slave_mode : t_wishbone_interface_mode := CLASSIC;
g_slave_granularity : t_wishbone_address_granularity := BYTE; g_slave_granularity : t_wishbone_address_granularity := BYTE;
g_simulation : integer := 0 g_simulation : integer := 0;
g_use_ref_clock_for_data : integer := 0
); );
port ( port (
...@@ -333,4 +335,4 @@ package streamers_pkg is ...@@ -333,4 +335,4 @@ package streamers_pkg is
); );
end component; end component;
end streamers_pkg; end streamers_pkg;
\ No newline at end of file
...@@ -76,11 +76,15 @@ entity xrx_streamer is ...@@ -76,11 +76,15 @@ entity xrx_streamer is
-- rate fo the White Rabbit referene clock. By default, this clock is -- rate fo the White Rabbit referene clock. By default, this clock is
-- 125MHz for WR Nodes. There are some WR Nodes that work with 62.5MHz. -- 125MHz for WR Nodes. There are some WR Nodes that work with 62.5MHz.
-- in the future, more frequences might be supported.. -- in the future, more frequences might be supported..
g_clk_ref_rate : integer := 125000000 g_clk_ref_rate : integer := 125000000;
g_use_ref_clock_for_data : integer := 0
); );
port ( port (
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
-- White Rabbit reference clock
clk_ref_i : in std_logic := '0';
rst_n_i : in std_logic; rst_n_i : in std_logic;
-- Endpoint/WRC interface -- Endpoint/WRC interface
...@@ -92,8 +96,6 @@ entity xrx_streamer is ...@@ -92,8 +96,6 @@ entity xrx_streamer is
-- Caution: uses clk_ref_i clock domain! -- Caution: uses clk_ref_i clock domain!
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- White Rabbit reference clock
clk_ref_i : in std_logic := '0';
-- Time valid flag -- Time valid flag
tm_time_valid_i : in std_logic := '0'; tm_time_valid_i : in std_logic := '0';
...@@ -161,33 +163,32 @@ architecture rtl of xrx_streamer is ...@@ -161,33 +163,32 @@ architecture rtl of xrx_streamer is
signal fifo_drop, fifo_accept, fifo_accept_d0, fifo_dvalid : std_logic; signal fifo_drop, fifo_accept, fifo_accept_d0, fifo_dvalid : std_logic;
signal fifo_sync, fifo_last, frames_lost, blocks_lost : std_logic; signal fifo_sync, fifo_last, frames_lost, blocks_lost : std_logic;
signal fifo_dout, fifo_din : std_logic_vector(g_data_width + 1 downto 0); signal fifo_dout, fifo_din : std_logic_vector(g_data_width + 1 + 28 + 1 downto 0);
signal fifo_target_ts_en : std_logic;
signal fifo_target_ts : unsigned(27 downto 0);
signal pending_write, fab_dvalid_pre : std_logic; signal pending_write, fab_dvalid_pre : std_logic;
signal tx_tag_cycles, rx_tag_cycles : std_logic_vector(27 downto 0); signal tx_tag_cycles, rx_tag_cycles : std_logic_vector(27 downto 0);
signal tx_tag_valid, rx_tag_valid : std_logic; signal tx_tag_valid, rx_tag_valid : std_logic;
signal rx_tag_valid_stored : std_logic;
signal got_next_subframe : std_logic; signal got_next_subframe : std_logic;
signal is_frame_seq_id : std_logic; signal is_frame_seq_id : std_logic;
signal word_count : unsigned(11 downto 0); signal word_count : unsigned(11 downto 0);
signal sync_seq_no : std_logic; signal sync_seq_no : std_logic;
-- fixed latency signals
type t_rx_delay_state is (DISABLED, DELAY, ALLOW);
signal timestamped : std_logic;
signal delay_cnt : unsigned(27 downto 0);
signal rx_dreq_allow : std_logic;
signal rx_latency : unsigned(27 downto 0); signal rx_latency : unsigned(27 downto 0);
signal rx_latency_stored : unsigned(27 downto 0); signal rx_latency_stored : unsigned(27 downto 0);
signal rx_latency_valid : std_logic; signal rx_latency_valid : std_logic;
signal delay_state : t_rx_delay_state;
signal rx_dreq : std_logic;
signal is_vlan : std_logic; signal is_vlan : std_logic;
constant c_fixed_latency_zero : unsigned(27 downto 0) := (others => '0'); constant c_fixed_latency_zero : unsigned(27 downto 0) := (others => '0');
constant c_timestamper_delay : unsigned(27 downto 0) := to_unsigned(12, 28); -- cycles constant c_timestamper_delay : unsigned(27 downto 0) := to_unsigned(12, 28); -- cycles
signal fifo_last_int : std_logic;
begin -- rtl begin -- rtl
...@@ -253,35 +254,9 @@ begin -- rtl ...@@ -253,35 +254,9 @@ begin -- rtl
fsm_in.eof <= fab.eof or fab.error; fsm_in.eof <= fab.eof or fab.error;
fsm_in.sof <= fab.sof; fsm_in.sof <= fab.sof;
U_Output_FIFO : dropping_buffer
generic map (
g_size => g_buffer_size,
g_data_width => g_data_width + 2)
port map (
clk_i => clk_sys_i,
rst_n_i => rst_n_i,
d_i => fifo_din,
d_req_o => fsm_in.dreq,
d_drop_i => fifo_drop,
d_accept_i => fifo_accept_d0,
d_valid_i => fifo_dvalid,
d_o => fifo_dout,
d_valid_o => rx_valid_o,
d_req_i => rx_dreq);
fifo_din(g_data_width+1) <= fifo_sync;
fifo_din(g_data_width) <= fifo_last or
((not pending_write) and is_escape); -- when word is 16 bits
fifo_din(g_data_width-1 downto 0) <= fifo_data;
rx_data_o <= fifo_dout(g_data_width-1 downto 0);
rx_first_p1_o <= fifo_dout(g_data_width+1);
rx_last_p1_o <= fifo_dout(g_data_width);
U_RX_Timestamper : pulse_stamper U_RX_Timestamper : pulse_stamper
generic map( generic map(
g_ref_clk_rate => g_clk_ref_rate) g_ref_clk_rate => g_clk_ref_rate)
port map ( port map (
clk_ref_i => clk_ref_i, clk_ref_i => clk_ref_i,
clk_sys_i => clk_sys_i, clk_sys_i => clk_sys_i,
...@@ -290,66 +265,84 @@ begin -- rtl ...@@ -290,66 +265,84 @@ begin -- rtl
tm_time_valid_i => tm_time_valid_i, tm_time_valid_i => tm_time_valid_i,
tm_tai_i => tm_tai_i, tm_tai_i => tm_tai_i,
tm_cycles_i => tm_cycles_i, tm_cycles_i => tm_cycles_i,
tag_cycles_o => rx_tag_cycles); tag_cycles_o => rx_tag_cycles,
tag_valid_o => rx_tag_valid);
------------------------------------------------------------------------------------------- fifo_last_int <= fifo_last or ((not pending_write) and is_escape); -- when word is 16 bit
-- fixed latency implementation
-------------------------------------------------------------------------------------------
-- mask rx_dreq to prevent reception U_FixLatencyDelay : entity work.fixed_latency_delay
rx_dreq <= rx_dreq_i and rx_dreq_allow; generic map (
-- produce a pulse when SOF is timestamped, this pulse starts counter in clk_sys clock g_data_width => g_data_width,
-- domain g_buffer_size => 32,
U_sync_with_clk : gc_sync_ffs g_use_ref_clock_for_data => g_use_ref_clock_for_data,
g_clk_ref_rate => g_clk_ref_rate)
port map ( port map (
clk_i => clk_sys_i, rst_n_i => rst_n_i,
rst_n_i => rst_n_i, clk_sys_i => clk_sys_i,
data_i => fsm_in.sof, clk_ref_i => clk_ref_i,
synced_o => timestamped); tm_time_valid_i => tm_time_valid_i,
tm_tai_i => tm_tai_i,
-- introduce fixed latency, if configured to do so tm_cycles_i => tm_cycles_i,
p_fixed_latency_fsm : process(clk_sys_i) d_data_i => fifo_data,
begin d_last_i => fifo_last_int,
if rising_edge(clk_sys_i) then d_sync_i => fifo_sync,
if rst_n_i = '0' then d_target_ts_en_i => fifo_target_ts_en,
delay_state <= DISABLED; d_target_ts_i => std_logic_vector(fifo_target_ts),
rx_latency_stored <= (others=>'0'); d_valid_i => fifo_dvalid,
rx_dreq_allow <= '1'; d_drop_i => fifo_drop,
delay_cnt <= c_timestamper_delay; d_accept_i => fifo_accept_d0,
else d_req_o => fsm_in.dreq,
case delay_state is rx_first_p1_o => rx_first_p1_o,
when DISABLED => rx_last_p1_o => rx_last_p1_o,
if unsigned(rx_streamer_cfg_i.fixed_latency) /= c_fixed_latency_zero then rx_data_o => rx_data_o,
delay_state <= ALLOW; rx_valid_o => rx_valid_o,
end if; rx_dreq_i => rx_dreq_i,
rx_latency_stored <= (others=>'0'); rx_streamer_cfg_i => rx_streamer_cfg_i);
delay_cnt <= c_timestamper_delay;
rx_dreq_allow <= '1'; -- introduce fixed latency, if configured to do so
when ALLOW => -- p_fixed_latency_fsm : process(clk_sys_i)
if unsigned(rx_streamer_cfg_i.fixed_latency) = c_fixed_latency_zero then -- begin
delay_state <= DISABLED; -- if rising_edge(clk_sys_i) then
elsif(rx_latency_valid ='1') then -- if rst_n_i = '0' then
rx_dreq_allow <= '0'; -- delay_state <= DISABLED;
rx_latency_stored <= rx_latency; -- rx_latency_stored <= (others => '0');
delay_state <= DELAY; -- rx_dreq_allow <= '1';
end if; -- delay_cnt <= c_timestamper_delay;
if(timestamped = '1') then -- else
delay_cnt <= c_timestamper_delay; -- case delay_state is
else -- when DISABLED =>
delay_cnt <= delay_cnt + 2; -- if unsigned(rx_streamer_cfg_i.fixed_latency) /= c_fixed_latency_zero then
end if; -- delay_state <= ALLOW;
when DELAY => -- end if;
if unsigned(rx_streamer_cfg_i.fixed_latency) <= delay_cnt + rx_latency_stored then -- rx_latency_stored <= (others => '0');
rx_latency_stored <= (others=>'0'); -- delay_cnt <= c_timestamper_delay;
rx_dreq_allow <= '1'; -- rx_dreq_allow <= '1';
delay_state <= ALLOW; -- when ALLOW =>
else -- if unsigned(rx_streamer_cfg_i.fixed_latency) = c_fixed_latency_zero then
delay_cnt <= delay_cnt + 2; -- delay_state <= DISABLED;
end if; -- elsif(rx_latency_valid = '1') then
end case; -- rx_dreq_allow <= '0';
end if; -- rx_latency_stored <= rx_latency;
end if; -- delay_state <= DELAY;
end process; -- 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 -- end of fixed latency implementation
...@@ -383,6 +376,7 @@ begin -- rtl ...@@ -383,6 +376,7 @@ begin -- rtl
blocks_lost <= '0'; blocks_lost <= '0';
pack_data <= (others=>'0'); pack_data <= (others=>'0');
is_vlan <= '0'; is_vlan <= '0';
rx_tag_valid_stored <= '0';
else else
case state is case state is
when IDLE => when IDLE =>
...@@ -406,7 +400,7 @@ begin -- rtl ...@@ -406,7 +400,7 @@ begin -- rtl
rx_latency <= (others=>'0'); rx_latency <= (others=>'0');
rx_latency_valid <= '0'; rx_latency_valid <= '0';
is_vlan <= '0'; is_vlan <= '0';
rx_tag_valid_stored <= '0';
if(fsm_in.sof = '1') then if(fsm_in.sof = '1') then
state <= HEADER; state <= HEADER;
end if; end if;
...@@ -500,7 +494,18 @@ begin -- rtl ...@@ -500,7 +494,18 @@ begin -- rtl
ser_count <= (others => '0'); ser_count <= (others => '0');
word_count <= word_count + 1; -- count words, increment in advance word_count <= word_count + 1; -- count words, increment in advance
got_next_subframe <= '1'; got_next_subframe <= '1';
if(tx_tag_valid = '1') then fifo_target_ts_en <= '0';
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'; rx_latency_valid <= '1';
if(unsigned(tx_tag_cycles) > unsigned(rx_tag_cycles)) then if(unsigned(tx_tag_cycles) > unsigned(rx_tag_cycles)) then
rx_latency <= unsigned(rx_tag_cycles) - unsigned(tx_tag_cycles) + to_unsigned(125000000, 28); rx_latency <= unsigned(rx_tag_cycles) - unsigned(tx_tag_cycles) + to_unsigned(125000000, 28);
...@@ -511,6 +516,8 @@ begin -- rtl ...@@ -511,6 +516,8 @@ begin -- rtl
else else
rx_latency_valid <= '0'; rx_latency_valid <= '0';
end if; end if;
rx_tag_valid_stored <= '0';
if(std_logic_vector(seq_no) /= fsm_in.data(14 downto 0)) then if(std_logic_vector(seq_no) /= fsm_in.data(14 downto 0)) then
seq_no <= unsigned(fsm_in.data(14 downto 0))+1; seq_no <= unsigned(fsm_in.data(14 downto 0))+1;
...@@ -530,6 +537,10 @@ begin -- rtl ...@@ -530,6 +537,10 @@ begin -- rtl
end if; end if;
when SUBFRAME_HEADER => when SUBFRAME_HEADER =>
if fifo_dvalid = '1' then
fifo_target_ts_en <= '0';
end if;
fifo_drop <= '0'; fifo_drop <= '0';
fifo_accept <= '0'; fifo_accept <= '0';
ser_count <= (others => '0'); ser_count <= (others => '0');
...@@ -552,6 +563,10 @@ begin -- rtl ...@@ -552,6 +563,10 @@ begin -- rtl
end if; end if;
when PAYLOAD => when PAYLOAD =>
if fifo_dvalid = '1' then
fifo_target_ts_en <= '0';
end if;
frames_lost <= '0'; frames_lost <= '0';
rx_lost_frames_cnt_o <= (others => '0'); rx_lost_frames_cnt_o <= (others => '0');
rx_latency_valid <= '0'; rx_latency_valid <= '0';
......
...@@ -83,11 +83,19 @@ entity xtx_streamer is ...@@ -83,11 +83,19 @@ entity xtx_streamer is
-- rate fo the White Rabbit referene clock. By default, this clock is -- rate fo the White Rabbit referene clock. By default, this clock is
-- 125MHz for WR Nodes. There are some WR Nodes that work with 62.5MHz. -- 125MHz for WR Nodes. There are some WR Nodes that work with 62.5MHz.
-- in the future, more frequences might be supported.. -- in the future, more frequences might be supported..
g_clk_ref_rate : integer := 125000000 g_clk_ref_rate : integer := 125000000;
-- when non-zero, the datapath (tx_/rx_ ports) are in the clk_ref_i clock
-- domain instead of clk_sys_i. This is a must for fixed latency mode if
-- clk_sys_i is asynchronous (i.e. not locked) to the WR timing.
g_use_ref_clock_for_data : integer := 0
); );
port ( port (
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
-- White Rabbit reference clock
clk_ref_i : in std_logic := '0';
rst_n_i : in std_logic; rst_n_i : in std_logic;
-- Endpoint/WRC interface - packet source -- Endpoint/WRC interface - packet source
...@@ -99,8 +107,6 @@ entity xtx_streamer is ...@@ -99,8 +107,6 @@ entity xtx_streamer is
-- Caution: uses clk_ref_i clock domain! -- Caution: uses clk_ref_i clock domain!
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- White Rabbit reference clock
clk_ref_i : in std_logic := '0';
-- Time valid flag -- Time valid flag
tm_time_valid_i : in std_logic := '0'; tm_time_valid_i : in std_logic := '0';
...@@ -127,6 +133,10 @@ entity xtx_streamer is ...@@ -127,6 +133,10 @@ entity xtx_streamer is
-- the following clock cycle. -- the following clock cycle.
tx_dreq_o : out std_logic; tx_dreq_o : out std_logic;
-- sync signal, allowing to align transmission of the frames to the
-- least supported WR reference clock frequency. Used in fixed latency mode.
tx_sync_o : out std_logic;
-- Last signal. Can be used to indicate the last data word in a larger -- Last signal. Can be used to indicate the last data word in a larger
-- block of samples (see documentation for more details). -- block of samples (see documentation for more details).
tx_last_p1_i : in std_logic := '1'; tx_last_p1_i : in std_logic := '1';
...@@ -155,8 +165,12 @@ architecture rtl of xtx_streamer is ...@@ -155,8 +165,12 @@ architecture rtl of xtx_streamer is
signal tx_threshold_hit : std_logic; signal tx_threshold_hit : std_logic;
signal tx_timeout_hit : std_logic; signal tx_timeout_hit : std_logic;
signal tx_flush_latched : std_logic; signal tx_flush_latched : std_logic;
signal tx_idle : std_logic;
signal tx_fifo_last, tx_fifo_we, tx_fifo_full, tx_fifo_empty, tx_fifo_rd : std_logic; signal tx_fifo_last, tx_fifo_we, tx_fifo_full, tx_fifo_empty, tx_fifo_rd : std_logic;
signal tx_fifo_empty_int, tx_fifo_rd_int, tx_fifo_rd_int_d : std_logic;
signal tx_fifo_q_int, tx_fifo_q_reg : std_logic_vector(g_data_width downto 0);
signal tx_fifo_q_valid : std_logic;
signal tx_fifo_q, tx_fifo_d : std_logic_vector(g_data_width downto 0); signal tx_fifo_q, tx_fifo_d : std_logic_vector(g_data_width downto 0);
signal state : t_tx_state; signal state : t_tx_state;
signal seq_no, count : unsigned(14 downto 0); signal seq_no, count : unsigned(14 downto 0);
...@@ -176,6 +190,9 @@ architecture rtl of xtx_streamer is ...@@ -176,6 +190,9 @@ architecture rtl of xtx_streamer is
signal tx_almost_empty, tx_almost_full : std_logic; signal tx_almost_empty, tx_almost_full : std_logic;
signal buf_frame_count_inc_ref : std_logic;
signal buf_frame_count_dec_sys : std_logic;
signal buf_frame_count : unsigned(5 downto 0) := (others => '0'); signal buf_frame_count : unsigned(5 downto 0) := (others => '0');
...@@ -183,6 +200,15 @@ architecture rtl of xtx_streamer is ...@@ -183,6 +200,15 @@ architecture rtl of xtx_streamer is
signal tag_valid, tag_valid_latched : std_logic; signal tag_valid, tag_valid_latched : std_logic;
signal link_ok_delay_cnt : unsigned(25 downto 0); signal link_ok_delay_cnt : unsigned(25 downto 0);
signal link_ok_delay_expired : std_logic;
signal link_ok_delay_expired_ref : std_logic;
signal link_ok_ref : std_logic;
signal clk_data : std_logic;
signal rst_n_ref : std_logic;
signal stamper_pulse_a : std_logic;
constant c_link_ok_rst_delay : unsigned(25 downto 0) := to_unsigned(62500000, 26);-- 1s constant c_link_ok_rst_delay : unsigned(25 downto 0) := to_unsigned(62500000, 26);-- 1s
constant c_link_ok_rst_delay_sim : unsigned(25 downto 0) := to_unsigned(g_sim_startup_cnt, 26); constant c_link_ok_rst_delay_sim : unsigned(25 downto 0) := to_unsigned(g_sim_startup_cnt, 26);
...@@ -258,7 +284,7 @@ begin -- rtl ...@@ -258,7 +284,7 @@ begin -- rtl
d_valid_o => fab_src.dvalid, d_valid_o => fab_src.dvalid,
d_req_i => fab_src.dreq); d_req_i => fab_src.dreq);
end generate gen_escape; end generate gen_escape;
gen_no_escape: if (g_escape_code_disable = TRUE) generate gen_no_escape : if (g_escape_code_disable = true) generate
fab_src.data <= fsm_out.data; fab_src.data <= fsm_out.data;
fab_src.dvalid <= fsm_out.dvalid; fab_src.dvalid <= fsm_out.dvalid;
fsm_out.dreq <= fab_src.dreq; fsm_out.dreq <= fab_src.dreq;
...@@ -267,6 +293,8 @@ begin -- rtl ...@@ -267,6 +293,8 @@ begin -- rtl
tx_fifo_we <= tx_valid_i and not tx_fifo_full; tx_fifo_we <= tx_valid_i and not tx_fifo_full;
tx_fifo_d <= tx_last_p1_i & tx_data_i; tx_fifo_d <= tx_last_p1_i & tx_data_i;
gen_use_sys_clock_for_data : if g_use_ref_clock_for_data = 0 generate
U_TX_Buffer : generic_sync_fifo U_TX_Buffer : generic_sync_fifo
generic map ( generic map (
g_data_width => g_data_width + 1, g_data_width => g_data_width + 1,
...@@ -288,10 +316,102 @@ begin -- rtl ...@@ -288,10 +316,102 @@ begin -- rtl
almost_empty_o => tx_almost_empty, almost_empty_o => tx_almost_empty,
almost_full_o => tx_almost_full almost_full_o => tx_almost_full
); );
tx_fifo_rd <= '1' when (state = PAYLOAD and ser_count = g_data_width/16-1 and
fsm_out.dreq = '1' and tx_fifo_empty = '0') else clk_data <= clk_sys_i;
'0'; stamper_pulse_a <= fsm_out.sof;
tx_threshold_hit <= '1' when tx_almost_empty = '0' and (buf_frame_count /= 0) else '0';
end generate gen_use_sys_clock_for_data;
gen_use_ref_clock_for_data : if g_use_ref_clock_for_data /= 0 generate
U_TX_Buffer : generic_async_fifo
generic map (
g_data_width => g_data_width + 1,
g_size => g_tx_buffer_size,
g_with_rd_empty => true,
g_with_wr_full => true,
g_with_wr_almost_full => true,
g_with_rd_almost_empty => true,
g_almost_empty_threshold => g_tx_threshold,
g_almost_full_threshold => g_tx_buffer_size - 2,
g_show_ahead => true)
port map (
rst_n_i => rst_n_i,
clk_wr_i => clk_ref_i,
clk_rd_i => clk_sys_i,
d_i => tx_fifo_d,
we_i => tx_fifo_we,
q_o => tx_fifo_q_int,
rd_i => tx_fifo_rd_int,
rd_empty_o => tx_fifo_empty_int,
wr_full_o => tx_fifo_full,
rd_almost_empty_o => tx_almost_empty,
wr_almost_full_o => tx_almost_full
);
-- emulate show-ahead mode, not supported by async fifos in the
-- general-cores library.
tx_fifo_rd_int <= not tx_fifo_empty_int when tx_fifo_q_valid = '0' else tx_fifo_rd;
tx_fifo_q <= tx_fifo_q_int when tx_fifo_rd_int_d = '1' else tx_fifo_q_reg;
p_show_ahead : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
tx_fifo_empty <= '0';
tx_fifo_q_valid <= '0';
else
if tx_fifo_rd_int = '1' then
tx_fifo_q_valid <= '1';
tx_fifo_empty <= '0';
elsif tx_fifo_rd = '1' then
tx_fifo_q_valid <= not tx_fifo_empty_int;
tx_fifo_empty <= not tx_fifo_q_valid;
end if;
if tx_fifo_rd_int_d = '1' then
tx_fifo_q_reg <= tx_fifo_q;
end if;
tx_fifo_rd_int_d <= tx_fifo_rd_int;
end if;
end if;
end process;
clk_data <= clk_ref_i;
p_detect_sof : process(clk_ref_i)
begin
if rising_edge(clk_ref_i) then
if rst_n_ref = '0' then
tx_idle <= '1';
stamper_pulse_a <= '0';
else
if tx_last_p1_i = '1' and tx_valid_i = '1' then
tx_idle <= '1';
elsif tx_valid_i = '1' then
tx_idle <= '0';
end if;
stamper_pulse_a <= tx_valid_i and tx_idle;
end if;
end if;
end process;
end generate gen_use_ref_clock_for_data;
-- sys clock domain
tx_fifo_rd <= '1' when (state = PAYLOAD and ser_count = g_data_width/16-1 and
fsm_out.dreq = '1' and tx_fifo_empty = '0') else
'0';
-- sys clock domain
tx_threshold_hit <= '1' when tx_almost_empty = '0' and (signed(buf_frame_count) > 0) else '0';
tx_fifo_last <= tx_fifo_q(g_data_width); tx_fifo_last <= tx_fifo_q(g_data_width);
U_Timestamper : pulse_stamper U_Timestamper : pulse_stamper
...@@ -301,7 +421,7 @@ begin -- rtl ...@@ -301,7 +421,7 @@ begin -- rtl
clk_ref_i => clk_ref_i, clk_ref_i => clk_ref_i,
clk_sys_i => clk_sys_i, clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i, rst_n_i => rst_n_i,
pulse_a_i => fsm_out.sof, pulse_a_i => stamper_pulse_a,
tm_time_valid_i => tm_time_valid_i, tm_time_valid_i => tm_time_valid_i,
tm_tai_i => tm_tai_i, tm_tai_i => tm_tai_i,
tm_cycles_i => tm_cycles_i, tm_cycles_i => tm_cycles_i,
...@@ -309,20 +429,21 @@ begin -- rtl ...@@ -309,20 +429,21 @@ begin -- rtl
tag_cycles_o => tag_cycles, tag_cycles_o => tag_cycles,
tag_valid_o => tag_valid); tag_valid_o => tag_valid);
p_frame_counter : process(clk_sys_i) buf_frame_count_inc_ref <= tx_fifo_we and tx_last_p1_i;
begin buf_frame_count_dec_sys <= tx_fifo_rd and tx_fifo_last;
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then U_FrameCounter: gc_async_counter_diff
buf_frame_count <= (others => '0'); generic map (
else g_bits => 5,
if(tx_fifo_we = '1' and tx_last_p1_i = '1' and (tx_fifo_rd = '0' or tx_fifo_last = '0')) then g_output_clock => "dec")
buf_frame_count <= buf_frame_count+ 1; port map (
elsif((tx_fifo_we = '0' or tx_last_p1_i = '0') and (tx_fifo_rd = '1' and tx_fifo_last = '1')) then rst_n_i => rst_n_i,
buf_frame_count <= buf_frame_count - 1; clk_inc_i => clk_data,
end if; clk_dec_i => clk_sys_i,
end if; inc_i => buf_frame_count_inc_ref,
end if; dec_i => buf_frame_count_dec_sys,
end process; counter_o => buf_frame_count);
p_tx_timeout : process(clk_sys_i) p_tx_timeout : process(clk_sys_i)
begin begin
...@@ -346,6 +467,18 @@ begin -- rtl ...@@ -346,6 +467,18 @@ begin -- rtl
end if; end if;
end process; end process;
p_latch_timestamp : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' or state = IDLE then
tag_valid_latched <= '0';
elsif tag_valid = '1' then
tag_valid_latched <= '1';
end if;
end if;
end process;
p_fsm : process(clk_sys_i) p_fsm : process(clk_sys_i)
begin begin
if rising_edge(clk_sys_i) then if rising_edge(clk_sys_i) then
...@@ -401,6 +534,8 @@ begin -- rtl ...@@ -401,6 +534,8 @@ begin -- rtl
when ETH_HEADER => when ETH_HEADER =>
if(fsm_out.dreq = '1') then if(fsm_out.dreq = '1') then
fsm_out.dvalid <= '1';
case count(7 downto 0) is case count(7 downto 0) is
when x"00" => when x"00" =>
fsm_out.data <= tx_streamer_cfg_i.mac_target(47 downto 32); fsm_out.data <= tx_streamer_cfg_i.mac_target(47 downto 32);
...@@ -429,11 +564,18 @@ begin -- rtl ...@@ -429,11 +564,18 @@ begin -- rtl
count <= count + 1; count <= count + 1;
when x"07" => when x"07" =>
if(tx_streamer_cfg_i.qtag_ena = '0') then if(tx_streamer_cfg_i.qtag_ena = '0') then
fsm_out.data <= tag_valid_latched & "000" & tag_cycles(27 downto 16);
fsm_out.data <= "1000" & tag_cycles(27 downto 16);
if tag_valid_latched = '1' then
count <= count + 1;
fsm_out.dvalid <= '1';
else
fsm_out.dvalid <= '0';
end if;
else else
fsm_out.data <= tx_streamer_cfg_i.qtag_prio & '0' & tx_streamer_cfg_i.qtag_vid; fsm_out.data <= tx_streamer_cfg_i.qtag_prio & '0' & tx_streamer_cfg_i.qtag_vid;
count <= count + 1;
end if; end if;
count <= count + 1;
when x"08" => when x"08" =>
if(tx_streamer_cfg_i.qtag_ena = '0') then if(tx_streamer_cfg_i.qtag_ena = '0') then
fsm_out.data <= tag_cycles(15 downto 0); fsm_out.data <= tag_cycles(15 downto 0);
...@@ -443,8 +585,13 @@ begin -- rtl ...@@ -443,8 +585,13 @@ begin -- rtl
end if; end if;
count <= count + 1; count <= count + 1;
when x"09" => when x"09" =>
fsm_out.data <= tag_valid_latched & "000" & tag_cycles(27 downto 16); if tag_valid_latched = '1' then
count <= count + 1; count <= count + 1;
fsm_out.dvalid <= '1';
else
fsm_out.dvalid <= '0';
end if;
fsm_out.data <= "1000" & tag_cycles(27 downto 16);
when x"0A" => when x"0A" =>
fsm_out.data <= tag_cycles(15 downto 0); fsm_out.data <= tag_cycles(15 downto 0);
state <= FRAME_SEQ_ID; state <= FRAME_SEQ_ID;
...@@ -453,7 +600,6 @@ begin -- rtl ...@@ -453,7 +600,6 @@ begin -- rtl
fsm_out.data <= (others => 'X'); fsm_out.data <= (others => 'X');
count <= (others => 'X'); count <= (others => 'X');
end case; end case;
fsm_out.dvalid <= '1';
else else
fsm_out.dvalid <= '0'; fsm_out.dvalid <= '0';
end if; end if;
...@@ -469,7 +615,7 @@ begin -- rtl ...@@ -469,7 +615,7 @@ begin -- rtl
crc_reset <= '0'; crc_reset <= '0';
state <= PAYLOAD; state <= PAYLOAD;
else else
fsm_out.dvalid <= '0'; fsm_out.dvalid <= '0';
end if; end if;
when SUBFRAME_HEADER => when SUBFRAME_HEADER =>
...@@ -589,16 +735,52 @@ begin -- rtl ...@@ -589,16 +735,52 @@ begin -- rtl
else else
link_ok_delay_cnt <= c_link_ok_rst_delay; link_ok_delay_cnt <= c_link_ok_rst_delay;
end if; end if;
link_ok_delay_expired <= '0';
else else
-- first initial moments of link_ok_i high are ignored -- first initial moments of link_ok_i high are ignored
if(link_ok_i = '1' and link_ok_delay_cnt > 0) then if(link_ok_i = '1' and link_ok_delay_cnt > 0) then
link_ok_delay_cnt <= link_ok_delay_cnt-1; link_ok_delay_cnt <= link_ok_delay_cnt-1;
end if; end if;
if link_ok_delay_cnt > 0 then
link_ok_delay_expired <= '0';
else
link_ok_delay_expired <= '1';
end if;
end if; end if;
end if; end if;
end process; end process;
tx_dreq_o <= '0' when (link_ok_delay_cnt > 0) else U_SyncReset_to_RefClk : gc_sync_ffs
(not tx_almost_full) and link_ok_i; port map (
clk_i => clk_ref_i,
rst_n_i => '1',
data_i => rst_n_i,
synced_o => rst_n_ref);
U_SyncLinkOK_to_RefClk : gc_sync_ffs
port map (
clk_i => clk_ref_i,
rst_n_i => rst_n_ref,
data_i => link_ok_i,
synced_o => link_ok_ref);
U_SyncLinkDelayExpired_to_RefClk : gc_sync_ffs
port map (
clk_i => clk_ref_i,
rst_n_i => rst_n_ref,
data_i => link_ok_delay_expired,
synced_o => link_ok_delay_expired_ref);
p_tx_dreq_gen : process(link_ok_delay_expired_ref, tx_almost_full, link_ok_ref)
begin
if link_ok_delay_expired_ref = '0' then
tx_dreq_o <= '0';
else
tx_dreq_o <= not tx_almost_full and link_ok_ref;
end if;
end process;
end rtl; end rtl;
...@@ -75,6 +75,12 @@ entity xwr_streamers is ...@@ -75,6 +75,12 @@ entity xwr_streamers is
-- 125MHz for WR Nodes. There are some WR Nodes that work with 62.5MHz. -- 125MHz for WR Nodes. There are some WR Nodes that work with 62.5MHz.
-- in the future, more frequences might be supported.. -- in the future, more frequences might be supported..
g_clk_ref_rate : integer := 125000000; g_clk_ref_rate : integer := 125000000;
-- when non-zero, the datapath (tx_/rx_ ports) are in the clk_ref_i clock
-- domain instead of clk_sys_i. This is a must for fixed latency mode if
-- clk_sys_i is asynchronous (i.e. not locked) to the WR timing.
g_use_ref_clock_for_data : integer := 0;
----------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------
-- Transmission/reception parameters -- Transmission/reception parameters
----------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------
...@@ -97,11 +103,22 @@ entity xwr_streamers is ...@@ -97,11 +103,22 @@ entity xwr_streamers is
); );
port ( port (
---------------------------------------------------------------------------
-- Clocks & Resets
---------------------------------------------------------------------------
-- System clock. Used always for the WR fabric interface (src/snk) and
-- for the data path (tx_/rx_ ports) if g_use_ref_clock_for_data = 0.
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
-- WR Reference clock, 62.5 or 125 MHz. Frequency must match g_ref_clk_rate
-- generic. Used for latency measurement and timestamping (tm_ ports).
-- It also clocks Tx_/rx_ interfaces if g_use_ref_clock_for_data != 0.
clk_ref_i : in std_logic := '0';
rst_n_i : in std_logic; rst_n_i : in std_logic;
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- WR tx/rx interface -- WR tx/rx interface (clk_sys clock domain)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- Tx -- Tx
src_i : in t_wrf_source_in; src_i : in t_wrf_source_in;
...@@ -110,8 +127,9 @@ entity xwr_streamers is ...@@ -110,8 +127,9 @@ entity xwr_streamers is
snk_i : in t_wrf_sink_in; snk_i : in t_wrf_sink_in;
snk_o : out t_wrf_sink_out; snk_o : out t_wrf_sink_out;
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- User tx interface -- User tx interface (clk_data clock domain)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- Data word to be sent. -- Data word to be sent.
tx_data_i : in std_logic_vector(g_tx_streamer_params.data_width-1 downto 0); tx_data_i : in std_logic_vector(g_tx_streamer_params.data_width-1 downto 0);
...@@ -146,8 +164,6 @@ entity xwr_streamers is ...@@ -146,8 +164,6 @@ entity xwr_streamers is
-- WRC Timing interface, used for latency measurement -- WRC Timing interface, used for latency measurement
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- White Rabbit reference clock
clk_ref_i : in std_logic := '0';
-- Time valid flag -- Time valid flag
tm_time_valid_i : in std_logic := '0'; tm_time_valid_i : in std_logic := '0';
-- TAI seconds -- TAI seconds
...@@ -220,13 +236,14 @@ begin ...@@ -220,13 +236,14 @@ begin
g_tx_timeout => g_tx_streamer_params.timeout, g_tx_timeout => g_tx_streamer_params.timeout,
g_escape_code_disable => g_tx_streamer_params.escape_code_disable, g_escape_code_disable => g_tx_streamer_params.escape_code_disable,
g_simulation => g_simulation, g_simulation => g_simulation,
g_clk_ref_rate => g_clk_ref_rate) g_clk_ref_rate => g_clk_ref_rate,
g_use_ref_clock_for_data => g_use_ref_clock_for_data)
port map( port map(
clk_sys_i => clk_sys_i, clk_sys_i => clk_sys_i,
clk_ref_i => clk_ref_i,
rst_n_i => rst_n_i, rst_n_i => rst_n_i,
src_i => src_i, src_i => src_i,
src_o => src_o, src_o => src_o,
clk_ref_i => clk_ref_i,
tm_time_valid_i => tm_time_valid_i, tm_time_valid_i => tm_time_valid_i,
tm_tai_i => tm_tai_i, tm_tai_i => tm_tai_i,
tm_cycles_i => tm_cycles_i, tm_cycles_i => tm_cycles_i,
...@@ -471,4 +488,4 @@ begin ...@@ -471,4 +488,4 @@ begin
rx_streamer_cfg_i.filter_remote; rx_streamer_cfg_i.filter_remote;
rx_streamer_cfg.fixed_latency <= from_wb.rx_cfg5_fixed_latency_o when (from_wb.cfg_or_rx_fix_lat_o='1') else rx_streamer_cfg.fixed_latency <= from_wb.rx_cfg5_fixed_latency_o when (from_wb.cfg_or_rx_fix_lat_o='1') else
rx_streamer_cfg_i.fixed_latency; rx_streamer_cfg_i.fixed_latency;
end rtl; end rtl;
\ No newline at end of file
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