From 5d4a9d4d32f461e2aa59b8de528f610afa18834d Mon Sep 17 00:00:00 2001 From: Peter Lemmens Date: Thu, 4 Sep 2014 16:42:35 +0200 Subject: [PATCH] Writing new quad output soda source with onlu a trb-endpoint to control it but no trbnet over the optical link. --- code/ip/serdes_4_sync_downstream.ipx | 14 +- code/ip/serdes_4_sync_downstream.lpc | 4 +- code/ip/serdes_sync_upstream.ipx | 14 +- code/ip/serdes_sync_upstream.lpc | 4 +- code/med_ecp3_sfp_4_SODA.vhd | 651 +++++++++++++++++++++++ code/med_ecp3_sfp_sync_down.vhd | 71 +-- code/med_ecp3_sfp_sync_up.vhd | 20 +- code/soda_4source.vhd | 447 ++++++++++++++++ code/soda_4source_synconstraints.fdc | 67 +++ code/soda_components.vhd | 588 ++++++++++++--------- code/trb3_periph_EP_soda4source.vhd | 756 ++++++++++++++++++++++++++ code/trb3_periph_hub.vhd | 758 +++++++++++++++++++++++++++ code/trb3_periph_sodaclient.vhd | 45 +- soda_4source_EP.ldf | 335 ++++++++++++ soda_4source_EP.lpf | 213 ++++++++ soda_client.ldf | 2 +- soda_hub.ldf | 3 +- soda_hub_probe.rvl | 64 ++- soda_source_probe.rvl | 42 +- trb3_soda_client.xcf | 9 +- trb3_soda_hub.xcf | 13 +- trb3_soda_source.xcf | 9 +- 22 files changed, 3747 insertions(+), 382 deletions(-) create mode 100644 code/med_ecp3_sfp_4_SODA.vhd create mode 100644 code/soda_4source.vhd create mode 100644 code/soda_4source_synconstraints.fdc create mode 100644 code/trb3_periph_EP_soda4source.vhd create mode 100644 code/trb3_periph_hub.vhd create mode 100644 soda_4source_EP.ldf create mode 100644 soda_4source_EP.lpf diff --git a/code/ip/serdes_4_sync_downstream.ipx b/code/ip/serdes_4_sync_downstream.ipx index 9c4b2c1..bb723b0 100644 --- a/code/ip/serdes_4_sync_downstream.ipx +++ b/code/ip/serdes_4_sync_downstream.ipx @@ -1,11 +1,11 @@ - + - - - - - - + + + + + + diff --git a/code/ip/serdes_4_sync_downstream.lpc b/code/ip/serdes_4_sync_downstream.lpc index 62b6d65..e480fca 100644 --- a/code/ip/serdes_4_sync_downstream.lpc +++ b/code/ip/serdes_4_sync_downstream.lpc @@ -16,8 +16,8 @@ CoreRevision=8.1 ModuleName=serdes_4_sync_downstream SourceFormat=VHDL ParameterFileVersion=1.0 -Date=05/13/2014 -Time=16:08:01 +Date=09/01/2014 +Time=11:06:05 [Parameters] Verilog=0 diff --git a/code/ip/serdes_sync_upstream.ipx b/code/ip/serdes_sync_upstream.ipx index c75996b..ba43a74 100644 --- a/code/ip/serdes_sync_upstream.ipx +++ b/code/ip/serdes_sync_upstream.ipx @@ -1,11 +1,11 @@ - + - - - - - - + + + + + + diff --git a/code/ip/serdes_sync_upstream.lpc b/code/ip/serdes_sync_upstream.lpc index 832cc40..332fc40 100644 --- a/code/ip/serdes_sync_upstream.lpc +++ b/code/ip/serdes_sync_upstream.lpc @@ -16,8 +16,8 @@ CoreRevision=8.1 ModuleName=serdes_sync_upstream SourceFormat=VHDL ParameterFileVersion=1.0 -Date=07/08/2014 -Time=16:04:19 +Date=08/27/2014 +Time=11:44:00 [Parameters] Verilog=0 diff --git a/code/med_ecp3_sfp_4_SODA.vhd b/code/med_ecp3_sfp_4_SODA.vhd new file mode 100644 index 0000000..2d4e86d --- /dev/null +++ b/code/med_ecp3_sfp_4_SODA.vhd @@ -0,0 +1,651 @@ +--4 channel Media interface for Lattice ECP3 using PCS at 2GHz + +LIBRARY IEEE; +use IEEE.std_logic_1164.ALL; +use IEEE.numeric_std.all; +use IEEE.std_logic_unsigned.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.med_sync_define.all; +use work.soda_components.all; + +entity med_ecp3_sfp_4_soda is + generic( SERDES_NUM : integer range 0 to 3 := 0; + IS_SYNC_SLAVE : integer := c_NO); -- hub downlink is NO slave + port( + OSC_CLK : in std_logic; -- 200 MHz reference clock + TX_DATACLK : in std_logic; -- 200 MHz data clock + SYSCLK : in std_logic; -- 100 MHz main clock net, synchronous to OSC clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + --------------------------------------------------------------------------------------------------------------------------------------------------------- +-- LINK_DISABLE_IN : in std_logic; -- downlinks must behave as slaves to uplink connection. Downlinks are released once unlink is established. + --------------------------------------------------------------------------------------------------------------------------------------------------------- + RX_HALF_CLK_OUT : out std_logic_vector(3 downto 0) := (others => '0'); --100 MHz + RX_FULL_CLK_OUT : out std_logic_vector(3 downto 0) := (others => '0'); --200 MHz + TX_HALF_CLK_OUT : out std_logic_vector(3 downto 0) := (others => '0'); --100 MHz + TX_FULL_CLK_OUT : out std_logic_vector(3 downto 0) := (others => '0'); --200 MHz + + --Sync operation + RX_DLM_OUT : out t_HUB_BIT; --std_logic_vector(3 downto 0) := (others => '0'); + RX_DLM_WORD_OUT : out t_HUB_BYTE; --std_logic_vector(4*8 - 1 downto 0) := (others => '0'); + TX_DLM_IN : in t_HUB_BIT; --std_logic_vector(3 downto 0) := (others => '0'); + TX_DLM_WORD_IN : in t_HUB_BYTE; --std_logic_vector(4*8 - 1 downto 0) := (others => '0'); + TX_DLM_PREVIEW_IN : in t_HUB_BIT; --std_logic_vector(3 downto 0) := (others => '0'); --PL! + LINK_PHASE_OUT : out t_HUB_BIT; --std_logic_vector(3 downto 0) := (others => '0'); --PL! + + --SFP Connection + SD_RXD_P_IN : in t_HUB_BIT; --std_logic_vector(3 downto 0); + SD_RXD_N_IN : in t_HUB_BIT; --std_logic_vector(3 downto 0); + SD_TXD_P_OUT : out t_HUB_BIT; --std_logic_vector(3 downto 0); + SD_TXD_N_OUT : out t_HUB_BIT; --std_logic_vector(3 downto 0); + SD_REFCLK_P_IN : in t_HUB_BIT; --std_logic; --not used + SD_REFCLK_N_IN : in t_HUB_BIT; --std_logic; --not used + SD_PRSNT_N_IN : in t_HUB_BIT; --std_logic; -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) + SD_LOS_IN : in t_HUB_BIT; --std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) + SD_TXDIS_OUT : out t_HUB_BIT; --std_logic := '0'; -- SFP disable + --Control Interface + SCI_DATA_IN : in std_logic_vector(7 downto 0) := (others => '0'); + SCI_DATA_OUT : out std_logic_vector(7 downto 0) := (others => '0'); + SCI_ADDR : in std_logic_vector(8 downto 0) := (others => '0'); + SCI_READ : in std_logic := '0'; + SCI_WRITE : in std_logic := '0'; + SCI_ACK : out std_logic := '0'; + SCI_NACK : out std_logic := '0'; + -- Status and control port +-- STAT_OP : out t_HUB_WORD; --std_logic_vector (15 downto 0); +-- CTRL_OP : in t_HUB_WORD; --std_logic_vector (15 downto 0) := (others => '0'); + STAT_DEBUG : out std_logic_vector (63 downto 0); + CTRL_DEBUG : in std_logic_vector (63 downto 0) := (others => '0') + ); +end entity; + + +architecture med_ecp3_sfp_4_soda_arch of med_ecp3_sfp_4_soda is + + -- Placer Directives + attribute HGROUP : string; + -- for whole architecture + attribute HGROUP of med_ecp3_sfp_4_sync_down_arch : architecture is "media_downlink_group"; + attribute syn_sharing : string; + attribute syn_sharing of med_ecp3_sfp_4_sync_down_arch : architecture is "off"; + + + +signal clk_200_osc : std_logic; +signal clk_200_txdata : std_logic; +signal clk_200_rxdn : std_logic_vector(3 downto 0); +signal clk_200_i : std_logic_vector(3 downto 0); +signal rx_full_clk : std_logic_vector(3 downto 0); +signal rx_half_clk : std_logic_vector(3 downto 0); +signal tx_full_clk : std_logic_vector(3 downto 0); +signal tx_half_clk : std_logic_vector(3 downto 0); + +signal tx_data : t_HUB_BYTE; --std_logic_vector(4*8-1 downto 0); +signal tx_k : std_logic_vector(3 downto 0); +signal rx_data : t_HUB_BYTE; --std_logic_vector(4*8-1 downto 0); +signal rx_k : t_HUB_BIT; --std_logic_vector(3 downto 0); +signal rx_error : t_HUB_BIT; --std_logic_vector(3 downto 0); + +signal rst_n : t_HUB_BIT; +signal rst : t_HUB_BIT; -- PL! +signal rx_serdes_rst : t_HUB_BIT; +signal tx_serdes_rst : std_logic; +signal tx_pcs_rst : t_HUB_BIT; +signal rx_pcs_rst : t_HUB_BIT; +signal rst_qd : t_HUB_BIT; +signal rst_down_quad : std_logic; +signal serdes_rst_qd : t_HUB_BIT; +signal serdes_rst_down_quad : std_logic; -- combined serdes reset for whole quad +signal sd_los_i : t_HUB_BIT; --PL! + +signal rx_los_low : t_HUB_BIT; +signal lsm_status : t_HUB_BIT; +signal rx_cdr_lol : t_HUB_BIT; +signal tx_pll_lol : t_HUB_BIT; +signal tx_pll_lol_quad : std_logic; -- combined Loss-Of-Lock for whole quad + +signal sci_ch_i : std_logic_vector(3 downto 0); +signal sci_qd_i : std_logic; +signal sci_reg_i : std_logic; +signal sci_addr_i : std_logic_vector(8 downto 0); +signal sci_data_in_i : std_logic_vector(7 downto 0); +signal sci_data_out_i : std_logic_vector(7 downto 0); +signal sci_read_i : std_logic; +signal sci_write_i : std_logic; +signal sci_write_shift_i : std_logic_vector(2 downto 0); +signal sci_read_shift_i : std_logic_vector(2 downto 0); + +signal wa_position : t_HUB_NIBL := (others => (others => '1')); --std_logic_vector(15 downto 0) := x"FFFF"; +signal wa_position_rx : t_HUB_NIBL := (others => (others => '1')); --std_logic_vector(15 downto 0) := x"FFFF"; +signal tx_allow : t_HUB_BIT; --std_logic_vector(3 downto 0); +signal rx_allow : t_HUB_BIT; --std_logic_vector(3 downto 0); +signal tx_allow_q : t_HUB_BIT; --std_logic_vector(3 downto 0); +signal rx_allow_q : t_HUB_BIT; --std_logic_vector(3 downto 0); +signal link_phase_S : t_HUB_BIT; --std_logic_vector(3 downto 0); --PL! +signal request_retr_i : t_HUB_BIT; --std_logic_vector(3 downto 0); +signal start_retr_i : t_HUB_BIT; --std_logic_vector(3 downto 0); +signal request_retr_position_i : t_HUB_BYTE; --std_logic_vector(7 downto 0); +signal start_retr_position_i : t_HUB_BYTE; --std_logic_vector(7 downto 0); +signal send_link_reset_i : t_HUB_BIT; --std_logic_vector(3 downto 0); +signal make_link_reset_i : t_HUB_BIT; --std_logic_vector(3 downto 0); +signal got_link_ready_i : t_HUB_BIT; --std_logic_vector(3 downto 0); +signal internal_make_link_reset_out : t_HUB_BIT; --std_logic_vector(3 downto 0); + +signal start_timer : t_HUB_TIMER19 := (others => (others => '0')); --unsigned(18 downto 0) := (others => '0'); +signal watchdog_timer : t_HUB_TIMER21 := (others => (others => '0')); --unsigned(20 downto 0) := (others => '0'); +signal watchdog_trigger : t_HUB_BIT := (others => '0'); --std_logic_vector(3 downto 0) := (others => '0'); + +signal rx_fsm_state : t_HUB_NIBL; --std_logic_vector(3 downto 0); +signal tx_fsm_state : t_HUB_NIBL; --std_logic_vector(3 downto 0); + +signal stat_rx_control_i : t_HUB_LWORD; --std_logic_vector(31 downto 0); +signal stat_tx_control_i : t_HUB_LWORD; --std_logic_vector(31 downto 0); +signal debug_rx_control_i : t_HUB_LWORD; --std_logic_vector(31 downto 0); +signal debug_tx_control_i : t_HUB_LWORD; --std_logic_vector(31 downto 0); +signal debug_reg : std_logic_vector(63 downto 0); + +type sci_ctrl is (IDLE, SCTRL, SCTRL_WAIT, SCTRL_WAIT2, SCTRL_FINISH, GET_WA, GET_WA_WAIT, GET_WA_WAIT2, GET_WA_FINISH); +signal sci_state : sci_ctrl; +signal sci_timer : t_HUB_TIMER13 := (others => (others => '0')); --unsigned(12 downto 0) := (others => '0'); + +begin + + +--SD_TXDIS_OUT <= not (rx_allow_q or not IS_SLAVE); --slave only switches on when RX is ready + +clk_200_osc <= OSC_CLK; -- This external clock is oscillator/pll generated !!! +clk_200_txdata <= TX_DATACLK; -- This external clock is the rx_full of the uplink !!! + + +gen_clocks : for i in 0 to 3 generate + + rst(i) <= (CLEAR or sd_los_i(i) or internal_make_link_reset_out(i) or watchdog_trigger(i)); + rst_n(i) <= not(CLEAR or sd_los_i(i) or internal_make_link_reset_out(i) or watchdog_trigger(i)); + + RX_HALF_CLK_OUT(i) <= rx_half_clk(i); + RX_FULL_CLK_OUT(i) <= rx_full_clk(i); + TX_HALF_CLK_OUT(i) <= tx_half_clk(i); + TX_FULL_CLK_OUT(i) <= tx_full_clk(i); + +-- gen_slave_clock : if IS_SYNC_SLAVE = c_YES generate -- NO WAY IN HELL !! this downlink is a master +-- clk_200_i(i) <= rx_full_clk(i); +-- end generate; + +-- gen_master_clock : if IS_SYNC_SLAVE = c_NO generate +-- clk_200_i(i) <= clk_200_txdata; +-- clk_200_rxdn(i) <= rx_full_clk(i); -- These clocks are the rx_full of the DOWNLINKs !!! +-- end generate; +end generate; + +------------------------------------------------- +-- Serdes +------------------------------------------------- +THE_SERDES : entity work.serdes_4_sync_downstream + port map( + -- CHANNEL0 -- + hdinp_ch0 => SD_RXD_P_IN(0), + hdinn_ch0 => SD_RXD_N_IN(0), + hdoutp_ch0 => SD_TXD_P_OUT(0), + hdoutn_ch0 => SD_TXD_N_OUT(0), + rxiclk_ch0 => clk_200_txdata, --clk_200_i(0), + sci_sel_ch0 => sci_ch_i(0), + txiclk_ch0 => clk_200_txdata, + rx_full_clk_ch0 => rx_full_clk(0), + rx_half_clk_ch0 => rx_half_clk(0), + tx_full_clk_ch0 => tx_full_clk(0), + tx_half_clk_ch0 => tx_half_clk(0), + fpga_rxrefclk_ch0 => clk_200_osc, + txdata_ch0 => tx_data(0), + tx_k_ch0 => tx_k(0), + tx_force_disp_ch0 => '0', + tx_disp_sel_ch0 => '0', + rxdata_ch0 => rx_data(0), + rx_k_ch0 => rx_k(0), + rx_disp_err_ch0 => open, + rx_cv_err_ch0 => rx_error(0), + rx_serdes_rst_ch0_c => rx_serdes_rst(0), + sb_felb_ch0_c => '0', + sb_felb_rst_ch0_c => '0', + tx_pcs_rst_ch0_c => tx_pcs_rst(0), + tx_pwrup_ch0_c => '1', + rx_pcs_rst_ch0_c => rx_pcs_rst(0), + rx_pwrup_ch0_c => '1', + rx_los_low_ch0_s => rx_los_low(0), + lsm_status_ch0_s => lsm_status(0), + rx_cdr_lol_ch0_s => rx_cdr_lol(0), + tx_div2_mode_ch0_c => '0', + rx_div2_mode_ch0_c => '0', + -- CHANNEL1 -- + hdinp_ch1 => SD_RXD_P_IN(1), + hdinn_ch1 => SD_RXD_N_IN(1), + hdoutp_ch1 => SD_TXD_P_OUT(1), + hdoutn_ch1 => SD_TXD_N_OUT(1), + rxiclk_ch1 => clk_200_txdata, --clk_200_i(1), + sci_sel_ch1 => sci_ch_i(1), + txiclk_ch1 => clk_200_txdata, + rx_full_clk_ch1 => rx_full_clk(1), + rx_half_clk_ch1 => rx_half_clk(1), + tx_full_clk_ch1 => tx_full_clk(1), + tx_half_clk_ch1 => tx_half_clk(1), + fpga_rxrefclk_ch1 => clk_200_osc, + txdata_ch1 => tx_data(1), + tx_k_ch1 => tx_k(1), + tx_force_disp_ch1 => '0', + tx_disp_sel_ch1 => '0', + rxdata_ch1 => rx_data(1), + rx_k_ch1 => rx_k(1), + rx_disp_err_ch1 => open, + rx_cv_err_ch1 => rx_error(1), + rx_serdes_rst_ch1_c => rx_serdes_rst(1), + sb_felb_ch1_c => '0', + sb_felb_rst_ch1_c => '0', + tx_pcs_rst_ch1_c => tx_pcs_rst(1), + tx_pwrup_ch1_c => '1', + rx_pcs_rst_ch1_c => rx_pcs_rst(1), + rx_pwrup_ch1_c => '1', + rx_los_low_ch1_s => rx_los_low(1), + lsm_status_ch1_s => lsm_status(1), + rx_cdr_lol_ch1_s => rx_cdr_lol(1), + tx_div2_mode_ch1_c => '0', + rx_div2_mode_ch1_c => '0', + -- CHANNEL2 -- + hdinp_ch2 => SD_RXD_P_IN(2), + hdinn_ch2 => SD_RXD_N_IN(2), + hdoutp_ch2 => SD_TXD_P_OUT(2), + hdoutn_ch2 => SD_TXD_N_OUT(2), + rxiclk_ch2 => clk_200_txdata, --clk_200_i(2), + sci_sel_ch2 => sci_ch_i(2), + txiclk_ch2 => clk_200_txdata, + rx_full_clk_ch2 => rx_full_clk(2), + rx_half_clk_ch2 => rx_half_clk(2), + tx_full_clk_ch2 => tx_full_clk(2), + tx_half_clk_ch2 => tx_half_clk(2), + fpga_rxrefclk_ch2 => clk_200_osc, + txdata_ch2 => tx_data(2), + tx_k_ch2 => tx_k(2), + tx_force_disp_ch2 => '0', + tx_disp_sel_ch2 => '0', + rxdata_ch2 => rx_data(2), + rx_k_ch2 => rx_k(2), + rx_disp_err_ch2 => open, + rx_cv_err_ch2 => rx_error(2), + rx_serdes_rst_ch2_c => rx_serdes_rst(2), + sb_felb_ch2_c => '0', + sb_felb_rst_ch2_c => '0', + tx_pcs_rst_ch2_c => tx_pcs_rst(2), + tx_pwrup_ch2_c => '1', + rx_pcs_rst_ch2_c => rx_pcs_rst(2), + rx_pwrup_ch2_c => '1', + rx_los_low_ch2_s => rx_los_low(2), + lsm_status_ch2_s => lsm_status(2), + rx_cdr_lol_ch2_s => rx_cdr_lol(2), + tx_div2_mode_ch2_c => '0', + rx_div2_mode_ch2_c => '0', + -- CHANNEL3 -- + hdinp_ch3 => SD_RXD_P_IN(3), + hdinn_ch3 => SD_RXD_N_IN(3), + hdoutp_ch3 => SD_TXD_P_OUT(3), + hdoutn_ch3 => SD_TXD_N_OUT(3), + rxiclk_ch3 => clk_200_txdata, --clk_200_i(3), + sci_sel_ch3 => sci_ch_i(3), + txiclk_ch3 => clk_200_txdata, + rx_full_clk_ch3 => rx_full_clk(3), + rx_half_clk_ch3 => rx_half_clk(3), + tx_full_clk_ch3 => tx_full_clk(3), + tx_half_clk_ch3 => tx_half_clk(3), + fpga_rxrefclk_ch3 => clk_200_osc, + txdata_ch3 => tx_data(3), + tx_k_ch3 => tx_k(3), + tx_force_disp_ch3 => '0', + tx_disp_sel_ch3 => '0', + rxdata_ch3 => rx_data(3), + rx_k_ch3 => rx_k(3), + rx_disp_err_ch3 => open, + rx_cv_err_ch3 => rx_error(3), + rx_serdes_rst_ch3_c => rx_serdes_rst(3), + sb_felb_ch3_c => '0', + sb_felb_rst_ch3_c => '0', + tx_pcs_rst_ch3_c => tx_pcs_rst(3), + tx_pwrup_ch3_c => '1', + rx_pcs_rst_ch3_c => rx_pcs_rst(3), + rx_pwrup_ch3_c => '1', + rx_los_low_ch3_s => rx_los_low(3), + lsm_status_ch3_s => lsm_status(3), + rx_cdr_lol_ch3_s => rx_cdr_lol(3), + tx_div2_mode_ch3_c => '0', + rx_div2_mode_ch3_c => '0', + -- COMMON -- + sci_wrdata => sci_data_in_i, + sci_rddata => sci_data_out_i, + sci_addr => sci_addr_i(5 downto 0), + sci_sel_quad => sci_qd_i, + sci_rd => sci_read_i, + sci_wrn => sci_write_i, + + fpga_txrefclk => clk_200_txdata, --clk_200_osc, --clk_200_i(0), + tx_serdes_rst_c => '0', --tx_serdes_rst(0), -- resets tx_pll PL 1906 + tx_pll_lol_qd_s => tx_pll_lol_quad, + tx_sync_qd_c => '0', -- unused; signal to synchronise channels/serdesses for multi-channel protocols + rst_qd_c => rst_down_quad, -- jemig wat is Oscar toch gasfjkl[glk + serdes_rst_qd_c => serdes_rst_down_quad + ); + +------------------------- +-- combined quad reset -- +------------------------- +--rst_down_quad <= '1' when (rst_qd(0)='1' or rst_qd(1)='1' or rst_qd(2)='1' or rst_qd(3)='1') else '0'; +rst_down_quad <= RESET; -- PL: 18/06/14 +--serdes_rst_down_quad <= '1' when (serdes_rst_qd(0)='1' or serdes_rst_qd(1)='1' or serdes_rst_qd(2)='1' or serdes_rst_qd(3)='1') else '0'; +serdes_rst_down_quad <= '0'; -- PL: 23/06/14 + +generated_logic : for i in 0 to 3 generate + + SD_TXDIS_OUT(i) <= LINK_DISABLE_IN; --not (rx_allow_q(i) or not IS_SLAVE); --slave only switches on when RX is ready + + tx_pll_lol(i) <= tx_pll_lol_quad; + + ------------------------------------------------- + -- Reset FSM & Link states + ------------------------------------------------- + THE_RX_FSM : rx_reset_fsm + port map( + RST_N => rst_n(i), + RX_REFCLK => rx_full_clk(i), --clk_200_osc, -- want de rx_refclk is clk_200_osc !!! en moet er altijd zijn + TX_PLL_LOL_QD_S => tx_pll_lol(i), + RX_SERDES_RST_CH_C => rx_serdes_rst(i), + RX_CDR_LOL_CH_S => rx_cdr_lol(i), + RX_LOS_LOW_CH_S => rx_los_low(i), + RX_PCS_RST_CH_C => rx_pcs_rst(i), + WA_POSITION => wa_position_rx(i), + STATE_OUT => rx_fsm_state(i) + ); + + THE_TX_FSM : tx_reset_fsm + port map( + RST_N => rst_n(i), + TX_REFCLK => clk_200_txdata, --clk_200_osc, + TX_PLL_LOL_QD_S => tx_pll_lol(i), + RST_QD_C => rst_qd(i), + TX_PCS_RST_CH_C => tx_pcs_rst(i), + STATE_OUT => tx_fsm_state(i) + ); + + + -- Master does not do bit-locking + wa_position_rx(i) <= wa_position(i) when (IS_SYNC_SLAVE = c_YES) else x"0"; + + + PROC_ALLOW : process(clk_200_txdata) --clk_200_i(i)) + begin + if rising_edge(clk_200_txdata) then -- clk_200_txdata ?? + if rx_fsm_state(i) = x"6" and (IS_SYNC_SLAVE = c_YES or start_timer(i)(start_timer'left) = '1') then + rx_allow(i) <= '1'; + tx_allow(i) <= '1'; + else + rx_allow(i) <= '0'; + tx_allow(i) <= '1'; + end if; + end if; + end process; + + rx_allow_q(i) <= rx_allow(i) when rising_edge(SYSCLK); + tx_allow_q(i) <= tx_allow(i) when rising_edge(SYSCLK); + + + PROC_START_TIMER : process(clk_200_txdata) --clk_200_i(i)) + begin + if rising_edge(clk_200_txdata) then + if got_link_ready_i(i) = '1' then + watchdog_timer(i) <= (others => '0'); + if start_timer(i)(start_timer'left) = '0' then + start_timer(i) <= start_timer(i) + 1; +-- start_timer(i)(start_timer'left downto 0) <= start_timer(i)(start_timer'left downto 0) + 1; + end if; + else + start_timer(i) <= (others => '0'); + if ((watchdog_timer(i)(watchdog_timer(i)'left) = '1') and (watchdog_timer(i)(watchdog_timer(i)'left - 1) = '1')) then + watchdog_trigger(i) <= '1'; + else + watchdog_trigger(i) <= '0'; + end if; + if watchdog_trigger(i) = '0' then + watchdog_timer(i) <= watchdog_timer(i) + 1; + else + watchdog_timer(i) <= (others => '0'); + end if; + end if; + end if; + end process; +-- ------------------------------------------------- +-- -- TX Data +-- ------------------------------------------------- +-- THE_TX : soda_tx_control +-- port map( +-- CLK_200 => clk_200_txdata, --tx_full_clk(i), --clk_200_i(i), +-- CLK_100 => SYSCLK, +-- RESET_IN => rst(i), --CLEAR, PL! + +-- TX_DATA_IN => MED_DATA_IN(i), +-- TX_PACKET_NUMBER_IN => MED_PACKET_NUM_IN(i), +-- TX_WRITE_IN => MED_DATAREADY_IN(i), +-- TX_READ_OUT => MED_READ_OUT(i), + +-- TX_DATA_OUT => tx_data(i), +-- TX_K_OUT => tx_k(i), + +-- REQUEST_RETRANSMIT_IN => request_retr_i(i), --TODO +-- REQUEST_POSITION_IN => request_retr_position_i(i), --TODO + +-- START_RETRANSMIT_IN => start_retr_i(i), --TODO +-- START_POSITION_IN => request_retr_position_i(i), --TODO + +-- TX_DLM_PREVIEW_IN => TX_DLM_PREVIEW_IN(i), +-- SEND_DLM => TX_DLM(i), +-- SEND_DLM_WORD => TX_DLM_WORD(i), + +-- SEND_LINK_RESET_IN => CTRL_OP(i)(15), +-- TX_ALLOW_IN => tx_allow(i), +-- RX_ALLOW_IN => rx_allow(i), +-- LINK_PHASE_OUT => link_phase_S(i), --PL! + +-- DEBUG_OUT => debug_tx_control_i(i), +-- STAT_REG_OUT => stat_tx_control_i(i) +-- ); + +-- LINK_PHASE_OUT(i) <= link_phase_S(i); --PL! +-- ------------------------------------------------- +-- -- RX Data +-- ------------------------------------------------- +-- THE_RX_CONTROL : rx_control +-- port map( +-- CLK_200 => clk_200_txdata, --clk_200_i(i), --PL! +-- CLK_100 => SYSCLK, +-- RESET_IN => rst(i), --CLEAR, PL! + +-- RX_DATA_OUT => MED_DATA_OUT(i), +-- RX_PACKET_NUMBER_OUT => MED_PACKET_NUM_OUT(i), +-- RX_WRITE_OUT => MED_DATAREADY_OUT(i), +-- RX_READ_IN => MED_READ_IN(i), + +-- RX_DATA_IN => rx_data(i), +-- RX_K_IN => rx_k(i), + +-- REQUEST_RETRANSMIT_OUT => request_retr_i(i), +-- REQUEST_POSITION_OUT => request_retr_position_i(i), + +-- START_RETRANSMIT_OUT => start_retr_i(i), +-- START_POSITION_OUT => start_retr_position_i(i), + + --send_dlm: 200 MHz, 1 clock strobe, data valid until next DLM +-- RX_DLM => RX_DLM(i), +-- RX_DLM_WORD => RX_DLM_WORD(i), + +-- SEND_LINK_RESET_OUT => send_link_reset_i(i), +-- MAKE_RESET_OUT => make_link_reset_i(i), +-- RX_ALLOW_IN => rx_allow(i), +-- GOT_LINK_READY => got_link_ready_i(i), + +-- DEBUG_OUT => debug_rx_control_i(i), +-- STAT_REG_OUT => stat_rx_control_i(i) +-- ); + + internal_make_link_reset_out(i) <= make_link_reset_i(i) when (IS_SYNC_SLAVE=c_YES) else '0'; + sd_los_i(i) <= SD_LOS_IN(i) when rising_edge(SYSCLK); -- PL! + +end generate; + +------------------------------------------------- +-- 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; +begin +wait until rising_edge(SYSCLK); + SCI_ACK <= '0'; + case sci_state is + when IDLE => + sci_ch_i <= x"0"; + sci_qd_i <= '0'; + sci_reg_i <= '0'; + sci_read_i <= '0'; + sci_write_i <= '0'; + sci_timer(0) <= sci_timer(0) + 1; + sci_timer(1) <= sci_timer(1) + 1; + sci_timer(2) <= sci_timer(2) + 1; + sci_timer(3) <= sci_timer(3) + 1; + if SCI_READ = '1' or SCI_WRITE = '1' then + sci_ch_i(0) <= not SCI_ADDR(6) and not SCI_ADDR(7) and not SCI_ADDR(8); + sci_ch_i(1) <= SCI_ADDR(6) and not SCI_ADDR(7) and not SCI_ADDR(8); + sci_ch_i(2) <= not SCI_ADDR(6) and SCI_ADDR(7) and not SCI_ADDR(8); + sci_ch_i(3) <= SCI_ADDR(6) and SCI_ADDR(7) and not SCI_ADDR(8); + sci_qd_i <= not SCI_ADDR(6) and not SCI_ADDR(7) and SCI_ADDR(8); + sci_reg_i <= SCI_ADDR(6) and not SCI_ADDR(7) and SCI_ADDR(8); + sci_addr_i <= SCI_ADDR; + sci_data_in_i <= SCI_DATA_IN; + sci_read_i <= SCI_READ and not (SCI_ADDR(6) and not SCI_ADDR(7) and SCI_ADDR(8)); + sci_write_i <= SCI_WRITE and not (SCI_ADDR(6) and not SCI_ADDR(7) and SCI_ADDR(8)); + sci_state <= SCTRL; + else + if sci_timer(0)(sci_timer'left) = '1' then + sci_timer(0) <= (others => '0'); + sci_state <= GET_WA; + end if; + if sci_timer(1)(sci_timer'left) = '1' then + sci_timer(1) <= (others => '0'); + sci_state <= GET_WA; + end if; + if sci_timer(2)(sci_timer'left) = '1' then + sci_timer(2) <= (others => '0'); + sci_state <= GET_WA; + end if; + if sci_timer(3)(sci_timer'left) = '1' then + sci_timer(3) <= (others => '0'); + sci_state <= GET_WA; + end if; + end if; +when SCTRL => + if sci_reg_i = '1' then + SCI_DATA_OUT <= debug_reg(8*(to_integer(unsigned(SCI_ADDR(3 downto 0))))+7 downto 8*(to_integer(unsigned(SCI_ADDR(3 downto 0))))); + SCI_ACK <= '1'; + sci_write_i <= '0'; + sci_read_i <= '0'; + sci_state <= IDLE; + else + sci_state <= SCTRL_WAIT; + end if; +when SCTRL_WAIT => + sci_state <= SCTRL_WAIT2; +when SCTRL_WAIT2 => + sci_state <= SCTRL_FINISH; +when SCTRL_FINISH => + SCI_DATA_OUT <= sci_data_out_i; + SCI_ACK <= '1'; + sci_write_i <= '0'; + sci_read_i <= '0'; + sci_state <= IDLE; + +when GET_WA => + if cnt = 4 then + cnt := 0; + sci_state <= IDLE; + 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'; + end if; +when GET_WA_WAIT => + sci_state <= GET_WA_WAIT2; +when GET_WA_WAIT2 => + sci_state <= GET_WA_FINISH; +when GET_WA_FINISH => +-- wa_position(cnt*4+3 downto cnt*4) <= sci_data_out_i(3 downto 0); + wa_position(cnt) <= 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 + SCI_NACK <= '1'; +else + SCI_NACK <= '0'; +end if; + +end process; + + +-- ------------------------------------------------- +-- -- Debug Registers +-- ------------------------------------------------- +-- debug_reg(3 downto 0) <= rx_fsm_state; +-- debug_reg(4) <= rx_k; +-- debug_reg(5) <= rx_error; +-- debug_reg(6) <= rx_los_low; +-- debug_reg(7) <= rx_cdr_lol; +-- +-- debug_reg(8) <= tx_k; +-- debug_reg(9) <= tx_pll_lol; +-- debug_reg(10) <= lsm_status; +-- debug_reg(11) <= make_link_reset_i; +-- debug_reg(15 downto 12) <= tx_fsm_state; +-- -- debug_reg(31 downto 24) <= tx_data; +-- +-- debug_reg(16) <= '0'; +-- debug_reg(17) <= tx_allow; +-- debug_reg(18) <= RESET; +-- debug_reg(19) <= CLEAR; +-- debug_reg(31 downto 20) <= debug_rx_control_i(4) & debug_rx_control_i(2 downto 0) & debug_rx_control_i(15 downto 8); +-- +-- debug_reg(35 downto 32) <= wa_position(3 downto 0); +-- debug_reg(36) <= debug_tx_control_i(6); +-- debug_reg(39 downto 37) <= "000"; +-- debug_reg(63 downto 40) <= debug_rx_control_i(23 downto 0); + + + STAT_DEBUG <= (others => '0'); --debug_reg; + + generated_status : for i in 0 to 3 generate + -- internal_make_link_reset_out(i) <= make_link_reset_i(i) when (IS_SYNC_SLAVE=c_YES) else '0'; + -- sd_los_i(i) <= SD_LOS_IN(i) when rising_edge(SYSCLK); -- PL! + + STAT_OP(i)(15) <= send_link_reset_i(i) when rising_edge(SYSCLK); + STAT_OP(i)(14) <= '0'; + STAT_OP(i)(13) <= internal_make_link_reset_out(i) when rising_edge(SYSCLK); --make trbnet reset + STAT_OP(i)(12) <= '0'; + STAT_OP(i)(11) <= '0'; + STAT_OP(i)(10) <= rx_allow(i); + STAT_OP(i)(9) <= tx_allow(i); + STAT_OP(i)(8) <= got_link_ready_i(i); + STAT_OP(i)(7) <= send_link_reset_i(i); + STAT_OP(i)(6) <= make_link_reset_i(i); + STAT_OP(i)(5) <= request_retr_i(i); + STAT_OP(i)(4) <= start_retr_i(i); + STAT_OP(i)(3 downto 0) <= x"0" when rx_allow_q(i) = '1' and tx_allow_q(i) = '1' else x"7"; + end generate; + +end med_ecp3_sfp_4_soda_arch; diff --git a/code/med_ecp3_sfp_sync_down.vhd b/code/med_ecp3_sfp_sync_down.vhd index 2842779..e11814a 100644 --- a/code/med_ecp3_sfp_sync_down.vhd +++ b/code/med_ecp3_sfp_sync_down.vhd @@ -96,6 +96,7 @@ end component; --signal clk_200_i : std_logic; --signal clk_200_internal : std_logic; signal clk_200_osc : std_logic; +signal clk_100_osc : std_logic; signal rx_full_clk_ch0 : std_logic; signal rx_half_clk_ch0 : std_logic; signal tx_full_clk_ch0 : std_logic; @@ -196,6 +197,7 @@ signal start_timer : unsigned(18 downto 0) := (others => '0'); begin clk_200_osc <= OSCCLK; +clk_100_osc <= SYSCLK; RX_HALF_CLK_OUT <= rx_half_clk_ch0; RX_FULL_CLK_OUT <= rx_full_clk_ch0; @@ -211,15 +213,6 @@ SD_TXDIS_OUT <= '0'; --not (rx_allow_q or not IS_SLAVE); --slave only switches rst_n <= not(CLEAR or internal_make_link_reset_out); rst <= (CLEAR or internal_make_link_reset_out); ---gen_slave_clock : if IS_SYNC_SLAVE = c_YES generate --- clk_200_i <= rx_full_clk_ch0; ---end generate; - ---gen_master_clock : if IS_SYNC_SLAVE = c_NO generate --- clk_200_i <= clk_200_internal; ---end generate; - - ------------------------------------------------- -- Serdes ------------------------------------------------- @@ -229,13 +222,13 @@ THE_SERDES : entity work.serdes_sync_source_downstream hdinn_ch0 => SD_RXD_N_IN, hdoutp_ch0 => SD_TXD_P_OUT, hdoutn_ch0 => SD_TXD_N_OUT, - rxiclk_ch0 => tx_full_clk_ch0, --clk_200_i, -- read fifo is no longer present! PL! - txiclk_ch0 => tx_full_clk_ch0, --clk_200_i, + rxiclk_ch0 => tx_full_clk_ch0, -- read fifo is no longer present! PL! + txiclk_ch0 => tx_full_clk_ch0, rx_full_clk_ch0 => rx_full_clk_ch0, rx_half_clk_ch0 => rx_half_clk_ch0, tx_full_clk_ch0 => tx_full_clk_ch0, tx_half_clk_ch0 => tx_half_clk_ch0, - fpga_rxrefclk_ch0 => clk_200_osc, --clk_200_internal, -- REF CLK MUST ALWAYS BE PRESENT + fpga_rxrefclk_ch0 => clk_200_osc, -- REF CLK MUST ALWAYS BE PRESENT txdata_ch0 => tx_data, tx_k_ch0 => tx_k, tx_force_disp_ch0 => '0', @@ -266,7 +259,7 @@ THE_SERDES : entity work.serdes_sync_source_downstream SCI_RD => sci_read_i, SCI_WRN => sci_write_i, - fpga_txrefclk => clk_200_osc, --clk_200_internal, -- REF CLK MUST ALWAYS BE PRESENT + fpga_txrefclk => clk_200_osc, -- REF CLK MUST ALWAYS BE PRESENT tx_serdes_rst_c => tx_serdes_rst, tx_pll_lol_qd_s => tx_pll_lol, rst_qd_c => rst_qd, @@ -280,7 +273,7 @@ THE_SERDES : entity work.serdes_sync_source_downstream THE_RX_FSM : rx_reset_fsm port map( RST_N => rst_n, - RX_REFCLK => rx_full_clk_ch0, --clk_200_i, + RX_REFCLK => clk_200_osc, --rx_full_clk_ch0, TX_PLL_LOL_QD_S => tx_pll_lol, RX_SERDES_RST_CH_C => rx_serdes_rst, RX_CDR_LOL_CH_S => rx_cdr_lol, @@ -293,7 +286,7 @@ THE_RX_FSM : rx_reset_fsm THE_TX_FSM : tx_reset_fsm port map( RST_N => rst_n, - TX_REFCLK => clk_200_osc, --clk_200_internal, + TX_REFCLK => clk_200_osc, TX_PLL_LOL_QD_S => tx_pll_lol, RST_QD_C => rst_qd, TX_PCS_RST_CH_C => tx_pcs_rst, @@ -319,21 +312,10 @@ PROC_ALLOW : process begin end if; end process; -rx_allow_q <= rx_allow when rising_edge(SYSCLK); -tx_allow_q <= tx_allow when rising_edge(SYSCLK); - +rx_allow_q <= rx_allow when rising_edge(clk_100_osc); +tx_allow_q <= tx_allow when rising_edge(clk_100_osc); ---PROC_START_TIMER : process begin - --wait until rising_edge(clk_200_i); - --if got_link_ready_i = '1' then - --if start_timer(start_timer'left) = '0' then - --start_timer <= start_timer + 1; - --end if; - --else - --start_timer <= (others => '0'); - --end if; ---end process; - + -- start_timer begins when the rx-link is ready; i.e.: there is a working link. -- If you are a SLAVE, you can then start transmitting right away. -- if you are a MASTER, you wait for the start_timer MSB to go high. -- This gives a slave on the other side time to start-up @@ -342,32 +324,22 @@ PROC_START_TIMER : process(clk_200_osc) --clk_200_i) begin if rising_edge(clk_200_osc) then if got_link_ready_i = '1' then --- watchdog_timer <= (others => '0'); if start_timer(start_timer'left) = '0' then start_timer <= start_timer + 1; end if; else start_timer <= (others => '0'); --- if ((watchdog_timer(watchdog_timer'left) = '1') and (watchdog_timer(watchdog_timer'left - 1) = '1')) then --- watchdog_trigger <= '1'; --- else --- watchdog_trigger <= '0'; --- end if; --- if watchdog_trigger = '0' then --- watchdog_timer <= watchdog_timer + 1; --- else --- watchdog_timer <= (others => '0'); --- end if; end if; end if; -end process; +end process; + ------------------------------------------------- -- TX Data ------------------------------------------------- THE_TX : soda_tx_control port map( - CLK_200 => clk_200_osc, --clk_200_i, - CLK_100 => SYSCLK, + CLK_200 => clk_200_osc, + CLK_100 => clk_100_osc, RESET_IN => rst, --CLEAR, PL! TX_DATA_IN => MED_DATA_IN, @@ -403,8 +375,8 @@ LINK_PHASE_OUT <= link_phase_S; --PL! ------------------------------------------------- THE_RX_CONTROL : rx_control port map( - CLK_200 => rx_full_clk_ch0, --clk_200_i, PL! - CLK_100 => SYSCLK, + CLK_200 => clk_200_osc, --rx_full_clk_ch0, PL! 270814 + CLK_100 => clk_100_osc, RESET_IN => rst, --CLEAR, PL! RX_DATA_OUT => MED_DATA_OUT, @@ -443,7 +415,7 @@ THE_RX_CONTROL : rx_control PROC_SCI_CTRL: process variable cnt : integer range 0 to 4 := 0; begin - wait until rising_edge(SYSCLK); + wait until rising_edge(clk_100_osc); SCI_ACK <= '0'; case sci_state is when IDLE => @@ -551,11 +523,11 @@ debug_reg(63 downto 40) <= debug_rx_control_i(23 downto 0); STAT_DEBUG <= debug_reg; internal_make_link_reset_out <= make_link_reset_i when IS_SYNC_SLAVE = c_YES else '0'; -sd_los_i <= SD_LOS_IN when rising_edge(SYSCLK); -- PL! +sd_los_i <= SD_LOS_IN when rising_edge(clk_100_osc); -- PL! -STAT_OP(15) <= send_link_reset_i when rising_edge(SYSCLK); +STAT_OP(15) <= send_link_reset_i when rising_edge(clk_100_osc); STAT_OP(14) <= '0'; -STAT_OP(13) <= internal_make_link_reset_out when rising_edge(SYSCLK); --make trbnet reset +STAT_OP(13) <= internal_make_link_reset_out when rising_edge(clk_100_osc); --make trbnet reset STAT_OP(12) <= '0'; STAT_OP(11) <= '0'; STAT_OP(10) <= rx_allow; @@ -567,4 +539,5 @@ STAT_OP(6) <= make_link_reset_i; STAT_OP(5) <= request_retr_i; STAT_OP(4) <= start_retr_i; STAT_OP(3 downto 0) <= x"0" when rx_allow_q = '1' and tx_allow_q = '1' else x"7"; + end med_ecp3_sfp_sync_down_arch; \ No newline at end of file diff --git a/code/med_ecp3_sfp_sync_up.vhd b/code/med_ecp3_sfp_sync_up.vhd index 99cce96..8bd0d72 100644 --- a/code/med_ecp3_sfp_sync_up.vhd +++ b/code/med_ecp3_sfp_sync_up.vhd @@ -233,12 +233,12 @@ THE_SERDES : entity work.serdes_sync_upstream hdinn_ch3 => SD_RXD_N_IN, hdoutp_ch3 => SD_TXD_P_OUT, hdoutn_ch3 => SD_TXD_N_OUT, - txiclk_ch3 => rx_full_clk, --clk_200_i, + txiclk_ch3 => rx_full_clk, rx_full_clk_ch3 => rx_full_clk, rx_half_clk_ch3 => rx_half_clk, tx_full_clk_ch3 => tx_full_clk, tx_half_clk_ch3 => tx_half_clk, - fpga_rxrefclk_ch3 => clk_200_osc, --clk_200_internal, + fpga_rxrefclk_ch3 => clk_200_osc, txdata_ch3 => tx_data, tx_k_ch3 => tx_k, tx_force_disp_ch3 => '0', @@ -268,7 +268,7 @@ THE_SERDES : entity work.serdes_sync_upstream SCI_RD => sci_read_i, SCI_WRN => sci_write_i, - fpga_txrefclk => rx_full_clk, --clk_200_osc, --clk_200_i, + fpga_txrefclk => rx_full_clk, tx_serdes_rst_c => tx_serdes_rst, tx_pll_lol_qd_s => tx_pll_lol, rst_qd_c => rst_qd, @@ -282,7 +282,7 @@ THE_SERDES : entity work.serdes_sync_upstream THE_RX_FSM : rx_reset_fsm port map( RST_N => rst_n, - RX_REFCLK => clk_200_osc, --clk_200_internal, -- allways running PL! + RX_REFCLK => clk_200_osc, -- allways running PL! TX_PLL_LOL_QD_S => tx_pll_lol, RX_SERDES_RST_CH_C => rx_serdes_rst, RX_CDR_LOL_CH_S => rx_cdr_lol, @@ -295,7 +295,7 @@ THE_RX_FSM : rx_reset_fsm THE_TX_FSM : tx_reset_fsm port map( RST_N => rst_n, - TX_REFCLK => rx_full_clk, --clk_200_osc, --clk_200_internal, -- allways running PL! 18-06 was clk_200_i + TX_REFCLK => clk_200_osc, -- allways running PL! 18-06 was clk_200_i TX_PLL_LOL_QD_S => tx_pll_lol, RST_QD_C => rst_qd, TX_PCS_RST_CH_C => tx_pcs_rst, @@ -321,8 +321,8 @@ PROC_ALLOW : process begin end if; end process; -rx_allow_q <= rx_allow when rising_edge(SYSCLK); -tx_allow_q <= tx_allow when rising_edge(SYSCLK); +rx_allow_q <= rx_allow when rising_edge(rx_half_clk); --SYSCLK); +tx_allow_q <= tx_allow when rising_edge(rx_half_clk); --SYSCLK); PROC_START_TIMER : process(rx_full_clk) --clk_200_osc) --clk_200_i) @@ -354,7 +354,7 @@ end process; THE_TX : soda_tx_control port map( CLK_200 => rx_full_clk, --clk_200_osc, --clk_200_i, - CLK_100 => SYSCLK, + CLK_100 => rx_half_clk, --SYSCLK, RESET_IN => rst, --CLEAR, PL! TX_DATA_IN => MED_DATA_IN, @@ -391,7 +391,7 @@ LINK_PHASE_OUT <= link_phase_S; --PL! THE_RX_CONTROL : rx_control port map( CLK_200 => rx_full_clk, --clk_200_i, PL! - CLK_100 => SYSCLK, + CLK_100 => rx_half_clk, --SYSCLK, RESET_IN => rst, --CLEAR, PL! RX_DATA_OUT => MED_DATA_OUT, @@ -430,7 +430,7 @@ THE_RX_CONTROL : rx_control PROC_SCI_CTRL: process variable cnt : integer range 0 to 4 := 0; begin - wait until rising_edge(SYSCLK); + wait until rising_edge(rx_half_clk); --SYSCLK); SCI_ACK <= '0'; case sci_state is when IDLE => diff --git a/code/soda_4source.vhd b/code/soda_4source.vhd new file mode 100644 index 0000000..526297c --- /dev/null +++ b/code/soda_4source.vhd @@ -0,0 +1,447 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_unsigned.all; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; +use work.soda_components.all; + +entity soda_4source is + port( + SYSCLK : in std_logic; -- fabric clock + SODACLK : in std_logic; + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + CLK_EN : in std_logic; + + SODA_BURST_PULSE_IN : in std_logic := '0'; -- + + -- MULTIPLE DUPLEX DOWN-LINKS + RX_DLM_IN : in t_HUB_BIT; + RX_DLM_WORD_IN : in t_HUB_BYTE; + TX_DLM_OUT : out t_HUB_BIT; + TX_DLM_WORD_OUT : out t_HUB_BYTE; + TX_DLM_PREVIEW_OUT : out t_HUB_BIT; --PL! + LINK_PHASE_IN : in t_HUB_BIT; --PL! + + SODA_DATA_IN : in std_logic_vector(31 downto 0) := (others => '0'); + SODA_DATA_OUT : out std_logic_vector(31 downto 0) := (others => '0'); + SODA_ADDR_IN : in std_logic_vector(3 downto 0) := (others => '0'); + SODA_READ_IN : in std_logic := '0'; + SODA_WRITE_IN : in std_logic := '0'; + SODA_ACK_OUT : out std_logic := '0'; + LEDS_OUT : out std_logic_vector(3 downto 0); + LINK_DEBUG_IN : in std_logic_vector(31 downto 0) := (others => '0') + ); +end soda_4source; + +architecture Behavioral of soda_4source is + + --SODA + signal soda_cmd_word_S : std_logic_vector(30 downto 0) := (others => '0'); + signal soda_cmd_valid_S : std_logic := '0'; + signal soda_cmd_strobe_S : std_logic := '0'; -- for commands sent in a SODA package + signal soda_cmd_strobe_sodaclk_S : std_logic := '0'; -- for commands sent in a SODA package + signal trb_cmd_word_S : std_logic_vector(30 downto 0) := (others => '0'); + signal trb_cmd_valid_S : std_logic := '0'; + signal trb_cmd_strobe_S : std_logic := '0'; -- for commands sent over trbnet + signal trb_cmd_strobe_sodaclk_S : std_logic := '0'; -- for commands sent over trbnet +-- signal soda_cmd_pending_S : std_logic := '0'; +-- signal soda_send_cmd_S : std_logic := '0'; + signal start_of_superburst_S : std_logic := '0'; + signal super_burst_nr_S : std_logic_vector(30 downto 0) := (others => '0'); -- from super-burst-nr-generator + signal crc_data_S : std_logic_vector(7 downto 0) := (others => '0'); + signal crc_valid_S : std_logic := '0'; + +-- Signals + type STATES is (SLEEP,RD_RDY,WR_RDY,RD_ACK,WR_ACK,DONE); + signal CURRENT_STATE, NEXT_STATE: STATES; + + signal last_packet_sent_S : t_PACKET_TYPE_SENT; + signal expected_reply_S : t_HUB_BYTE_ARRAY; --std_logic_vector(7 downto 0); + signal reply_data_valid_S : t_HUB_BIT_ARRAY; + signal reply_OK_S : t_HUB_BIT_ARRAY; + signal recv_start_calibration_S : std_logic := '0'; + signal send_start_calibration_S : t_HUB_BIT_ARRAY; + signal start_calibration_S : t_HUB_BIT_ARRAY; + signal calib_data_valid_S : t_HUB_BIT_ARRAY; + signal calibration_time_S : t_HUB_WORD_ARRAY; + signal calib_register_s : t_HUB_LWORD_ARRAY; + signal reply_timeout_error_S : t_HUB_BIT_ARRAY; + signal channel_timeout_status_S : t_HUB_BIT_ARRAY; + signal downstream_error_S : t_HUB_BIT_ARRAY; + + signal dead_channel_S : t_HUB_BIT_ARRAY; + + signal CTRL_STATUS_register_S : t_HUB_LWORD_ARRAY; + + signal TXstart_of_superburst_S : t_HUB_BIT_ARRAY; + signal TXsuper_burst_nr_S : t_HUB_LWORD_ARRAY; -- from super-burst-nr-generator + signal TXsoda_cmd_valid_S : t_HUB_BIT_ARRAY; + signal TXsoda_cmd_word_S : t_HUB_LWORD_ARRAY; + + +-- signal channel_status_S : t_HUB_BIT_ARRAY; +-- signal status_register : std_logic_vector(31 downto 0) := (others => '0'); + +-- slave bus signals + signal bus_ack_x : std_logic; + signal bus_ack : std_logic; + signal store_wr_x : std_logic; + signal store_wr : std_logic; + signal store_rd_x : std_logic; + signal store_rd : std_logic; + signal buf_bus_data_out : std_logic_vector(31 downto 0) := (others => '0'); + signal ledregister_i : std_logic_vector(31 downto 0) := (others => '0'); + signal txup_dlm_out_S : std_logic; + +-- debug +-- signal debug_status_S : std_logic_vector(31 downto 0) := (others => '0'); +-- signal debug_rx_cnt_S : std_logic_vector(31 downto 0) := (others => '0'); +-- signal debug_tx_cnt_S : std_logic_vector(31 downto 0) := (others => '0'); +-- signal debug_SOS_cnt_S : std_logic_vector(31 downto 0) := (others => '0'); +-- signal debug_cmd_cnt_S : std_logic_vector(31 downto 0) := (others => '0'); + +begin + + + + + channel :for i in c_HUB_CHILDREN-1 downto 0 generate + + TXsoda_cmd_valid_S(i) <= soda_cmd_valid_S; + TXstart_of_superburst_S(i) <= start_of_superburst_S; + TXsoda_cmd_word_S(i) <= '0' & soda_cmd_word_S; + TXsuper_burst_nr_S(i) <= '0' & super_burst_nr_S; + + + + start_calibration_S(i) <= send_start_calibration_S(i); + + packet_builder : soda_packet_builder + port map( + SODACLK => SODACLK, + RESET => RESET, + --Internal Connection + SODA_CMD_STROBE_IN => TXsoda_cmd_valid_S(i), + START_OF_SUPERBURST => TXstart_of_superburst_S(i), + SUPER_BURST_NR_IN => TXsuper_burst_nr_S(i)(30 downto 0), + SODA_CMD_WORD_IN => TXsoda_cmd_word_S(i)(30 downto 0), + EXPECTED_REPLY_OUT => expected_reply_S(i), + TIME_CAL_OUT => send_start_calibration_S(i), + TX_DLM_PREVIEW_OUT => TX_DLM_PREVIEW_OUT(i), + TX_DLM_OUT => TX_DLM_OUT(i), + TX_DLM_WORD_OUT => TX_DLM_WORD_OUT(i) + ); + + hub_reply_handler : soda_reply_handler + port map( + SODACLK => SODACLK, + RESET => RESET, + CLEAR => '0', + CLK_EN => '1', + --Internal Connection +-- LAST_PACKET => last_packet_sent_S, + EXPECTED_REPLY_IN => expected_reply_S(i), + RX_DLM_IN => RX_DLM_IN(i), + RX_DLM_WORD_IN => RX_DLM_WORD_IN(i), + REPLY_VALID_OUT => reply_data_valid_S(i), + REPLY_OK_OUT => reply_OK_S(i) + ); + + hub_calibration_timer : soda_calibration_timer + port map( + SODACLK => SODACLK, + RESET => RESET, + CLEAR => '0', + CLK_EN => '1', + --Internal Connection + START_CALIBRATION => start_calibration_S(i), + END_CALIBRATION => reply_data_valid_S(i), + VALID_OUT => calib_data_valid_S(i), + CALIB_TIME_OUT => calibration_time_S(i), + TIMEOUT_ERROR => reply_timeout_error_S(i) + ); + + sodahub_calib_timeout_proc : process(SYSCLK) -- converting to sysclk domain + begin + if rising_edge(SYSCLK) then + if( RESET = '1' ) then + calib_register_S(i) <= (others => '0'); + channel_timeout_status_S(i) <= '0'; + downstream_error_S(i) <= '0'; + CTRL_STATUS_register_S(i)(16) <= '0'; -- reset DOWNSTREAM_ERROR status-bit + CTRL_STATUS_register_S(i)(17) <= '0'; -- reset DOWNSTREAM_ERROR status-bit + CTRL_STATUS_register_S(i)(31) <= '0'; -- reset REPORT_ERROR status-bit + elsif (calib_data_valid_S(i) = '1') then -- calibration finished in time + calib_register_S(i) <= x"0000" & calibration_time_S(i); + channel_timeout_status_S(i) <= '0'; + elsif (reply_data_valid_S(i) = '1') then -- the reply was correct + channel_timeout_status_S(i) <= '0'; + if (reply_OK_S(i) = '1') then + downstream_error_S(i) <= '0'; + elsif (dead_channel_S(i) = '0') then + downstream_error_S(i) <= '1'; + CTRL_STATUS_register_S(i)(16) <= '1'; -- set DOWNSTREAM_ERROR status-bit + CTRL_STATUS_register_S(i)(31) <= '1'; -- set REPORT_ERROR status-bit + end if; + elsif ((reply_timeout_error_S(i) = '1') and (reply_OK_S(i) = '1')) then + channel_timeout_status_S(i) <= '1'; + CTRL_STATUS_register_S(i)(17) <= '1'; -- set CALIBRATION_TIMEOUT_ERROR status-bit + CTRL_STATUS_register_S(i)(31) <= '1'; -- set REPORT_ERROR status-bit + elsif (CTRL_STATUS_register_S(i)(15) = '1') then -- check if slowcontrol wants to reset errors + CTRL_STATUS_register_S(i)(16) <= '0'; -- reset DOWNSTREAM_ERROR status-bit + CTRL_STATUS_register_S(i)(17) <= '0'; -- reset DOWNSTREAM_ERROR status-bit + CTRL_STATUS_register_S(i)(31) <= '0'; -- reset REPORT_ERROR status-bit + end if; + end if; + end process; + +-- hub_store_calib_proc : process(SYSCLK) +-- begin +-- if rising_edge(SYSCLK) then +-- if( RESET = '1' ) then +-- calib_register_S(i) <= (others => '0'); +-- else +-- calib_register_S(i)(15 downto 0) <= calibration_time_S(i); +-- end if; +-- end if; +-- end process; + + ----------------------------------------------------------- + -- Reply status report -- + ----------------------------------------------------------- +-- reply_report_proc : process(SYSCLK) +-- begin +-- if rising_edge(SYSCLK) then +-- if( RESET = '1' ) then +-- channel_status_S(i) <= '0'; +-- elsif (reply_data_valid_S(i)='1') then +-- channel_status_S(i) <= reply_OK_S(i) or dead_channels_S(i); +-- else +-- channel_status_S(i) <= '0'; +-- end if; +-- end if; +-- +-- end process; + + end generate; + +----------------------------------------------------------- +-- Reset the unused bits of channel_status_S -- +----------------------------------------------------------- +-- other_bits :for j in 31 downto c_HUB_CHILDREN generate +-- init_unused_bits_proc : process(SYSCLK) +-- begin +-- if rising_edge(SYSCLK) then +-- if( RESET = '1' ) then +-- channel_status_S(j) <= '0'; -- reset status bits +-- end if; +-- end if; +-- end process; +-- end generate; + +----------------------------------------------------------- +-- Transmission history for reply-checking -- +----------------------------------------------------------- + packet_history_proc : process(SYSCLK) + begin + if rising_edge(SYSCLK) then + if( RESET = '1' ) then + last_packet_sent_S <= c_NO_PACKET; + elsif (start_of_superburst_S='1') then + last_packet_sent_S <= c_BST_PACKET; + elsif (soda_cmd_valid_S='1') then + last_packet_sent_S <= c_CMD_PACKET; + end if; + end if; + end process; + +--------------------------------------------------------- +-- RegIO Statemachine +--------------------------------------------------------- + STATE_MEM: process( SYSCLK) + begin + if( rising_edge(SYSCLK) ) then + if( RESET = '1' ) then + CURRENT_STATE <= SLEEP; + bus_ack <= '0'; + store_wr <= '0'; + store_rd <= '0'; + else + CURRENT_STATE <= NEXT_STATE; + bus_ack <= bus_ack_x; + store_wr <= store_wr_x; + store_rd <= store_rd_x; + end if; + end if; + end process STATE_MEM; + +-- Transition matrix + TRANSFORM: process(CURRENT_STATE, SODA_READ_IN, SODA_WRITE_IN ) + begin + NEXT_STATE <= SLEEP; + bus_ack_x <= '0'; + store_wr_x <= '0'; + store_rd_x <= '0'; + case CURRENT_STATE is + when SLEEP => + if ( (SODA_READ_IN = '1') ) then + NEXT_STATE <= RD_RDY; + store_rd_x <= '1'; + elsif( (SODA_WRITE_IN = '1') ) then + NEXT_STATE <= WR_RDY; + store_wr_x <= '1'; + else + NEXT_STATE <= SLEEP; + end if; + when RD_RDY => + NEXT_STATE <= RD_ACK; + when WR_RDY => + NEXT_STATE <= WR_ACK; + when RD_ACK => + if( SODA_READ_IN = '0' ) then + NEXT_STATE <= DONE; + bus_ack_x <= '1'; + else + NEXT_STATE <= RD_ACK; + bus_ack_x <= '1'; + end if; + when WR_ACK => + if( SODA_WRITE_IN = '0' ) then + NEXT_STATE <= DONE; + bus_ack_x <= '1'; + else + NEXT_STATE <= WR_ACK; + bus_ack_x <= '1'; + end if; + when DONE => + NEXT_STATE <= SLEEP; + when others => + NEXT_STATE <= SLEEP; + end case; +end process TRANSFORM; + + +--------------------------------------------------------- +-- data handling -- +--------------------------------------------------------- +-- For sim purposes the CLIENT gets addresses 11XX +-- register write + THE_WRITE_REG_PROC: process( SYSCLK ) + begin + if( rising_edge(SYSCLK) ) then + if ( RESET = '1' ) then + trb_cmd_strobe_S <= '0'; + trb_cmd_word_S <= (others => '0'); + CTRL_STATUS_register_S(0)(15 downto 0) <= (others => '0'); + CTRL_STATUS_register_S(1)(15 downto 0) <= (others => '0'); + CTRL_STATUS_register_S(2)(15 downto 0) <= (others => '0'); + CTRL_STATUS_register_S(3)(15 downto 0) <= (others => '0'); + elsif( (store_wr = '1') and (SODA_ADDR_IN = "0000") ) then + trb_cmd_strobe_S <= '1'; + trb_cmd_word_S <= SODA_DATA_IN(30 downto 0); + elsif( (store_wr = '1') and (SODA_ADDR_IN = "0001") ) then + trb_cmd_strobe_S <= '0'; + CTRL_STATUS_register_S(0)(15 downto 0) <= SODA_DATA_IN(15 downto 0); -- use only the 16 lower bits for control + elsif( (store_wr = '1') and (SODA_ADDR_IN = "0010") ) then + trb_cmd_strobe_S <= '0'; + CTRL_STATUS_register_S(1)(15 downto 0) <= SODA_DATA_IN(15 downto 0); -- use only the 16 lower bits for control + elsif( (store_wr = '1') and (SODA_ADDR_IN = "0011") ) then + trb_cmd_strobe_S <= '0'; + CTRL_STATUS_register_S(2)(15 downto 0) <= SODA_DATA_IN(15 downto 0); -- use only the 16 lower bits for control + elsif( (store_wr = '1') and (SODA_ADDR_IN = "0100") ) then + trb_cmd_strobe_S <= '0'; + CTRL_STATUS_register_S(3)(15 downto 0) <= SODA_DATA_IN(15 downto 0); -- use only the 16 lower bits for control + else + trb_cmd_strobe_S <= '0'; + end if; + end if; + end process THE_WRITE_REG_PROC; + + dead_channel_S(0) <= CTRL_STATUS_register_S(0)(8); -- slow-control can declare a channel dead + dead_channel_S(1) <= CTRL_STATUS_register_S(1)(8); -- slow-control can declare a channel dead + dead_channel_S(2) <= CTRL_STATUS_register_S(2)(8); -- slow-control can declare a channel dead + dead_channel_S(3) <= CTRL_STATUS_register_S(3)(8); -- slow-control can declare a channel dead + +-- register read + THE_READ_REG_PROC: process( SYSCLK ) + begin + if( rising_edge(SYSCLK) ) then + if ( RESET = '1' ) then + buf_bus_data_out <= (others => '0'); + elsif( (store_rd = '1') and (SODA_ADDR_IN = "0000") ) then + buf_bus_data_out <= '0' & soda_cmd_word_S; + elsif( (store_rd = '1') and (SODA_ADDR_IN = "0001") ) then + buf_bus_data_out <= '0' & super_burst_nr_S; + elsif( (store_rd = '1') and (SODA_ADDR_IN = "0100") ) then + buf_bus_data_out <= calib_register_S(0); + elsif( (store_rd = '1') and (SODA_ADDR_IN = "0101") ) then + buf_bus_data_out <= calib_register_S(0); + elsif( (store_rd = '1') and (SODA_ADDR_IN = "0110") ) then + buf_bus_data_out <= calib_register_S(0); + elsif( (store_rd = '1') and (SODA_ADDR_IN = "0111") ) then + buf_bus_data_out <= calib_register_S(0); + elsif( (store_rd = '1') and (SODA_ADDR_IN = "0011") ) then + buf_bus_data_out <= CTRL_STATUS_register_S(0); + elsif( (store_rd = '1') and (SODA_ADDR_IN = "0100") ) then + buf_bus_data_out <= CTRL_STATUS_register_S(1); + elsif( (store_rd = '1') and (SODA_ADDR_IN = "0101") ) then + buf_bus_data_out <= CTRL_STATUS_register_S(2); + elsif( (store_rd = '1') and (SODA_ADDR_IN = "0110") ) then + buf_bus_data_out <= CTRL_STATUS_register_S(3); + end if; + end if; + end process THE_READ_REG_PROC; +-- buf_bus_data_out <= debug_status_S; +-- elsif( (store_rd = '1') and (SODA_ADDR_IN = "0100") ) then +-- buf_bus_data_out <= debug_rx_cnt_S; +-- elsif( (store_rd = '1') and (SODA_ADDR_IN = "0101") ) then +-- buf_bus_data_out <= debug_tx_cnt_S; +-- elsif( (store_rd = '1') and (SODA_ADDR_IN = "0110") ) then +-- buf_bus_data_out <= debug_sos_cnt_S; +-- elsif( (store_rd = '1') and (SODA_ADDR_IN = "0111") ) then +-- buf_bus_data_out <= debug_cmd_cnt_S; +-- end if; +-- end if; +-- end process THE_READ_REG_PROC; + +-- debug signals + --DEBUG_HUB : process(SODACLK) + --begin + --if( rising_edge(SODACLK) ) then + --debug_status_S(0) <= RESET; + --debug_status_S(1) <= CLEAR; + --debug_status_S(2) <= CLK_EN; + --if ( RESET = '1' ) then + --debug_rx_cnt_S <= (others => '0'); + --debug_tx_cnt_S <= (others => '0'); + --else + --if (txup_dlm_out_S = '1') then + --debug_tx_cnt_S <= debug_tx_cnt_S + 1; + --end if; + --if (RXUP_DLM_IN = '1') then + --debug_rx_cnt_S <= debug_rx_cnt_S + 1; + --end if; + --if (start_of_superburst_S = '1') then + --debug_sos_cnt_S <= debug_sos_cnt_S + 1; + --end if; + --if (soda_cmd_valid_S = '1') then + --debug_cmd_cnt_S <= debug_cmd_cnt_S + 1; + --end if; + --end if; + --end if; + --end process; + + --debug_status_S(31 downto 3) <= LINK_DEBUG_IN(31 downto 3); +-- TXUP_DLM_OUT <= txup_dlm_out_S; +-- output signals + LEDS_OUT <= LEDregister_i(3 downto 0); + + SODA_DATA_OUT <= buf_bus_data_out; + SODA_ACK_OUT <= bus_ack; + +end architecture; diff --git a/code/soda_4source_synconstraints.fdc b/code/soda_4source_synconstraints.fdc new file mode 100644 index 0000000..c61076d --- /dev/null +++ b/code/soda_4source_synconstraints.fdc @@ -0,0 +1,67 @@ +################################################################################ +#### This file contains constraints from Synplicity SDC files that have been +#### translated into Synopsys FPGA Design Constraints (FDC). +#### Translated FDC output file: +#### /local/lemmens/lattice/soda/soda_client/FDC_constraints/soda_client/soda_client_syn_translated.fdc +#### client SDC files to the translation: +#### /local/lemmens/lattice/soda/client/soda_client_clock_constraints.sdc +################################################################################ + + +###==== BEGIN Header + +# Synopsys, Inc. constraint file +# /local/lemmens/lattice/soda/code/soda_hub_synconstraints.fdc +# Written on Tue May 20 15:36:03 2014 +# by Synplify Pro, I-2013.09L FDC Constraint Editor + +# Custom constraint commands may be added outside of the SCOPE tab sections bounded with BEGIN/END. +# These sections are generated from SCOPE spreadsheet tabs. + +###==== END Header + + +################################################################################ +#### The following Synplicity constraints from file: +#### /local/lemmens/lattice/soda/client/soda_client_clock_constraints.sdc +#### are disabled and have not been translated. +############################################################################## +# FDC constraints translated from Synplify Legacy Timing & Design Constraints +############################################################################## + +set_rtl_ff_names {} +###==== BEGIN Collections - (Populated from tab in SCOPE, do not edit) +define_scope_collection {all_inputs_fdc} {find -port * -filter @direction==input} -disable +define_scope_collection {all_outputs_fdc} {find -port * -filter @direction==output} -disable +define_scope_collection {all_clocks_fdc} {find -hier -clock *} -disable +define_scope_collection {all_registers_fdc} {find -hier -seq *} -disable +###==== END Collections +###==== BEGIN Clocks - (Populated from tab in SCOPE, do not edit) +create_clock -name {clk_raw_internal} {n:clk_raw_internal} -period {5.0} -waveform {0 2.5} -add +create_clock -name {clk_sys_internal} {n:clk_sys_internal} -period {10.0} -waveform {0 5.0} -add +create_clock -name {THE_HUB_SYNC_UPLINK/THE_SERDES.rx_full_clk_ch3} {n:THE_HUB_SYNC_UPLINK/THE_SERDES.rx_full_clk_ch3} -period {5.0} -waveform {0 2.5} -add +create_clock -name {THE_HUB_SYNC_DOWNLINK/THE_SERDES.rx_full_clk_ch0} {n:THE_HUB_SYNC_UPLINK/THE_SERDES.rx_full_clk_ch0} -period {5.0} -waveform {0 2.5} -add +create_clock -name {THE_HUB_SYNC_DOWNLINK/THE_SERDES.rx_full_clk_ch1} {n:THE_HUB_SYNC_UPLINK/THE_SERDES.rx_full_clk_ch1} -period {5.0} -waveform {0 2.5} -add +create_clock -name {THE_HUB_SYNC_DOWNLINK/THE_SERDES.rx_full_clk_ch2} {n:THE_HUB_SYNC_UPLINK/THE_SERDES.rx_full_clk_ch2} -period {5.0} -waveform {0 2.5} -add +create_clock -name {THE_HUB_SYNC_DOWNLINK/THE_SERDES.rx_full_clk_ch3} {n:THE_HUB_SYNC_UPLINK/THE_SERDES.rx_full_clk_ch3} -period {5.0} -waveform {0 2.5} -add +###==== END Clocks +###==== BEGIN "Generated Clocks" - (Populated from tab in SCOPE, do not edit) +###==== END "Generated Clocks" +###==== BEGIN Inputs/Outputs - (Populated from tab in SCOPE, do not edit) +###==== END Inputs/Outputs +###==== BEGIN "Delay Paths" - (Populated from tab in SCOPE, do not edit) +###==== END "Delay Paths" +###==== BEGIN Attributes - (Populated from tab in SCOPE, do not edit) +###==== END Attributes +###==== BEGIN "I/O Standards" - (Populated from tab in SCOPE, do not edit) +###==== END "I/O Standards" +###==== BEGIN "Compile Points" - (Populated from tab in SCOPE, do not edit) +###==== END "Compile Points" + + + + + + + + diff --git a/code/soda_components.vhd b/code/soda_components.vhd index c075021..3c7189a 100644 --- a/code/soda_components.vhd +++ b/code/soda_components.vhd @@ -145,6 +145,35 @@ package soda_components is LEDS_OUT : out std_logic_vector(3 downto 0) ); end component; + + component soda_4source is + port( + SYSCLK : in std_logic; -- fabric clock + SODACLK : in std_logic; + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + CLK_EN : in std_logic; + + SODA_BURST_PULSE_IN : in std_logic := '0'; -- + + -- MULTIPLE DUPLEX DOWN-LINKS + RX_DLM_IN : in t_HUB_BIT; + RX_DLM_WORD_IN : in t_HUB_BYTE; + TX_DLM_OUT : out t_HUB_BIT; + TX_DLM_WORD_OUT : out t_HUB_BYTE; + TX_DLM_PREVIEW_OUT : out t_HUB_BIT; --PL! + LINK_PHASE_IN : in t_HUB_BIT; --PL! + + SODA_DATA_IN : in std_logic_vector(31 downto 0) := (others => '0'); + SODA_DATA_OUT : out std_logic_vector(31 downto 0) := (others => '0'); + SODA_ADDR_IN : in std_logic_vector(3 downto 0) := (others => '0'); + SODA_READ_IN : in std_logic := '0'; + SODA_WRITE_IN : in std_logic := '0'; + SODA_ACK_OUT : out std_logic := '0'; + LEDS_OUT : out std_logic_vector(3 downto 0); + LINK_DEBUG_IN : in std_logic_vector(31 downto 0) := (others => '0') + ); + end component; component soda_hub port( @@ -304,267 +333,318 @@ package soda_components is ); end component; -component med_ecp3_sfp_sync_down is - generic( - SERDES_NUM : integer range 0 to 3 := 0; - IS_SYNC_SLAVE : integer := c_NO); --select slave mode - port( - OSCCLK : in std_logic; -- _internal_ 200 MHz reference clock - SYSCLK : in std_logic; -- 100 MHz main clock net, synchronous to RX clock - RESET : in std_logic; -- synchronous reset - CLEAR : in std_logic; -- asynchronous reset --- PCSA_REFCLKP : in std_logic; -- external refclock straight into serdes --- PCSA_REFCLKN : in std_logic; -- external refclock straight into serdes - --Internal Connection TX - MED_DATA_IN : in std_logic_vector(c_DATA_WIDTH-1 downto 0); - MED_PACKET_NUM_IN : in std_logic_vector(c_NUM_WIDTH-1 downto 0); - MED_DATAREADY_IN : in std_logic; - MED_READ_OUT : out std_logic := '0'; - --Internal Connection RX - MED_DATA_OUT : out std_logic_vector(c_DATA_WIDTH-1 downto 0) := (others => '0'); - MED_PACKET_NUM_OUT : out std_logic_vector(c_NUM_WIDTH-1 downto 0) := (others => '0'); - MED_DATAREADY_OUT : out std_logic := '0'; - MED_READ_IN : in std_logic; - RX_HALF_CLK_OUT : out std_logic := '0'; --received 100 MHz - RX_FULL_CLK_OUT : out std_logic := '0'; --received 200 MHz - TX_HALF_CLK_OUT : out std_logic := '0'; --received 100 MHz - TX_FULL_CLK_OUT : out std_logic := '0'; --received 200 MHz - - --Sync operation - RX_DLM : out std_logic := '0'; - RX_DLM_WORD : out std_logic_vector(7 downto 0) := x"00"; - TX_DLM : in std_logic := '0'; - TX_DLM_WORD : in std_logic_vector(7 downto 0) := x"00"; - TX_DLM_PREVIEW_IN : in std_logic := '0'; --PL! - LINK_PHASE_OUT : out std_logic := '0'; --PL! - - --SFP Connection - SD_RXD_P_IN : in std_logic; - SD_RXD_N_IN : in std_logic; - SD_TXD_P_OUT : out std_logic; - SD_TXD_N_OUT : out std_logic; - SD_REFCLK_P_IN : in std_logic; --not used - SD_REFCLK_N_IN : in std_logic; --not used - SD_PRSNT_N_IN : in std_logic; -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) - SD_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) - SD_TXDIS_OUT : out std_logic := '0'; -- SFP disable - --Control Interface - SCI_DATA_IN : in std_logic_vector(7 downto 0) := (others => '0'); - SCI_DATA_OUT : out std_logic_vector(7 downto 0) := (others => '0'); - SCI_ADDR : in std_logic_vector(8 downto 0) := (others => '0'); - SCI_READ : in std_logic := '0'; - SCI_WRITE : in std_logic := '0'; - SCI_ACK : out std_logic := '0'; - SCI_NACK : out std_logic := '0'; - -- Status and control port - STAT_OP : out std_logic_vector (15 downto 0); - CTRL_OP : in std_logic_vector (15 downto 0) := (others => '0'); - STAT_DEBUG : out std_logic_vector (63 downto 0); - CTRL_DEBUG : in std_logic_vector (63 downto 0) := (others => '0') - ); -end component; + component med_ecp3_sfp_sync_down is + generic( + SERDES_NUM : integer range 0 to 3 := 0; + IS_SYNC_SLAVE : integer := c_NO); --select slave mode + port( + OSCCLK : in std_logic; -- _internal_ 200 MHz reference clock + SYSCLK : in std_logic; -- 100 MHz main clock net, synchronous to RX clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + -- PCSA_REFCLKP : in std_logic; -- external refclock straight into serdes + -- PCSA_REFCLKN : in std_logic; -- external refclock straight into serdes + --Internal Connection TX + MED_DATA_IN : in std_logic_vector(c_DATA_WIDTH-1 downto 0); + MED_PACKET_NUM_IN : in std_logic_vector(c_NUM_WIDTH-1 downto 0); + MED_DATAREADY_IN : in std_logic; + MED_READ_OUT : out std_logic := '0'; + --Internal Connection RX + MED_DATA_OUT : out std_logic_vector(c_DATA_WIDTH-1 downto 0) := (others => '0'); + MED_PACKET_NUM_OUT : out std_logic_vector(c_NUM_WIDTH-1 downto 0) := (others => '0'); + MED_DATAREADY_OUT : out std_logic := '0'; + MED_READ_IN : in std_logic; + RX_HALF_CLK_OUT : out std_logic := '0'; --received 100 MHz + RX_FULL_CLK_OUT : out std_logic := '0'; --received 200 MHz + TX_HALF_CLK_OUT : out std_logic := '0'; --received 100 MHz + TX_FULL_CLK_OUT : out std_logic := '0'; --received 200 MHz + + --Sync operation + RX_DLM : out std_logic := '0'; + RX_DLM_WORD : out std_logic_vector(7 downto 0) := x"00"; + TX_DLM : in std_logic := '0'; + TX_DLM_WORD : in std_logic_vector(7 downto 0) := x"00"; + TX_DLM_PREVIEW_IN : in std_logic := '0'; --PL! + LINK_PHASE_OUT : out std_logic := '0'; --PL! + + --SFP Connection + SD_RXD_P_IN : in std_logic; + SD_RXD_N_IN : in std_logic; + SD_TXD_P_OUT : out std_logic; + SD_TXD_N_OUT : out std_logic; + SD_REFCLK_P_IN : in std_logic; --not used + SD_REFCLK_N_IN : in std_logic; --not used + SD_PRSNT_N_IN : in std_logic; -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) + SD_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) + SD_TXDIS_OUT : out std_logic := '0'; -- SFP disable + --Control Interface + SCI_DATA_IN : in std_logic_vector(7 downto 0) := (others => '0'); + SCI_DATA_OUT : out std_logic_vector(7 downto 0) := (others => '0'); + SCI_ADDR : in std_logic_vector(8 downto 0) := (others => '0'); + SCI_READ : in std_logic := '0'; + SCI_WRITE : in std_logic := '0'; + SCI_ACK : out std_logic := '0'; + SCI_NACK : out std_logic := '0'; + -- Status and control port + STAT_OP : out std_logic_vector (15 downto 0); + CTRL_OP : in std_logic_vector (15 downto 0) := (others => '0'); + STAT_DEBUG : out std_logic_vector (63 downto 0); + CTRL_DEBUG : in std_logic_vector (63 downto 0) := (others => '0') + ); + end component; -component med_ecp3_sfp_4_sync_down is - generic( SERDES_NUM : integer range 0 to 3 := 0; - IS_SYNC_SLAVE : integer := c_NO); --select slave mode - port( - OSC_CLK : in std_logic; -- 200 MHz reference clock - TX_DATACLK : in std_logic; -- 200 MHz data clock - SYSCLK : in std_logic; -- 100 MHz main clock net, synchronous to OSC clock - RESET : in std_logic; -- synchronous reset - CLEAR : in std_logic; -- asynchronous reset - --------------------------------------------------------------------------------------------------------------------------------------------------------- - LINK_DISABLE_IN : in std_logic; -- downlinks must behave as slaves to uplink connection. Downlinks are released once unlink is established. - --------------------------------------------------------------------------------------------------------------------------------------------------------- - --Internal Connection TX - MED_DATA_IN : in t_HUB_WORD; --std_logic_vector(c_QUAD_DATA_WIDTH-1 downto 0); - MED_PACKET_NUM_IN : in t_HUB_NUM; --std_logic_vector(c_QUAD_NUM_WIDTH-1 downto 0); - MED_DATAREADY_IN : in std_logic_vector(3 downto 0); - MED_READ_OUT : out std_logic_vector(3 downto 0) := (others => '0'); - --Internal Connection RX - MED_DATA_OUT : out t_HUB_WORD; -- std_logic_vector(4*c_DATA_WIDTH-1 downto 0) := (others => '0'); - MED_PACKET_NUM_OUT : out t_HUB_NUM; -- std_logic_vector(4*c_NUM_WIDTH-1 downto 0) := (others => '0'); - MED_DATAREADY_OUT : out std_logic_vector(3 downto 0) := (others => '0'); - MED_READ_IN : in std_logic_vector(3 downto 0); - RX_HALF_CLK_OUT : out std_logic_vector(3 downto 0) := (others => '0'); --100 MHz - RX_FULL_CLK_OUT : out std_logic_vector(3 downto 0) := (others => '0'); --200 MHz - TX_HALF_CLK_OUT : out std_logic_vector(3 downto 0) := (others => '0'); --100 MHz - TX_FULL_CLK_OUT : out std_logic_vector(3 downto 0) := (others => '0'); --200 MHz - - --Sync operation - RX_DLM : out t_HUB_BIT; --std_logic_vector(3 downto 0) := (others => '0'); - RX_DLM_WORD : out t_HUB_BYTE; --std_logic_vector(4*8 - 1 downto 0) := (others => '0'); - TX_DLM : in t_HUB_BIT; --std_logic_vector(3 downto 0) := (others => '0'); - TX_DLM_WORD : in t_HUB_BYTE; --std_logic_vector(4*8 - 1 downto 0) := (others => '0'); - TX_DLM_PREVIEW_IN : in t_HUB_BIT; --std_logic_vector(3 downto 0) := (others => '0'); --PL! - LINK_PHASE_OUT : out t_HUB_BIT; --std_logic_vector(3 downto 0) := (others => '0'); --PL! - - --SFP Connection - SD_RXD_P_IN : in t_HUB_BIT; --std_logic; - SD_RXD_N_IN : in t_HUB_BIT; --std_logic; - SD_TXD_P_OUT : out t_HUB_BIT; --std_logic; - SD_TXD_N_OUT : out t_HUB_BIT; --std_logic; - SD_REFCLK_P_IN : in t_HUB_BIT; --std_logic; --not used - SD_REFCLK_N_IN : in t_HUB_BIT; --std_logic; --not used - SD_PRSNT_N_IN : in t_HUB_BIT; --std_logic; -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) - SD_LOS_IN : in t_HUB_BIT; --std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) - SD_TXDIS_OUT : out t_HUB_BIT; --std_logic := '0'; -- SFP disable - --Control Interface - SCI_DATA_IN : in std_logic_vector(7 downto 0) := (others => '0'); - SCI_DATA_OUT : out std_logic_vector(7 downto 0) := (others => '0'); - SCI_ADDR : in std_logic_vector(8 downto 0) := (others => '0'); - SCI_READ : in std_logic := '0'; - SCI_WRITE : in std_logic := '0'; - SCI_ACK : out std_logic := '0'; - SCI_NACK : out std_logic := '0'; - -- Status and control port - STAT_OP : out t_HUB_WORD; --std_logic_vector (15 downto 0); - CTRL_OP : in t_HUB_WORD; --std_logic_vector (15 downto 0) := (others => '0'); - STAT_DEBUG : out std_logic_vector (63 downto 0); - CTRL_DEBUG : in std_logic_vector (63 downto 0) := (others => '0') - ); -end component; + component med_ecp3_sfp_4_sync_down is + generic( SERDES_NUM : integer range 0 to 3 := 0; + IS_SYNC_SLAVE : integer := c_NO); --select slave mode + port( + OSC_CLK : in std_logic; -- 200 MHz reference clock + TX_DATACLK : in std_logic; -- 200 MHz data clock + SYSCLK : in std_logic; -- 100 MHz main clock net, synchronous to OSC clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + --------------------------------------------------------------------------------------------------------------------------------------------------------- + LINK_DISABLE_IN : in std_logic; -- downlinks must behave as slaves to uplink connection. Downlinks are released once unlink is established. + --------------------------------------------------------------------------------------------------------------------------------------------------------- + --Internal Connection TX + MED_DATA_IN : in t_HUB_WORD; --std_logic_vector(c_QUAD_DATA_WIDTH-1 downto 0); + MED_PACKET_NUM_IN : in t_HUB_NUM; --std_logic_vector(c_QUAD_NUM_WIDTH-1 downto 0); + MED_DATAREADY_IN : in std_logic_vector(3 downto 0); + MED_READ_OUT : out std_logic_vector(3 downto 0) := (others => '0'); + --Internal Connection RX + MED_DATA_OUT : out t_HUB_WORD; -- std_logic_vector(4*c_DATA_WIDTH-1 downto 0) := (others => '0'); + MED_PACKET_NUM_OUT : out t_HUB_NUM; -- std_logic_vector(4*c_NUM_WIDTH-1 downto 0) := (others => '0'); + MED_DATAREADY_OUT : out std_logic_vector(3 downto 0) := (others => '0'); + MED_READ_IN : in std_logic_vector(3 downto 0); + RX_HALF_CLK_OUT : out std_logic_vector(3 downto 0) := (others => '0'); --100 MHz + RX_FULL_CLK_OUT : out std_logic_vector(3 downto 0) := (others => '0'); --200 MHz + TX_HALF_CLK_OUT : out std_logic_vector(3 downto 0) := (others => '0'); --100 MHz + TX_FULL_CLK_OUT : out std_logic_vector(3 downto 0) := (others => '0'); --200 MHz + + --Sync operation + RX_DLM : out t_HUB_BIT; --std_logic_vector(3 downto 0) := (others => '0'); + RX_DLM_WORD : out t_HUB_BYTE; --std_logic_vector(4*8 - 1 downto 0) := (others => '0'); + TX_DLM : in t_HUB_BIT; --std_logic_vector(3 downto 0) := (others => '0'); + TX_DLM_WORD : in t_HUB_BYTE; --std_logic_vector(4*8 - 1 downto 0) := (others => '0'); + TX_DLM_PREVIEW_IN : in t_HUB_BIT; --std_logic_vector(3 downto 0) := (others => '0'); --PL! + LINK_PHASE_OUT : out t_HUB_BIT; --std_logic_vector(3 downto 0) := (others => '0'); --PL! + + --SFP Connection + SD_RXD_P_IN : in t_HUB_BIT; --std_logic; + SD_RXD_N_IN : in t_HUB_BIT; --std_logic; + SD_TXD_P_OUT : out t_HUB_BIT; --std_logic; + SD_TXD_N_OUT : out t_HUB_BIT; --std_logic; + SD_REFCLK_P_IN : in t_HUB_BIT; --std_logic; --not used + SD_REFCLK_N_IN : in t_HUB_BIT; --std_logic; --not used + SD_PRSNT_N_IN : in t_HUB_BIT; --std_logic; -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) + SD_LOS_IN : in t_HUB_BIT; --std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) + SD_TXDIS_OUT : out t_HUB_BIT; --std_logic := '0'; -- SFP disable + --Control Interface + SCI_DATA_IN : in std_logic_vector(7 downto 0) := (others => '0'); + SCI_DATA_OUT : out std_logic_vector(7 downto 0) := (others => '0'); + SCI_ADDR : in std_logic_vector(8 downto 0) := (others => '0'); + SCI_READ : in std_logic := '0'; + SCI_WRITE : in std_logic := '0'; + SCI_ACK : out std_logic := '0'; + SCI_NACK : out std_logic := '0'; + -- Status and control port + STAT_OP : out t_HUB_WORD; --std_logic_vector (15 downto 0); + CTRL_OP : in t_HUB_WORD; --std_logic_vector (15 downto 0) := (others => '0'); + STAT_DEBUG : out std_logic_vector (63 downto 0); + CTRL_DEBUG : in std_logic_vector (63 downto 0) := (others => '0') + ); + end component; -component med_ecp3_sfp_sync_up is - generic( - SERDES_NUM : integer range 0 to 3 := 0; - IS_SYNC_SLAVE : integer := c_YES --select slave mode + component med_ecp3_sfp_sync_up is + generic( + SERDES_NUM : integer range 0 to 3 := 0; + IS_SYNC_SLAVE : integer := c_YES --select slave mode + ); + port( + OSCCLK : in std_logic; -- 200 MHz reference clock + SYSCLK : in std_logic; -- 100 MHz main clock net, synchronous to RX clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + --Internal Connection TX + MED_DATA_IN : in std_logic_vector(c_DATA_WIDTH-1 downto 0); + MED_PACKET_NUM_IN : in std_logic_vector(c_NUM_WIDTH-1 downto 0); + MED_DATAREADY_IN : in std_logic; + MED_READ_OUT : out std_logic := '0'; + --Internal Connection RX + MED_DATA_OUT : out std_logic_vector(c_DATA_WIDTH-1 downto 0) := (others => '0'); + MED_PACKET_NUM_OUT : out std_logic_vector(c_NUM_WIDTH-1 downto 0) := (others => '0'); + MED_DATAREADY_OUT : out std_logic := '0'; + MED_READ_IN : in std_logic; + RX_HALF_CLK_OUT : out std_logic := '0'; --received 100 MHz + RX_FULL_CLK_OUT : out std_logic := '0'; --received 200 MHz + TX_HALF_CLK_OUT : out std_logic := '0'; --pll 100 MHz + TX_FULL_CLK_OUT : out std_logic := '0'; --pll 200 MHz + RX_CDR_LOL_OUT : out std_logic := '0'; -- CLOCK_DATA RECOVERY LOSS_OF_LOCK !PL14082014 + --Sync operation + RX_DLM : out std_logic := '0'; + RX_DLM_WORD : out std_logic_vector(7 downto 0) := x"00"; + TX_DLM : in std_logic := '0'; + TX_DLM_WORD : in std_logic_vector(7 downto 0) := x"00"; + TX_DLM_PREVIEW_IN : in std_logic := '0'; --PL! + LINK_PHASE_OUT : out std_logic := '0'; --PL! + LINK_READY_OUT : out std_logic := '0'; --PL! + + --SFP Connection + SD_RXD_P_IN : in std_logic; + SD_RXD_N_IN : in std_logic; + SD_TXD_P_OUT : out std_logic; + SD_TXD_N_OUT : out std_logic; + SD_REFCLK_P_IN : in std_logic; --not used + SD_REFCLK_N_IN : in std_logic; --not used + SD_PRSNT_N_IN : in std_logic; -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) + SD_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) + SD_TXDIS_OUT : out std_logic := '0'; -- SFP disable + --Control Interface + SCI_DATA_IN : in std_logic_vector(7 downto 0) := (others => '0'); + SCI_DATA_OUT : out std_logic_vector(7 downto 0) := (others => '0'); + SCI_ADDR : in std_logic_vector(8 downto 0) := (others => '0'); + SCI_READ : in std_logic := '0'; + SCI_WRITE : in std_logic := '0'; + SCI_ACK : out std_logic := '0'; + SCI_NACK : out std_logic := '0'; + -- Status and control port + STAT_OP : out std_logic_vector (15 downto 0); + CTRL_OP : in std_logic_vector (15 downto 0) := (others => '0'); + STAT_DEBUG : out std_logic_vector (63 downto 0); + CTRL_DEBUG : in std_logic_vector (63 downto 0) := (others => '0') ); - port( - OSCCLK : in std_logic; -- 200 MHz reference clock - SYSCLK : in std_logic; -- 100 MHz main clock net, synchronous to RX clock - RESET : in std_logic; -- synchronous reset - CLEAR : in std_logic; -- asynchronous reset - --Internal Connection TX - MED_DATA_IN : in std_logic_vector(c_DATA_WIDTH-1 downto 0); - MED_PACKET_NUM_IN : in std_logic_vector(c_NUM_WIDTH-1 downto 0); - MED_DATAREADY_IN : in std_logic; - MED_READ_OUT : out std_logic := '0'; - --Internal Connection RX - MED_DATA_OUT : out std_logic_vector(c_DATA_WIDTH-1 downto 0) := (others => '0'); - MED_PACKET_NUM_OUT : out std_logic_vector(c_NUM_WIDTH-1 downto 0) := (others => '0'); - MED_DATAREADY_OUT : out std_logic := '0'; - MED_READ_IN : in std_logic; - RX_HALF_CLK_OUT : out std_logic := '0'; --received 100 MHz - RX_FULL_CLK_OUT : out std_logic := '0'; --received 200 MHz - TX_HALF_CLK_OUT : out std_logic := '0'; --pll 100 MHz - TX_FULL_CLK_OUT : out std_logic := '0'; --pll 200 MHz - RX_CDR_LOL_OUT : out std_logic := '0'; -- CLOCK_DATA RECOVERY LOSS_OF_LOCK !PL14082014 - --Sync operation - RX_DLM : out std_logic := '0'; - RX_DLM_WORD : out std_logic_vector(7 downto 0) := x"00"; - TX_DLM : in std_logic := '0'; - TX_DLM_WORD : in std_logic_vector(7 downto 0) := x"00"; - TX_DLM_PREVIEW_IN : in std_logic := '0'; --PL! - LINK_PHASE_OUT : out std_logic := '0'; --PL! - LINK_READY_OUT : out std_logic := '0'; --PL! - - --SFP Connection - SD_RXD_P_IN : in std_logic; - SD_RXD_N_IN : in std_logic; - SD_TXD_P_OUT : out std_logic; - SD_TXD_N_OUT : out std_logic; - SD_REFCLK_P_IN : in std_logic; --not used - SD_REFCLK_N_IN : in std_logic; --not used - SD_PRSNT_N_IN : in std_logic; -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) - SD_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) - SD_TXDIS_OUT : out std_logic := '0'; -- SFP disable - --Control Interface - SCI_DATA_IN : in std_logic_vector(7 downto 0) := (others => '0'); - SCI_DATA_OUT : out std_logic_vector(7 downto 0) := (others => '0'); - SCI_ADDR : in std_logic_vector(8 downto 0) := (others => '0'); - SCI_READ : in std_logic := '0'; - SCI_WRITE : in std_logic := '0'; - SCI_ACK : out std_logic := '0'; - SCI_NACK : out std_logic := '0'; - -- Status and control port - STAT_OP : out std_logic_vector (15 downto 0); - CTRL_OP : in std_logic_vector (15 downto 0) := (others => '0'); - STAT_DEBUG : out std_logic_vector (63 downto 0); - CTRL_DEBUG : in std_logic_vector (63 downto 0) := (others => '0') - ); -end component; - -component soda_tx_control - port( - CLK_200 : in std_logic; - CLK_100 : in std_logic; - RESET_IN : in std_logic; - - TX_DATA_IN : in std_logic_vector(15 downto 0); - TX_PACKET_NUMBER_IN : in std_logic_vector(2 downto 0); - TX_WRITE_IN : in std_logic; - TX_READ_OUT : out std_logic; - - TX_DATA_OUT : out std_logic_vector( 7 downto 0); - TX_K_OUT : out std_logic; - - REQUEST_RETRANSMIT_IN : in std_logic := '0'; - REQUEST_POSITION_IN : in std_logic_vector( 7 downto 0) := (others => '0'); - - START_RETRANSMIT_IN : in std_logic := '0'; - START_POSITION_IN : in std_logic_vector( 7 downto 0) := (others => '0'); - --send_dlm: 200 MHz, 1 clock strobe, data valid until next DLM - TX_DLM_PREVIEW_IN : in std_logic := '0'; - SEND_DLM : in std_logic := '0'; - SEND_DLM_WORD : in std_logic_vector( 7 downto 0) := (others => '0'); - - SEND_LINK_RESET_IN : in std_logic := '0'; - TX_ALLOW_IN : in std_logic := '0'; - RX_ALLOW_IN : in std_logic := '0'; - LINK_PHASE_OUT : out std_logic := '0'; - - DEBUG_OUT : out std_logic_vector(31 downto 0); - STAT_REG_OUT : out std_logic_vector(31 downto 0) - ); -end component; - -component soda_cmd_window_generator - generic( CLOCK_PERIOD : natural range 1 to 20 := cSODA_CLOCK_PERIOD; -- clock-period in ns - COMMAND_WINDOS_SIZE : natural range 1 to 65335 := cSODA_COMMAND_WINDOS_SIZE -- command window size in ns - ); - port( - SODACLK : in std_logic; -- fabric clock - RESET : in std_logic; -- synchronous reset - START_OF_SUPERBURST_IN : in std_logic := '0'; -- - SODA_CMD_WINDOW_OUT : out std_logic := '0' + end component; + + component med_ecp3_sfp_4_soda is + generic( SERDES_NUM : integer range 0 to 3 := 0; + IS_SYNC_SLAVE : integer := c_NO); -- hub downlink is NO slave + port( + OSC_CLK : in std_logic; -- 200 MHz reference clock + TX_DATACLK : in std_logic; -- 200 MHz data clock + SYSCLK : in std_logic; -- 100 MHz main clock net, synchronous to OSC clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + --------------------------------------------------------------------------------------------------------------------------------------------------------- +-- LINK_DISABLE_IN : in std_logic; -- downlinks must behave as slaves to uplink connection. Downlinks are released once unlink is established. + --------------------------------------------------------------------------------------------------------------------------------------------------------- + RX_HALF_CLK_OUT : out std_logic_vector(3 downto 0) := (others => '0'); --100 MHz + RX_FULL_CLK_OUT : out std_logic_vector(3 downto 0) := (others => '0'); --200 MHz + TX_HALF_CLK_OUT : out std_logic_vector(3 downto 0) := (others => '0'); --100 MHz + TX_FULL_CLK_OUT : out std_logic_vector(3 downto 0) := (others => '0'); --200 MHz + + --Sync operation + RX_DLM_OUT : out t_HUB_BIT; --std_logic_vector(3 downto 0) := (others => '0'); + RX_DLM_WORD_OUT : out t_HUB_BYTE; --std_logic_vector(4*8 - 1 downto 0) := (others => '0'); + TX_DLM_IN : in t_HUB_BIT; --std_logic_vector(3 downto 0) := (others => '0'); + TX_DLM_WORD_IN : in t_HUB_BYTE; --std_logic_vector(4*8 - 1 downto 0) := (others => '0'); + TX_DLM_PREVIEW_IN : in t_HUB_BIT; --std_logic_vector(3 downto 0) := (others => '0'); --PL! + LINK_PHASE_OUT : out t_HUB_BIT; --std_logic_vector(3 downto 0) := (others => '0'); --PL! + + --SFP Connection + SD_RXD_P_IN : in t_HUB_BIT; --std_logic_vector(3 downto 0); + SD_RXD_N_IN : in t_HUB_BIT; --std_logic_vector(3 downto 0); + SD_TXD_P_OUT : out t_HUB_BIT; --std_logic_vector(3 downto 0); + SD_TXD_N_OUT : out t_HUB_BIT; --std_logic_vector(3 downto 0); + SD_REFCLK_P_IN : in t_HUB_BIT; --std_logic; --not used + SD_REFCLK_N_IN : in t_HUB_BIT; --std_logic; --not used + SD_PRSNT_N_IN : in t_HUB_BIT; --std_logic; -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) + SD_LOS_IN : in t_HUB_BIT; --std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) + SD_TXDIS_OUT : out t_HUB_BIT; --std_logic := '0'; -- SFP disable + --Control Interface + SCI_DATA_IN : in std_logic_vector(7 downto 0) := (others => '0'); + SCI_DATA_OUT : out std_logic_vector(7 downto 0) := (others => '0'); + SCI_ADDR : in std_logic_vector(8 downto 0) := (others => '0'); + SCI_READ : in std_logic := '0'; + SCI_WRITE : in std_logic := '0'; + SCI_ACK : out std_logic := '0'; + SCI_NACK : out std_logic := '0'; + -- Status and control port +-- STAT_OP : out t_HUB_WORD; --std_logic_vector (15 downto 0); +-- CTRL_OP : in t_HUB_WORD; --std_logic_vector (15 downto 0) := (others => '0'); + STAT_DEBUG : out std_logic_vector (63 downto 0); + CTRL_DEBUG : in std_logic_vector (63 downto 0) := (others => '0') ); -end component; - -component soda_clockscaler is - port( - CLK : in std_logic; -- fabric clock - RESET : in std_logic; -- synchronous reset - CLOCK_ENABLE_OUT : out std_logic := '0'; - CLOCK_OUT : out std_logic + end component; + + component soda_tx_control + port( + CLK_200 : in std_logic; + CLK_100 : in std_logic; + RESET_IN : in std_logic; + + TX_DATA_IN : in std_logic_vector(15 downto 0); + TX_PACKET_NUMBER_IN : in std_logic_vector(2 downto 0); + TX_WRITE_IN : in std_logic; + TX_READ_OUT : out std_logic; + + TX_DATA_OUT : out std_logic_vector( 7 downto 0); + TX_K_OUT : out std_logic; + + REQUEST_RETRANSMIT_IN : in std_logic := '0'; + REQUEST_POSITION_IN : in std_logic_vector( 7 downto 0) := (others => '0'); + + START_RETRANSMIT_IN : in std_logic := '0'; + START_POSITION_IN : in std_logic_vector( 7 downto 0) := (others => '0'); + --send_dlm: 200 MHz, 1 clock strobe, data valid until next DLM + TX_DLM_PREVIEW_IN : in std_logic := '0'; + SEND_DLM : in std_logic := '0'; + SEND_DLM_WORD : in std_logic_vector( 7 downto 0) := (others => '0'); + + SEND_LINK_RESET_IN : in std_logic := '0'; + TX_ALLOW_IN : in std_logic := '0'; + RX_ALLOW_IN : in std_logic := '0'; + LINK_PHASE_OUT : out std_logic := '0'; + + DEBUG_OUT : out std_logic_vector(31 downto 0); + STAT_REG_OUT : out std_logic_vector(31 downto 0) ); -end component; + end component; + + component soda_cmd_window_generator + generic( CLOCK_PERIOD : natural range 1 to 20 := cSODA_CLOCK_PERIOD; -- clock-period in ns + COMMAND_WINDOS_SIZE : natural range 1 to 65335 := cSODA_COMMAND_WINDOS_SIZE -- command window size in ns + ); + port( + SODACLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + START_OF_SUPERBURST_IN : in std_logic := '0'; -- + SODA_CMD_WINDOW_OUT : out std_logic := '0' + ); + end component; -component DCS --- synthesis translate_off -generic - ( - DCSMODE : string :=“POS” - ); --- synthesis translate_on -port ( - CLK0 : in std_logic ; - CLK1 : in std_logic ; - SEL : in std_logic ; - DCSOUT : out std_logic) ; -end component; + component soda_clockscaler is + port( + CLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLOCK_ENABLE_OUT : out std_logic := '0'; + CLOCK_OUT : out std_logic + ); + end component; -component dff_re - Port ( - rst : in STD_LOGIC; - clk : in STD_LOGIC; - enable : in STD_LOGIC; - d : in STD_LOGIC_VECTOR; - q : out STD_LOGIC_VECTOR; - data_valid : out STD_LOGIC - ); -end component; + component DCS + -- synthesis translate_off + generic + ( + DCSMODE : string :=“POS” + ); + -- synthesis translate_on + port ( + CLK0 : in std_logic ; + CLK1 : in std_logic ; + SEL : in std_logic ; + DCSOUT : out std_logic) ; + end component; + + component dff_re + Port ( + rst : in STD_LOGIC; + clk : in STD_LOGIC; + enable : in STD_LOGIC; + d : in STD_LOGIC_VECTOR; + q : out STD_LOGIC_VECTOR; + data_valid : out STD_LOGIC + ); + end component; -end package; \ No newline at end of file +end package; diff --git a/code/trb3_periph_EP_soda4source.vhd b/code/trb3_periph_EP_soda4source.vhd new file mode 100644 index 0000000..0b33f16 --- /dev/null +++ b/code/trb3_periph_EP_soda4source.vhd @@ -0,0 +1,756 @@ +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.trb_net16_hub_func.all; +use work.trb3_components.all; +use work.soda_components.all; +use work.med_sync_define.all; +use work.version.all; + +entity trb3_periph_EP_soda4source is + generic( + SYNC_MODE : integer range 0 to 1 := c_NO; --use the RX clock for internal logic and transmission. Should be NO for soda tests! + USE_125_MHZ : integer := c_NO; + CLOCK_FREQUENCY : integer := 100; + NUM_TRB_INTERFACES : integer := 1 + ); + port( + --Clocks + CLK_GPLL_LEFT : in std_logic; --Clock Manager 1/(2468), 125 MHz + CLK_GPLL_RIGHT : in std_logic; --Clock Manager 2/(2468), 200 MHz <-- MAIN CLOCK for FPGA + CLK_PCLK_LEFT : in std_logic; --Clock Fan-out, 200/400 MHz <-- For TDC. Same oscillator as GPLL right! + CLK_PCLK_RIGHT : in std_logic; --Clock Fan-out, 200/400 MHz <-- For TDC. Same oscillator as GPLL right! + + --serdes I/O - connect as you like, no real use + SERDES_ADDON_TX : out std_logic_vector(15 downto 0); + SERDES_ADDON_RX : in std_logic_vector(15 downto 0); + + --Inter-FPGA Communication + FPGA5_COMM : inout std_logic_vector(11 downto 0); --Bit 0/1 input, serial link RX active + --Bit 2/3 output, serial link TX active + --others yet undefined + --Connection to AddOn + LED_LINKOK : out std_logic_vector(6 downto 1); + LED_RX : out std_logic_vector(6 downto 1); + LED_TX : out std_logic_vector(6 downto 1); + SFP_MOD0 : in std_logic_vector(6 downto 1); + SFP_TXDIS : out std_logic_vector(6 downto 1); + SFP_LOS : in std_logic_vector(6 downto 1); + --SFP_MOD1 : inout std_logic_vector(6 downto 1); + --SFP_MOD2 : inout std_logic_vector(6 downto 1); + --SFP_RATESEL : out std_logic_vector(6 downto 1); + --SFP_TXFAULT : in std_logic_vector(6 downto 1); + + --Flash ROM & Reboot + FLASH_CLK : out std_logic; + FLASH_CS : out std_logic; + FLASH_DIN : out std_logic; + FLASH_DOUT : in std_logic; + PROGRAMN : out std_logic; --reboot FPGA + + --Misc + TEMPSENS : inout std_logic; --Temperature Sensor + CODE_LINE : in std_logic_vector(1 downto 0); + LED_GREEN : out std_logic; + LED_ORANGE : out std_logic; + LED_RED : out std_logic; + LED_YELLOW : out std_logic; + SUPPL : in std_logic; --terminated diff pair, PCLK, Pads + + --Test Connectors + TEST_LINE : out std_logic_vector(15 downto 0) + ); + + + attribute syn_useioff : boolean; + --no IO-FF for LEDs relaxes timing constraints + attribute syn_useioff of LED_GREEN : signal is false; + attribute syn_useioff of LED_ORANGE : signal is false; + attribute syn_useioff of LED_RED : signal is false; + attribute syn_useioff of LED_YELLOW : signal is false; + attribute syn_useioff of TEMPSENS : signal is false; + attribute syn_useioff of PROGRAMN : signal is false; + attribute syn_useioff of CODE_LINE : signal is false; + attribute syn_useioff of LED_LINKOK : signal is false; + attribute syn_useioff of LED_TX : signal is false; + attribute syn_useioff of LED_RX : signal is false; + attribute syn_useioff of SFP_MOD0 : signal is false; + attribute syn_useioff of SFP_TXDIS : signal is false; + attribute syn_useioff of SFP_LOS : signal is false; + attribute syn_useioff of TEST_LINE : signal is false; + + --important signals _with_ IO-FF + attribute syn_useioff of FLASH_CLK : signal is true; + attribute syn_useioff of FLASH_CS : signal is true; + attribute syn_useioff of FLASH_DIN : signal is true; + attribute syn_useioff of FLASH_DOUT : signal is true; + attribute syn_useioff of FPGA5_COMM : signal is true; + + +end entity; + +architecture trb3_periph_EP_soda4source_arch of trb3_periph_EP_soda4source is + --Constants + constant REGIO_NUM_STAT_REGS : integer := 0; + constant REGIO_NUM_CTRL_REGS : integer := 2; + + attribute syn_keep : boolean; + attribute syn_preserve : boolean; + + constant USE_200_MHZ : integer := 1 - USE_125_MHZ; + + --Clock / Reset + signal pll_lock : std_logic; --Internal PLL locked. E.g. used to reset all internal logic. + signal clear_i : std_logic; + signal reset_i : std_logic; + signal GSR_N : std_logic; + attribute syn_keep of GSR_N : signal is true; + attribute syn_preserve of GSR_N : signal is true; + signal clk_100_osc : std_logic; + signal clk_200_osc : std_logic; + signal time_counter : unsigned(31 downto 0); + --Media Interface + signal med_stat_op : std_logic_vector (NUM_TRB_INTERFACES*16-1 downto 0); + signal med_ctrl_op : std_logic_vector (NUM_TRB_INTERFACES*16-1 downto 0); + signal med_stat_debug : std_logic_vector (NUM_TRB_INTERFACES*64-1 downto 0); +-- signal med_ctrl_debug : std_logic_vector (NUM_TRB_INTERFACES*64-1 downto 0); + signal med_data_out : std_logic_vector (NUM_TRB_INTERFACES*16-1 downto 0); + signal med_packet_num_out : std_logic_vector (NUM_TRB_INTERFACES* 3-1 downto 0); + signal med_dataready_out : std_logic_vector (NUM_TRB_INTERFACES* 1-1 downto 0); + signal med_read_out : std_logic_vector (NUM_TRB_INTERFACES* 1-1 downto 0); + signal med_data_in : std_logic_vector (NUM_TRB_INTERFACES*16-1 downto 0); + signal med_packet_num_in : std_logic_vector (NUM_TRB_INTERFACES* 3-1 downto 0); + signal med_dataready_in : std_logic_vector (NUM_TRB_INTERFACES* 1-1 downto 0); + signal med_read_in : std_logic_vector (NUM_TRB_INTERFACES* 1-1 downto 0); + + --Slow Control channel +-- signal common_stat_reg : std_logic_vector(std_COMSTATREG*32-1 downto 0); + signal common_ctrl_reg : std_logic_vector(std_COMCTRLREG*32-1 downto 0); + signal stat_reg : std_logic_vector(32*2**REGIO_NUM_STAT_REGS-1 downto 0); + signal ctrl_reg : std_logic_vector(32*2**REGIO_NUM_CTRL_REGS-1 downto 0); + signal common_stat_reg_strobe : std_logic_vector(std_COMSTATREG-1 downto 0); + signal common_ctrl_reg_strobe : std_logic_vector(std_COMCTRLREG-1 downto 0); + signal stat_reg_strobe : std_logic_vector(2**REGIO_NUM_STAT_REGS-1 downto 0); + signal ctrl_reg_strobe : std_logic_vector(2**REGIO_NUM_CTRL_REGS-1 downto 0); + + --RegIO +-- signal my_address : std_logic_vector (15 downto 0); + signal regio_addr_out : std_logic_vector (15 downto 0); + signal regio_read_enable_out : std_logic; + signal regio_write_enable_out : std_logic; + signal regio_data_out : std_logic_vector (31 downto 0); + signal regio_data_in : std_logic_vector (31 downto 0); + signal regio_dataready_in : std_logic; + signal regio_no_more_data_in : std_logic; + signal regio_write_ack_in : std_logic; + signal regio_unknown_addr_in : std_logic; + signal regio_timeout_out : std_logic; + + --Timer + signal global_time : std_logic_vector(31 downto 0); + signal local_time : std_logic_vector(7 downto 0); + signal time_since_last_trg : std_logic_vector(31 downto 0); + signal timer_ticks : std_logic_vector(1 downto 0); + + --Flash + signal spimem_read_en : std_logic; + signal spimem_write_en : std_logic; + signal spimem_data_in : std_logic_vector(31 downto 0); + signal spimem_addr : std_logic_vector(8 downto 0); + signal spimem_data_out : std_logic_vector(31 downto 0); + signal spimem_dataready_out : std_logic; + signal spimem_no_more_data_out : std_logic; + signal spimem_unknown_addr_out : std_logic; + signal spimem_write_ack_out : std_logic; + +-- SCI for the uplink + signal sci1_ack : std_logic; + signal sci1_write : std_logic; + signal sci1_read : std_logic; + signal sci1_data_in : std_logic_vector(7 downto 0); + signal sci1_data_out : std_logic_vector(7 downto 0); + signal sci1_addr : std_logic_vector(8 downto 0); +-- SCI for the downlink + signal sci2_ack : std_logic; + signal sci2_nack : std_logic; + signal sci2_write : std_logic; + signal sci2_read : std_logic; + signal sci2_data_in : std_logic_vector(7 downto 0); + signal sci2_data_out : std_logic_vector(7 downto 0); + signal sci2_addr : std_logic_vector(8 downto 0); + + signal sfp_txdis_S : std_logic_vector(6 downto 1) := (others => '1'); + + --SODA + signal soda_ack : std_logic; + signal soda_nack : std_logic; + signal soda_write : std_logic; + signal soda_read : std_logic; + signal soda_data_in : std_logic_vector(31 downto 0); + signal soda_data_out : std_logic_vector(31 downto 0); + signal soda_addr : std_logic_vector(3 downto 0); + signal soda_leds : std_logic_vector(3 downto 0); + + --SODA downlink + signal rx_half_clk : t_HUB_BIT; + signal rx_full_clk : t_HUB_BIT; + signal tx_half_clk : t_HUB_BIT; + signal tx_full_clk : t_HUB_BIT; + + signal tx_dlm_i : t_HUB_BIT; + signal rx_dlm_i : t_HUB_BIT; + signal tx_dlm_word : t_HUB_BYTE; + signal rx_dlm_word : t_HUB_BYTE; + signal tx_dlm_preview_S : t_HUB_BIT; --PL! + signal link_phase_S : t_HUB_BIT; --PL! + + signal link_debug_in_S : std_logic_vector(31 downto 0); + + --SODA + signal SOB_S : std_logic := '0'; + -- fix signal names for constraining + attribute syn_preserve of rx_full_clk : signal is true; + attribute syn_keep of rx_full_clk : signal is true; + attribute syn_preserve of rx_half_clk : signal is true; + attribute syn_keep of rx_half_clk : signal is true; + attribute syn_preserve of tx_full_clk : signal is true; + attribute syn_keep of tx_full_clk : signal is true; + attribute syn_preserve of tx_half_clk : signal is true; + attribute syn_keep of tx_half_clk : signal is true; + attribute syn_preserve of clk_100_osc : signal is true; + attribute syn_keep of clk_100_osc : signal is true; + attribute syn_preserve of clk_200_osc : signal is true; + attribute syn_keep of clk_200_osc : signal is true; + attribute syn_preserve of tx_dlm_i : signal is true; + attribute syn_keep of tx_dlm_i : signal is true; + attribute syn_preserve of rx_dlm_i : signal is true; + attribute syn_keep of rx_dlm_i : signal is true; + + +begin +--------------------------------------------------------------------------- +-- Reset Generation +--------------------------------------------------------------------------- + + GSR_N <= pll_lock; + + THE_RESET_HANDLER : trb_net_reset_handler + generic map( + RESET_DELAY => x"FEEE" + ) + port map( + CLEAR_IN => '0', -- reset input (high active, async) + CLEAR_N_IN => '1', -- reset input (low active, async) + CLK_IN => clk_200_osc, -- raw master clock, NOT from PLL/DLL! + SYSCLK_IN => clk_100_osc, -- PLL/DLL remastered clock + PLL_LOCKED_IN => pll_lock, -- master PLL lock signal (async) + RESET_IN => '0', -- general reset signal (SYSCLK) + TRB_RESET_IN => med_stat_op(13), -- TRBnet reset signal (SYSCLK) + CLEAR_OUT => clear_i, -- async reset out, USE WITH CARE! + RESET_OUT => reset_i, -- synchronous reset out (SYSCLK) + DEBUG_OUT => open + ); + + +--------------------------------------------------------------------------- +-- Clock Handling +--------------------------------------------------------------------------- +gen_200_PLL : if USE_125_MHZ = c_NO generate + THE_MAIN_PLL : pll_in200_out100 + port map( + CLK => CLK_GPLL_RIGHT, + CLKOP => clk_100_osc, + CLKOK => clk_200_osc, + LOCK => pll_lock + ); +end generate; + +gen_125 : if USE_125_MHZ = c_YES generate + clk_100_osc <= CLK_GPLL_LEFT; + clk_200_osc <= CLK_GPLL_LEFT; +end generate; + + +--------------------------------------------------------------------------- +-- The TrbNet media interface (to other FPGA) +--------------------------------------------------------------------------- + THE_MEDIA_UPLINK : trb_net16_med_ecp3_sfp + generic map( + SERDES_NUM => 1, --number of serdes in quad + EXT_CLOCK => c_NO, --use internal clock + USE_200_MHZ => USE_200_MHZ, --run on 200 MHz clock + USE_125_MHZ => USE_125_MHZ, + USE_CTC => c_NO, + USE_SLAVE => SYNC_MODE + ) + port map( + CLK => clk_200_osc, + SYSCLK => clk_100_osc, + RESET => reset_i, + CLEAR => clear_i, + CLK_EN => '1', + --Internal Connection + MED_DATA_IN => med_data_out(15 downto 0), + MED_PACKET_NUM_IN => med_packet_num_out(2 downto 0), + MED_DATAREADY_IN => med_dataready_out(0), + MED_READ_OUT => med_read_in(0), + MED_DATA_OUT => med_data_in(15 downto 0), + MED_PACKET_NUM_OUT => med_packet_num_in(2 downto 0), + MED_DATAREADY_OUT => med_dataready_in(0), + MED_READ_IN => med_read_out(0), + REFCLK2CORE_OUT => open, + CLK_RX_HALF_OUT => open, + CLK_RX_FULL_OUT => open, + + --SFP Connection + SD_RXD_P_IN => SERDES_ADDON_RX(4), + SD_RXD_N_IN => SERDES_ADDON_RX(5), + SD_TXD_P_OUT => SERDES_ADDON_TX(4), + SD_TXD_N_OUT => SERDES_ADDON_TX(5), + SD_REFCLK_P_IN => '0', + SD_REFCLK_N_IN => '0', + SD_PRSNT_N_IN => FPGA5_COMM(0), + SD_LOS_IN => FPGA5_COMM(0), + SD_TXDIS_OUT => FPGA5_COMM(2), + + SCI_DATA_IN => sci1_data_in, + SCI_DATA_OUT => sci1_data_out, + SCI_ADDR => sci1_addr, + SCI_READ => sci1_read, + SCI_WRITE => sci1_write, + SCI_ACK => sci1_ack, + -- Status and control port + STAT_OP => med_stat_op(15 downto 0), + CTRL_OP => med_ctrl_op(15 downto 0), + STAT_DEBUG => med_stat_debug(63 downto 0), + CTRL_DEBUG => (others => '0') + ); + + +--------------------------------------------------------------------------- +-- Endpoint +--------------------------------------------------------------------------- + THE_ENDPOINT : trb_net16_endpoint_hades_full_handler + generic map( +-- USE_CHANNEL => (c_YES,c_YES,c_NO,c_YES), + REGIO_NUM_STAT_REGS => REGIO_NUM_STAT_REGS, --4, --16 stat reg + REGIO_NUM_CTRL_REGS => REGIO_NUM_CTRL_REGS, --3, --8 cotrol reg + ADDRESS_MASK => x"FFFF", + BROADCAST_BITMASK => x"FF", + BROADCAST_SPECIAL_ADDR => x"45", + REGIO_COMPILE_TIME => std_logic_vector(to_unsigned(VERSION_NUMBER_TIME, 32)), + REGIO_HARDWARE_VERSION => x"9100b000", + REGIO_INIT_ADDRESS => x"f356", + REGIO_USE_VAR_ENDPOINT_ID => c_YES, + CLOCK_FREQUENCY => CLOCK_FREQUENCY, + TIMING_TRIGGER_RAW => c_YES, + --Configure data handler + DATA_INTERFACE_NUMBER => 1, + DATA_BUFFER_DEPTH => 9, --13 + DATA_BUFFER_WIDTH => 32, + DATA_BUFFER_FULL_THRESH => 256, + TRG_RELEASE_AFTER_DATA => c_YES, + HEADER_BUFFER_DEPTH => 9, + HEADER_BUFFER_FULL_THRESH => 256 + ) + port map( + CLK => clk_100_osc, + RESET => reset_i, + CLK_EN => '1', + MED_DATAREADY_OUT => med_dataready_out(0), + MED_DATA_OUT => med_data_out, + MED_PACKET_NUM_OUT => med_packet_num_out, + MED_READ_IN => med_read_in(0), + MED_DATAREADY_IN => med_dataready_in(0), + MED_DATA_IN => med_data_in, + MED_PACKET_NUM_IN => med_packet_num_in, + MED_READ_OUT => med_read_out(0), + MED_STAT_OP_IN => med_stat_op, + MED_CTRL_OP_OUT => med_ctrl_op, + + --Timing trigger in + TRG_TIMING_TRG_RECEIVED_IN => '0', + --LVL1 trigger to FEE + LVL1_TRG_DATA_VALID_OUT => open, + LVL1_VALID_TIMING_TRG_OUT => open, + LVL1_VALID_NOTIMING_TRG_OUT => open, + LVL1_INVALID_TRG_OUT => open, + + LVL1_TRG_TYPE_OUT => open, + LVL1_TRG_NUMBER_OUT => open, + LVL1_TRG_CODE_OUT => open, + LVL1_TRG_INFORMATION_OUT => open, + LVL1_INT_TRG_NUMBER_OUT => open, + + --Information about trigger handler errors + TRG_MULTIPLE_TRG_OUT => open, + TRG_TIMEOUT_DETECTED_OUT => open, + TRG_SPURIOUS_TRG_OUT => open, + TRG_MISSING_TMG_TRG_OUT => open, + TRG_SPIKE_DETECTED_OUT => open, + + --Response from FEE + FEE_TRG_RELEASE_IN(0) => '1', + FEE_TRG_STATUSBITS_IN => (others => '0'), + FEE_DATA_IN => (others => '0'), + FEE_DATA_WRITE_IN(0) => '0', + FEE_DATA_FINISHED_IN(0) => '1', + FEE_DATA_ALMOST_FULL_OUT(0) => open, + + -- Slow Control Data Port + REGIO_COMMON_STAT_REG_IN => (others => '0'), --common_stat_reg, --0x00 because it is floating + REGIO_COMMON_CTRL_REG_OUT => common_ctrl_reg, --0x20 + REGIO_COMMON_STAT_STROBE_OUT => common_stat_reg_strobe, + REGIO_COMMON_CTRL_STROBE_OUT => common_ctrl_reg_strobe, + REGIO_STAT_REG_IN => stat_reg, --start 0x80 + REGIO_CTRL_REG_OUT => ctrl_reg, --start 0xc0 + REGIO_STAT_STROBE_OUT => stat_reg_strobe, + REGIO_CTRL_STROBE_OUT => ctrl_reg_strobe, + REGIO_VAR_ENDPOINT_ID(1 downto 0) => CODE_LINE, + REGIO_VAR_ENDPOINT_ID(15 downto 2) => (others => '0'), + + BUS_ADDR_OUT => regio_addr_out, + BUS_READ_ENABLE_OUT => regio_read_enable_out, + BUS_WRITE_ENABLE_OUT => regio_write_enable_out, + BUS_DATA_OUT => regio_data_out, + BUS_DATA_IN => regio_data_in, + BUS_DATAREADY_IN => regio_dataready_in, + BUS_NO_MORE_DATA_IN => regio_no_more_data_in, + BUS_WRITE_ACK_IN => regio_write_ack_in, + BUS_UNKNOWN_ADDR_IN => regio_unknown_addr_in, + BUS_TIMEOUT_OUT => regio_timeout_out, + ONEWIRE_INOUT => TEMPSENS, + ONEWIRE_MONITOR_OUT => open, + + TIME_GLOBAL_OUT => global_time, + TIME_LOCAL_OUT => local_time, + TIME_SINCE_LAST_TRG_OUT => time_since_last_trg, + TIME_TICKS_OUT => timer_ticks, + + STAT_DEBUG_IPU => open, + STAT_DEBUG_1 => open, + STAT_DEBUG_2 => open, + STAT_DEBUG_DATA_HANDLER_OUT => open, + STAT_DEBUG_IPU_HANDLER_OUT => open, + STAT_TRIGGER_OUT => open, + CTRL_MPLEX => (others => '0'), + IOBUF_CTRL_GEN => (others => '0'), + STAT_ONEWIRE => open, + STAT_ADDR_DEBUG => open, + DEBUG_LVL1_HANDLER_OUT => open + ); + + + +--------------------------------------------------------------------------- +-- Bus Handler +--------------------------------------------------------------------------- + THE_BUS_HANDLER : trb_net16_regio_bus_handler + generic map( + PORT_NUMBER => 4, + PORT_ADDRESSES => (0 => x"d000", 1 => x"b000", 2 => x"be00", others => x"0000"), + PORT_ADDR_MASK => (0 => 9, 1 => 9, 2 => 4, others => 0) + ) + port map( + CLK => clk_100_osc, + RESET => reset_i, + + DAT_ADDR_IN => regio_addr_out, + DAT_DATA_IN => regio_data_out, + DAT_DATA_OUT => regio_data_in, + DAT_READ_ENABLE_IN => regio_read_enable_out, + DAT_WRITE_ENABLE_IN => regio_write_enable_out, + DAT_TIMEOUT_IN => regio_timeout_out, + DAT_DATAREADY_OUT => regio_dataready_in, + DAT_WRITE_ACK_OUT => regio_write_ack_in, + DAT_NO_MORE_DATA_OUT => regio_no_more_data_in, + DAT_UNKNOWN_ADDR_OUT => regio_unknown_addr_in, + + BUS_READ_ENABLE_OUT(0) => spimem_read_en, + BUS_READ_ENABLE_OUT(1) => sci1_read, + BUS_READ_ENABLE_OUT(2) => sci2_read, + BUS_READ_ENABLE_OUT(3) => soda_read, + + BUS_WRITE_ENABLE_OUT(0) => spimem_write_en, + BUS_WRITE_ENABLE_OUT(1) => sci1_write, + BUS_WRITE_ENABLE_OUT(2) => sci2_write, + BUS_WRITE_ENABLE_OUT(3) => soda_write, + + BUS_DATA_OUT(0*32+31 downto 0*32) => spimem_data_in, + BUS_DATA_OUT(1*32+7 downto 1*32) => sci1_data_in, + BUS_DATA_OUT(1*32+31 downto 1*32+8) => open, + BUS_DATA_OUT(2*32+7 downto 2*32) => sci2_data_in, + BUS_DATA_OUT(2*32+31 downto 2*32+8) => open, + BUS_DATA_OUT(2*32+31 downto 2*32) => soda_data_in, + + BUS_ADDR_OUT(0*16+8 downto 0*16) => spimem_addr, + BUS_ADDR_OUT(0*16+15 downto 0*16+9) => open, + BUS_ADDR_OUT(1*16+8 downto 1*16) => sci1_addr, + BUS_ADDR_OUT(1*16+15 downto 1*16+9) => open, + BUS_ADDR_OUT(2*16+8 downto 2*16) => sci2_addr, + BUS_ADDR_OUT(2*16+15 downto 2*16+9) => open, + BUS_ADDR_OUT(3*16+3 downto 3*16) => soda_addr, + BUS_ADDR_OUT(3*16+15 downto 3*16+4) => open, + + BUS_TIMEOUT_OUT(0) => open, + BUS_TIMEOUT_OUT(1) => open, + BUS_TIMEOUT_OUT(2) => open, + + BUS_DATA_IN(0*32+31 downto 0*32) => spimem_data_out, + BUS_DATA_IN(1*32+7 downto 1*32) => sci1_data_out, + BUS_DATA_IN(1*32+31 downto 1*32+8) => open, + BUS_DATA_IN(2*32+7 downto 2*32) => sci2_data_out, + BUS_DATA_IN(2*32+31 downto 2*32+8) => open, + BUS_DATA_IN(3*32+31 downto 3*32) => soda_data_out, + + BUS_DATAREADY_IN(0) => spimem_dataready_out, + BUS_DATAREADY_IN(1) => sci1_ack, + BUS_DATAREADY_IN(2) => sci2_ack, + BUS_DATAREADY_IN(3) => soda_ack, + + BUS_WRITE_ACK_IN(0) => spimem_write_ack_out, + BUS_WRITE_ACK_IN(1) => sci1_ack, + BUS_WRITE_ACK_IN(2) => sci2_ack, + BUS_WRITE_ACK_IN(3) => soda_ack, + + BUS_NO_MORE_DATA_IN(0) => spimem_no_more_data_out, + BUS_NO_MORE_DATA_IN(1) => '0', + BUS_NO_MORE_DATA_IN(2) => '0', + BUS_NO_MORE_DATA_IN(3) => '0', + + BUS_UNKNOWN_ADDR_IN(0) => spimem_unknown_addr_out, + BUS_UNKNOWN_ADDR_IN(1) => '0', + BUS_UNKNOWN_ADDR_IN(2) => '0', + BUS_UNKNOWN_ADDR_IN(3) => '0', + + STAT_DEBUG => open + ); + +--------------------------------------------------------------------------- +-- SPI / Flash +--------------------------------------------------------------------------- + +THE_SPI_RELOAD : spi_flash_and_fpga_reload --.flash_reboot_arch + port map( + CLK_IN => clk_100_osc, + RESET_IN => reset_i, + + BUS_ADDR_IN => spimem_addr, + BUS_READ_IN => spimem_read_en, + BUS_WRITE_IN => spimem_write_en, + BUS_DATAREADY_OUT => spimem_dataready_out, + BUS_WRITE_ACK_OUT => spimem_write_ack_out, + BUS_UNKNOWN_ADDR_OUT => spimem_unknown_addr_out, + BUS_NO_MORE_DATA_OUT => spimem_no_more_data_out, + BUS_DATA_IN => spimem_data_in, + BUS_DATA_OUT => spimem_data_out, + + DO_REBOOT_IN => common_ctrl_reg(15), + PROGRAMN => PROGRAMN, + + SPI_CS_OUT => FLASH_CS, + SPI_SCK_OUT => FLASH_CLK, + SPI_SDO_OUT => FLASH_DIN, + SPI_SDI_IN => FLASH_DOUT + ); + + +--------------------------------------------------------------------------- +-- The synchronous quad-downlink interface for Soda +--------------------------------------------------------------------------- + + MED_ECP3_SODA_QUAD_SOURCE : med_ecp3_sfp_4_soda + generic map( + SERDES_NUM => 0, --number of serdes in quad + IS_SYNC_SLAVE => c_NO + ) + port map( + OSC_CLK => clk_200_osc, + TX_DATACLK => clk_200_osc, + SYSCLK => clk_100_osc, -- rx_half_clk is selectively used inside med_ecp3_sfp_4_sync_down.vhd + RESET => reset_i, + CLEAR => clear_i, + --------------------------------------------------------------------------------------------------------------------------------------------------------- +-- LINK_DISABLE_IN => sfp_txdis_S(3),-- downlinks must behave as slaves to uplink connection. Downlinks are released once unlink is established. + --------------------------------------------------------------------------------------------------------------------------------------------------------- +-- MED_DATA_IN(0*16+15 downto 0*16) => med_data_out(1*16+15 downto 1*16), + RX_HALF_CLK_OUT(0) => rx_half_clk(0), + RX_HALF_CLK_OUT(1) => rx_half_clk(1), + RX_HALF_CLK_OUT(2) => rx_half_clk(2), + RX_HALF_CLK_OUT(3) => rx_half_clk(3), + + RX_FULL_CLK_OUT(0) => rx_full_clk(0), -- needed for sync replies i.e. calibration + RX_FULL_CLK_OUT(1) => rx_full_clk(1), -- needed for sync replies i.e. calibration + RX_FULL_CLK_OUT(2) => rx_full_clk(2), -- needed for sync replies i.e. calibration + RX_FULL_CLK_OUT(3) => rx_full_clk(3), -- needed for sync replies i.e. calibration + + TX_HALF_CLK_OUT(0) => tx_half_clk(0), + TX_HALF_CLK_OUT(1) => tx_half_clk(1), + TX_HALF_CLK_OUT(2) => tx_half_clk(2), + TX_HALF_CLK_OUT(3) => tx_half_clk(3), + + TX_FULL_CLK_OUT(0) => tx_full_clk(0), + TX_FULL_CLK_OUT(1) => tx_full_clk(1), + TX_FULL_CLK_OUT(2) => tx_full_clk(2), + TX_FULL_CLK_OUT(3) => tx_full_clk(3), + + RX_DLM_OUT(0) => rx_dlm_i(0), + RX_DLM_OUT(1) => rx_dlm_i(1), + RX_DLM_OUT(2) => rx_dlm_i(2), + RX_DLM_OUT(3) => rx_dlm_i(3), + + RX_DLM_WORD_OUT(0) => rx_dlm_word(0), + RX_DLM_WORD_OUT(1) => rx_dlm_word(1), + RX_DLM_WORD_OUT(2) => rx_dlm_word(2), + RX_DLM_WORD_OUT(3) => rx_dlm_word(3), + + TX_DLM_IN(0) => tx_dlm_i(0), + TX_DLM_IN(1) => tx_dlm_i(1), + TX_DLM_IN(2) => tx_dlm_i(2), + TX_DLM_IN(3) => tx_dlm_i(3), + + TX_DLM_WORD_IN(0) => tx_dlm_word(0), + TX_DLM_WORD_IN(1) => tx_dlm_word(1), + TX_DLM_WORD_IN(2) => tx_dlm_word(2), + TX_DLM_WORD_IN(3) => tx_dlm_word(3), + + TX_DLM_PREVIEW_IN(0) => tx_dlm_preview_S(0), --PL! + TX_DLM_PREVIEW_IN(1) => tx_dlm_preview_S(1), --PL! + TX_DLM_PREVIEW_IN(2) => tx_dlm_preview_S(2), --PL! + TX_DLM_PREVIEW_IN(3) => tx_dlm_preview_S(3), --PL! + + LINK_PHASE_OUT(0) => link_phase_S(0), --PL! + LINK_PHASE_OUT(1) => link_phase_S(1), --PL! + LINK_PHASE_OUT(2) => link_phase_S(2), --PL! + LINK_PHASE_OUT(3) => link_phase_S(3), --PL! + + --SFP Connection + SD_RXD_P_IN(0) => SERDES_ADDON_RX(0), -- B0 + SD_RXD_P_IN(1) => SERDES_ADDON_RX(1), + SD_RXD_P_IN(2) => SERDES_ADDON_RX(10), -- B1 + SD_RXD_P_IN(3) => SERDES_ADDON_RX(11), + SD_RXD_N_IN(0) => SERDES_ADDON_RX(2), -- B2 + SD_RXD_N_IN(1) => SERDES_ADDON_RX(3), + SD_RXD_N_IN(2) => SERDES_ADDON_RX(6), -- B3 + SD_RXD_N_IN(3) => SERDES_ADDON_RX(7), + SD_TXD_P_OUT(0) => SERDES_ADDON_TX(0), -- B0 + SD_TXD_P_OUT(1) => SERDES_ADDON_TX(1), + SD_TXD_P_OUT(2) => SERDES_ADDON_TX(10), -- B1 + SD_TXD_P_OUT(3) => SERDES_ADDON_TX(11), + SD_TXD_N_OUT(0) => SERDES_ADDON_TX(2), -- B2 + SD_TXD_N_OUT(1) => SERDES_ADDON_TX(3), + SD_TXD_N_OUT(2) => SERDES_ADDON_TX(6), -- B3 + SD_TXD_N_OUT(3) => SERDES_ADDON_TX(7), + SD_REFCLK_P_IN => (others => '0'), + SD_REFCLK_N_IN => ('0','0','0','0'), + SD_PRSNT_N_IN(0) => SFP_MOD0(1), + SD_PRSNT_N_IN(1) => SFP_MOD0(6), + SD_PRSNT_N_IN(2) => SFP_MOD0(2), + SD_PRSNT_N_IN(3) => SFP_MOD0(4), + SD_LOS_IN(0) => SFP_LOS(1), + SD_LOS_IN(1) => SFP_LOS(6), + SD_LOS_IN(2) => SFP_LOS(2), + SD_LOS_IN(3) => SFP_LOS(4), + SD_TXDIS_OUT(0) => sfp_txdis_S(1), + SD_TXDIS_OUT(1) => sfp_txdis_S(6), + SD_TXDIS_OUT(2) => sfp_txdis_S(2), + SD_TXDIS_OUT(3) => sfp_txdis_S(4), + + SCI_DATA_IN => sci2_data_in, + SCI_DATA_OUT => sci2_data_out, + SCI_ADDR => sci2_addr, + SCI_READ => sci2_read, + SCI_WRITE => sci2_write, + SCI_ACK => sci2_ack, + SCI_NACK => sci2_nack, + + --Status and control port +-- STAT_OP(0) => med_stat_op(15 downto 0), --med_stat_op(1*16+15 downto 1*16), +-- CTRL_OP(0) => med_ctrl_op(15 downto 0), --med_ctrl_op(0*16+15 downto 0*16), + + STAT_DEBUG => open, + CTRL_DEBUG => (others => '0') + ); + + + + SFP_TXDIS(1) <= sfp_txdis_S(1); + +--------------------------------------------------------------------------- +-- The Soda Central +--------------------------------------------------------------------------- + +THE_SOB_SOURCE : soda_start_of_burst_faker + generic map( + CLOCK_PERIOD => cSYS_CLOCK_PERIOD, -- clock-period in ns + BURST_PERIOD => cBURST_PERIOD -- burst-period in ns + ) + port map( + SYSCLK => clk_100_osc, + RESET => reset_i, + SODA_BURST_PULSE_OUT => SOB_S + ); + +--------------------------------------------------------------------------- +-- The Soda Central +--------------------------------------------------------------------------- + + THE_SODA_QUAD_SOURCE : soda_4source + port map( + SYSCLK => clk_100_osc, + SODACLK => clk_200_osc, + RESET => reset_i, + CLEAR => clear_i, + CLK_EN => '1', + + SODA_BURST_PULSE_IN => SOB_S, + + -- MULTIPLE DUPLEX DOWN-LINKS TO THE BOTTOM + RX_DLM_IN => rx_dlm_i, + RX_DLM_WORD_IN => rx_dlm_word, + TX_DLM_OUT => tx_dlm_i, + TX_DLM_WORD_OUT => tx_dlm_word, + TX_DLM_PREVIEW_OUT => tx_dlm_preview_S, + LINK_PHASE_IN => link_phase_S, + + SODA_DATA_IN => soda_data_in, + SODA_DATA_OUT => soda_data_out, + SODA_ADDR_IN => soda_addr, + SODA_READ_IN => soda_read, + SODA_WRITE_IN => soda_write, + SODA_ACK_OUT => soda_ack, + LEDS_OUT => soda_leds, + LINK_DEBUG_IN => link_debug_in_S + ); + +-- downlink_reset <= '1' when (reset_i = '1' or uplink_ready_S = '0') else '0'; +-- downlink_clear <= '1' when (clear_i = '1' or uplink_ready_S = '0') else '0'; + +--------------------------------------------------------------------------- +-- LED +--------------------------------------------------------------------------- + LED_ORANGE <= SFP_LOS(1); --med_stat_op(8); + LED_YELLOW <= sfp_txdis_S(1); --med_stat_op(10); + LED_GREEN <= med_stat_op(12); --tx_pll_lol + LED_RED <= med_stat_op(11); --rx_cdr_lol + + +--------------------------------------------------------------------------- +-- Test Connector +--------------------------------------------------------------------------- +-- TEST_LINE(15 downto 0) <= (others => '0'); +--------------------------------------------------------------------------- +-- Test Circuits +--------------------------------------------------------------------------- + process + begin + wait until rising_edge(clk_100_osc); + time_counter <= time_counter + 1; + end process; + + +end trb3_periph_EP_soda4source_arch; \ No newline at end of file diff --git a/code/trb3_periph_hub.vhd b/code/trb3_periph_hub.vhd new file mode 100644 index 0000000..75ac24b --- /dev/null +++ b/code/trb3_periph_hub.vhd @@ -0,0 +1,758 @@ +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.trb_net16_hub_func.all; +use work.trb3_components.all; +use work.version.all; + + + +entity trb3_periph_hub is + generic( + SYNC_MODE : integer range 0 to 1 := c_NO --use the RX clock for internal logic and transmission. 4 SFP links only. + ); + port( + --Clocks + CLK_GPLL_LEFT : in std_logic; --Clock Manager 1/(2468), 125 MHz + CLK_GPLL_RIGHT : in std_logic; --Clock Manager 2/(2468), 200 MHz <-- MAIN CLOCK for FPGA + CLK_PCLK_LEFT : in std_logic; --Clock Fan-out, 200/400 MHz <-- For TDC. Same oscillator as GPLL right! + CLK_PCLK_RIGHT : in std_logic; --Clock Fan-out, 200/400 MHz <-- For TDC. Same oscillator as GPLL right! + + --Trigger + TRIGGER_LEFT : in std_logic; --left side trigger input from fan-out + TRIGGER_RIGHT : in std_logic; --right side trigger input from fan-out + + --Serdes + CLK_SERDES_INT_LEFT : in std_logic; --Clock Manager 1/(1357), off, 125 MHz possible + CLK_SERDES_INT_RIGHT : in std_logic; --Clock Manager 2/(1357), 200 MHz, only in case of problems +-- SERDES_INT_TX : out std_logic_vector(3 downto 0); +-- SERDES_INT_RX : in std_logic_vector(3 downto 0); + SERDES_ADDON_TX : out std_logic_vector(15 downto 0); + SERDES_ADDON_RX : in std_logic_vector(15 downto 0); + + --Inter-FPGA Communication + FPGA5_COMM : inout std_logic_vector(11 downto 0); + --Bit 0/1 input, serial link RX active + --Bit 2/3 output, serial link TX active + --others yet undefined + --Connection to AddOn + LED_LINKOK : out std_logic_vector(6 downto 1); + LED_RX : out std_logic_vector(6 downto 1); + LED_TX : out std_logic_vector(6 downto 1); + SFP_MOD0 : in std_logic_vector(6 downto 1); + SFP_TXDIS : out std_logic_vector(6 downto 1); + SFP_LOS : in std_logic_vector(6 downto 1); +-- SFP_MOD1 : inout std_logic_vector(6 downto 1); +-- SFP_MOD2 : inout std_logic_vector(6 downto 1); +-- SFP_RATESEL : out std_logic_vector(6 downto 1); +-- SFP_TXFAULT : in std_logic_vector(6 downto 1); + + --Flash ROM & Reboot + FLASH_CLK : out std_logic; + FLASH_CS : out std_logic; + FLASH_DIN : out std_logic; + FLASH_DOUT : in std_logic; + PROGRAMN : out std_logic; --reboot FPGA + + --Misc + TEMPSENS : inout std_logic; --Temperature Sensor + CODE_LINE : in std_logic_vector(1 downto 0); + LED_GREEN : out std_logic; + LED_ORANGE : out std_logic; + LED_RED : out std_logic; + LED_YELLOW : out std_logic; + SUPPL : in std_logic; --terminated diff pair, PCLK, Pads + + --Test Connectors + TEST_LINE : out std_logic_vector(15 downto 0) + ); + + + attribute syn_useioff : boolean; + --no IO-FF for LEDs relaxes timing constraints + attribute syn_useioff of LED_GREEN : signal is false; + attribute syn_useioff of LED_ORANGE : signal is false; + attribute syn_useioff of LED_RED : signal is false; + attribute syn_useioff of LED_YELLOW : signal is false; + attribute syn_useioff of TEMPSENS : signal is false; + attribute syn_useioff of PROGRAMN : signal is false; + attribute syn_useioff of CODE_LINE : signal is false; + attribute syn_useioff of TRIGGER_LEFT : signal is false; + attribute syn_useioff of TRIGGER_RIGHT : signal is false; + attribute syn_useioff of LED_LINKOK : signal is false; + attribute syn_useioff of LED_TX : signal is false; + attribute syn_useioff of LED_RX : signal is false; + attribute syn_useioff of SFP_MOD0 : signal is false; + attribute syn_useioff of SFP_TXDIS : signal is false; + attribute syn_useioff of SFP_LOS : signal is false; + + + --important signals _with_ IO-FF + attribute syn_useioff of FLASH_CLK : signal is true; + attribute syn_useioff of FLASH_CS : signal is true; + attribute syn_useioff of FLASH_DIN : signal is true; + attribute syn_useioff of FLASH_DOUT : signal is true; + attribute syn_useioff of FPGA5_COMM : signal is true; + attribute syn_useioff of TEST_LINE : signal is false; +-- attribute syn_useioff of DQLL : signal is true; +-- attribute syn_useioff of DQUL : signal is true; +-- attribute syn_useioff of DQLR : signal is true; +-- attribute syn_useioff of DQUR : signal is true; +-- attribute syn_useioff of SPARE_LINE : signal is true; + + +end entity; + +architecture trb3_periph_hub_arch of trb3_periph_hub is + --Constants + constant REGIO_NUM_STAT_REGS : integer := 2; + constant REGIO_NUM_CTRL_REGS : integer := 2; + + attribute syn_keep : boolean; + attribute syn_preserve : boolean; + + --Clock / Reset + signal clk_100_i : std_logic; --clock for main logic, 100 MHz, via Clock Manager and internal PLL + signal clk_200_i : std_logic; --clock for logic at 200 MHz, via Clock Manager and bypassed PLL + signal pll_lock : std_logic; --Internal PLL locked. E.g. used to reset all internal logic. + signal clear_i : std_logic; + signal reset_i : std_logic; + signal GSR_N : std_logic; + attribute syn_keep of GSR_N : signal is true; + attribute syn_preserve of GSR_N : signal is true; + signal clk_100_internal : std_logic; + signal clk_200_internal : std_logic; + signal rx_clock_100 : std_logic; + signal rx_clock_200 : std_logic; + + --Media Interface + signal med_stat_op : std_logic_vector (7*16-1 downto 0); + signal med_ctrl_op : std_logic_vector (7*16-1 downto 0); + signal med_stat_debug : std_logic_vector (7*64-1 downto 0); + signal med_ctrl_debug : std_logic_vector (7*64-1 downto 0); + signal med_data_out : std_logic_vector (7*16-1 downto 0); + signal med_packet_num_out : std_logic_vector (7*3-1 downto 0); + signal med_dataready_out : std_logic_vector (6 downto 0); + signal med_read_out : std_logic_vector (6 downto 0); + signal med_data_in : std_logic_vector (7*16-1 downto 0); + signal med_packet_num_in : std_logic_vector (7*3-1 downto 0); + signal med_dataready_in : std_logic_vector (6 downto 0); + signal med_read_in : std_logic_vector (6 downto 0); + + + --Slow Control channel + signal common_stat_reg : std_logic_vector(std_COMSTATREG*32-1 downto 0); + signal common_ctrl_reg : std_logic_vector(std_COMCTRLREG*32-1 downto 0); + signal stat_reg : std_logic_vector(32*2**REGIO_NUM_STAT_REGS-1 downto 0); + signal ctrl_reg : std_logic_vector(32*2**REGIO_NUM_CTRL_REGS-1 downto 0); + signal common_stat_reg_strobe : std_logic_vector(std_COMSTATREG-1 downto 0); + signal common_ctrl_reg_strobe : std_logic_vector(std_COMCTRLREG-1 downto 0); + signal stat_reg_strobe : std_logic_vector(2**REGIO_NUM_STAT_REGS-1 downto 0); + signal ctrl_reg_strobe : std_logic_vector(2**REGIO_NUM_CTRL_REGS-1 downto 0); + + --RegIO + signal my_address : std_logic_vector (15 downto 0); + signal regio_addr_out : std_logic_vector (15 downto 0); + signal regio_read_enable_out : std_logic; + signal regio_write_enable_out : std_logic; + signal regio_data_out : std_logic_vector (31 downto 0); + signal regio_data_in : std_logic_vector (31 downto 0); + signal regio_dataready_in : std_logic; + signal regio_no_more_data_in : std_logic; + signal regio_write_ack_in : std_logic; + signal regio_unknown_addr_in : std_logic; + signal regio_timeout_out : std_logic; + + --Timer + signal global_time : std_logic_vector(31 downto 0); + signal local_time : std_logic_vector(7 downto 0); + signal time_since_last_trg : std_logic_vector(31 downto 0); + signal timer_ticks : std_logic_vector(1 downto 0); + + --Flash + signal spictrl_read_en : std_logic; + signal spictrl_write_en : std_logic; + signal spictrl_data_in : std_logic_vector(31 downto 0); + signal spictrl_addr : std_logic; + signal spictrl_data_out : std_logic_vector(31 downto 0); + signal spictrl_ack : std_logic; + signal spictrl_busy : std_logic; + signal spimem_read_en : std_logic; + signal spimem_write_en : std_logic; + signal spimem_data_in : std_logic_vector(31 downto 0); + signal spimem_addr : std_logic_vector(5 downto 0); + signal spimem_data_out : std_logic_vector(31 downto 0); + signal spimem_ack : std_logic; + + signal spi_bram_addr : std_logic_vector(7 downto 0); + signal spi_bram_wr_d : std_logic_vector(7 downto 0); + signal spi_bram_rd_d : std_logic_vector(7 downto 0); + signal spi_bram_we : std_logic; + + signal sci1_ack : std_logic; + signal sci1_write : std_logic; + signal sci1_read : std_logic; + signal sci1_data_in : std_logic_vector(7 downto 0); + signal sci1_data_out : std_logic_vector(7 downto 0); + signal sci1_addr : std_logic_vector(8 downto 0); + + signal sci2_ack : std_logic; + signal sci2_write : std_logic; + signal sci2_read : std_logic; + signal sci2_data_in : std_logic_vector(7 downto 0); + signal sci2_data_out : std_logic_vector(7 downto 0); + signal sci2_addr : std_logic_vector(8 downto 0); + + --FPGA Test + signal time_counter : unsigned(31 downto 0); + + +begin +--------------------------------------------------------------------------- +-- Reset Generation +--------------------------------------------------------------------------- + + GSR_N <= pll_lock; + + THE_RESET_HANDLER : trb_net_reset_handler + generic map( + RESET_DELAY => x"FEEE" + ) + port map( + CLEAR_IN => '0', -- reset input (high active, async) + CLEAR_N_IN => '1', -- reset input (low active, async) + CLK_IN => clk_200_internal, -- raw master clock, NOT from PLL/DLL! + SYSCLK_IN => clk_100_i, -- PLL/DLL remastered clock + PLL_LOCKED_IN => pll_lock, -- master PLL lock signal (async) + RESET_IN => '0', -- general reset signal (SYSCLK) + TRB_RESET_IN => med_stat_op(13), -- TRBnet reset signal (SYSCLK) + CLEAR_OUT => clear_i, -- async reset out, USE WITH CARE! + RESET_OUT => reset_i, -- synchronous reset out (SYSCLK) + DEBUG_OUT => open + ); + + +--------------------------------------------------------------------------- +-- Clock Handling +--------------------------------------------------------------------------- + + THE_MAIN_PLL : pll_in200_out100 + port map( + CLK => CLK_GPLL_RIGHT, + CLKOP => clk_100_internal, + CLKOK => clk_200_internal, + LOCK => pll_lock + ); + +gen_sync_clocks : if SYNC_MODE = c_YES generate + clk_100_i <= rx_clock_100; + clk_200_i <= rx_clock_200; +end generate; + +gen_local_clocks : if SYNC_MODE = c_NO generate + clk_100_i <= clk_100_internal; + clk_200_i <= clk_200_internal; +end generate; + + +--------------------------------------------------------------------------- +-- The TrbNet media interface (to other FPGA) +--------------------------------------------------------------------------- +gen_full_media : if SYNC_MODE = c_NO generate + THE_MEDIA_UPLINK : trb_net16_med_ecp3_sfp_4 + generic map( + REVERSE_ORDER => c_NO, --order of ports + FREQUENCY => 200 --run on 200 MHz clock + ) + port map( + CLK => clk_200_i, + SYSCLK => clk_100_i, + RESET => reset_i, + CLEAR => clear_i, + CLK_EN => '1', + --Internal Connection + MED_DATA_IN(0*16+15 downto 0*16) => (others => '0'), + MED_DATA_IN(1*16+15 downto 1*16) => med_data_out(0*16+15 downto 0*16), + MED_DATA_IN(2*16+15 downto 2*16) => med_data_out(5*16+15 downto 5*16), + MED_DATA_IN(3*16+15 downto 3*16) => med_data_out(3*16+15 downto 3*16), + + MED_PACKET_NUM_IN(0*3+2 downto 0*3) => "000", + MED_PACKET_NUM_IN(1*3+2 downto 1*3) => med_packet_num_out(0*3+2 downto 0*3), + MED_PACKET_NUM_IN(2*3+2 downto 2*3) => med_packet_num_out(5*3+2 downto 5*3), + MED_PACKET_NUM_IN(3*3+2 downto 3*3) => med_packet_num_out(3*3+2 downto 3*3), + + MED_DATAREADY_IN(0) => '0', + MED_DATAREADY_IN(1) => med_dataready_out(0), + MED_DATAREADY_IN(2) => med_dataready_out(5), + MED_DATAREADY_IN(3) => med_dataready_out(3), + + MED_READ_OUT(0) => open, + MED_READ_OUT(1) => med_read_in(0), + MED_READ_OUT(2) => med_read_in(5), + MED_READ_OUT(3) => med_read_in(3), + + MED_DATA_OUT(0*16+15 downto 0*16) => open, + MED_DATA_OUT(1*16+15 downto 1*16) => med_data_in(0*16+15 downto 0*16), + MED_DATA_OUT(2*16+15 downto 2*16) => med_data_in(5*16+15 downto 5*16), + MED_DATA_OUT(3*16+15 downto 3*16) => med_data_in(3*16+15 downto 3*16), + + MED_PACKET_NUM_OUT(0*3+2 downto 0*3) => open, + MED_PACKET_NUM_OUT(1*3+2 downto 1*3) => med_packet_num_in(0*3+2 downto 0*3), + MED_PACKET_NUM_OUT(2*3+2 downto 2*3) => med_packet_num_in(5*3+2 downto 5*3), + MED_PACKET_NUM_OUT(3*3+2 downto 3*3) => med_packet_num_in(3*3+2 downto 3*3), + + MED_DATAREADY_OUT(0) => open, + MED_DATAREADY_OUT(1) => med_dataready_in(0), + MED_DATAREADY_OUT(2) => med_dataready_in(5), + MED_DATAREADY_OUT(3) => med_dataready_in(3), + + MED_READ_IN(0) => '1', + MED_READ_IN(1) => med_read_out(0), + MED_READ_IN(2) => med_read_out(5), + MED_READ_IN(3) => med_read_out(3), + + REFCLK2CORE_OUT => open, + --SFP Connection + SD_RXD_P_IN => SERDES_ADDON_RX(11 downto 8), + SD_RXD_N_IN => SERDES_ADDON_RX(15 downto 12), + SD_TXD_P_OUT => SERDES_ADDON_TX(11 downto 8), + SD_TXD_N_OUT => SERDES_ADDON_TX(15 downto 12), + SD_REFCLK_P_IN => open, + SD_REFCLK_N_IN => open, + SD_PRSNT_N_IN(0) => '1', + SD_PRSNT_N_IN(1) => FPGA5_COMM(0), + SD_PRSNT_N_IN(2) => SFP_MOD0(5), + SD_PRSNT_N_IN(3) => SFP_MOD0(3), + SD_LOS_IN(0) => '1', + SD_LOS_IN(1) => FPGA5_COMM(0), + SD_LOS_IN(2) => SFP_LOS(5), + SD_LOS_IN(3) => SFP_LOS(3), + SD_TXDIS_OUT(0) => open, + SD_TXDIS_OUT(1) => FPGA5_COMM(2), + SD_TXDIS_OUT(2) => SFP_TXDIS(5), + SD_TXDIS_OUT(3) => SFP_TXDIS(3), + + SCI_DATA_IN => sci1_data_in, + SCI_DATA_OUT => sci1_data_out, + SCI_ADDR => sci1_addr, + SCI_READ => sci1_read, + SCI_WRITE => sci1_write, + SCI_ACK => sci1_ack, + -- Status and control port + + STAT_OP(0*16+15 downto 0*16) => open, + STAT_OP(1*16+15 downto 1*16) => med_stat_op(0*16+15 downto 0*16), + STAT_OP(2*16+15 downto 2*16) => med_stat_op(5*16+15 downto 5*16), + STAT_OP(3*16+15 downto 3*16) => med_stat_op(3*16+15 downto 3*16), + + CTRL_OP(0*16+15 downto 0*16) => x"0000", + CTRL_OP(1*16+15 downto 1*16) => med_ctrl_op(0*16+15 downto 0*16), + CTRL_OP(2*16+15 downto 2*16) => med_ctrl_op(5*16+15 downto 5*16), + CTRL_OP(3*16+15 downto 3*16) => med_ctrl_op(3*16+15 downto 3*16), + + STAT_DEBUG => open, + CTRL_DEBUG => (others => '0') + ); +end generate; + +gen_sync_media : if SYNC_MODE = c_YES generate + med_stat_op(3*16+15 downto 3*16) <= x"0007"; + med_stat_op(5*16+15 downto 5*16) <= x"0007"; + + THE_MEDIA_UPLINK : trb_net16_med_ecp3_sfp + generic map( + SERDES_NUM => 1, --number of serdes in quad + EXT_CLOCK => c_NO, --use internal clock + USE_200_MHZ => c_YES, --run on 200 MHz clock + USE_CTC => c_NO, + USE_SLAVE => c_YES + ) + port map( + CLK => clk_200_internal, + SYSCLK => clk_100_i, + RESET => reset_i, + CLEAR => clear_i, + CLK_EN => '1', + --Internal Connection + MED_DATA_IN => med_data_out(15 downto 0), + MED_PACKET_NUM_IN => med_packet_num_out(2 downto 0), + MED_DATAREADY_IN => med_dataready_out(0), + MED_READ_OUT => med_read_in(0), + MED_DATA_OUT => med_data_in(15 downto 0), + MED_PACKET_NUM_OUT => med_packet_num_in(2 downto 0), + MED_DATAREADY_OUT => med_dataready_in(0), + MED_READ_IN => med_read_out(0), + REFCLK2CORE_OUT => open, + CLK_RX_HALF_OUT => rx_clock_100, + CLK_RX_FULL_OUT => rx_clock_200, + --SFP Connection + SD_RXD_P_IN => SERDES_ADDON_RX(8), + SD_RXD_N_IN => SERDES_ADDON_RX(9), + SD_TXD_P_OUT => SERDES_ADDON_TX(8), + SD_TXD_N_OUT => SERDES_ADDON_TX(9), + SD_REFCLK_P_IN => open, + SD_REFCLK_N_IN => open, + SD_PRSNT_N_IN => FPGA5_COMM(0), + SD_LOS_IN => FPGA5_COMM(0), + SD_TXDIS_OUT => FPGA5_COMM(2), + + SCI_DATA_IN => sci1_data_in, + SCI_DATA_OUT => sci1_data_out, + SCI_ADDR => sci1_addr, + SCI_READ => sci1_read, + SCI_WRITE => sci1_write, + SCI_ACK => sci1_ack, + -- Status and control port + STAT_OP => med_stat_op(15 downto 0), + CTRL_OP => med_ctrl_op(15 downto 0), + STAT_DEBUG => med_stat_debug(63 downto 0), + CTRL_DEBUG => (others => '0') + ); +end generate; + +THE_MEDIA_DOWNLINK : trb_net16_med_ecp3_sfp_4 + generic map( + REVERSE_ORDER => c_NO, --order of ports + FREQUENCY => 200 --run on 200 MHz clock + ) + port map( + CLK => clk_200_i, + SYSCLK => clk_100_i, + RESET => reset_i, + CLEAR => clear_i, + CLK_EN => '1', + --Internal Connection + MED_DATA_IN(0*16+15 downto 0*16) => med_data_out(1*16+15 downto 1*16), + MED_DATA_IN(1*16+15 downto 1*16) => med_data_out(6*16+15 downto 6*16), + MED_DATA_IN(2*16+15 downto 2*16) => med_data_out(2*16+15 downto 2*16), + MED_DATA_IN(3*16+15 downto 3*16) => med_data_out(4*16+15 downto 4*16), + + MED_PACKET_NUM_IN(0*3+2 downto 0*3) => med_packet_num_out(1*3+2 downto 1*3), + MED_PACKET_NUM_IN(1*3+2 downto 1*3) => med_packet_num_out(6*3+2 downto 6*3), + MED_PACKET_NUM_IN(2*3+2 downto 2*3) => med_packet_num_out(2*3+2 downto 2*3), + MED_PACKET_NUM_IN(3*3+2 downto 3*3) => med_packet_num_out(4*3+2 downto 4*3), + + MED_DATAREADY_IN(0) => med_dataready_out(1), + MED_DATAREADY_IN(1) => med_dataready_out(6), + MED_DATAREADY_IN(2) => med_dataready_out(2), + MED_DATAREADY_IN(3) => med_dataready_out(4), + + MED_READ_OUT(0) => med_read_in(1), + MED_READ_OUT(1) => med_read_in(6), + MED_READ_OUT(2) => med_read_in(2), + MED_READ_OUT(3) => med_read_in(4), + + MED_DATA_OUT(0*16+15 downto 0*16) => med_data_in(1*16+15 downto 1*16), + MED_DATA_OUT(1*16+15 downto 1*16) => med_data_in(6*16+15 downto 6*16), + MED_DATA_OUT(2*16+15 downto 2*16) => med_data_in(2*16+15 downto 2*16), + MED_DATA_OUT(3*16+15 downto 3*16) => med_data_in(4*16+15 downto 4*16), + + MED_PACKET_NUM_OUT(0*3+2 downto 0*3) => med_packet_num_in(1*3+2 downto 1*3), + MED_PACKET_NUM_OUT(1*3+2 downto 1*3) => med_packet_num_in(6*3+2 downto 6*3), + MED_PACKET_NUM_OUT(2*3+2 downto 2*3) => med_packet_num_in(2*3+2 downto 2*3), + MED_PACKET_NUM_OUT(3*3+2 downto 3*3) => med_packet_num_in(4*3+2 downto 4*3), + + MED_DATAREADY_OUT(0) => med_dataready_in(1), + MED_DATAREADY_OUT(1) => med_dataready_in(6), + MED_DATAREADY_OUT(2) => med_dataready_in(2), + MED_DATAREADY_OUT(3) => med_dataready_in(4), + + MED_READ_IN(0) => med_read_out(1), + MED_READ_IN(1) => med_read_out(6), + MED_READ_IN(2) => med_read_out(2), + MED_READ_IN(3) => med_read_out(4), + + REFCLK2CORE_OUT => open, + --SFP Connection + SD_RXD_P_IN => SERDES_ADDON_RX(3 downto 0), + SD_RXD_N_IN => SERDES_ADDON_RX(7 downto 4), + SD_TXD_P_OUT => SERDES_ADDON_TX(3 downto 0), + SD_TXD_N_OUT => SERDES_ADDON_TX(7 downto 4), + SD_REFCLK_P_IN => open, + SD_REFCLK_N_IN => open, + SD_PRSNT_N_IN(0) => SFP_MOD0(1), + SD_PRSNT_N_IN(1) => SFP_MOD0(6), + SD_PRSNT_N_IN(2) => SFP_MOD0(2), + SD_PRSNT_N_IN(3) => SFP_MOD0(4), + SD_LOS_IN(0) => SFP_LOS(1), + SD_LOS_IN(1) => SFP_LOS(6), + SD_LOS_IN(2) => SFP_LOS(2), + SD_LOS_IN(3) => SFP_LOS(4), + SD_TXDIS_OUT(0) => SFP_TXDIS(1), + SD_TXDIS_OUT(1) => SFP_TXDIS(6), + SD_TXDIS_OUT(2) => SFP_TXDIS(2), + SD_TXDIS_OUT(3) => SFP_TXDIS(4), + + SCI_DATA_IN => sci2_data_in, + SCI_DATA_OUT => sci2_data_out, + SCI_ADDR => sci2_addr, + SCI_READ => sci2_read, + SCI_WRITE => sci2_write, + SCI_ACK => sci2_ack, + -- Status and control port + + STAT_OP(0*16+15 downto 0*16) => med_stat_op(1*16+15 downto 1*16), + STAT_OP(1*16+15 downto 1*16) => med_stat_op(6*16+15 downto 6*16), + STAT_OP(2*16+15 downto 2*16) => med_stat_op(2*16+15 downto 2*16), + STAT_OP(3*16+15 downto 3*16) => med_stat_op(4*16+15 downto 4*16), + + CTRL_OP(0*16+15 downto 0*16) => med_ctrl_op(1*16+15 downto 1*16), + CTRL_OP(1*16+15 downto 1*16) => med_ctrl_op(6*16+15 downto 6*16), + CTRL_OP(2*16+15 downto 2*16) => med_ctrl_op(2*16+15 downto 2*16), + CTRL_OP(3*16+15 downto 3*16) => med_ctrl_op(4*16+15 downto 4*16), + + STAT_DEBUG => open, + CTRL_DEBUG => (others => '0') + ); + + + +--------------------------------------------------------------------------- +-- Hub +--------------------------------------------------------------------------- + +THE_HUB : trb_net16_hub_base + generic map ( + HUB_USED_CHANNELS => (c_YES,c_YES,c_NO,c_YES), + IBUF_SECURE_MODE => c_YES, + MII_NUMBER => 7, + MII_IS_UPLINK => (0 => 1, others => 0), + MII_IS_DOWNLINK => (0 => 0, others => 1), + MII_IS_UPLINK_ONLY=> (0 => 1, others => 0), + INT_NUMBER => 0, +-- INT_CHANNELS => (0,1,3,3,3,3,3,3), + USE_ONEWIRE => c_YES, + COMPILE_TIME => std_logic_vector(to_unsigned(VERSION_NUMBER_TIME,32)), + HARDWARE_VERSION => x"91003200", + INIT_ENDPOINT_ID => x"0000", + INIT_ADDRESS => x"F300", + USE_VAR_ENDPOINT_ID => c_YES, + BROADCAST_SPECIAL_ADDR => x"45" + ) + port map ( + CLK => clk_100_i, + RESET => reset_i, + CLK_EN => '1', + + --Media interfacces + MED_DATAREADY_OUT(7*1-1 downto 0) => med_dataready_out, + MED_DATA_OUT(7*16-1 downto 0) => med_data_out, + MED_PACKET_NUM_OUT(7*3-1 downto 0) => med_packet_num_out, + MED_READ_IN(7*1-1 downto 0) => med_read_in, + MED_DATAREADY_IN(7*1-1 downto 0) => med_dataready_in, + MED_DATA_IN(7*16-1 downto 0) => med_data_in, + MED_PACKET_NUM_IN(7*3-1 downto 0) => med_packet_num_in, + MED_READ_OUT(7*1-1 downto 0) => med_read_out, + MED_STAT_OP(7*16-1 downto 0) => med_stat_op, + MED_CTRL_OP(7*16-1 downto 0) => med_ctrl_op, + + COMMON_STAT_REGS => common_stat_reg, + COMMON_CTRL_REGS => common_ctrl_reg, + MY_ADDRESS_OUT => my_address, + --REGIO INTERFACE + REGIO_ADDR_OUT => regio_addr_out, + REGIO_READ_ENABLE_OUT => regio_read_enable_out, + REGIO_WRITE_ENABLE_OUT => regio_write_enable_out, + REGIO_DATA_OUT => regio_data_out, + REGIO_DATA_IN => regio_data_in, + REGIO_DATAREADY_IN => regio_dataready_in, + REGIO_NO_MORE_DATA_IN => regio_no_more_data_in, + REGIO_WRITE_ACK_IN => regio_write_ack_in, + REGIO_UNKNOWN_ADDR_IN => regio_unknown_addr_in, + REGIO_TIMEOUT_OUT => regio_timeout_out, + REGIO_VAR_ENDPOINT_ID(1 downto 0) => CODE_LINE, + REGIO_VAR_ENDPOINT_ID(15 downto 2) => (others => '0'), + ONEWIRE => TEMPSENS, + ONEWIRE_MONITOR_OUT => open, + --Status ports (for debugging) + MPLEX_CTRL => (others => '0'), + CTRL_DEBUG => (others => '0'), + STAT_DEBUG => open + ); + + + + +--------------------------------------------------------------------------- +-- AddOn +--------------------------------------------------------------------------- +-- DQLL <= (others => '0'); +-- DQUL <= (others => '0'); +-- DQLR <= (others => '0'); +-- DQUR <= (others => '0'); + +--------------------------------------------------------------------------- +-- Bus Handler +--------------------------------------------------------------------------- + THE_BUS_HANDLER : trb_net16_regio_bus_handler + generic map( + PORT_NUMBER => 4, + PORT_ADDRESSES => (0 => x"d000", 1 => x"d100", 2 => x"b000", 3 => x"b200", others => x"0000"), + PORT_ADDR_MASK => (0 => 1, 1 => 6, 2 => 9, 3 => 9, others => 0) + ) + port map( + CLK => clk_100_i, + RESET => reset_i, + + DAT_ADDR_IN => regio_addr_out, + DAT_DATA_IN => regio_data_out, + DAT_DATA_OUT => regio_data_in, + DAT_READ_ENABLE_IN => regio_read_enable_out, + DAT_WRITE_ENABLE_IN => regio_write_enable_out, + DAT_TIMEOUT_IN => regio_timeout_out, + DAT_DATAREADY_OUT => regio_dataready_in, + DAT_WRITE_ACK_OUT => regio_write_ack_in, + DAT_NO_MORE_DATA_OUT => regio_no_more_data_in, + DAT_UNKNOWN_ADDR_OUT => regio_unknown_addr_in, + + --Bus Handler (SPI CTRL) + BUS_READ_ENABLE_OUT(0) => spictrl_read_en, + BUS_WRITE_ENABLE_OUT(0) => spictrl_write_en, + BUS_DATA_OUT(0*32+31 downto 0*32) => spictrl_data_in, + BUS_ADDR_OUT(0*16) => spictrl_addr, + BUS_ADDR_OUT(0*16+15 downto 0*16+1) => open, + BUS_TIMEOUT_OUT(0) => open, + BUS_DATA_IN(0*32+31 downto 0*32) => spictrl_data_out, + BUS_DATAREADY_IN(0) => spictrl_ack, + BUS_WRITE_ACK_IN(0) => spictrl_ack, + BUS_NO_MORE_DATA_IN(0) => spictrl_busy, + BUS_UNKNOWN_ADDR_IN(0) => '0', + --Bus Handler (SPI Memory) + BUS_READ_ENABLE_OUT(1) => spimem_read_en, + BUS_WRITE_ENABLE_OUT(1) => spimem_write_en, + BUS_DATA_OUT(1*32+31 downto 1*32) => spimem_data_in, + BUS_ADDR_OUT(1*16+5 downto 1*16) => spimem_addr, + BUS_ADDR_OUT(1*16+15 downto 1*16+6) => open, + BUS_TIMEOUT_OUT(1) => open, + BUS_DATA_IN(1*32+31 downto 1*32) => spimem_data_out, + BUS_DATAREADY_IN(1) => spimem_ack, + BUS_WRITE_ACK_IN(1) => spimem_ack, + BUS_NO_MORE_DATA_IN(1) => '0', + BUS_UNKNOWN_ADDR_IN(1) => '0', + --SCI first Media Interface + BUS_READ_ENABLE_OUT(2) => sci1_read, + BUS_WRITE_ENABLE_OUT(2) => sci1_write, + BUS_DATA_OUT(2*32+7 downto 2*32) => sci1_data_in, + BUS_DATA_OUT(2*32+31 downto 2*32+8) => open, + BUS_ADDR_OUT(2*16+8 downto 2*16) => sci1_addr, + BUS_ADDR_OUT(2*16+15 downto 2*16+9) => open, + BUS_TIMEOUT_OUT(2) => open, + BUS_DATA_IN(2*32+7 downto 2*32) => sci1_data_out, + BUS_DATAREADY_IN(2) => sci1_ack, + BUS_WRITE_ACK_IN(2) => sci1_ack, + BUS_NO_MORE_DATA_IN(2) => '0', + BUS_UNKNOWN_ADDR_IN(2) => '0', + --SCI second Media Interface + BUS_READ_ENABLE_OUT(3) => sci2_read, + BUS_WRITE_ENABLE_OUT(3) => sci2_write, + BUS_DATA_OUT(3*32+7 downto 3*32) => sci2_data_in, + BUS_DATA_OUT(3*32+31 downto 3*32+8) => open, + BUS_ADDR_OUT(3*16+8 downto 3*16) => sci2_addr, + BUS_ADDR_OUT(3*16+15 downto 3*16+9) => open, + BUS_TIMEOUT_OUT(3) => open, + BUS_DATA_IN(3*32+7 downto 3*32) => sci2_data_out, + BUS_DATAREADY_IN(3) => sci2_ack, + BUS_WRITE_ACK_IN(3) => sci2_ack, + BUS_NO_MORE_DATA_IN(3) => '0', + BUS_UNKNOWN_ADDR_IN(3) => '0', + + STAT_DEBUG => open + ); + +--------------------------------------------------------------------------- +-- SPI / Flash +--------------------------------------------------------------------------- + + THE_SPI_MASTER : spi_master + port map( + CLK_IN => clk_100_i, + RESET_IN => reset_i, + -- Slave bus + BUS_READ_IN => spictrl_read_en, + BUS_WRITE_IN => spictrl_write_en, + BUS_BUSY_OUT => spictrl_busy, + BUS_ACK_OUT => spictrl_ack, + BUS_ADDR_IN(0) => spictrl_addr, + BUS_DATA_IN => spictrl_data_in, + BUS_DATA_OUT => spictrl_data_out, + -- SPI connections + SPI_CS_OUT => FLASH_CS, + SPI_SDI_IN => FLASH_DOUT, + SPI_SDO_OUT => FLASH_DIN, + SPI_SCK_OUT => FLASH_CLK, + -- BRAM for read/write data + BRAM_A_OUT => spi_bram_addr, + BRAM_WR_D_IN => spi_bram_wr_d, + BRAM_RD_D_OUT => spi_bram_rd_d, + BRAM_WE_OUT => spi_bram_we, + -- Status lines + STAT => open + ); + +-- data memory for SPI accesses + THE_SPI_MEMORY : spi_databus_memory + port map( + CLK_IN => clk_100_i, + RESET_IN => reset_i, + -- Slave bus + BUS_ADDR_IN => spimem_addr, + BUS_READ_IN => spimem_read_en, + BUS_WRITE_IN => spimem_write_en, + BUS_ACK_OUT => spimem_ack, + BUS_DATA_IN => spimem_data_in, + BUS_DATA_OUT => spimem_data_out, + -- state machine connections + BRAM_ADDR_IN => spi_bram_addr, + BRAM_WR_D_OUT => spi_bram_wr_d, + BRAM_RD_D_IN => spi_bram_rd_d, + BRAM_WE_IN => spi_bram_we, + -- Status lines + STAT => open + ); + +--------------------------------------------------------------------------- +-- Reboot FPGA +--------------------------------------------------------------------------- + THE_FPGA_REBOOT : fpga_reboot + port map( + CLK => clk_100_i, + RESET => reset_i, + DO_REBOOT => common_ctrl_reg(15), + PROGRAMN => PROGRAMN + ); + + + +--------------------------------------------------------------------------- +-- LED +--------------------------------------------------------------------------- + LED_GREEN <= not med_stat_op(9); + LED_ORANGE <= not med_stat_op(10); + LED_RED <= not time_counter(26); + LED_YELLOW <= not med_stat_op(11); + + + gen_LED : for i in 1 to 6 generate + LED_LINKOK(i) <= not med_stat_op(i*16+9); + LED_RX(i) <= not med_stat_op(i*16+10); + LED_TX(i) <= not med_stat_op(i*16+11); + end generate; + + + +--------------------------------------------------------------------------- +-- Test Connector +--------------------------------------------------------------------------- + TEST_LINE(7 downto 0) <= med_data_in(7 downto 0); + TEST_LINE(8) <= med_dataready_in(0); + TEST_LINE(9) <= med_dataready_out(0); + TEST_LINE(10) <= stat_reg_strobe(0); + TEST_LINE(15 downto 11) <= (others => '0'); + + + +end architecture; diff --git a/code/trb3_periph_sodaclient.vhd b/code/trb3_periph_sodaclient.vhd index 743ea40..248c997 100644 --- a/code/trb3_periph_sodaclient.vhd +++ b/code/trb3_periph_sodaclient.vhd @@ -207,6 +207,8 @@ signal rx_dlm_word : std_logic_vector(7 downto 0); signal make_reset : std_logic; signal tx_dlm_preview_S : std_logic; --PL! signal link_phase_S : std_logic; --PL! +signal rx_cdr_lol_S : std_logic; +signal link_locked_S : std_logic; --PL! -- SODA slow controll signal soda_ack : std_logic; @@ -224,12 +226,10 @@ signal link_phase_S : std_logic; --PL! signal soda_counter_i : unsigned(3 downto 0); attribute syn_keep of soda_counter_i : signal is true; -- fix signal names for constraining --- attribute syn_preserve of clk_soda_i : signal is true; --- attribute syn_keep of clk_soda_i : signal is true; --- attribute syn_preserve of soda_rx_clock_full : signal is true; --- attribute syn_keep of soda_rx_clock_full : signal is true; --- attribute syn_preserve of soda_rx_clock_half : signal is true; --- attribute syn_keep of soda_rx_clock_half : signal is true; + attribute syn_preserve of rx_full_clk : signal is true; + attribute syn_keep of rx_full_clk : signal is true; + attribute syn_preserve of rx_half_clk : signal is true; + attribute syn_keep of rx_half_clk : signal is true; attribute syn_preserve of clk_sys_internal : signal is true; attribute syn_keep of clk_sys_internal : signal is true; attribute syn_preserve of clk_200_osc : signal is true; @@ -250,7 +250,7 @@ begin LED_TX <= (others => '0'); -- otherwise it is floating LED_LINKOK <= (others => '0'); -- otherwise it is floating - GSR_N <= pll_lock; + GSR_N <= pll_lock; THE_RESET_HANDLER : trb_net_reset_handler generic map( @@ -260,7 +260,7 @@ begin CLEAR_IN => '0', -- reset input (high active, async) CLEAR_N_IN => '1', -- reset input (low active, async) CLK_IN => clk_200_osc, --clk_raw_internal, -- raw master clock, NOT from PLL/DLL! - SYSCLK_IN => clk_sys_internal, -- PLL/DLL remastered clock + SYSCLK_IN => rx_half_clk, --clk_sys_internal, -- PLL/DLL remastered clock PLL_LOCKED_IN => pll_lock, -- master PLL lock signal (async) RESET_IN => '0', --general_reset_i, -- '0', -- general reset signal (SYSCLK) --peter schakel TRB_RESET_IN => med_stat_op(13), -- TRBnet reset signal (SYSCLK) @@ -269,12 +269,12 @@ begin DEBUG_OUT => open ); - process(clk_sys_internal) - begin - if rising_edge(clk_sys_internal) then - general_reset_i <= not SFP_LOS(1); - end if; - end process; +-- process(clk_sys_internal) +-- begin +-- if rising_edge(clk_sys_internal) then +-- general_reset_i <= not SFP_LOS(1); +-- end if; +-- end process; --------------------------------------------------------------------------- -- Clock Handling @@ -334,7 +334,7 @@ end generate; HEADER_BUFFER_FULL_THRESH => 256 ) port map( - CLK => clk_sys_internal, --clk_sys_i, + CLK => rx_half_clk, --clk_sys_internal, RESET => reset_i, CLK_EN => '1', MED_DATAREADY_OUT => med_dataready_out(0), @@ -430,7 +430,7 @@ end generate; PORT_ADDR_MASK => (0 => 9, 1 => 9, 2 => 4, others => 0) ) port map( - CLK => clk_sys_internal, --clk_sys_i, + CLK => rx_half_clk, --clk_sys_internal, RESET => reset_i, DAT_ADDR_IN => regio_addr_out, @@ -498,7 +498,7 @@ end generate; THE_SPI_RELOAD : spi_flash_and_fpga_reload --.flash_reboot_arch port map( - CLK_IN => clk_sys_internal, --clk_sys_i, + CLK_IN => rx_half_clk, --clk_sys_internal, RESET_IN => reset_i, BUS_ADDR_IN => spimem_addr, @@ -531,8 +531,8 @@ THE_SYNC_LINK : med_ecp3_sfp_sync_up IS_SYNC_SLAVE => c_YES ) port map( - OSCCLK => clk_200_osc, --clk_raw_internal, --clk_200_i, - SYSCLK => clk_sys_internal, --clk_sys_i, + OSCCLK => clk_200_osc, --clk_raw_internal, + SYSCLK => clk_sys_internal, RESET => reset_i, CLEAR => clear_i, --Internal Connection for TrbNet data -> not used a.t.m. @@ -548,7 +548,8 @@ THE_SYNC_LINK : med_ecp3_sfp_sync_up RX_FULL_CLK_OUT => rx_full_clk, --soda_rx_clock_full, TX_HALF_CLK_OUT => tx_half_clk, TX_FULL_CLK_OUT => tx_full_clk, - + RX_CDR_LOL_OUT => rx_cdr_lol_S, + RX_DLM => rx_dlm_i, RX_DLM_WORD => rx_dlm_word, TX_DLM => tx_dlm_i, @@ -590,8 +591,8 @@ THE_SYNC_LINK : med_ecp3_sfp_sync_up A_SODA_CLIENT : soda_client port map( - SYSCLK => clk_sys_internal, --clk_sys_i, - SODACLK => rx_full_clk, --soda_rx_clock_full, --clk_soda_i, + SYSCLK => rx_half_clk, --clk_sys_internal, + SODACLK => rx_full_clk, RESET => reset_i, CLEAR => clear_i, CLK_EN => '1', diff --git a/soda_4source_EP.ldf b/soda_4source_EP.ldf new file mode 100644 index 0000000..f1e3569 --- /dev/null +++ b/soda_4source_EP.ldf @@ -0,0 +1,335 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soda_4source_EP.lpf b/soda_4source_EP.lpf new file mode 100644 index 0000000..78ae222 --- /dev/null +++ b/soda_4source_EP.lpf @@ -0,0 +1,213 @@ +rvl_alias "clk_raw_internal" "clk_raw_internal"; +RVL_ALIAS "clk_raw_internal" "clk_raw_internal"; +RVL_ALIAS "clk_raw_internal" "clk_raw_internal"; +BLOCK RESETPATHS ; +BLOCK ASYNCPATHS ; +BLOCK RD_DURING_WR_PATHS ; +################################################################# +# Basic Settings +################################################################# +# SYSCONFIG MCCLK_FREQ = 2.5; +# FREQUENCY PORT CLK_PCLK_RIGHT 200 MHz; +# FREQUENCY PORT CLK_PCLK_LEFT 200 MHz; +# FREQUENCY PORT CLK_GPLL_LEFT 125 MHz; +################################################################# +# Clock I/O +################################################################# +LOCATE COMP "CLK_PCLK_RIGHT" SITE "U20" ; +LOCATE COMP "CLK_PCLK_LEFT" SITE "M4" ; +LOCATE COMP "CLK_GPLL_RIGHT" SITE "W1" ;# NOTE: This is not a clock input; it's a FB input !! WHY??? +LOCATE COMP "CLK_GPLL_LEFT" SITE "U25" ; +#LOCATE COMP "CLK_SERDES_INT_RIGHT" SITE "AC18"; +#LOCATE COMP "PCSA_REFCLKP" SITE "AC17"; +#LOCATE COMP "PCSA_REFCLKN" SITE "AC18"; +#LOCATE COMP "CLK_SERDES_INT_LEFT" SITE "AC10"; +#LOCATE COMP "gen_200_PLL.THE_MAIN_PLL/PLLInst_0" SITE "PLL_R79C5" ; PL! +DEFINE PORT GROUP "CLK_group" "*CLK*" ; +IOBUF GROUP "CLK_group" IO_TYPE=LVDS25 ; +################################################################# +# To central FPGA +################################################################# +LOCATE COMP "FPGA5_COMM[0]" SITE "AD4" ; +LOCATE COMP "FPGA5_COMM[1]" SITE "AE3" ; +LOCATE COMP "FPGA5_COMM[2]" SITE "AA7" ; +LOCATE COMP "FPGA5_COMM[3]" SITE "AB7" ; +LOCATE COMP "FPGA5_COMM[4]" SITE "AD3" ; +LOCATE COMP "FPGA5_COMM[5]" SITE "AC4" ; +LOCATE COMP "FPGA5_COMM[6]" SITE "AE2" ; +LOCATE COMP "FPGA5_COMM[7]" SITE "AF3" ; +LOCATE COMP "FPGA5_COMM[8]" SITE "AE4" ; +LOCATE COMP "FPGA5_COMM[9]" SITE "AF4" ; +LOCATE COMP "FPGA5_COMM[10]" SITE "V10" ; +LOCATE COMP "FPGA5_COMM[11]" SITE "W10" ; +DEFINE PORT GROUP "FPGA_group" "FPGA*" ; +IOBUF GROUP "FPGA_group" IO_TYPE=LVCMOS25 PULLMODE=UP ; +LOCATE COMP "TEST_LINE[0]" SITE "A5" ; +LOCATE COMP "TEST_LINE[1]" SITE "A6" ; +LOCATE COMP "TEST_LINE[2]" SITE "G8" ; +LOCATE COMP "TEST_LINE[3]" SITE "F9" ; +LOCATE COMP "TEST_LINE[4]" SITE "D9" ; +LOCATE COMP "TEST_LINE[5]" SITE "D10" ; +LOCATE COMP "TEST_LINE[6]" SITE "F10" ; +LOCATE COMP "TEST_LINE[7]" SITE "E10" ; +LOCATE COMP "TEST_LINE[8]" SITE "A8" ; +LOCATE COMP "TEST_LINE[9]" SITE "B8" ; +LOCATE COMP "TEST_LINE[10]" SITE "G10" ; +LOCATE COMP "TEST_LINE[11]" SITE "G9" ; +LOCATE COMP "TEST_LINE[12]" SITE "C9" ; +LOCATE COMP "TEST_LINE[13]" SITE "C10" ; +LOCATE COMP "TEST_LINE[14]" SITE "H10" ; +LOCATE COMP "TEST_LINE[15]" SITE "H11" ; +DEFINE PORT GROUP "TEST_LINE_group" "TEST_LINE*" ; +IOBUF GROUP "TEST_LINE_group" IO_TYPE=LVCMOS25 PULLMODE=DOWN DRIVE=12 ; +################################################################# +# Connection to AddOn +################################################################# +LOCATE COMP "LED_LINKOK[1]" SITE "P1" ;#DQLL0_0 #1 +LOCATE COMP "LED_RX[1]" SITE "P2" ;#DQLL0_1 #3 +LOCATE COMP "LED_TX[1]" SITE "T2" ;#DQLL0_2 #5 +LOCATE COMP "SFP_MOD0[1]" SITE "U3" ;#DQLL0_3 #7 +#LOCATE COMP "SFP_MOD1_1" SITE "R1"; #DQLL0_4 #9 +#LOCATE COMP "SFP_MOD2_1" SITE "R2"; #DQLL0_5 #11 +#LOCATE COMP "SFP_RATESEL_1" SITE "N3"; #DQSLL0_T #13 +LOCATE COMP "SFP_TXDIS[1]" SITE "P3" ;#DQSLL0_C #15 +LOCATE COMP "SFP_LOS[1]" SITE "P5" ;#DQLL0_6 #17 +#LOCATE COMP "SFP_TXFAULT_1" SITE "P6"; #DQLL0_7 #19 +LOCATE COMP "LED_LINKOK[2]" SITE "N5" ;#DQLL0_8 #21 +LOCATE COMP "LED_RX[2]" SITE "N6" ;#DQLL0_9 #23 +LOCATE COMP "LED_TX[2]" SITE "AC2" ;#DQLL2_0 #25 +LOCATE COMP "SFP_MOD0[2]" SITE "AC3" ;#DQLL2_1 #27 +#LOCATE COMP "SFP_MOD1_2" SITE "AB1"; #DQLL2_2 #29 +#LOCATE COMP "SFP_MOD2_2" SITE "AC1"; #DQLL2_3 #31 +#LOCATE COMP "SFP_RATESEL_2" SITE "AA1"; #DQLL2_4 #33 +LOCATE COMP "SFP_TXDIS[2]" SITE "AA2" ;#DQLL2_5 #35 +LOCATE COMP "SFP_LOS[2]" SITE "W7" ;#DQLL2_T #37 #should be DQSLL2 +#LOCATE COMP "SFP_TXFAULT_2" SITE "W6"; #DQLL2_C #39 #should be DQSLL2 +LOCATE COMP "LED_LINKOK[3]" SITE "AD1" ;#DQLL3_0 #2 +LOCATE COMP "LED_RX[3]" SITE "AD2" ;#DQLL3_1 #4 +LOCATE COMP "LED_TX[3]" SITE "AB5" ;#DQLL3_2 #6 +LOCATE COMP "SFP_MOD0[3]" SITE "AB6" ;#DQLL3_3 #8 +#LOCATE COMP "SFP_MOD1_3" SITE "AB3"; #DQLL3_4 #10 +#LOCATE COMP "SFP_MOD2_3" SITE "AB4"; #DQLL3_5 #12 +#LOCATE COMP "SFP_RATESEL_3" SITE "Y6"; #DQLL3_T #14 #should be DQSLL3 +LOCATE COMP "SFP_TXDIS[3]" SITE "Y7" ;#DQLL3_C #16 #should be DQSLL3 +LOCATE COMP "SFP_LOS[3]" SITE "AA3" ;#DQLL3_6 #18 +#LOCATE COMP "SFP_TXFAULT_3" SITE "AA4"; #DQLL3_7 #20 +LOCATE COMP "LED_LINKOK[4]" SITE "W8" ;#DQLL3_8 #22 +LOCATE COMP "LED_RX[4]" SITE "W9" ;#DQLL3_9 #24 +LOCATE COMP "LED_TX[4]" SITE "V1" ;#DQLL1_0 #26 +LOCATE COMP "SFP_MOD0[4]" SITE "U2" ;#DQLL1_1 #28 +#LOCATE COMP "SFP_MOD1_4" SITE "T1"; #DQLL1_2 #30 +#LOCATE COMP "SFP_MOD2_4" SITE "U1"; #DQLL1_3 #32 +#LOCATE COMP "SFP_RATESEL_4" SITE "P4"; #DQLL1_4 #34 +LOCATE COMP "SFP_TXDIS[4]" SITE "R3" ;#DQLL1_5 #36 +LOCATE COMP "SFP_LOS[4]" SITE "T3" ;#DQSLL1_T #38 +#LOCATE COMP "SFP_TXFAULT_4" SITE "R4"; #DQSLL1_C #40 +LOCATE COMP "LED_LINKOK[5]" SITE "W23" ;#DQLR1_0 #169 +LOCATE COMP "LED_RX[5]" SITE "W22" ;#DQLR1_1 #171 +LOCATE COMP "LED_TX[5]" SITE "AA25" ;#DQLR1_2 #173 +LOCATE COMP "SFP_MOD0[5]" SITE "Y24" ;#DQLR1_3 #175 +#LOCATE COMP "SFP_MOD1_5" SITE "AA26"; #DQLR1_4 #177 +#LOCATE COMP "SFP_MOD2_5" SITE "AB26"; #DQLR1_5 #179 +#LOCATE COMP "SFP_RATESEL_5" SITE "W21"; #DQSLR1_T #181 +LOCATE COMP "SFP_TXDIS[5]" SITE "W20" ;#DQSLR1_C #183 +LOCATE COMP "SFP_LOS[5]" SITE "AA24" ;#DQLR1_6 #185 +#LOCATE COMP "SFP_TXFAULT_5" SITE "AA23"; #DQLR1_7 #187 +LOCATE COMP "LED_LINKOK[6]" SITE "R25" ;#DQLR2_0 #170 +LOCATE COMP "LED_RX[6]" SITE "R26" ;#DQLR2_1 #172 +LOCATE COMP "LED_TX[6]" SITE "T25" ;#DQLR2_2 #174 +LOCATE COMP "SFP_MOD0[6]" SITE "T24" ;#DQLR2_3 #176 +#LOCATE COMP "SFP_MOD1_6" SITE "T26"; #DQLR2_4 #178 +#LOCATE COMP "SFP_MOD2_6" SITE "U26"; #DQLR2_5 #180 +#LOCATE COMP "SFP_RATESEL_6" SITE "V21"; #DQSLR2_T #182 +LOCATE COMP "SFP_TXDIS[6]" SITE "V22" ;#DQSLR2_C #184 +LOCATE COMP "SFP_LOS[6]" SITE "U24" ;#DQLR2_6 #186 +#LOCATE COMP "SFP_TXFAULT_6" SITE "V24"; #DQLR2_7 #188 +DEFINE PORT GROUP "SFP_group" "SFP*" ; +IOBUF GROUP "SFP_group" IO_TYPE=LVCMOS25 PULLMODE=UP ; +################################################################# +# Additional Lines to AddOn +################################################################# +#Lines 0/1 are terminated with 100 Ohm, pads available on 0-3 +#all lines are input only +#line 4/5 go to PLL input +#LOCATE COMP "SPARE_LINE_0" SITE "M25"; #194 +#LOCATE COMP "SPARE_LINE_1" SITE "M26"; #196 +#LOCATE COMP "SPARE_LINE_2" SITE "W4"; #198 +#LOCATE COMP "SPARE_LINE_3" SITE "W5"; #200 +#LOCATE COMP "SPARE_LINE_4" SITE "M3"; #DQUL3_8_OUTOFLANE_FPGA__3 #69 +#LOCATE COMP "SPARE_LINE_5" SITE "M2"; #DQUL3_9_OUTOFLANE_FPGA__3 #71 +################################################################# +# Flash ROM and Reboot +################################################################# +LOCATE COMP "FLASH_CLK" SITE "B12" ; +LOCATE COMP "FLASH_CS" SITE "E11" ; +LOCATE COMP "FLASH_DIN" SITE "E12" ; +LOCATE COMP "FLASH_DOUT" SITE "A12" ; +DEFINE PORT GROUP "FLASH_group" "FLASH*" ; +IOBUF GROUP "FLASH_group" IO_TYPE=LVCMOS25 PULLMODE=NONE ; +LOCATE COMP "PROGRAMN" SITE "B11" ; +IOBUF PORT "PROGRAMN" IO_TYPE=LVCMOS25 PULLMODE=UP DRIVE=8 ; +################################################################# +# Misc +################################################################# +LOCATE COMP "TEMPSENS" SITE "A13" ; +IOBUF PORT "TEMPSENS" IO_TYPE=LVCMOS25 PULLMODE=UP DRIVE=8 ; +#coding of FPGA number +LOCATE COMP "CODE_LINE[1]" SITE "AA20" ; +LOCATE COMP "CODE_LINE[0]" SITE "Y21" ; +IOBUF PORT "CODE_LINE[1]" IO_TYPE=LVCMOS25 PULLMODE=UP ; +IOBUF PORT "CODE_LINE[0]" IO_TYPE=LVCMOS25 PULLMODE=UP ; +#terminated differential pair to pads +LOCATE COMP "SUPPL" SITE "C14" ; +#IOBUF PORT "SUPPL" IO_TYPE=LVDS25 ; +################################################################# +# LED +################################################################# +LOCATE COMP "LED_GREEN" SITE "F12" ; +LOCATE COMP "LED_ORANGE" SITE "G13" ; +LOCATE COMP "LED_RED" SITE "A15" ; +LOCATE COMP "LED_YELLOW" SITE "A16" ; +DEFINE PORT GROUP "LED_group" "LED*" ; +IOBUF GROUP "LED_group" IO_TYPE=LVCMOS25 PULLMODE=NONE DRIVE=12 ; +BLOCK RESETPATHS ; +BLOCK ASYNCPATHS ; +BLOCK RD_DURING_WR_PATHS ; +################################################################# +#GSR_NET NET "GSR_N"; +################################################################# +# Locate Serdes and media interfaces +################################################################# +LOCATE COMP "THE_MEDIA_UPLINK/gen_serdes_1_200.THE_SERDES/PCSD_INST" SITE "PCSA" ; +#LOCATE COMP "THE_MEDIA_UPLINK/gen_serdes_1_200_ctc_THE_SERDES/PCSD_INST" SITE "PCSA" ; +#LOCATE COMP "THE_MEDIA_UPLINK/gen_serdes_200/PCSD_INST" SITE "PCSA" ; +LOCATE COMP "THE_SYNC_LINK/THE_SERDES/PCSD_INST" SITE "PCSB" ; +#REGION "MEDIA_UPLINK_REGION" "R90C95D" 20 25 DEVSIZE; +#REGION "MEDIA_DOWNLINK_REGION" "R90C45D" 25 35 DEVSIZE; +#REGION "IOBUF_REGION" "R10C43D" 88 86 DEVSIZE; +#REGION "SPI_REGION" "R10C150D" 15 16 DEVSIZE; +#LOCATE UGROUP "THE_SPI_RELOAD/THE_SPI_MASTER/SPI_group" REGION "SPI_REGION" ; +#LOCATE UGROUP "THE_SPI_RELOAD/THE_SPI_MEMORY/SPI_group" REGION "SPI_REGION" ; +#LOCATE UGROUP "THE_MEDIA_UPLINK/media_interface_group" REGION "MEDIA_UPLINK_REGION" ; +#LOCATE UGROUP "THE_SYNC_LINK/media_downlink_group" REGION "MEDIA_DOWNLINK_REGION" ; +#USE SECONDARY NET "THE_MEDIA_UPLINK/rx_clock_half_c" "MEDIA_DOWNLINK_REGION" ; +MULTICYCLE FROM CELL "THE_RESET_HANDLER/rese*" 20.000000 ns ; +MULTICYCLE TO CELL "THE_SYNC_LINK/SCI_DATA_OUT*" 20.000000 ns ; +MULTICYCLE TO CELL "THE_SYNC_LINK/sci*" 20.000000 ns ; +MULTICYCLE FROM CELL "THE_SYNC_LINK/sci*" 25.000000 ns ; +MULTICYCLE TO CELL "THE_MEDIA_UPLINK/SCI_DATA_OUT*" 50.000000 ns ; +BLOCK JTAGPATHS ; +## IOBUF ALLPORTS ; +#USE PRIMARY PURE NET "CLK_PCLK_LEFT_c" QUADRANT_TL QUADRANT_TR QUADRANT_BL QUADRANT_BR ; +#USE PRIMARY PURE NET "CLK_GPLL_RIGHT_c" QUADRANT_TL QUADRANT_TR QUADRANT_BL QUADRANT_BR ; +#FREQUENCY NET "THE_SYNC_LINK/THE_SERDES.rx_full_clk_ch0" 200.000000 MHz ; +#FREQUENCY NET "THE_SYNC_LINK/THE_SERDES.rx_half_clk_ch0" 100.000000 MHz ; +#FREQUENCY NET "THE_SYNC_LINK/THE_SERDES.tx_full_clk_ch0" 200.000000 MHz ; +#FREQUENCY NET "THE_SYNC_LINK/THE_SERDES.tx_half_clk_ch0" 100.000000 MHz ; +#USE PRIMARY PURE NET "THE_SYNC_LINK/THE_SERDES.tx_full_clk_ch0" ; +#USE PRIMARY PURE NET "THE_SYNC_LINK/THE_SERDES.tx_half_clk_ch0" ; +#USE PRIMARY PURE NET "THE_SYNC_LINK/THE_SERDES.rx_full_clk_ch0" ; +#USE PRIMARY PURE NET "THE_SYNC_LINK/THE_SERDES.rx_half_clk_ch0" ; +USE PRIMARY NET "THE_SYNC_LINK/CLK_RX_FULL_OUT_c" ; +USE PRIMARY NET "clk_sys_internal_c" ; +MULTICYCLE FROM CELL "THE_SYNC_LINK/PROC_SCI_CTRL.wa_pos*" 20.000000 ns ; diff --git a/soda_client.ldf b/soda_client.ldf index ab0653e..b568910 100644 --- a/soda_client.ldf +++ b/soda_client.ldf @@ -320,7 +320,7 @@ - + diff --git a/soda_hub.ldf b/soda_hub.ldf index ae19f78..d18c856 100644 --- a/soda_hub.ldf +++ b/soda_hub.ldf @@ -344,7 +344,7 @@ - + @@ -352,4 +352,5 @@ + diff --git a/soda_hub_probe.rvl b/soda_hub_probe.rvl index 8516c6e..44250d1 100644 --- a/soda_hub_probe.rvl +++ b/soda_hub_probe.rvl @@ -1,10 +1,10 @@ - + - + - - + + @@ -188,20 +188,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + - diff --git a/soda_source_probe.rvl b/soda_source_probe.rvl index 0b0c9dd..af0f175 100644 --- a/soda_source_probe.rvl +++ b/soda_source_probe.rvl @@ -1,7 +1,7 @@ - + - + @@ -58,16 +58,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trb3_soda_client.xcf b/trb3_soda_client.xcf index e38f152..7316181 100644 --- a/trb3_soda_client.xcf +++ b/trb3_soda_client.xcf @@ -47,8 +47,8 @@ 1 0 - /local/lemmens/lattice/soda/trb3_periph_sodaclient_20140707.bit - 07/07/14 13:26:49 + /local/lemmens/lattice/soda/trb3_periph_sodaclient_20140827.bit + 08/27/14 11:21:53 Fast Program