From c107f6816b95e8af011976965e58cf40a3459fb0 Mon Sep 17 00:00:00 2001 From: Manuel Penschuck Date: Thu, 3 Oct 2013 15:33:12 +0200 Subject: [PATCH] Phy finally operational (again) --- cbmnet/code/cbmnet_interface_pkg.vhd | 6 +- cbmnet/code/cbmnet_phy_ecp3.vhd | 269 ++++++++++--------- cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd | 6 +- cbmnet/code/cbmnet_phy_gear.vhd | 160 +++++++++++ cbmnet/code/cbmnet_phy_pkg.vhd | 119 ++++---- cbmnet/code/cbmnet_pkg.vhd | 129 --------- cbmnet/compile_periph_frankfurt.pl | 16 -- cbmnet/trb3_periph_cbmnet.vhd | 27 +- 8 files changed, 392 insertions(+), 340 deletions(-) create mode 100644 cbmnet/code/cbmnet_phy_gear.vhd delete mode 100644 cbmnet/code/cbmnet_pkg.vhd diff --git a/cbmnet/code/cbmnet_interface_pkg.vhd b/cbmnet/code/cbmnet_interface_pkg.vhd index da8f286..8460f90 100644 --- a/cbmnet/code/cbmnet_interface_pkg.vhd +++ b/cbmnet/code/cbmnet_interface_pkg.vhd @@ -15,7 +15,11 @@ package cbmnet_interface_pkg is 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; diff --git a/cbmnet/code/cbmnet_phy_ecp3.vhd b/cbmnet/code/cbmnet_phy_ecp3.vhd index b3a3dae..8ea9cae 100644 --- a/cbmnet/code/cbmnet_phy_ecp3.vhd +++ b/cbmnet/code/cbmnet_phy_ecp3.vhd @@ -80,10 +80,10 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is 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; @@ -120,10 +120,13 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is 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; @@ -132,8 +135,19 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is 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; @@ -146,6 +160,11 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is 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; @@ -179,11 +198,11 @@ begin 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, @@ -211,8 +230,8 @@ begin 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, @@ -226,7 +245,7 @@ begin 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, @@ -242,26 +261,16 @@ begin 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 @@ -274,14 +283,18 @@ begin 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( @@ -292,73 +305,36 @@ begin 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 @@ -367,8 +343,8 @@ begin 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", @@ -387,15 +363,14 @@ begin 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); @@ -410,22 +385,37 @@ begin 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"; @@ -441,15 +431,21 @@ begin 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; @@ -460,7 +456,7 @@ begin 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 @@ -468,6 +464,8 @@ begin 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 @@ -479,7 +477,7 @@ begin 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; @@ -514,25 +512,44 @@ begin 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; diff --git a/cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd b/cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd index 7d192e7..68c5b9b 100644 --- a/cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd +++ b/cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd @@ -74,7 +74,9 @@ begin 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; @@ -154,8 +156,8 @@ begin 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; diff --git a/cbmnet/code/cbmnet_phy_gear.vhd b/cbmnet/code/cbmnet_phy_gear.vhd new file mode 100644 index 0000000..6a43775 --- /dev/null +++ b/cbmnet/code/cbmnet_phy_gear.vhd @@ -0,0 +1,160 @@ +--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 diff --git a/cbmnet/code/cbmnet_phy_pkg.vhd b/cbmnet/code/cbmnet_phy_pkg.vhd index 3adddc2..87eaa8d 100644 --- a/cbmnet/code/cbmnet_phy_pkg.vhd +++ b/cbmnet/code/cbmnet_phy_pkg.vhd @@ -55,66 +55,71 @@ package cbmnet_phy_pkg is 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 ( diff --git a/cbmnet/code/cbmnet_pkg.vhd b/cbmnet/code/cbmnet_pkg.vhd deleted file mode 100644 index da8f286..0000000 --- a/cbmnet/code/cbmnet_pkg.vhd +++ /dev/null @@ -1,129 +0,0 @@ -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 diff --git a/cbmnet/compile_periph_frankfurt.pl b/cbmnet/compile_periph_frankfurt.pl index fd58eed..939fd0d 100755 --- a/cbmnet/compile_periph_frankfurt.pl +++ b/cbmnet/compile_periph_frankfurt.pl @@ -31,13 +31,6 @@ if ($build_master and $build_slave) { 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; } @@ -55,7 +48,6 @@ my $lm_license_file_for_par = "1702\@hadeb05.gsi.de"; my $workdir = "workdir_" . ($build_slave ? 'slave' : 'master'); -system "touch .lock_" . ($build_slave ? 'slave' : 'master'); symlink($CbmNetPath, 'cbmnet') unless (-e 'cbmnet'); unless(-e $workdir) { @@ -182,14 +174,6 @@ execute($c); 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) = @_; diff --git a/cbmnet/trb3_periph_cbmnet.vhd b/cbmnet/trb3_periph_cbmnet.vhd index c00e9ab..97db0e1 100644 --- a/cbmnet/trb3_periph_cbmnet.vhd +++ b/cbmnet/trb3_periph_cbmnet.vhd @@ -14,7 +14,7 @@ use work.cbmnet_phy_pkg.all; 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( @@ -281,6 +281,8 @@ architecture trb3_periph_arch of trb3_periph_cbmnet is 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; @@ -330,7 +332,8 @@ begin 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'); @@ -421,12 +424,17 @@ begin 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; @@ -439,7 +447,8 @@ begin end case; end if; end process; - + + --TEST_LINE <= phy_stat_op; --------------------------------------------------------------------------- -- Reset Generation -- 2.43.0