Commit 36138211 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

wr_endpoint: moved TX timestamp output port from TSU to TX framer to avoid FIFO race conditions

parent 009740be
......@@ -7,7 +7,7 @@
-- Author : Tomasz Wlostowski
-- Company : CERN BE-CO-HT
-- Created : 2009-06-22
-- Last update: 2012-01-20
-- Last update: 2012-02-09
-- Platform : FPGA-generic
-- Standard : VHDL'87
-------------------------------------------------------------------------------
......@@ -44,7 +44,7 @@ entity ep_timestamping_unit is
g_timestamp_bits_r : natural := 28;
-- size of falling edge timestamp
g_timestamp_bits_f : natural := 4;
g_ref_clock_rate: integer := 125000000
g_ref_clock_rate : integer := 125000000
);
port (
......@@ -65,7 +65,7 @@ entity ep_timestamping_unit is
-- PPS pulse input (active HI for 1 clk_ref_i cycle) for internal TS counter synchronization
pps_csync_p1_i : in std_logic;
-- TX/RX timestamp strobes (from PCS)
-- asynchronous TX/RX timestamp strobes (from PCS)
tx_timestamp_stb_p_i : in std_logic;
rx_timestamp_stb_p_i : in std_logic;
......@@ -73,50 +73,26 @@ entity ep_timestamping_unit is
-- RX Timestamp outpt
-------------------------------------------------------------------------------
-- RX timestamp
-- RX timestamp (to RX deframer)
rxts_timestamp_o : out std_logic_vector(31 downto 0);
-- RX timestamp valid
-- RX timestamp valid (to RX deframer)
rxts_timestamp_valid_o : out std_logic;
-- TX timestamp output (to TXTSU/Framer)
txts_timestamp_o : out std_logic_vector(31 downto 0);
-------------------------------------------------------------------------------
-- TX OOB stuff
-------------------------------------------------------------------------------
-- TX OOB frame ID (extracted from OOB fields from fabric interface by TX framer)
txoob_fid_i : in std_logic_vector(16 - 1 downto 0);
-- TX OOB strobe, denotes valid FID on txoob_fid_i.
txoob_stb_p_i : in std_logic;
-------------------------------------------------------------------------------
-- TXTSU interface
-------------------------------------------------------------------------------
-- Port ID value
txtsu_port_id_o : out std_logic_vector(4 downto 0);
-- Frame ID value
txtsu_fid_o : out std_logic_vector(16 -1 downto 0);
-- Encoded timestamps
txtsu_tsval_o : out std_logic_vector(28 + 4 - 1 downto 0);
-- TX timestamp valid: HI tells the TX timestamping unit that there is a valid
-- timestmap on txtsu_tsval_o, txtsu_fid_o and txtsu_port_id_o. Line remains HI
-- until assertion of txtsu_ack_i.
txtsu_valid_o : out std_logic;
-- TX timestamp valid (to TXTSU/Framer)
txts_timestamp_valid_o : out std_logic;
-- TX timestamp acknowledge: HI indicates that TXTSU has successfully received
-- the timestamp
txtsu_ack_i : in std_logic;
-------------------------------------------------------------------------------
-- Wishbone regs
-------------------------------------------------------------------------------
regs_i: in t_ep_out_registers;
regs_o: out t_ep_in_registers
);
regs_i : in t_ep_out_registers;
regs_o : out t_ep_in_registers
);
end ep_timestamping_unit;
......@@ -247,18 +223,21 @@ begin -- syn
tx_sync_delay <= (others => '0');
else
-- shift reg
rx_sync_delay <= '0' & rx_sync_delay(rx_sync_delay'length-1 downto 1);
tx_sync_delay <= '0' & tx_sync_delay(tx_sync_delay'length-1 downto 1);
if take_rx_synced_p = '1' then
cntr_rx_r <= cntr_r;
rx_sync_delay(rx_sync_delay'length-1 downto rx_sync_delay'length-4) <= (others => '1');
else
rx_sync_delay <= '0' & rx_sync_delay(rx_sync_delay'length-1 downto 1);
end if;
if take_tx_synced_p = '1' then
cntr_tx_r <= cntr_r;
tx_sync_delay(tx_sync_delay'length-1 downto tx_sync_delay'length-4) <= (others => '1');
else
tx_sync_delay <= '0' & tx_sync_delay(tx_sync_delay'length-1 downto 1);
end if;
end if;
end if;
end process;
......@@ -281,7 +260,7 @@ begin -- syn
end process;
-- timestamping "done" signals sync chains (refclk/rbclk -> refclk2)
-- timestamping "done" signals sync chains (clk_ref -> clk_sys)
tx_done_gen : gc_sync_ffs
generic map (
g_sync_edge => "positive")
......@@ -293,7 +272,7 @@ begin -- syn
npulse_o => tx_ts_done,
ppulse_o => open);
-- timestamping "done" signals sync chains (refclk/rbclk -> refclk2)
-- timestamping "done" signals sync chains (clk_rx -> clk_sys)
rx_done_gen : gc_sync_ffs
generic map (
g_sync_edge => "positive")
......@@ -305,62 +284,33 @@ begin -- syn
npulse_o => rx_ts_done,
ppulse_o => open);
-- TX OOB & timestamp combiner
tx_oob_stuff : process (clk_sys_i)
begin -- process
if rising_edge(clk_sys_i) then
if(rst_n_sys_i = '0') then
txtsu_fid_o <= (others => '0');
txtsu_valid_o <= '0';
txts_valid <= '0';
got_tx_oob <= '0';
else
if(txtsu_ack_i = '1' and (got_tx_oob = '0' or txts_valid = '0')) then
txtsu_valid_o <= '0';
end if;
if(got_tx_oob = '1' and txts_valid = '1') then
-- send we have a TX timestamp for this frame, send it to the TXTSU
txtsu_valid_o <= regs_i.tscr_en_txts_o;
txts_valid <= '0';
got_tx_oob <= '0';
end if;
if(txoob_stb_p_i = '1' and regs_i.tscr_en_txts_o = '1') then
txtsu_fid_o <= txoob_fid_i;
got_tx_oob <= '1';
end if;
if(tx_ts_done = '1' and regs_i.tscr_en_txts_o = '1') then
txtsu_tsval_o <= cntr_tx_f & cntr_tx_r;
txts_valid <= '1';
end if;
end if;
end if;
end process;
p_output_rx_ts : process (clk_rx_i)
begin
if rising_edge(clk_rx_i) then
if(rst_n_rx_i = '0') then
rxts_timestamp_valid_o <= '0';
rxts_timestamp_o <= (others => '0');
rxts_timestamp_o <= (others => '0');
else
if(regs_i. tscr_en_rxts_o = '0') then
if(regs_i. tscr_en_rxts_o = '0') then
rxts_timestamp_valid_o <= '0';
elsif(rx_ts_done = '1' and regs_i.tscr_en_rxts_o = '1') then
rxts_timestamp_valid_o <= '1';
rxts_timestamp_o <= cntr_rx_f & cntr_rx_r;
rxts_timestamp_o <= cntr_rx_f & cntr_rx_r;
end if;
end if;
end if;
end process;
txtsu_port_id_o <= regs_i.ecr_portid_o;
p_output_tx_ts : process (clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if(rst_n_sys_i = '0') then
txts_timestamp_o <= (others => '0');
elsif(tx_ts_done = '1' and regs_i.tscr_en_txts_o = '1') then
txts_timestamp_o <= cntr_tx_f & cntr_tx_r;
end if;
end if;
end process;
end syn;
......@@ -6,7 +6,7 @@
-- Author : Tomasz Wlostowski
-- Company : CERN BE-CO-HT
-- Created : 2009-06-22
-- Last update: 2012-01-23
-- Last update: 2012-02-09
-- Platform : FPGA-generic
-- Standard : VHDL'87
-------------------------------------------------------------------------------
......@@ -85,9 +85,28 @@ entity ep_tx_framer is
-- OOB/TSU signals
-------------------------------------------------------------------------------
-- Port ID value
txtsu_port_id_o : out std_logic_vector(4 downto 0);
-- Frame ID value
txtsu_fid_o : out std_logic_vector(16 -1 downto 0);
-- Encoded timestamps
txtsu_tsval_o : out std_logic_vector(28 + 4 - 1 downto 0);
-- TX timestamp valid: HI tells the TX timestamping unit that there is a valid
-- timestmap on txtsu_tsval_o, txtsu_fid_o and txtsu_port_id_o. Line remains HI
-- until assertion of txtsu_ack_i.
txtsu_valid_o : out std_logic;
-- TX timestamp acknowledge: HI indicates that TXTSU has successfully received
-- the timestamp
txtsu_ack_i : in std_logic;
txts_timestamp_i : in std_logic_vector(31 downto 0);
-- OOB frame tag value and strobing signal
oob_fid_value_o : out std_logic_vector(15 downto 0);
oob_fid_stb_o : out std_logic;
-- oob_fid_value_o : out std_logic_vector(15 downto 0);
-- oob_fid_stb_o : out std_logic;
-------------------------------------------------------------------------------
-- control registers
......@@ -104,7 +123,7 @@ architecture behavioral of ep_tx_framer is
constant c_IFG_LENGTH : integer := 1;
type t_tx_framer_state is (TXF_IDLE, TXF_ADDR, TXF_PAUSE, TXF_QHEADER, TXF_DATA, TXF_OOB, TXF_WAIT_CRC, TXF_EMBED_CRC1, TXF_EMBED_CRC2, TXF_EMBED_CRC3, TXF_GAP, TXF_PAD, TXF_ABORT);
type t_tx_framer_state is (TXF_IDLE, TXF_ADDR, TXF_PAUSE, TXF_QHEADER, TXF_DATA, TXF_OOB, TXF_WAIT_CRC, TXF_EMBED_CRC1, TXF_EMBED_CRC2, TXF_EMBED_CRC3, TXF_GAP, TXF_PAD, TXF_ABORT, TXF_STORE_TSTAMP);
-- general signals
signal state : t_tx_framer_state;
......@@ -173,7 +192,24 @@ architecture behavioral of ep_tx_framer is
signal vut_stored_tag : std_logic_vector(15 downto 0);
signal vut_stored_ethertype : std_logic_vector(15 downto 0);
function f_fabric_2_slv (
in_i : t_wrf_sink_in;
in_o : t_wrf_sink_out) return std_logic_vector is
variable tmp : std_logic_vector(31 downto 0);
begin
tmp(15 downto 0) := in_i.dat;
tmp(17 downto 16) := in_i.adr;
tmp(19 downto 18) := in_i.sel;
tmp(20) := in_i.cyc;
tmp(21) := in_i.stb;
tmp(22) := in_i.we;
tmp(23) := in_o.ack;
tmp(24) := in_o.stall;
tmp(25) := in_o.err;
tmp(26) := in_o.rty;
return tmp;
end f_fabric_2_slv;
begin -- behavioral
......@@ -320,7 +356,8 @@ begin -- behavioral
crc_gen_enable_mask <= '1';
crc_gen_force_reset <= '0';
oob_fid_stb_o <= '0';
--oob_fid_stb_o <= '0';
txtsu_valid_o <= '0';
else
......@@ -352,7 +389,9 @@ begin -- behavioral
snk_out.err <= '0';
snk_out.rty <= '0';
txtsu_valid_o <= '0';
q_abort <= '0';
q_eof <= '0';
tx_ready <= fc_flow_enable_i;
......@@ -362,7 +401,6 @@ begin -- behavioral
if(pcs_dreq_i = '1' and (sof_p1 = '1' or fc_pause_p_i = '1') and regs_i.ecr_tx_en_o = '1') then
-- enable writing to PCS FIFO
q_sof <= '1';
q_eof <= '0';
write_mask <= '1';
......@@ -567,9 +605,9 @@ begin -- behavioral
tx_ready <= '0';
-- check if we have an OOB block
if(oob.valid = '1' and oob.oob_type = c_WRF_OOB_TYPE_TX and g_with_timestamper) then
oob_fid_stb_o <= '1';
end if;
--if(oob.valid = '1' and g_with_timestamper) then
-- oob_fid_stb_o <= '1';
--end if;
end if;
if(snk_valid = '1' and snk_i.adr = c_WRF_DATA) then
......@@ -587,7 +625,7 @@ begin -- behavioral
-------------------------------------------------------------------------------
when TXF_WAIT_CRC =>
oob_fid_stb_o <= '0';
--oob_fid_stb_o <= '0';
q_valid <= '0';
state <= TXF_EMBED_CRC1;
crc_gen_enable_mask <= '0';
......@@ -638,10 +676,15 @@ begin -- behavioral
q_bytesel <= '0';
if(counter = 0 or g_force_gap_length = 0) then
if(oob.valid = '1') then
-- Submit the TX timestamp to the TXTSU queue
if(oob.valid = '1' and oob.oob_type = c_WRF_OOB_TYPE_TX) then
if(pcs_busy_i = '0') then
state <= TXF_IDLE;
txtsu_valid_o <='1';
txtsu_tsval_o <= txts_timestamp_i;
txtsu_port_id_o <= regs_i.ecr_portid_o;
txtsu_fid_o <= oob.frame_id;
state <= TXF_STORE_TSTAMP;
end if;
else
state <= TXF_IDLE;
......@@ -651,6 +694,12 @@ begin -- behavioral
counter <= counter - 1;
end if;
when TXF_STORE_TSTAMP =>
if(txtsu_ack_i = '1') then
txtsu_valid_o <= '0';
state <= TXF_IDLE;
end if;
-------------------------------------------------------------------------------
-- TX FSM state ABORT: signalize underlying PCS block to abort the frame
-- immediately, corrupting its contents
......@@ -661,7 +710,7 @@ begin -- behavioral
q_abort <= '1';
counter <= (others => '0');
state <= TXF_GAP;
state <= TXF_IDLE;
when others => null;
end case;
......@@ -670,12 +719,10 @@ begin -- behavioral
end if;
end process;
oob_fid_value_o <= oob.frame_id;
stall_int <= not (pcs_dreq_i and tx_ready) and regs_i.ecr_tx_en_o; -- /dev/null if disabled
stall_int <= (not (pcs_dreq_i and tx_ready) and regs_i.ecr_tx_en_o) or (snk_i.cyc xor snk_cyc_d0); -- /dev/null if disabled
snk_out.stall <= stall_int or (not snk_i.cyc and snk_cyc_d0);
snk_out.stall <= stall_int;
p_gen_ack : process(clk_sys_i)
begin
......
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