-- LSM state machine signals
signal swap_bytes : std_logic; -- sysclk
-signal swap_bytes_q : std_logic; -- ff_rxhalfclk
+signal swap_bytes_q : std_logic; -- rx_halfclk
signal tx_allow : std_logic; -- sysclk
signal tx_allow_delay : std_logic; -- sysclk
-signal tx_allow_q : std_logic; -- ff_txhalfclk
+signal tx_allow_q : std_logic; -- tx_halfclk
signal rx_allow : std_logic; -- sysclk
signal rx_allow_delay : std_logic; -- sysclk
-signal rx_allow_q : std_logic; -- ff_rxhalfclk
+signal rx_allow_q : std_logic; -- rx_halfclk
signal quad_rst : std_logic; -- sysclk
signal lane_rst : std_logic; -- sysclk
-- SerDes genuine signals
-signal tx_data : std_logic_vector(15 downto 0); -- ff_txhalfclk
-signal tx_k : std_logic_vector(1 downto 0); -- ff_txhalfclk
-signal rx_data : std_logic_vector(15 downto 0); -- ff_rxhalfclk
-signal rx_k : std_logic_vector(1 downto 0); -- ff_rxhalfclk
+signal tx_data : std_logic_vector(15 downto 0); -- tx_halfclk
+signal tx_k : std_logic_vector(1 downto 0); -- tx_halfclk
+signal rx_data : std_logic_vector(15 downto 0); -- rx_halfclk
+signal rx_k : std_logic_vector(1 downto 0); -- rx_halfclk
+signal rx_k_q : std_logic_vector(1 downto 0); -- sysclk
signal link_ok : std_logic_vector(0 downto 0);
signal link_error : std_logic_vector(8 downto 0);
-signal ff_txhalfclk : std_logic;
-signal ff_rxhalfclk : std_logic;
+signal tx_halfclk : std_logic; -- 100MHz clock from SerDes
+signal rx_halfclk : std_logic; -- 100MHz clock from SerDes
--rx fifo signals
signal fifo_rx_reset : std_logic; -- async signal, does not matter
signal fifo_rx_dout : std_logic_vector(17 downto 0); -- sysclk
signal fifo_rx_empty : std_logic; -- sysclk
signal last_fifo_rx_empty : std_logic; -- sysclk
-signal fifo_rx_wr_en : std_logic; -- ff_rxhalfclk
-signal fifo_rx_din : std_logic_vector(17 downto 0); -- ff_rxhalfclk
-signal fifo_rx_full : std_logic; -- ff_rxhalfclk
+signal fifo_rx_wr_en : std_logic; -- rx_halfclk
+signal fifo_rx_din : std_logic_vector(17 downto 0); -- rx_halfclk
+signal fifo_rx_full : std_logic; -- rx_halfclk
--rx path
signal rx_counter : std_logic_vector(c_NUM_WIDTH-1 downto 0); -- sysclk
--tx fifo signals
signal fifo_tx_reset : std_logic; -- async signal, does not matter
-signal fifo_tx_rd_en : std_logic; -- ff_txhalfclk
-signal fifo_tx_dout : std_logic_vector(17 downto 0); -- ff_txhalfclk
-signal fifo_tx_empty : std_logic; -- ff_txhalfclk
-signal last_fifo_tx_empty : std_logic; -- ff_txhalfclk
+signal fifo_tx_rd_en : std_logic; -- tx_halfclk
+signal fifo_tx_dout : std_logic_vector(17 downto 0); -- tx_halfclk
+signal fifo_tx_empty : std_logic; -- tx_halfclk
+signal last_fifo_tx_empty : std_logic; -- tx_halfclk
signal fifo_tx_wr_en : std_logic; -- sysclk
signal fifo_tx_din : std_logic_vector(17 downto 0); -- sysclk
signal fifo_tx_full : std_logic; -- sysclk
--link status
signal link_led : std_logic;
-signal rx_k_q : std_logic_vector(1 downto 0);
signal info_led : std_logic;
signal tx_correct : std_logic_vector(1 downto 0); -- GbE mode SERDES: automatic IDLE2 -> IDLE1 conversion
signal first_idle : std_logic; -- tag the first IDLE2 after data
-signal reset_word_cnt : std_logic_vector(4 downto 0);
-signal make_trbnet_reset : std_logic;
-signal send_reset_words : std_logic;
-signal send_reset_in : std_logic;
+signal reset_word_cnt : std_logic_vector(4 downto 0); -- sysclk
+signal make_trbnet_reset : std_logic; -- sysclk
+signal send_reset_words : std_logic; -- sysclk
+signal send_reset_q : std_logic; -- tx_halfclk
signal reset_i : std_logic; -- sysclk
attribute syn_keep : boolean;
attribute syn_preserve : boolean;
attribute syn_keep of led_counter : signal is true;
-attribute syn_keep of send_reset_in : signal is true;
+attribute syn_keep of send_reset_q : signal is true;
attribute syn_keep of reset_i : signal is true;
attribute syn_preserve of reset_i : signal is true;
--------------------------------------------------------------------------
-- Reset signal syncing
-SYSCLK_SYNC_PROC: process( SYSCLK )
-begin
- if rising_edge(SYSCLK) then
- reset_i <= RESET;
- send_reset_in <= ctrl_op(15);
- end if;
-end process SYSCLK_SYNC_PROC;
+THE_RESET_DELAY: signal_sync
+generic map( DEPTH => 1, WIDTH => 1 )
+port map(
+ RESET => '0',
+ D_IN(0) => RESET,
+ CLK0 => sysclk,
+ CLK1 => sysclk,
+ D_OUT(0) => reset_i
+);
+
+-- Transfer clock domain
+THE_SEND_RESET_SYNC: signal_sync
+generic map( DEPTH => 2, WIDTH => 1 )
+port map(
+ RESET => '0',
+ D_IN(0) => CTRL_OP(15),
+ CLK0 => sysclk,
+ CLK1 => tx_halfclk,
+ D_OUT(0) => send_reset_q
+);
-- Input synchronizer for SFP_PRESENT and SFP_LOS signals (external signals from SFP)
-- DO NOT SAVE ON REGISTERS HERE!!!
THE_RX_K_SYNC: signal_sync
generic map( DEPTH => 2, WIDTH => 2 )
port map(
- RESET => reset_i,
+ RESET => reset_i, -- should not harm
D_IN => rx_k,
- CLK0 => ff_rxhalfclk,
+ CLK0 => rx_halfclk,
CLK1 => sysclk,
D_OUT => rx_k_q
);
SD_TXCLK_BAD_IN => link_error(5), -- unknown sync
SD_RXCLK_BAD_IN => link_error(4), -- unknown sync
SD_RETRY_IN => '0', -- OK fixed
- SD_ALIGNMENT_IN => rx_k_q, -- OK sysclk sync'ed
+ SD_ALIGNMENT_IN => rx_k_q, -- OK
SD_CV_IN => link_error(7 downto 6), -- unknown sync
FULL_RESET_OUT => quad_rst, -- sysclk sync'ed
LANE_RESET_OUT => lane_rst, -- sysclk sync'ed
THE_SWAPBYTES_SYNC: signal_sync
generic map( DEPTH => 2, WIDTH => 1 )
port map(
- RESET => reset_i,
+ RESET => reset_i, -- should not harm
D_IN(0) => swap_bytes,
CLK0 => sysclk,
- CLK1 => ff_rxhalfclk,
+ CLK1 => rx_halfclk,
D_OUT(0) => swap_bytes_q
);
THE_TX_ALLOW_SYNC: signal_sync
generic map( DEPTH => 2, WIDTH => 1 )
port map(
- RESET => reset_i,
+ RESET => reset_i, -- should not harm
D_IN(0) => tx_allow,
CLK0 => sysclk,
- CLK1 => ff_txhalfclk,
+ CLK1 => tx_halfclk,
D_OUT(0) => tx_allow_q,
);
THE_RX_ALLOW_SYNC: signal_sync
generic map( DEPTH => 2, WIDTH => 1 )
port map(
- RESET => reset_i,
+ RESET => reset_i, -- should not harm
D_IN(0) => rx_allow,
CLK0 => sysclk,
- CLK1 => ff_rxhalfclk,
+ CLK1 => rx_halfclk,
D_OUT(0) => rx_allow_q,
);
--------------------------------------------------------------------------
-- SerDes clock output to FPGA fabric
-REFCLK2CORE_OUT <= ff_txhalfclk; --refck2core;
+REFCLK2CORE_OUT <= tx_halfclk;
-------------------------------------------------------------------------
-------------------------------------------------------------------------
refclkn => SD_REFCLK_N_IN, -- not used here
rxrefclk => CLK, -- raw 200MHz clock
refclk => CLK, -- raw 200MHz clock
- rxa_pclk => ff_rxhalfclk, -- clock multiplier set by data bus width
+ rxa_pclk => rx_halfclk, -- clock multiplier set by data bus width
rxb_pclk => open,
hdinp_0 => SD_RXD_P_IN, -- SerDes I/O
hdinn_0 => SD_RXD_N_IN, -- SerDes I/O
hdoutp_0 => SD_TXD_P_IN, -- SerDes I/O
hdoutn_0 => SD_TXD_N_IN, -- SerDes I/O
- tclk_0 => ff_txhalfclk, -- 100MHz
- rclk_0 => ff_rxhalfclk, -- 100MHz
+ tclk_0 => tx_halfclk, -- 100MHz
+ rclk_0 => rx_halfclk, -- 100MHz
tx_rst_0 => lane_rst, -- async reset
rx_rst_0 => lane_rst, -- async reset
ref_0_sclk => open,
mca_resync_01 => '0', -- not needed
quad_rst => '0', -- hands off - kills registers!
serdes_rst => quad_rst, -- unknown if will work
- ref_pclk => ff_txhalfclk -- clock multiplier set by data bus width
+ ref_pclk => tx_halfclk -- clock multiplier set by data bus width
);
end generate;
-------------------------------------------------------------------------
-- Received bytes need to be swapped if the SerDes is "off by one" in its internal 8bit path
-THE_BYTE_SWAP_PROC: process( ff_rxhalfclk )
+THE_BYTE_SWAP_PROC: process( rx_halfclk )
begin
- if( rising_edge(ff_rxhalfclk) ) then
+ if( rising_edge(rx_halfclk) ) then
last_rx <= rx_k(1) & rx_data(15 downto 8); -- OK
if( swap_bytes_q = '0' ) then
fifo_rx_din <= rx_k(1) & rx_k(0) & rx_data(15 downto 8) & rx_data(7 downto 0); -- OK
read_enable_in => fifo_rx_rd_en, -- OK
read_data_out => fifo_rx_dout, -- OK
empty_out => fifo_rx_empty, -- OK
- write_clock_in => ff_rxhalfclk,
+ write_clock_in => rx_halfclk,
write_enable_in => fifo_rx_wr_en, -- OK
write_data_in => fifo_rx_din, -- OK
full_out => fifo_rx_full -- OK
)
port map(
fifo_gsr_in => fifo_tx_reset, -- async signal, does not matter
- read_clock_in => ff_txhalfclk,
+ read_clock_in => tx_halfclk,
read_enable_in => fifo_tx_rd_en, -- OK
read_data_out => fifo_tx_dout, -- OK
empty_out => fifo_tx_empty, -- OK
-- empty -> read clock
-- full -> write clock
-THE_SERDES_INPUT_PROC: process( ff_txhalfclk )
+THE_SERDES_INPUT_PROC: process( tx_halfclk )
begin
- if( rising_edge(ff_txhalfclk) ) then
+ if( rising_edge(tx_halfclk) ) then
last_fifo_tx_empty <= fifo_tx_empty; -- OK
first_idle <= not last_fifo_tx_empty and fifo_tx_empty; -- OK
- if ( send_reset_in = '1' ) then
+ if ( send_reset_q = '1' ) then -- OK
tx_data <= x"fefe";
tx_k <= "11";
elsif( (last_fifo_tx_empty = '1') or (tx_allow_q = '0') ) then -- OK