entity med_ecp3_sfp_sync is
generic(
SERDES_NUM : integer range 0 to 3 := 0;
- MASTER_CLOCK_SWITCH : integer := 0
+ MASTER_CLOCK_SWITCH : integer := c_NO; --just for debugging, should be NO
+ IS_SYNC_SLAVE : integer := c_NO --select slave mode
);
port(
- CLK : in std_logic; -- SerDes clock
- SYSCLK : in std_logic; -- fabric clock
+ CLK : 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
- CLK_EN : in std_logic;
- --Internal Connection
+ --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;
- CLK_RX_HALF_OUT : out std_logic := '0';
- CLK_RX_FULL_OUT : out std_logic := '0';
+ CLK_RX_HALF_OUT : out std_logic := '0'; --received 100 MHz
+ CLK_RX_FULL_OUT : out std_logic := '0'; --received 200 MHz
- IS_SLAVE : in std_logic := '0';
+ --Sync operation
+ IS_SLAVE : in std_logic := '0'; --0 if generic is used
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";
+
--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;
- SD_REFCLK_N_IN : in 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
end component;
-COMPONENT DCS
+component DCS
-- synthesis translate_off
-GENERIC
+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;
+port (
+CLK0 :in std_logic ;
+CLK1 :in std_logic ;
+SEL :in std_logic ;
+DCSOUT :out std_logic) ;
+end component;
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 stat_rx_control_i : std_logic_vector(31 downto 0);
signal stat_tx_control_i : std_logic_vector(31 downto 0);
signal start_timer : unsigned(18 downto 0) := (others => '0');
begin
-clk_200_internal <= CLK;
-
-
+clk_200_internal <= CLK;
CLK_RX_HALF_OUT <= clk_rx_half;
CLK_RX_FULL_OUT <= clk_rx_full;
rst_n <= not CLEAR;
+
--Temporary clock switch for debugging, should be not used!
gen_clock_switch : if MASTER_CLOCK_SWITCH = 1 generate
-DCSInst0: DCS
--- synthesis translate_off
-GENERIC MAP (
-DCSMODE => “POS”
-);
--- synthesis translate_on
-PORT MAP (
-SEL => IS_SLAVE,
-CLK0 => clk_200_internal,
-CLK1 => clk_rx_full,
-DCSOUT => clk_200_i
-);
+ DCSInst0: DCS
+ -- synthesis translate_off
+ generic map (
+ DCSMODE => “POS”
+ );
+ -- synthesis translate_on
+ port map (
+ SEL => IS_SLAVE,
+ CLK0 => clk_200_internal,
+ CLK1 => clk_rx_full,
+ DCSOUT => clk_200_i
+ );
end generate;
-
-gen_no_clock_switch : if MASTER_CLOCK_SWITCH = 0 generate --and IS_SLAVE = c_YES
+gen_slave_clock : if MASTER_CLOCK_SWITCH = 0 and IS_SYNC_SLAVE = c_YES generate
clk_200_i <= clk_rx_full;
end generate;
--- gen_no_clock_switch : if MASTER_CLOCK_SWITCH = 0 generate --and IS_SLAVE = c_NO
--- clk_200_i <= clk_200_internal;
--- end generate;
+gen_master_clock : if MASTER_CLOCK_SWITCH = 0 and IS_SYNC_SLAVE = c_NO generate
+ clk_200_i <= clk_200_internal;
+end generate;
-------------------------------------------------
STATE_OUT => tx_fsm_state
);
-wa_position_rx <= wa_position when IS_SLAVE = '1' else x"0000";
-
+-- Master can't do bit-locking
+wa_position_rx <= wa_position when (IS_SLAVE = '1' or IS_SYNC_SLAVE = 1) else x"0000";
+
+
+--Slave enables RX/TX when sync is done, Master waits additional time to make sure link is stable
PROC_ALLOW : process begin
wait until rising_edge(clk_200_i);
- if rx_fsm_state = x"6" and (IS_SLAVE = '1' or start_timer(start_timer'left) = '1') then
+ if rx_fsm_state = x"6" and ((IS_SLAVE = '1' or IS_SYNC_SLAVE = 1) or start_timer(start_timer'left) = '1') then
rx_allow <= '1';
else
rx_allow <= '0';
end if;
- if rx_fsm_state = x"6" and (IS_SLAVE = '1' or start_timer(start_timer'left) = '1') then
+ if rx_fsm_state = x"6" and ((IS_SLAVE = '1' or IS_SYNC_SLAVE = 1) or start_timer(start_timer'left) = '1') then
tx_allow <= '1';
else
tx_allow <= '0';
DEBUG_OUT => debug_rx_control_i,
STAT_REG_OUT => stat_rx_control_i
);
+
+
+
-------------------------------------------------
-- 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
STAT_DEBUG <= debug_reg;
+internal_make_link_reset_out <= make_link_reset_i when IS_SLAVE = '1' or IS_SYNC_SLAVE = 1 else '0';
+
+
STAT_OP(15) <= send_link_reset_i when rising_edge(SYSCLK);
STAT_OP(14) <= '0';
-STAT_OP(13) <= ((make_link_reset_i and IS_SLAVE)) when rising_edge(SYSCLK); --make trbnet reset
+STAT_OP(13) <= internal_make_link_reset_out when rising_edge(SYSCLK); --make trbnet reset
STAT_OP(12) <= '0';
STAT_OP(11) <= '0';
STAT_OP(10) <= rx_allow;
USE IEEE.std_logic_ARITH.ALL;
USE IEEE.std_logic_UNSIGNED.ALL;
+use work.trb_net_std.all;
+
package med_sync_define is
constant K_IDLE : std_logic_vector(7 downto 0) := x"BC";
component med_ecp3_sfp_sync is
generic(
SERDES_NUM : integer range 0 to 3 := 0;
- MASTER_CLOCK_SWITCH : integer := 0
+ MASTER_CLOCK_SWITCH : integer := c_NO; --just for debugging, should be NO
+ IS_SYNC_SLAVE : integer := c_NO --select slave mode
);
port(
- CLK : in std_logic; -- SerDes clock
- SYSCLK : in std_logic; -- fabric clock
+ CLK : 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
- CLK_EN : in std_logic;
- --Internal Connection
- MED_DATA_IN : in std_logic_vector(15 downto 0);
- MED_PACKET_NUM_IN : in std_logic_vector(2 downto 0);
+ --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';
- MED_DATA_OUT : out std_logic_vector(15 downto 0) := (others => '0');
- MED_PACKET_NUM_OUT : out std_logic_vector(2 downto 0) := (others => '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;
- CLK_RX_HALF_OUT : out std_logic := '0';
- CLK_RX_FULL_OUT : out std_logic := '0';
+ CLK_RX_HALF_OUT : out std_logic := '0'; --received 100 MHz
+ CLK_RX_FULL_OUT : out std_logic := '0'; --received 200 MHz
- IS_SLAVE : in std_logic := '0';
+ --Sync operation
+ IS_SLAVE : in std_logic := '0'; --0 if generic is used
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_WORD : in std_logic_vector(7 downto 0) := x"00";
+
--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;
- SD_REFCLK_N_IN : in 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
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';
-- Status and control port
STAT_OP : out std_logic_vector (15 downto 0);
- CTRL_OP : in 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)
+ CTRL_DEBUG : in std_logic_vector (63 downto 0) := (others => '0')
);
end component;