constant K277 : std_logic_vector(7 downto 0) := "11111011";
constant K297 : std_logic_vector(7 downto 0) := "11111101";
constant K307 : std_logic_vector(7 downto 0) := "11111110";
-
+
+ constant CBMNET_READY_CHAR0 : std_logic_vector(7 downto 0) := K284;
+ constant CBMNET_READY_CHAR1 : std_logic_vector(7 downto 0) := K287;
+ constant CBMNET_ALIGN_CHAR : std_logic_vector(7 downto 0) := K285;
+
component gtp_rx_ready_module is
generic (
READY_CHAR0 : std_logic_vector(7 downto 0) := K284;
signal tx_data_i : std_logic_vector(17 downto 0);
- signal rx_data_i : std_logic_vector(17 downto 0);
+ signal rx_data_i : std_logic_vector(8 downto 0);
signal rx_data_buf_i : std_logic_vector(17 downto 0);
- signal rx_error : std_logic_vector(1 downto 0);
+ signal rx_error : std_logic;
signal rst_n : std_logic;
signal rst : std_logic;
signal rx_fsm_state : std_logic_vector(3 downto 0);
signal tx_fsm_state : std_logic_vector(3 downto 0);
+ signal tx_rst_fsm_ready_i : std_logic;
+ signal tx_rst_fsm_ready_buf_i : std_logic;
+
type sci_ctrl is (IDLE, GET_WA, GET_WA_WAIT, GET_WA_WAIT2, GET_WA_FINISH);
signal sci_state : sci_ctrl;
- signal sci_timer : unsigned(7 downto 0) := (others => '0');
+ signal sci_timer : unsigned( 4 downto 0) := (others => '0');
signal start_timer : unsigned(18 downto 0) := (others => '0');
signal led_ok : std_logic;
signal led_timer : unsigned(20 downto 0);
signal proper_byte_align_i : std_logic;
- signal proper_word_align_i : std_logic;
+ signal byte_alignment_to_fsm_i : std_logic;
+
+ signal gear_to_serder_rst_i : std_logic;
+ signal word_alignment_to_fsm_i : std_logic;
+
+ signal rx_rm_to_gear_reset_i : std_logic;
+ signal rx_rst_fsm_ready_i : std_logic;
+ signal rx_serdes_ready_for_gear_i : std_logic;
+
+ signal lsm_status_i : std_logic;
+
+ signal rx_error_delay : std_logic_vector(3 downto 0);
-- RX READY MODULE
signal rx_ready_i : std_logic;
signal rx_rm_rst_n, tx_rm_rst_n :std_logic;
+ signal dummy_output_i : std_logic_vector(8 downto 0);
+
+ signal gear_to_rm_rst_i : std_logic;
+ signal gear_to_rm_n_rst_i : std_logic;
+
-- TX READY MODULE
signal tx_ready_i : std_logic;
signal tx_almost_ready_i : std_logic;
hdoutn_ch0 => SD_TXD_N_OUT,
-- CLOCKS
- rxiclk_ch0 => clk_125_i,
+ --rxiclk_ch0 => clk_125_i,
txiclk_ch0 => clk_125_i,
rx_full_clk_ch0 => clk_rx_full,
- rx_half_clk_ch0 => clk_rx_half,
+ -- rx_half_clk_ch0 => clk_rx_half,
tx_full_clk_ch0 => open,
tx_half_clk_ch0 => open,
tx_div2_mode_ch0_c => '0',
-- RX DATA PORT
- rxdata_ch0 => rx_data_i(15 downto 0),
- rx_k_ch0 => rx_data_i(17 downto 16),
+ rxdata_ch0 => rx_data_i(7 downto 0),
+ rx_k_ch0 => rx_data_i(8),
rx_disp_err_ch0 => open,
rx_cv_err_ch0 => rx_error,
tx_pll_lol_qd_s => tx_pll_lol,
rx_los_low_ch0_s => rx_los_low,
rx_cdr_lol_ch0_s => rx_cdr_lol,
- lsm_status_ch0_s => open,
+ lsm_status_ch0_s => lsm_status_i,
SCI_WRDATA => sci_data_in_i,
SCI_RDDATA => sci_data_out_i,
DEBUG_OUT(19 downto 0) <= "00" & tx_data_i;
DEBUG_OUT(23 downto 20) <= "0" & tx_pll_lol & rx_los_low & rx_cdr_lol;
- DEBUG_OUT(27 downto 24) <= proper_word_align_i & proper_byte_align_i & SD_PRSNT_N_IN & SD_LOS_IN;
+ DEBUG_OUT(27 downto 24) <= gear_to_serder_rst_i & proper_byte_align_i & SD_PRSNT_N_IN & SD_LOS_IN;
DEBUG_OUT(31 downto 28) <= rst_qd & rx_serdes_rst & tx_pcs_rst & rx_pcs_rst;
DEBUG_OUT(51 downto 32) <= "00" & rx_data_buf_i;
DEBUG_OUT(59 downto 52) <= rx_fsm_state & tx_fsm_state;
- DEBUG_OUT(63 downto 60) <= "00" & tx_ready_i & tx_almost_ready_i;
+ DEBUG_OUT(63 downto 60) <= SERDES_ready & rx_ready_i & tx_ready_i & tx_almost_ready_i;
DEBUG_OUT(99 downto 96) <= rx_almost_ready_i & rx_see_ready0_i & rx_saw_ready1_i & rx_valid_char_i;
-
- process is
- variable cnt, cntr : unsigned(15 downto 0);
- begin
- wait until rising_edge(clk_125_i);
- cnt := cnt + 1;
- cntr := cntr + 1;
- if rst_n = '0' then
- cntr := x"0000";
- end if;
- DEBUG_OUT(31 + 64 downto 64) <= std_logic_vector(cnt) & std_logic_vector(cntr);
- end process;
+ DEBUG_OUT(103 downto 100) <= wa_position(3 downto 0);
+ DEBUG_OUT(107 downto 104) <= "00" & rx_rm_to_gear_reset_i & gear_to_rm_rst_i;
-------------------------------------------------
-- Reset FSM & Link states
RX_CDR_LOL_CH_S => rx_cdr_lol,
RX_LOS_LOW_CH_S => rx_los_low,
- RM_RESET_IN => '0', --rx_reset_from_rm_i,
- PROPER_BYTE_ALIGN_IN=> proper_byte_align_i,
- PROPER_WORD_ALIGN_IN=> proper_word_align_i,
+ RM_RESET_IN => CTRL_OP(4), --rx_reset_from_rm_i,
+ PROPER_BYTE_ALIGN_IN=> byte_alignment_to_fsm_i,
+ PROPER_WORD_ALIGN_IN=> word_alignment_to_fsm_i,
RX_SERDES_RST_CH_C => rx_serdes_rst,
RX_PCS_RST_CH_C => rx_pcs_rst,
STATE_OUT => rx_fsm_state
);
+ byte_alignment_to_fsm_i <= proper_byte_align_i or CTRL_OP(1);
+ word_alignment_to_fsm_i <= not (gear_to_serder_rst_i or AND_ALL(rx_error_delay)) or CTRL_OP(2);
+ rx_error_delay <= rx_error_delay(rx_error_delay'high - 1 downto 0) & rx_error when rising_edge(clk_125_local);
+
THE_TX_FSM : tx_reset_fsm
port map(
TX_PCS_RST_CH_C => tx_pcs_rst,
STATE_OUT => tx_fsm_state
);
+ --tx_data_i <= "01" & x"00" & CBMNET_READY_CHAR0;
- sd_los_i <= SD_LOS_IN when rising_edge(CLK);
+ proc_rst_fsms_ready: process is begin
+ wait until rising_edge(clk_125_local);
+ rx_rst_fsm_ready_i <= '0';
+ if rx_fsm_state = x"6" then
+ rx_rst_fsm_ready_i <= '1';
+ end if;
- gen_wa_fixation: if WA_FIXATION = c_YES generate
- -- In slave mode, we need the barrel shifter to lock on the lowest position in
- -- order to avoid a non-deterministic skew in the clock/data phase
- -- If we're the master, we don't care about the proper barrel shifter alignment
- proper_byte_align_i <=
- '1' when IS_SYNC_SLAVE = c_NO else
- proper_byte_align_i when not rising_edge(clk_125_i) else
- '1' when wa_position(3 downto 0) = x"0" else '0';
-
- -- detect misaligned gearing fifo
- proper_word_align_i <=
- '1' when rst_n = '0' or rx_serdes_rst = '1' else
- proper_word_align_i when not rising_edge(clk_125_i) else
- -- '0' when rx_serdes_rst ='1' or rst = '1' else
- '0' when rx_data_i(17 downto 16) = "10" and
- (rx_data_i(15 downto 8) = K284 or rx_data_i(15 downto 8) = K285 or rx_data_i(15 downto 8) = K287)
- and rx_data_i(7 downto 0) = x"00" else '1';
-
- serdes_rx_ready_i <= (not rx_cdr_lol) and proper_word_align_i and proper_byte_align_i when rx_fsm_state = x"6" else '0';
- serdes_tx_ready_i <= (not tx_pll_lol) when tx_fsm_state = x"5" else '0';
- serdes_ready_i <= serdes_rx_ready_i and serdes_tx_ready_i;
-
- rx_data_buf_i <= rx_data_i;
- end generate;
+ tx_rst_fsm_ready_i <= '0';
+ if tx_fsm_state = x"5" then
+ tx_rst_fsm_ready_i <= '1';
+ end if;
+ end process;
- gen_wa_no_fixation: if WA_FIXATION = c_NO generate
- proper_byte_align_i <= '1';
- serdes_ready_i <= not (rx_cdr_lol or tx_pll_lol) when tx_fsm_state = x"5" and rx_fsm_state = x"6" else '0';
-
- proc_wa: process is
- variable locked : std_logic;
- variable locked_with_delay : std_logic;
-
- variable delay : std_logic_vector(8 downto 0);
- variable rx_pcs_rst_del : std_logic := '0';
- begin
- wait until rising_edge(clk_125_i);
-
- if locked_with_delay = '1' then
- rx_data_buf_i <= delay(8) & rx_data_i(17) & delay(7 downto 0) & rx_data_i(15 downto 8);
- else
- rx_data_buf_i <= rx_data_i;
- end if;
-
- delay := rx_data_i(16) & rx_data_i(7 downto 0);
-
- if rx_pcs_rst = '1' and rx_pcs_rst_del = '0' then
- locked := '0';
-
- elsif locked = '0' then
- if rx_data_i(17 downto 16) = "10" and (rx_data_i(15 downto 8) = K284 or rx_data_i(15 downto 8) = K285 or rx_data_i(15 downto 8) = K287) and rx_data_i(7 downto 0) = x"00" then
- locked_with_delay := '1';
- locked := '1';
- elsif rx_data_i(17 downto 16) = "01" and (rx_data_i(7 downto 0) = K284 or rx_data_i(7 downto 0) = K285 or rx_data_i(7 downto 0) = K287) and rx_data_i(15 downto 8) = x"00" then
- locked_with_delay := '0';
- locked := '1';
- end if;
-
- end if;
-
- rx_pcs_rst_del := rx_pcs_rst;
- proper_word_align_i <= locked;
- end process;
- end generate;
+ THE_GEAR: CBMNET_PHY_GEAR port map (
+ -- SERDES PORT
+ CLK_250_IN => clk_rx_full, -- in std_logic;
+ PCS_READY_IN => rx_serdes_ready_for_gear_i, -- in std_logic;
+ SERDES_RESET_OUT=> gear_to_serder_rst_i, -- out std_logic;
+ DATA_IN => rx_data_i, -- in std_logic_vector( 8 downto 0);
+
+ -- RM PORT
+ RM_RESET_IN => rx_rm_to_gear_reset_i, -- in std_logic;
+ CLK_125_OUT => clk_rx_half, -- out std_logic;
+ RESET_OUT => gear_to_rm_rst_i, -- out std_logic;
+ DATA_OUT => rx_data_buf_i -- out std_logic_vector(17 downto 0)
+ );
+ rx_serdes_ready_for_gear_i <= (rx_rst_fsm_ready_i and proper_byte_align_i) or CTRL_OP(5);
+ rx_rm_to_gear_reset_i <= rx_reset_from_rm_i and not CTRL_OP(6);
-------------------------------------------------
-- CBMNet Ready Modules
generic map (INCL_8B10B_DEC => c_No)
port map (
clk => clk_125_i,
- res_n => rx_rm_rst_n,
- ready_MGT2RM => serdes_ready_i,
+ res_n => gear_to_rm_n_rst_i,
+ ready_MGT2RM => '1',
rxdata_in(17 downto 0) => rx_data_buf_i,
rxdata_in(19 downto 18) => "00",
reset_rx => rx_reset_from_rm_i
);
+ gear_to_rm_n_rst_i <= not gear_to_rm_rst_i when rising_edge(clk_125_i);
- rx_rm_rst_n <= not (rst or CTRL_OP(1) or not serdes_rx_ready_i); -- or not serdes_ready_i);
-
THE_TX_READY: gtp_tx_ready_module
port map (
clk => clk_125_i, -- : in std_logic;
- res_n => rx_rm_rst_n, -- : in std_logic;
+ res_n => tx_rst_fsm_ready_buf_i, -- : in std_logic;
restart_link => CTRL_OP(14), -- : in std_logic;
- ready_MGT2RM => serdes_tx_ready_i, -- : in std_logic;
+ ready_MGT2RM => '1', -- : in std_logic;
txdata_in => PHY_TXDATA_IN , -- : in std_logic_vector((DATAWIDTH-1) downto 0);
txcharisk_in => PHY_TXDATA_K_IN, -- : in std_logic_vector((WORDS-1) downto 0);
gt11_reinit => open -- : out std_logic
);
- tx_rm_rst_n <= not (rst or CTRL_OP(2) or not serdes_tx_ready_i);
-
+ process is begin
+ wait until rising_edge(clk_125_i);
+
+ if IS_SYNC_SLAVE = c_YES then
+ tx_rst_fsm_ready_buf_i <= tx_rst_fsm_ready_i and not gear_to_rm_rst_i;
+
+ else
+ tx_rst_fsm_ready_buf_i <= tx_rst_fsm_ready_i;
+
+ end if;
+ end process;
+
+
rx_rm_ready_i <= rx_almost_ready_i or rx_ready_i;
SERDES_ready <= tx_ready_i and rx_ready_i when rising_edge(clk_125_i);
led_ok <= SERDES_ready;
+
-------------------------------------------------
-- SCI
-------------------------------------------------
--gives access to serdes config port from slow control and reads word alignment every ~ 40 us
PROC_SCI_CTRL: process
variable cnt : integer range 0 to 4 := 0;
+ variable lsm_status_buf : std_logic;
begin
wait until rising_edge(CLK);
SCI_ACK <= '0';
+ proper_byte_align_i <= '1';
+
case sci_state is
when IDLE =>
sci_ch_i <= x"0";
when GET_WA =>
if cnt = 4 then
- cnt := 0;
- sci_state <= IDLE;
+ cnt := 0;
+ sci_state <= IDLE;
+
+ if lsm_status_buf = '1' and wa_position(3 downto 0) /= x"0" then
+ proper_byte_align_i <= '0';
+ end if;
+
else
- sci_state <= GET_WA_WAIT;
- sci_addr_i <= '0' & x"22";
- sci_ch_i <= x"0";
- sci_ch_i(cnt) <= '1';
- sci_read_i <= '1';
+ sci_state <= GET_WA_WAIT;
+ sci_addr_i <= '0' & x"22";
+ sci_ch_i <= x"0";
+ sci_ch_i(cnt) <= '1';
+ sci_read_i <= '1';
end if;
+
when GET_WA_WAIT =>
sci_state <= GET_WA_WAIT2;
wa_position(cnt*4+3 downto cnt*4) <= sci_data_out_i(3 downto 0);
sci_state <= GET_WA;
cnt := cnt + 1;
-
+
end case;
if (SCI_READ = '1' or SCI_WRITE = '1') and sci_state /= IDLE then
else
SCI_NACK <= '0';
end if;
+
+ lsm_status_buf := lsm_status_i;
end process;
-- RX/TX leds are on as soon as the correspondent pll is locked and data
led_rx <= not rx_cdr_lol;
led_tx <= not tx_pll_lol;
- if (led_timer(20) = '1') or (rx_data_i(17 downto 16) = "10" and rx_data_i(15 downto 0) = x"fcce") then
+ if (led_timer(20) = '1') or (rx_data_buf_i(17 downto 16) = "10" and rx_data_buf_i(15 downto 0) = x"fcce") then
led_rx <= '0';
end if;
end process;
-- STAT_OP REGISTER
-STAT_OP(0) <= clk_125_local;
-STAT_OP(1) <= clk_125_i;
-STAT_OP(2) <= rst;
-STAT_OP(3) <= SD_LOS_IN;
-
-STAT_OP(4) <= rx_serdes_rst;
-STAT_OP(5) <= rx_pcs_rst;
-STAT_OP(6) <= tx_pcs_rst;
-STAT_OP(7) <= rst_qd;
-
-STAT_OP(8) <= rx_los_low;
-STAT_OP(9) <= rx_cdr_lol;
-STAT_OP(10) <= OR_ALL(rx_error);
-STAT_OP(11) <= rx_reset_from_rm_i;
-
-STAT_OP(12) <= tx_pll_lol;
-STAT_OP(13) <= proper_byte_align_i;
-STAT_OP(14) <= proper_word_align_i;
-STAT_OP(15) <= serdes_ready_i;
+STAT_OP(8 downto 0) <= rx_data_i when CTRL_OP(8) = '0' else dummy_output_i;
+
+STAT_OP(9) <= clk_rx_full;
+STAT_OP(10) <= clk_125_i;
+STAT_OP(11) <= rx_cdr_lol;
+STAT_OP(12) <= rx_los_low;
+STAT_OP(13) <= lsm_status_i;
+STAT_OP(14) <= rx_serdes_rst;
+STAT_OP(15) <= rx_pcs_rst;
+
+dummy_output_i(3 downto 0) <= wa_position(3 downto 0);
+
+dummy_output_i(4) <= rx_rst_fsm_ready_i;
+dummy_output_i(5) <= tx_pll_lol;
+dummy_output_i(6) <= tx_pcs_rst;
+dummy_output_i(7) <= rx_serdes_ready_for_gear_i;
+dummy_output_i(8) <= serdes_rx_ready_i;
+
+
+-- STAT_OP(0) <= clk_125_i;
+-- STAT_OP(1) <= rst;
+-- STAT_OP(2) <= rx_serdes_rst;
+-- STAT_OP(3) <= rx_pcs_rst;
+--
+-- STAT_OP(4) <= tx_pcs_rst;
+-- STAT_OP(5) <= rst_qd;
+-- STAT_OP(6) <= tx_pll_lol;
+-- STAT_OP(7) <= rx_cdr_lol;
+--
+-- STAT_OP(8) <= rx_los_low;
+-- STAT_OP(9) <= rx_rst_fsm_ready_i;
+-- STAT_OP(10) <= proper_byte_align_i;
+-- STAT_OP(11) <= gear_to_serder_rst_i;
+--
+-- STAT_OP(12) <= serdes_rx_ready_i;
+-- STAT_OP(13) <= wa_position(0);
+-- STAT_OP(14) <= wa_position(1);
+-- STAT_OP(15) <= wa_position(2);
-- STAT_OP(3) <= rx_valid_char_i;
cs <= ns;
rx_lol_los_del <= rx_lol_los;
rx_lol_los_int <= rx_lol_los_del;
+
tx_pll_lol_qd_s_int <= tx_pll_lol_qd_s;
+
RX_PCS_RST_CH_C <= rx_pcs_rst_ch_c_int;
RX_SERDES_RST_CH_C <= rx_serdes_rst_ch_c_int;
rx_los_low_int <= rx_los_low_ch_s;
else
ns <= NORMAL;
end if;
- elsif rx_lol_los_int = '0' then
- ns <= NORMAL;
+ -- elsif rx_lol_los_int = '0' then
+ -- ns <= NORMAL;
else
ns <= WAIT_FOR_timer2;
end if;
--- /dev/null
+--Media interface for Lattice ECP3 using PCS at 2.5GHz
+
+LIBRARY IEEE;
+ USE IEEE.std_logic_1164.ALL;
+ USE IEEE.numeric_std.all;
+
+library work;
+ use work.trb_net_std.all;
+ use work.trb_net_components.all;
+ use work.med_sync_define.all;
+ use work.cbmnet_interface_pkg.all;
+ use work.cbmnet_phy_pkg.all;
+
+entity CBMNET_PHY_GEAR is
+ port (
+ -- SERDES PORT
+ CLK_250_IN : in std_logic;
+ PCS_READY_IN: in std_logic;
+ SERDES_RESET_OUT : out std_logic;
+ DATA_IN : in std_logic_vector( 8 downto 0);
+
+ -- RM PORT
+ RM_RESET_IN : in std_logic;
+ CLK_125_OUT : out std_logic;
+ RESET_OUT : out std_logic;
+ DATA_OUT : out std_logic_vector(17 downto 0)
+ );
+end entity;
+
+architecture RTL of CBMNET_PHY_GEAR is
+ type FSM_STATES_T is (FSM_START, FSM_WAIT_FOR_LOCK, FSM_RESET, FSM_DELAY, FSM_LOCKED);
+ signal fsm_i, fsm_next_i : FSM_STATES_T;
+
+ signal delay_clock_i : std_logic;
+
+ signal indi_alignment_i : std_logic;
+ signal indi_misalignment_i : std_logic;
+
+ signal data_delay_i : std_logic_vector(8 downto 0);
+ signal data_out_buf_i : std_logic_vector(17 downto 0);
+ signal clk_125_i : std_logic;
+
+ signal reset_timer_i : std_logic;
+ signal timeout_i : std_logic;
+begin
+-- FSM sych part
+ proc_sych: process is begin
+ wait until rising_edge(clk_125_i);
+
+ if PCS_READY_IN = '0' then
+ fsm_i <= FSM_START;
+ else
+ fsm_i <= fsm_next_i;
+ end if;
+ end process;
+
+
+ process(fsm_i, indi_alignment_i, indi_misalignment_i) is begin
+ fsm_next_i <= fsm_i;
+
+ SERDES_RESET_OUT <= '0';
+ RESET_OUT <= '1';
+ reset_timer_i <= '0';
+ delay_clock_i <= '0';
+
+ case (fsm_i) is
+ when FSM_START =>
+ reset_timer_i <= '1';
+ fsm_next_i <= FSM_WAIT_FOR_LOCK;
+
+ when FSM_WAIT_FOR_LOCK =>
+ if indi_alignment_i = '1' then
+ -- already correctly aligned, so just fix current state
+ fsm_next_i <= FSM_LOCKED;
+
+ elsif indi_misalignment_i = '1' then
+ -- we're off by one word. just wait a single frame
+ delay_clock_i <= '1';
+ fsm_next_i <= FSM_LOCKED;
+
+ elsif timeout_i = '1' then
+ fsm_next_i <= FSM_RESET;
+
+ end if;
+
+ when FSM_LOCKED =>
+ RESET_OUT <= '0';
+
+ if RM_RESET_IN = '1' then
+ fsm_next_i <= FSM_RESET;
+
+ elsif indi_misalignment_i = '1' then
+ -- in this state we should already have a stable and correct lock.
+ -- if we, however detect a missalignment, something is terribly wrong.
+ -- in this case, will perform a resychronisation
+
+ fsm_next_i <= FSM_RESET;
+ end if;
+
+
+ when FSM_RESET =>
+ SERDES_RESET_OUT <= '1';
+
+ end case;
+ end process;
+
+-- Timeout (approx. 1ms)
+ proc_timeout: process is
+ variable timer_v : unsigned(17 downto 0);
+ begin
+ wait until rising_edge(clk_125_i);
+
+ if reset_timer_i = '1' then
+ timer_v := TO_UNSIGNED(0, timer_v'length);
+
+ elsif timer_v(timer_v'high) = '0' then
+ timer_v := timer_v + TO_UNSIGNED(1,1);
+
+ end if;
+
+ timeout_i <= timer_v(timer_v'high);
+ end process;
+
+-- Implement the 2:1 gearing and clock down-sampling
+ proc_gear: process is
+ variable last_delay_clock_v : std_logic := '0';
+ variable word_idx_v : std_logic;
+ begin
+ wait until rising_edge(CLK_250_IN);
+
+ if (delay_clock_i = '1' and last_delay_clock_v = '0') then
+ -- just wait
+ else
+ if word_idx_v = '0' then
+ data_delay_i <= DATA_IN;
+ clk_125_i <= '0';
+
+ else
+ data_out_buf_i <= data_delay_i(8) & DATA_IN(8) & data_delay_i(7 downto 0) & DATA_IN(7 downto 0);
+ clk_125_i <= '1';
+
+ end if;
+
+ word_idx_v := not word_idx_v;
+ end if;
+
+ last_delay_clock_v := delay_clock_i;
+ end process;
+
+ DATA_OUT <= data_out_buf_i;
+ CLK_125_OUT <= clk_125_i;
+
+-- Detect Indications for correct or wrong alignment
+ indi_alignment_i <= '1' when data_out_buf_i(17 downto 16) = "01" and data_out_buf_i(15 downto 8) = x"00" and
+ (data_out_buf_i(7 downto 0) = CBMNET_READY_CHAR0 or data_out_buf_i(7 downto 0) = CBMNET_READY_CHAR1 or data_out_buf_i(7 downto 0) = CBMNET_ALIGN_CHAR) else '0';
+
+ indi_misalignment_i <= '1' when data_out_buf_i(17 downto 16) = "10" and data_out_buf_i(7 downto 0) = x"00" and
+ (data_out_buf_i(15 downto 8) = CBMNET_READY_CHAR0 or data_out_buf_i(15 downto 8) = CBMNET_READY_CHAR1 or data_out_buf_i(15 downto 8) = CBMNET_ALIGN_CHAR) else '0';
+
+end architecture RTL;
\ No newline at end of file
DEBUG_OUT : out std_logic_vector (127 downto 0) := (others => '0')
);
end component;
+
+ component CBMNET_PHY_GEAR is
+ port (
+ -- SERDES PORT
+ CLK_250_IN : in std_logic;
+ PCS_READY_IN: in std_logic;
+ SERDES_RESET_OUT : out std_logic;
+ DATA_IN : in std_logic_vector( 8 downto 0);
+
+ -- RM PORT
+ RM_RESET_IN : in std_logic;
+ CLK_125_OUT : out std_logic;
+ RESET_OUT : out std_logic;
+ DATA_OUT : out std_logic_vector(17 downto 0)
+ );
+ end component;
+
--------------------------------------------------- INTERNAL
- component cbmnet_sfp1 is
- generic (
- USER_CONFIG_FILE : String := "cbmnet_sfp1.txt"
- );
- port (
- ------------------
- -- CH0 --
- hdinp_ch0, hdinn_ch0 : in std_logic;
- hdoutp_ch0, hdoutn_ch0 : out std_logic;
- sci_sel_ch0 : in std_logic;
- rxiclk_ch0 : in std_logic;
- txiclk_ch0 : in std_logic;
- rx_full_clk_ch0 : out std_logic;
- rx_half_clk_ch0 : out std_logic;
- tx_full_clk_ch0 : out std_logic;
- tx_half_clk_ch0 : out std_logic;
- fpga_rxrefclk_ch0 : in std_logic;
- txdata_ch0 : in std_logic_vector (15 downto 0);
- tx_k_ch0 : in std_logic_vector (1 downto 0);
- tx_force_disp_ch0 : in std_logic_vector (1 downto 0);
- tx_disp_sel_ch0 : in std_logic_vector (1 downto 0);
- rxdata_ch0 : out std_logic_vector (15 downto 0);
- rx_k_ch0 : out std_logic_vector (1 downto 0);
- rx_disp_err_ch0 : out std_logic_vector (1 downto 0);
- rx_cv_err_ch0 : out std_logic_vector (1 downto 0);
- rx_serdes_rst_ch0_c : in std_logic;
- sb_felb_ch0_c : in std_logic;
- sb_felb_rst_ch0_c : in std_logic;
- --word_align_en_ch0_c : in std_logic;
- tx_pcs_rst_ch0_c : in std_logic;
- tx_pwrup_ch0_c : in std_logic;
- rx_pcs_rst_ch0_c : in std_logic;
- rx_pwrup_ch0_c : in std_logic;
- rx_los_low_ch0_s : out std_logic;
- rx_cdr_lol_ch0_s : out std_logic;
- tx_div2_mode_ch0_c : in std_logic;
- rx_div2_mode_ch0_c : in std_logic;
- lsm_status_ch0_s : OUT std_logic;
-
- -- CH1 --
- -- CH2 --
- -- CH3 --
- ---- Miscillaneous ports
- sci_wrdata : in std_logic_vector (7 downto 0);
- sci_addr : in std_logic_vector (5 downto 0);
- sci_rddata : out std_logic_vector (7 downto 0);
- sci_sel_quad : in std_logic;
- sci_rd : in std_logic;
- sci_wrn : in std_logic;
- sci_int : out std_logic;
- fpga_txrefclk : in std_logic;
- tx_serdes_rst_c : in std_logic;
- tx_pll_lol_qd_s : out std_logic;
- rst_qd_c : in std_logic;
- -- refclk2fpga : out std_logic;
- serdes_rst_qd_c : in std_logic
+ COMPONENT cbmnet_sfp1
+ PORT(
+ hdinp_ch0 : IN std_logic;
+ hdinn_ch0 : IN std_logic;
+ sci_sel_ch0 : IN std_logic;
+ txiclk_ch0 : IN std_logic;
+ fpga_rxrefclk_ch0 : IN std_logic;
+ txdata_ch0 : IN std_logic_vector(15 downto 0);
+ tx_k_ch0 : IN std_logic_vector(1 downto 0);
+ tx_force_disp_ch0 : IN std_logic_vector(1 downto 0);
+ tx_disp_sel_ch0 : IN std_logic_vector(1 downto 0);
+ rx_serdes_rst_ch0_c : IN std_logic;
+ sb_felb_ch0_c : IN std_logic;
+ sb_felb_rst_ch0_c : IN std_logic;
+ tx_pcs_rst_ch0_c : IN std_logic;
+ tx_pwrup_ch0_c : IN std_logic;
+ rx_pcs_rst_ch0_c : IN std_logic;
+ rx_pwrup_ch0_c : IN std_logic;
+ tx_div2_mode_ch0_c : IN std_logic;
+ rx_div2_mode_ch0_c : IN std_logic;
+ sci_wrdata : IN std_logic_vector(7 downto 0);
+ sci_addr : IN std_logic_vector(5 downto 0);
+ sci_sel_quad : IN std_logic;
+ sci_rd : IN std_logic;
+ sci_wrn : IN std_logic;
+ fpga_txrefclk : IN std_logic;
+ tx_serdes_rst_c : IN std_logic;
+ rst_qd_c : IN std_logic;
+ serdes_rst_qd_c : IN std_logic;
+ hdoutp_ch0 : OUT std_logic;
+ hdoutn_ch0 : OUT std_logic;
+ rx_full_clk_ch0 : OUT std_logic;
+ rx_half_clk_ch0 : OUT std_logic;
+ tx_full_clk_ch0 : OUT std_logic;
+ tx_half_clk_ch0 : OUT std_logic;
+ rxdata_ch0 : OUT std_logic_vector(7 downto 0);
+ rx_k_ch0 : OUT std_logic;
+ rx_disp_err_ch0 : OUT std_logic;
+ rx_cv_err_ch0 : OUT std_logic;
+ rx_los_low_ch0_s : OUT std_logic;
+ lsm_status_ch0_s : OUT std_logic;
+ rx_cdr_lol_ch0_s : OUT std_logic;
+ sci_rddata : OUT std_logic_vector(7 downto 0);
+ tx_pll_lol_qd_s : OUT std_logic
);
- end component;
+ END COMPONENT;
component cbmnet_phy_ecp3_rx_reset_fsm is
port (
+++ /dev/null
-library ieee;
- use ieee.std_logic_1164.all;
- use ieee.numeric_std.all;
-
-package cbmnet_interface_pkg is
- constant K280 : std_logic_vector(7 downto 0) := "00011100";
- constant K281 : std_logic_vector(7 downto 0) := "00111100";
- constant K282 : std_logic_vector(7 downto 0) := "01011100";
- constant K283 : std_logic_vector(7 downto 0) := "01111100";
- constant K284 : std_logic_vector(7 downto 0) := "10011100";
- constant K285 : std_logic_vector(7 downto 0) := "10111100";
- constant K286 : std_logic_vector(7 downto 0) := "11011100";
- constant K287 : std_logic_vector(7 downto 0) := "11111100";
- constant K237 : std_logic_vector(7 downto 0) := "11111110";
- constant K277 : std_logic_vector(7 downto 0) := "11111011";
- constant K297 : std_logic_vector(7 downto 0) := "11111101";
- constant K307 : std_logic_vector(7 downto 0) := "11111110";
-
- component gtp_rx_ready_module is
- generic (
- READY_CHAR0 : std_logic_vector(7 downto 0) := K284;
- READY_CHAR1 : std_logic_vector(7 downto 0) := K287;
- ALIGN_CHAR : std_logic_vector(7 downto 0) := K285;
- DATAWIDTH : integer := 16;
- WORDS : integer := 2; --DATAWIDTH/8;
-
- INCL_8B10B_DEC : integer range 0 to 1 := 1
- );
- port (
- clk : in std_logic;
- res_n : in std_logic;
- ready_MGT2RM : in std_logic;
- rxdata_in : in std_logic_vector((WORDS*10)-1 downto 0);
-
- tx_ready : in std_logic;
- tx_almost_ready : in std_logic;
-
- ready_RM2LP : out std_logic;
- almost_ready_OUT : out std_logic;
- rxdata_out : out std_logic_vector((DATAWIDTH-1) downto 0);
- charisk_out : out std_logic_vector((WORDS-1) downto 0);
- see_ready0 : out std_logic;
- saw_ready1 : out std_logic;
- valid_char : out std_logic;
- reset_rx : out std_logic
- );
- end component;
-
- component gtp_tx_ready_module is
- generic (
- READY_CHAR0 : std_logic_vector(7 downto 0) := K284;
- READY_CHAR1 : std_logic_vector(7 downto 0) := K287;
- ALIGN_CHAR : std_logic_vector(7 downto 0) := K285;
- DATAWIDTH : integer := 16;
- WORDS :integer := 2 --DATAWIDTH/8;
- );
- port (
- clk : in std_logic;
- res_n : in std_logic;
- restart_link : in std_logic;
- ready_MGT2RM : in std_logic;
- txdata_in : in std_logic_vector((DATAWIDTH-1) downto 0);
- txcharisk_in : in std_logic_vector((WORDS-1) downto 0);
-
- see_ready0 : in std_logic;
- saw_ready1 : in std_logic;
- valid_char : in std_logic;
- rx_rm_ready : in std_logic;
-
- ready_RM2LP : out std_logic;
- txdata_out : out std_logic_vector((WORDS*9)-1 downto 0);
- almost_ready : out std_logic;
- gt11_reinit : out std_logic
- );
- end component;
-
- component lp_top is
- generic (
- NUM_LANES : integer := 1; -- Number of data lanes
- TX_SLAVE : integer := 0 -- If set; module will act as TX slave; otherwise as RX slave
- -- If only one lane is used; parameter does not matter
- );
- port (
- clk : in std_logic; -- Main clock
- res_n : in std_logic; -- Active low reset; can be changed by define
- link_active : out std_logic; -- link is active and can send and receive data
-
- ctrl2send_stop : out std_logic; -- send control interface
- ctrl2send_start : in std_logic;
- ctrl2send_end : in std_logic;
- ctrl2send : in std_logic_vector(15 downto 0);
-
- data2send_stop : out std_logic_vector(NUM_LANES-1 downto 0); -- send data interface
- data2send_start : in std_logic_vector(NUM_LANES-1 downto 0);
- data2send_end : in std_logic_vector(NUM_LANES-1 downto 0);
- data2send : in std_logic_vector((16*NUM_LANES)-1 downto 0);
-
- dlm2send_va : in std_logic; -- send dlm interface
- dlm2send : in std_logic_vector(3 downto 0);
-
- dlm_rec_type : out std_logic_vector(3 downto 0); -- receive dlm interface
- dlm_rec_va : out std_logic;
-
- data_rec : out std_logic_vector((16*NUM_LANES)-1 downto 0); -- receive data interface
- data_rec_start : out std_logic_vector(NUM_LANES-1 downto 0);
- data_rec_end : out std_logic_vector(NUM_LANES-1 downto 0);
- data_rec_stop : in std_logic_vector(NUM_LANES-1 downto 0);
-
- ctrl_rec : out std_logic_vector(15 downto 0); -- receive control interface
- ctrl_rec_start : out std_logic;
- ctrl_rec_end : out std_logic;
- ctrl_rec_stop : in std_logic;
-
- data_from_link : in std_logic_vector((18*NUM_LANES)-1 downto 0); -- interface from the PHY
- data2link : out std_logic_vector((18*NUM_LANES)-1 downto 0); -- interface to the PHY
-
- link_activeovr : in std_logic; -- Overrides; set 0 by default
- link_readyovr : in std_logic;
-
- SERDES_ready : in std_logic -- signalize when PHY ready
- );
- end component;
-
-
-
-end package cbmnet_interface_pkg;
-
-package body cbmnet_interface_pkg is
-end package body;
\ No newline at end of file
system "xterm -e './compile_periph_frankfurt.pl s; read' &";
sleep 5;
system "xterm -e './compile_periph_frankfurt.pl w; read' &";
- sleep 5;
- local $| = 1;
- while ( (-e '.lock_slave') or (-e '.lock_master')) {
- sleep 3;
- print '.';
- }
-
exit;
}
my $workdir = "workdir_" . ($build_slave ? 'slave' : 'master');
-system "touch .lock_" . ($build_slave ? 'slave' : 'master');
symlink($CbmNetPath, 'cbmnet') unless (-e 'cbmnet');
unless(-e $workdir) {
chdir "..";
-unlink ".lock_" . ($build_slave ? 'slave' : 'master');
-
-print "DONE\n";
-
-unless (-e "$workdir/trb3_periph_cbmnet.bit") {
- print "no bit file found. press enter to continue\n\a"; <>;
-}
-
sub execute {
my ($c, $op) = @_;
entity trb3_periph_cbmnet is
generic (
- CBM_FEE_MODE : integer := c_YES -- in FEE mode, logic will run on recovered clock and (for now) listen only to data received
+ CBM_FEE_MODE : integer := CBM_FEE_MODE_C -- in FEE mode, logic will run on recovered clock and (for now) listen only to data received
-- in Master mode, logic will run on internal clock and regularly send dlms
);
port(
signal phy_stat_op, phy_ctrl_op : std_logic_vector(15 downto 0) := (others => '0');
signal phy_stat_debug, phy_ctrl_debug : std_logic_vector(63 downto 0) := (others => '0');
+
+ signal phy_debug_i : std_logic_vector (127 downto 0) := (others => '0');
begin
clk_125_i <= CLK_GPLL_LEFT;
STAT_OP => phy_stat_op,
CTRL_OP => phy_ctrl_op,
STAT_DEBUG => phy_stat_debug,
- CTRL_DEBUG => phy_ctrl_debug
+ CTRL_DEBUG => phy_ctrl_debug,
+ DEBUG_OUT => phy_debug_i
);
SFP_RATESEL <= (others => '1');
debug_ack <= debug_read_en or debug_write_en;
case (address) is
- when 0 => debug_data_out <= x"0000" & phy_stat_op;
- when 1 => debug_data_out <= x"0000" & phy_ctrl_op;
- when 2 => debug_data_out <= phy_stat_debug(31 downto 0);
- when 3 => debug_data_out <= phy_stat_debug(63 downto 32);
- when 4 => debug_data_out <= phy_ctrl_debug(31 downto 0);
- when 5 => debug_data_out <= phy_ctrl_debug(63 downto 32);
+ when 0 => debug_data_out <= x"0000" & phy_stat_op;
+ when 1 => debug_data_out <= x"0000" & phy_ctrl_op;
+ when 2 => debug_data_out <= phy_stat_debug(31 downto 0);
+ when 3 => debug_data_out <= phy_stat_debug(63 downto 32);
+ when 4 => debug_data_out <= phy_ctrl_debug(31 downto 0);
+ when 5 => debug_data_out <= phy_ctrl_debug(63 downto 32);
+ when 6 => debug_data_out <= STD_LOGIC_VECTOR(TO_UNSIGNED(CBM_FEE_MODE, 32));
+ when 8 => debug_data_out <= phy_debug_i(31+32*0 downto 32*0);
+ when 9 => debug_data_out <= phy_debug_i(31+32*1 downto 32*1);
+ when 10 => debug_data_out <= phy_debug_i(31+32*2 downto 32*2);
+ when 11 => debug_data_out <= phy_debug_i(31+32*3 downto 32*3);
when others => debug_ack <= '0';
end case;
end case;
end if;
end process;
-
+
+ --TEST_LINE <= phy_stat_op;
---------------------------------------------------------------------------
-- Reset Generation