From: Peter Lemmens Date: Wed, 17 Dec 2014 10:48:31 +0000 (+0100) Subject: Soda_client over SFP with trb over copper in the same quad (pcsa). X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=449795d35a2a016f5f6a3b582aaedf7b7726c263;p=soda.git Soda_client over SFP with trb over copper in the same quad (pcsa). Testing at length remains to be done to check reset processes. --- diff --git a/code/Cu_trb3_periph_soda_client.vhd b/code/Cu_trb3_periph_soda_client.vhd new file mode 100644 index 0000000..df8634c --- /dev/null +++ b/code/Cu_trb3_periph_soda_client.vhd @@ -0,0 +1,574 @@ +--------------- +-- TOP LEVEL -- +--------------- +-- TAB=3 !! + +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 Cu_trb3_periph_soda_client 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_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) + ); +end Cu_trb3_periph_soda_client; + +architecture Cu_trb3_periph_soda_client_arch of Cu_trb3_periph_soda_client is + -- Constants + constant REGIO_NUM_STAT_REGS : integer := 0; + constant REGIO_NUM_CTRL_REGS : integer := 2; + + + constant USE_200_MHZ : integer := 1 - USE_125_MHZ; -- if USE_125_MHZ=c_NO then USE_200_MHZ=c_YES and ViceVersa + + --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; + + 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_INTERFACES*16-1 downto 0); + signal med_ctrl_op : std_logic_vector (NUM_INTERFACES*16-1 downto 0); + signal med_stat_debug : std_logic_vector (NUM_INTERFACES*64-1 downto 0); + signal med_ctrl_debug : std_logic_vector (NUM_INTERFACES*64-1 downto 0); + signal med_data_out : std_logic_vector (NUM_INTERFACES*16-1 downto 0); + signal med_packet_num_out : std_logic_vector (NUM_INTERFACES* 3-1 downto 0); + signal med_dataready_out : std_logic_vector (NUM_INTERFACES* 1-1 downto 0); + signal med_read_out : std_logic_vector (NUM_INTERFACES* 1-1 downto 0); + signal med_data_in : std_logic_vector (NUM_INTERFACES*16-1 downto 0); + signal med_packet_num_in : std_logic_vector (NUM_INTERFACES* 3-1 downto 0); + signal med_dataready_in : std_logic_vector (NUM_INTERFACES* 1-1 downto 0); + signal med_read_in : std_logic_vector (NUM_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; + + --Cu media interface + 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 sfp_txdis_S : std_logic_vector(6 downto 1) := (others => '1'); + + + --SODA + signal soda_rx_full_clk : std_logic; + signal soda_rx_half_clk : std_logic; + signal soda_tx_full_clk : std_logic; + signal soda_tx_half_clk : std_logic; + + signal soda_tx_dlm_S : std_logic; + signal soda_tx_dlm_word_S : std_logic_vector(7 downto 0); + signal soda_rx_dlm_S : std_logic; + signal soda_rx_dlm_word_S : std_logic_vector(7 downto 0); +-- signal make_reset : std_logic; + signal soda_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; + 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); + + signal link_debug_in_S : std_logic_vector(31 downto 0); + signal general_reset_i : std_logic := '1'; + +begin +--------------------------------------------------------------------------- +-- Reset Generation +--------------------------------------------------------------------------- + + + LED_RX <= (others => '0'); -- otherwise it is floating + LED_TX <= (others => '0'); -- otherwise it is floating + LED_LINKOK <= (others => '0'); -- otherwise it is floating + 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, --clk_raw_internal, -- raw master clock, NOT from PLL/DLL! + SYSCLK_IN => clk_100_osc, --rx_half_clk, PL 111114, -- 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) + 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_osc, + CLKOK => clk_200_osc, + LOCK => pll_lock + ); + +--------------------------------------------------------------------------- +-- The TrbNet media interface (to other FPGA) +--------------------------------------------------------------------------- + TRB_MEDIA_AND_SODA_SYNC_UPLINK : Cu_trb_net16_soda_sync_ecp3_sfp + port map( + OSCCLK => clk_200_osc, + SYSCLK => clk_100_osc, + RESET => reset_i, + CLEAR => clear_i, + --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), + + --Copper SFP Connection + CU_RXD_P_IN => SERDES_ADDON_RX(2), + CU_RXD_N_IN => SERDES_ADDON_RX(3), + CU_TXD_P_OUT => SERDES_ADDON_TX(2), + CU_TXD_N_OUT => SERDES_ADDON_TX(3), + CU_PRSNT_N_IN => FPGA5_COMM(0), + CU_LOS_IN => FPGA5_COMM(0), + CU_TXDIS_OUT => FPGA5_COMM(2), + + -- sync clocks + SYNC_RX_HALF_CLK_OUT => soda_rx_half_clk, + SYNC_RX_FULL_CLK_OUT => soda_rx_full_clk, + SYNC_TX_HALF_CLK_OUT => soda_tx_half_clk, + SYNC_TX_FULL_CLK_OUT => soda_tx_full_clk, + + SYNC_RXD_P_IN => SERDES_ADDON_RX(4), + SYNC_RXD_N_IN => SERDES_ADDON_RX(5), + SYNC_TXD_P_OUT => SERDES_ADDON_TX(4), + SYNC_TXD_N_OUT => SERDES_ADDON_TX(5), + SYNC_DLM_IN => soda_tx_dlm_S, + SYNC_DLM_WORD_IN => soda_tx_dlm_word_S, + SYNC_DLM_OUT => soda_rx_dlm_S, + SYNC_DLM_WORD_OUT => soda_rx_dlm_word_S, + SYNC_PRSNT_N_IN => SFP_MOD0(3), + SYNC_LOS_IN => SFP_LOS(3), + SYNC_TXDIS_OUT => sfp_txdis_S(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 => 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"f35a", + 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, --rx_half_clk, PL 111114 + 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 => 3, + 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, --rx_half_clk, PL 111114 + 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) => soda_read, + + BUS_WRITE_ENABLE_OUT(0) => spimem_write_en, + BUS_WRITE_ENABLE_OUT(1) => sci1_write, + BUS_WRITE_ENABLE_OUT(2) => 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+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+3 downto 2*16) => soda_addr, + BUS_ADDR_OUT(2*16+15 downto 2*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+31 downto 2*32) => soda_data_out, + + BUS_DATAREADY_IN(0) => spimem_dataready_out, + BUS_DATAREADY_IN(1) => sci1_ack, + BUS_DATAREADY_IN(2) => soda_ack, + + BUS_WRITE_ACK_IN(0) => spimem_write_ack_out, + BUS_WRITE_ACK_IN(1) => sci1_ack, + BUS_WRITE_ACK_IN(2) => 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_UNKNOWN_ADDR_IN(0) => spimem_unknown_addr_out, + BUS_UNKNOWN_ADDR_IN(1) => '0', + BUS_UNKNOWN_ADDR_IN(2) => '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 + ); + + +-- SFP_TXDIS(1) <= sfp_txdis_S(1); + SFP_TXDIS <= sfp_txdis_S; + + ----------------------------------------------------------------------- + -- Since there is nomore trb on this link, link-phase does not need to + -- be controlled. To avoid changing code, link-phase is faked here. + ----------------------------------------------------------------------- + DUMMY_LINK_PHASE_PROC : process (soda_rx_full_clk) + begin + if rising_edge(soda_rx_full_clk) then + if (reset_i='1') then + link_phase_S <='0'; + elsif (link_phase_S='0') then + link_phase_S <='1'; + else + link_phase_S <='0'; + end if; + end if; + end process; + +--------------------------------------------------------------------------- +-- The Soda Central +--------------------------------------------------------------------------- + + A_SODA_CLIENT : soda_client + port map( + SYSCLK => soda_rx_half_clk, --clk_100_osc, + SODACLK => soda_rx_full_clk, + RESET => reset_i, + CLEAR => clear_i, + CLK_EN => '1', + --Internal Connection + RX_DLM_WORD_IN => soda_rx_dlm_word_S, + RX_DLM_IN => soda_rx_dlm_S, + TX_DLM_OUT => soda_tx_dlm_S, + TX_DLM_WORD_OUT => soda_tx_dlm_word_S, + TX_DLM_PREVIEW_OUT => soda_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 + ); + + +--------------------------------------------------------------------------- +-- LED +--------------------------------------------------------------------------- + + LED_ORANGE <= time_counter(26); + LED_YELLOW <= time_counter(26); + LED_GREEN <= time_counter(26); + LED_RED <= time_counter(26); +--------------------------------------------------------------------------- +-- DEBUG +--------------------------------------------------------------------------- + link_debug_in_S(31 downto 16) <= med_stat_op(15 downto 0); + link_debug_in_S(15 downto 0) <= (3 => pll_lock, others => '0'); +--------------------------------------------------------------------------- +-- Test Circuits +--------------------------------------------------------------------------- + blink : process (clk_100_osc) + begin + if rising_edge(clk_100_osc) then + if (time_counter = x"FFFFFFFF") then + time_counter <= x"00000000"; + else + time_counter <= time_counter + 1; + end if; + end if; + end process; + +end Cu_trb3_periph_soda_client_arch; \ No newline at end of file diff --git a/code/soda_components.vhd b/code/soda_components.vhd index 1a2d2ed..4ce848f 100644 --- a/code/soda_components.vhd +++ b/code/soda_components.vhd @@ -678,15 +678,6 @@ package soda_components is end component; component Cu_trb_net16_soda_sync_ecp3_sfp - generic( - SERDES_NUM : integer range 0 to 3 := 0; - EXT_CLOCK : integer range 0 to 1 := c_NO; - USE_200_MHZ : integer range 0 to 1 := c_YES; - USE_125_MHZ : integer range 0 to 1 := c_NO; - USE_CTC : integer range 0 to 1 := c_YES; - USE_SLAVE : integer range 0 to 1 := c_NO; - SODA_IS_SYNC_SLAVE : integer range 0 to 1 := c_YES - ); port( OSCCLK : in std_logic; -- 200 MHz reference clock SYSCLK : in std_logic; -- 100 MHz main clock net, synchronous to RX clock @@ -702,32 +693,31 @@ package soda_components is 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; - -- sync clocks - SYNC_RX_HALF_CLK_OUT : out std_logic := '0'; --received 100 MHz - SYNC_RX_FULL_CLK_OUT : out std_logic := '0'; --received 200 MHz - SYNC_TX_HALF_CLK_OUT : out std_logic := '0'; --received 100 MHz - SYNC_TX_FULL_CLK_OUT : out std_logic := '0'; --received 200 MHz --Copper SFP Connection CU_RXD_P_IN : in std_logic; CU_RXD_N_IN : in std_logic; CU_TXD_P_OUT : out std_logic; CU_TXD_N_OUT : out std_logic; - CU_REFCLK_P_IN : in std_logic; --not used - CU_REFCLK_N_IN : in std_logic; --not used CU_PRSNT_N_IN : in std_logic; -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) CU_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) CU_TXDIS_OUT : out std_logic := '0'; -- SFP disable - --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 + --Fiber/sync SFP Connection + SYNC_RX_HALF_CLK_OUT : out std_logic := '0'; --received 100 MHz + SYNC_RX_FULL_CLK_OUT : out std_logic := '0'; --received 200 MHz + SYNC_TX_HALF_CLK_OUT : out std_logic := '0'; --received 100 MHz + SYNC_TX_FULL_CLK_OUT : out std_logic := '0'; --received 200 MHz + SYNC_DLM_IN : in std_logic; + SYNC_DLM_WORD_IN : in std_logic_vector(7 downto 0); + SYNC_DLM_OUT : out std_logic; + SYNC_DLM_WORD_OUT : out std_logic_vector(7 downto 0); + SYNC_RXD_P_IN : in std_logic; + SYNC_RXD_N_IN : in std_logic; + SYNC_TXD_P_OUT : out std_logic; + SYNC_TXD_N_OUT : out std_logic; + SYNC_PRSNT_N_IN : in std_logic; -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) + SYNC_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) + SYNC_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'); diff --git a/code/trb_net16_med_1_2sync_3_ecp3_sfp.vhd b/code/trb_net16_med_1_2sync_3_ecp3_sfp.vhd index f245c3e..c8b2c04 100644 --- a/code/trb_net16_med_1_2sync_3_ecp3_sfp.vhd +++ b/code/trb_net16_med_1_2sync_3_ecp3_sfp.vhd @@ -696,6 +696,7 @@ THE_SERDES: sfp_1_2sync_3_200_int port map( syncfifo_din(7 downto 0) <= SODA_DLM_WORD_IN; syncfifo_din(17 downto 8) <= (others => '0'); SODA_dlm_word_S <= syncfifo_dout(7 downto 0); + sync_DLM_tx: trb_net_fifo_16bit_bram_dualport generic map( USE_STATUS_FLAGS => c_NO @@ -1147,4 +1148,4 @@ begin end if; end process; -end architecture; \ No newline at end of file +end architecture; diff --git a/code/trb_net16_soda_sync_ecp3_sfp.vhd b/code/trb_net16_soda_sync_ecp3_sfp.vhd index 437afc9..8000fb5 100644 --- a/code/trb_net16_soda_sync_ecp3_sfp.vhd +++ b/code/trb_net16_soda_sync_ecp3_sfp.vhd @@ -7,18 +7,10 @@ USE IEEE.numeric_std.all; library work; use work.trb_net_std.all; -use work.trb_net_components.all; +use work.trb_net_components.all; +use work.med_sync_define.all; entity Cu_trb_net16_soda_sync_ecp3_sfp is - generic( - SERDES_NUM : integer range 0 to 3 := 0; - EXT_CLOCK : integer range 0 to 1 := c_NO; - USE_200_MHZ : integer range 0 to 1 := c_YES; - USE_125_MHZ : integer range 0 to 1 := c_NO; - USE_CTC : integer range 0 to 1 := c_NO; - USE_SLAVE : integer range 0 to 1 := c_NO; - SODA_IS_SYNC_SLAVE : integer range 0 to 1 := c_YES - ); port( OSCCLK : in std_logic; -- 200 MHz reference clock SYSCLK : in std_logic; -- 100 MHz main clock net, synchronous to RX clock @@ -34,32 +26,31 @@ entity Cu_trb_net16_soda_sync_ecp3_sfp is 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; - -- sync clocks - SYNC_RX_HALF_CLK_OUT : out std_logic := '0'; --received 100 MHz - SYNC_RX_FULL_CLK_OUT : out std_logic := '0'; --received 200 MHz - SYNC_TX_HALF_CLK_OUT : out std_logic := '0'; --received 100 MHz - SYNC_TX_FULL_CLK_OUT : out std_logic := '0'; --received 200 MHz --Copper SFP Connection CU_RXD_P_IN : in std_logic; CU_RXD_N_IN : in std_logic; CU_TXD_P_OUT : out std_logic; CU_TXD_N_OUT : out std_logic; - CU_REFCLK_P_IN : in std_logic; --not used - CU_REFCLK_N_IN : in std_logic; --not used CU_PRSNT_N_IN : in std_logic; -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) CU_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) CU_TXDIS_OUT : out std_logic := '0'; -- SFP disable - --Fiber 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 + --Fiber/sync SFP Connection + SYNC_RX_HALF_CLK_OUT : out std_logic := '0'; --received 100 MHz + SYNC_RX_FULL_CLK_OUT : out std_logic := '0'; --received 200 MHz + SYNC_TX_HALF_CLK_OUT : out std_logic := '0'; --received 100 MHz + SYNC_TX_FULL_CLK_OUT : out std_logic := '0'; --received 200 MHz + SYNC_dlm_IN : in std_logic; + SYNC_dlm_WORD_IN : in std_logic_vector(7 downto 0); + SYNC_DLM_OUT : out std_logic; + SYNC_DLM_WORD_OUT : out std_logic_vector(7 downto 0); + SYNC_RXD_P_IN : in std_logic; + SYNC_RXD_N_IN : in std_logic; + SYNC_TXD_P_OUT : out std_logic; + SYNC_TXD_N_OUT : out std_logic; + SYNC_PRSNT_N_IN : in std_logic; -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) + SYNC_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) + SYNC_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'); @@ -67,7 +58,9 @@ entity Cu_trb_net16_soda_sync_ecp3_sfp is SCI_READ : in std_logic := '0'; SCI_WRITE : in std_logic := '0'; SCI_ACK : out std_logic := '0'; - SCI_NACK : out std_logic := '0'; + SCI_NACK : out std_logic := '0'; + + TX_READY_CH3 : out std_logic; -- Status and control port STAT_OP : out std_logic_vector (15 downto 0); CTRL_OP : in std_logic_vector (15 downto 0) := (others => '0'); @@ -248,7 +241,6 @@ architecture Cu_trb_net16_soda_sync_ecp3_sfp_arch of Cu_trb_net16_soda_sync_ecp3 signal reset_i : std_logic; signal reset_i_rx : std_logic; signal pwr_up : std_logic; - signal clear_n : std_logic; signal clk_sys : std_logic; signal clk_tx : std_logic; @@ -268,14 +260,15 @@ architecture Cu_trb_net16_soda_sync_ecp3_sfp_arch of Cu_trb_net16_soda_sync_ecp3 signal rst_qd : std_logic; signal link_OK_S : std_logic; signal trb_rx_fsm_state : std_logic_vector(3 downto 0); + signal trb_tx_fsm_state : std_logic_vector(3 downto 0); + signal sync_rx_fsm_state : std_logic_vector(3 downto 0); + signal sync_tx_fsm_state : std_logic_vector(3 downto 0); signal clk_200_osc : std_logic; signal sync_rx_full_clk : std_logic; signal sync_rx_half_clk : std_logic; signal sync_tx_full_clk : std_logic; signal sync_tx_half_clk : std_logic; - - signal rst_n : std_logic; - signal rst : std_logic; -- PL! + signal sync_tx_data : std_logic_vector(7 downto 0); signal sync_tx_k : std_logic; signal sync_rx_data : std_logic_vector(7 downto 0); @@ -287,9 +280,20 @@ architecture Cu_trb_net16_soda_sync_ecp3_sfp_arch of Cu_trb_net16_soda_sync_ecp3 signal sync_rx_los_low : std_logic; signal sync_lsm_status : std_logic; signal sync_rx_cdr_lol : std_logic; - signal sd_los_i : std_logic; --PL! + signal dlm_fifo_rd_en : std_logic; + signal dlm_fifo_empty : std_logic; + signal dlm_fifo_reading : std_logic; + signal dlm_received_S : std_logic; + + signal syncfifo_din : std_logic_vector(17 downto 0); + signal syncfifo_dout : std_logic_vector(17 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_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); @@ -297,9 +301,12 @@ architecture Cu_trb_net16_soda_sync_ecp3_sfp_arch of Cu_trb_net16_soda_sync_ecp3 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 tx_pll_lol_qd_i : std_logic; signal wa_position : std_logic_vector(15 downto 0) := x"FFFF"; signal wa_position_rx : std_logic_vector(15 downto 0) := x"FFFF"; + signal sync_wa_position_rx : std_logic_vector(15 downto 0) := x"FFFF"; signal sync_tx_allow : std_logic; signal sync_rx_allow : std_logic; signal sync_tx_allow_q : std_logic; @@ -311,12 +318,6 @@ architecture Cu_trb_net16_soda_sync_ecp3_sfp_arch of Cu_trb_net16_soda_sync_ecp3 signal start_retr_position_i : std_logic_vector(7 downto 0); signal send_link_reset_i : std_logic; signal make_link_reset_i : std_logic; - signal got_link_ready_i : std_logic; - signal internal_make_link_reset_out : std_logic; - - signal start_timer : unsigned(18 downto 0) := (others => '0'); - signal watchdog_timer : unsigned(20 downto 0) := (others => '0'); - signal watchdog_trigger : std_logic :='0'; attribute syn_keep : boolean; attribute syn_preserve : boolean; @@ -360,17 +361,8 @@ clk_tx <= SYSCLK; clk_rx <= ff_rxhalfclk; clk_rxref <= OSCCLK; clk_txref <= OSCCLK; --------------------------------------------------------------------------- --- Internal Lane Resets --------------------------------------------------------------------------- -clear_n <= not clear; - -internal_make_link_reset_out <= make_link_reset_i when SODA_IS_SYNC_SLAVE = c_YES else '0'; -sd_los_i <= SD_LOS_IN when rising_edge(SYSCLK); -- PL! - -rst_n <= not(CLEAR or SD_LOS_IN or internal_make_link_reset_out or watchdog_trigger); -rst <= (CLEAR or SD_LOS_IN or internal_make_link_reset_out or watchdog_trigger); +--sd_los_i <= SD_LOS_IN when rising_edge(SYSCLK); -- PL! -------------------------------------------------------------------------- -- Internal Lane Resets @@ -396,8 +388,8 @@ THE_SFP_STATUS_SYNC: signal_sync ) port map( RESET => '0', - D_IN(0) => sd_prsnt_n_in, - D_IN(1) => sd_los_in, + D_IN(0) => sync_prsnt_n_in, + D_IN(1) => sync_los_in, CLK0 => clk_sys, CLK1 => clk_sys, D_OUT(0) => sfp_prsnt_n, @@ -463,34 +455,34 @@ THE_RX_RESET: signal_sync -- Delay for ALLOW signals THE_RX_ALLOW_SYNC: signal_sync - generic map( - DEPTH => 2, - WIDTH => 2 - ) - port map( - RESET => reset_i, - D_IN(0) => rx_allow, - D_IN(1) => tx_allow, - CLK0 => clk_sys, - CLK1 => clk_sys, - D_OUT(0) => rx_allow_q, - D_OUT(1) => tx_allow_q - ); + generic map( + DEPTH => 2, + WIDTH => 2 + ) + port map( + RESET => reset_i, + D_IN(0) => rx_allow, + D_IN(1) => tx_allow, + CLK0 => clk_sys, + CLK1 => clk_sys, + D_OUT(0) => rx_allow_q, + D_OUT(1) => tx_allow_q + ); THE_TX_SYNC: signal_sync - generic map( - DEPTH => 1, - WIDTH => 2 - ) - port map( - RESET => '0', - D_IN(0) => send_reset_in, - D_IN(1) => tx_allow, - CLK0 => clk_tx, - CLK1 => clk_tx, - D_OUT(0) => send_reset_in_qtx, - D_OUT(1) => tx_allow_qtx - ); + generic map( + DEPTH => 1, + WIDTH => 2 + ) + port map( + RESET => '0', + D_IN(0) => send_reset_in, + D_IN(1) => tx_allow, + CLK0 => clk_tx, + CLK1 => clk_tx, + D_OUT(0) => send_reset_in_qtx, + D_OUT(1) => tx_allow_qtx + ); -------------------------------------------------------------------------- @@ -524,7 +516,7 @@ THE_SFP_LSM: trb_net16_lsm_sfp STAT_DEBUG => buf_stat_debug ); -sd_txdis_out <= quad_rst or reset_i; +SYNC_TXDIS_OUT <= quad_rst or reset_i; -------------------------------------------------------------------------- -------------------------------------------------------------------------- @@ -534,17 +526,17 @@ ffc_lane_tx_rst <= lane_rst; ffc_lane_rx_rst <= lane_rst; - + -- Instantiation of serdes module THE_SERDES: sfp_2_200_int port map( - HDINP_CH1 => cu_rxd_p_in, - HDINN_CH1 => cu_rxd_n_in, - HDOUTP_CH1 => cu_txd_p_out, - HDOUTN_CH1 => cu_txd_n_out, + HDINP_CH1 => CU_RXD_P_IN, + HDINN_CH1 => CU_RXD_N_IN, + HDOUTP_CH1 => CU_TXD_P_OUT, + HDOUTN_CH1 => CU_TXD_N_OUT, SCI_SEL_CH1 => sci_ch_i(1), RXICLK_CH1 => clk_rx, TXICLK_CH1 => clk_tx, @@ -574,10 +566,10 @@ ffc_lane_rx_rst <= lane_rst; TX_DIV2_MODE_CH1_C => '0', --full rate RX_DIV2_MODE_CH1_C => '0', --full rate - HDINP_CH3 => sd_rxd_p_in, - HDINN_CH3 => sd_rxd_n_in, - HDOUTP_CH3 => sd_txd_p_out, - HDOUTN_CH3 => sd_txd_n_out, + HDINP_CH3 => SYNC_RXD_P_IN, + HDINN_CH3 => SYNC_RXD_N_IN, + HDOUTP_CH3 => SYNC_TXD_P_OUT, + HDOUTN_CH3 => SYNC_TXD_N_OUT, SCI_SEL_CH3 => sci_ch_i(3), TXICLK_CH3 => sync_rx_full_clk, RX_FULL_CLK_CH3 => sync_rx_full_clk, @@ -763,75 +755,236 @@ THE_SERDES_INPUT_PROC: process( clk_tx ) end if; end process THE_SERDES_INPUT_PROC; -PROC_START_TIMER : process(sync_rx_full_clk) + +-- map 8-bit dlm on 18-bit fifo +syncfifo_din(7 downto 0) <= SYNC_dlm_WORD_IN; +syncfifo_din(17 downto 8) <= (others => '0'); +--sync_dlm_word_S <= syncfifo_dout(7 downto 0); + +sync_dlm_tx: trb_net_fifo_16bit_bram_dualport + generic map( + USE_STATUS_FLAGS => c_NO + ) + port map( + read_clock_in => sync_tx_full_clk, + write_clock_in => sync_rx_full_clk, + read_enable_in => dlm_fifo_rd_en, + write_enable_in => SYNC_dlm_IN, + fifo_gsr_in => reset, + write_data_in => syncfifo_din, + read_data_out => syncfifo_dout, + full_out => open, + empty_out => dlm_fifo_empty + ); + +sync_rx_proc : process(sync_rx_full_clk) +begin + if rising_edge(sync_rx_full_clk) then + SYNC_DLM_OUT <= '0'; + if dlm_received_S='1' then + dlm_received_S <= '0'; + SYNC_DLM_OUT <= '1'; + SYNC_dlm_WORD_OUT <= sync_rx_data; + elsif (sync_rx_data=x"DC") and (sync_rx_k='1') then + dlm_received_S <= '1'; + end if; + end if; +end process; + +sync_tx_proc : process(sync_tx_full_clk) begin - if rising_edge(sync_rx_full_clk) 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; + if rising_edge(sync_tx_full_clk) then + if dlm_fifo_rd_en='1' then + dlm_fifo_rd_en <= '0'; + sync_tx_data <= syncfifo_dout(7 downto 0); + sync_tx_k <= '0'; + elsif (dlm_fifo_empty='0') and (dlm_fifo_reading='1') then + dlm_fifo_rd_en <= '1'; + sync_tx_data <= x"DC"; + sync_tx_k <= '1'; + elsif dlm_fifo_empty='0' then + dlm_fifo_reading <= '1'; + dlm_fifo_rd_en <= '0'; + sync_tx_data <= x"BC"; -- idle + sync_tx_k <= '1'; else - start_timer <= (others => '0'); - if ((watchdog_timer(watchdog_timer'left) = '1') and (watchdog_timer(watchdog_timer'left - 2) = '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; + dlm_fifo_reading <= '0'; + dlm_fifo_rd_en <= '0'; + sync_tx_data <= x"BC"; -- idle + sync_tx_k <= '1'; end if; end if; -end process; ---SCI ----------------------- -PROC_SCI : process begin - wait until rising_edge(clk_sys); - 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_addr_i <= SCI_ADDR; - sci_data_in_i <= SCI_DATA_IN; - end if; - sci_read_shift_i <= sci_read_shift_i(1 downto 0) & SCI_READ; - sci_write_shift_i <= sci_write_shift_i(1 downto 0) & SCI_WRITE; - SCI_DATA_OUT <= sci_data_out_i; +end process; + +link_error(8) <= trb_rx_los_low; -- loss of signal +link_error(4) <= '1' when (trb_rx_cdr_lol='1') or (link_OK_S='0') else '0'; -- loss of lock +link_error(5) <= tx_pll_lol_qd_i; -- transmit loss of lock + +reset_n <= '0' when (RESET='1') or (CLEAR='1') else '1'; + +------------------------------------------------- +-- Reset FSM & Link states +------------------------------------------------- +THE_RX_FSM1: rx_reset_fsm + port map( + RST_N => reset_n, + RX_REFCLK => OSCCLK, + TX_PLL_LOL_QD_S => tx_pll_lol_qd_i, + RX_SERDES_RST_CH_C => trb_rx_serdes_rst, + RX_CDR_LOL_CH_S => trb_rx_cdr_lol, + RX_LOS_LOW_CH_S => trb_rx_los_low, + RX_PCS_RST_CH_C => trb_rx_pcs_rst, + WA_POSITION => "0000", + STATE_OUT => trb_rx_fsm_state + ); + +link_OK_S <= '1' when (link_ok(0)='1') and (trb_rx_fsm_state = x"6") else '0'; + +THE_TX_FSM1: tx_reset_fsm + port map( + RST_N => reset_n, + TX_REFCLK => OSCCLK, + TX_PLL_LOL_QD_S => tx_pll_lol_qd_i, + RST_QD_C => rst_qd, + TX_PCS_RST_CH_C => trb_tx_pcs_rst, + STATE_OUT => trb_tx_fsm_state --open + ); + +THE_RX_FSM3: rx_reset_fsm + port map( + RST_N => reset_n, + RX_REFCLK => sync_rx_full_clk, + TX_PLL_LOL_QD_S => tx_pll_lol_qd_i, + RX_SERDES_RST_CH_C => sync_rx_serdes_rst, + RX_CDR_LOL_CH_S => sync_rx_cdr_lol, + RX_LOS_LOW_CH_S => sync_rx_los_low, + RX_PCS_RST_CH_C => sync_rx_pcs_rst, + WA_POSITION => sync_wa_position_rx(11 downto 8), + STATE_OUT => sync_rx_fsm_state + ); + +SYNC_WA_POSITION : process(sync_rx_full_clk) --??CLK) +begin + if rising_edge(sync_rx_full_clk) then + sync_wa_position_rx <= wa_position; + end if; end process; -sci_write_i <= or_all(sci_write_shift_i); -sci_read_i <= or_all(sci_read_shift_i); -SCI_ACK <= sci_write_shift_i(2) or sci_read_shift_i(2); - - - +THE_TX_FSM3 : tx_reset_fsm + port map( + RST_N => reset_n, + TX_REFCLK => OSCCLK, + TX_PLL_LOL_QD_S => tx_pll_lol_qd_i, + RST_QD_C => open, --?? + TX_PCS_RST_CH_C => sync_tx_pcs_rst, + STATE_OUT => sync_tx_fsm_state + ); + +TX_READY_CH3 <= '1' when (sync_tx_fsm_state=x"5") and (tx_pll_lol_qd_i='0') else '0'; + +----------------------------------------------------------------------------------------------------- +-- SCI --gives access to serdes config port from slow control and reads word alignment every ~ 40 us +----------------------------------------------------------------------------------------------------- +PROC_SCI_CTRL: process(clk_sys) + variable cnt : integer range 0 to 4 := 0; +begin + if( rising_edge(clk_sys) ) then + 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 <= sci_timer + 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; + elsif sci_timer(sci_timer'left) = '1' then + sci_timer <= (others => '0'); + sci_state <= GET_WA; + 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_DATA_OUT <= (others => '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); + 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 if; +end process PROC_SCI_CTRL; +---------------------- --Generate LED signals ---------------------- -process( clk_sys ) - begin - if rising_edge(clk_sys) then - led_counter <= led_counter + to_unsigned(1,1); - - if buf_med_dataready_out = '1' then - rx_led <= '1'; - elsif led_counter = 0 then - rx_led <= '0'; - end if; - - if tx_k(0) = '0' then - tx_led <= '1'; - elsif led_counter = 0 then - tx_led <= '0'; - end if; +LED_PROC : process( clk_sys ) + begin + if rising_edge(clk_sys) then + led_counter <= led_counter + to_unsigned(1,1); + if buf_med_dataready_out = '1' then + rx_led <= '1'; + elsif led_counter = 0 then + rx_led <= '0'; + end if; + if tx_k(0) = '0' then + tx_led <= '1'; + elsif led_counter = 0 then + tx_led <= '0'; + end if; + end if; + end process LED_PROC; - end if; - end process; - stat_op(15) <= send_reset_words_q; stat_op(14) <= buf_stat_op(14); @@ -860,4 +1013,4 @@ stat_debug(59 downto 44) <= (others => '0'); stat_debug(63 downto 60) <= buf_stat_debug(3 downto 0); -end architecture; \ No newline at end of file +end Cu_trb_net16_soda_sync_ecp3_sfp_arch; \ No newline at end of file diff --git a/ctsc.ldf b/ctsc.ldf index d8dbbb0..84844b3 100644 --- a/ctsc.ldf +++ b/ctsc.ldf @@ -2,7 +2,7 @@ - + @@ -207,6 +207,12 @@ + + + + + + @@ -219,6 +225,9 @@ + + + @@ -273,12 +282,21 @@ + + + + + + + + + diff --git a/ctsc.lpf b/ctsc.lpf index 61d5cb0..0824311 100644 --- a/ctsc.lpf +++ b/ctsc.lpf @@ -1,3 +1,4 @@ +rvl_alias "soda_rx_full_clk" "soda_rx_full_clk"; BLOCK RESETPATHS; BLOCK ASYNCPATHS; BLOCK RD_DURING_WR_PATHS ; @@ -136,12 +137,12 @@ IOBUF GROUP "LED_group" IO_TYPE=LVCMOS25 PULLMODE=NONE DRIVE=12 ; ################################################################# # Locate Serdes and media interfaces ################################################################# -LOCATE COMP "TRB_MEDIA_AND_SODA_SYNC_UPLINK/PCSD_INST" SITE "PCSA" ; +LOCATE COMP "TRB_MEDIA_AND_SODA_SYNC_UPLINK/THE_SERDES/PCSD_INST" SITE "PCSA" ; MULTICYCLE FROM CELL "THE_RESET_HANDLER/rese*" 20.000000 ns ; MULTICYCLE TO CELL "TRB_MEDIA_AND_SODA_SYNC_UPLINK/SCI_DATA_OUT*" 20.000000 ns ; -MULTICYCLE TO CELL "TRB_MEDIA_AND_SODA_SYNC_UPLINK/sci*" 20.000000 ns ; -MULTICYCLE FROM CELL "TRB_MEDIA_AND_SODA_SYNC_UPLINK/sci*" 20.000000 ns ; +MULTICYCLE TO CELL "TRB_MEDIA_AND_SODA_SYNC_UPLINK/SCI*" 20.000000 ns ; +MULTICYCLE FROM CELL "TRB_MEDIA_AND_SODA_SYNC_UPLINK/SCI*" 20.000000 ns ; #MULTICYCLE TO CELL "TRB_MEDIA_AND_SODA_SYNC_UPLINK/SCI_DATA_OUT*" 50 ns; BLOCK JTAGPATHS ; @@ -151,7 +152,7 @@ USE PRIMARY NET "clk_100_osc" ; FREQUENCY NET "clk_200_osc" 200.000000 MHz ; FREQUENCY NET "clk_100_osc" 100.000000 MHz ; -FREQUENCY NET "rx_full_clk" 200.000000 MHz ; -FREQUENCY NET "rx_half_clk" 100.000000 MHz ; -#FREQUENCY NET "tx_full_clk" 200.000000 MHz ; -#FREQUENCY NET "tx_half_clk" 100.000000 MHz ; \ No newline at end of file +FREQUENCY NET "soda_rx_full_clk" 200.000000 MHz ; +FREQUENCY NET "soda_rx_half_clk" 100.000000 MHz ; +#FREQUENCY NET "soda_tx_full_clk" 200.000000 MHz ; +#FREQUENCY NET "soda_tx_half_clk" 100.000000 MHz ; \ No newline at end of file diff --git a/ctsc_20141217.bit b/ctsc_20141217.bit new file mode 100644 index 0000000..36f43d6 Binary files /dev/null and b/ctsc_20141217.bit differ