entity med_ecp3_sfp_sync is
generic(
- SERDES_NUM : integer range 0 to 3 := 0
+ SERDES_NUM : integer range 0 to 3 := 0;
+ MASTER_CLOCK_SWITCH : integer := 0
);
port(
CLK : in std_logic; -- SerDes clock
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;
signal wa_position_rx : std_logic_vector(15 downto 0) := x"FFFF";
signal tx_allow : std_logic;
signal rx_allow : std_logic;
+signal tx_allow_q : std_logic;
+signal rx_allow_q : std_logic;
signal request_retr_i : std_logic;
signal start_retr_i : std_logic;
signal request_retr_position_i : std_logic_vector(7 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 : unsigned(12 downto 0) := (others => '0');
-signal start_timer : unsigned(23 downto 0) := (others => '0');
+signal start_timer : unsigned(18 downto 0) := (others => '0');
begin
clk_200_internal <= CLK;
-clk_200_i <= clk_rx_full;
+
CLK_RX_HALF_OUT <= clk_rx_half;
-SD_TXDIS_OUT <= '0';
+SD_TXDIS_OUT <= '0'; --not (rx_allow_q or not IS_SLAVE); --slave only switches on when RX is ready
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
+);
+end generate;
+
+
+gen_no_clock_switch : if MASTER_CLOCK_SWITCH = 0 generate --and IS_SLAVE = c_YES
+ 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;
+
+
-------------------------------------------------
-- Serdes
-------------------------------------------------
end if;
end process;
+rx_allow_q <= rx_allow when rising_edge(SYSCLK);
+tx_allow_q <= tx_allow when rising_edge(SYSCLK);
+
+
PROC_START_TIMER : process begin
wait until rising_edge(clk_200_i);
if got_link_ready_i = '1' then
STAT_OP(10) <= rx_allow;
STAT_OP(9) <= tx_allow;
STAT_OP(8 downto 4) <= (others => '0');
-STAT_OP(3 downto 0) <= x"0" when rx_allow = '1' and tx_allow = '1' else x"7";
+STAT_OP(3 downto 0) <= x"0" when rx_allow_q = '1' and tx_allow_q = '1' else x"7";
end architecture;
component med_ecp3_sfp_sync is
generic(
- SERDES_NUM : integer range 0 to 3 := 0
+ SERDES_NUM : integer range 0 to 3 := 0;
+ MASTER_CLOCK_SWITCH : integer := 0
);
port(
CLK : in std_logic; -- SerDes clock
type rx_state_t is (SLEEP, WAIT_1, FIRST, GET_DATA, GET_IDLE, GET_DLM, MAKE_RESET, START_RETR);
signal rx_state : rx_state_t;
signal rx_state_bits : std_logic_vector(3 downto 0);
+signal rx_packet_num : std_logic_vector(2 downto 0) := "100";
+signal buf_rx_write_out : std_logic := '0';
signal rx_data : std_logic_vector(17 downto 0);
signal ct_fifo_write : std_logic := '0';
--note: no handshaking, read signal can be ignored!
ct_fifo_read <= not ct_fifo_reset when rising_edge(CLK_100);
+buf_rx_write_out <= last_ct_fifo_read and not last_ct_fifo_empty when rising_edge(CLK_100);
RX_DATA_OUT <= ct_fifo_data_out(15 downto 0) ;
-RX_WRITE_OUT <= last_ct_fifo_read and not last_ct_fifo_empty when rising_edge(CLK_100);
+RX_WRITE_OUT <= buf_rx_write_out;
+RX_PACKET_NUMBER_OUT <= rx_packet_num;
last_ct_fifo_read <= ct_fifo_read when rising_edge(CLK_100);
last_ct_fifo_empty <= ct_fifo_empty when rising_edge(CLK_100);
+process begin
+ wait until rising_edge(CLK_100);
+ if RX_ALLOW_IN = '0' then
+ rx_packet_num <= "100";
+ elsif buf_rx_write_out = '1' then
+ if rx_packet_num = "100" then
+ rx_packet_num <= "000";
+ else
+ rx_packet_num <= std_logic_vector(unsigned(rx_packet_num)+1);
+ end if;
+ end if;
+end process;
+
----------------------------------------------------------------------
-- Clock Domain Transfer
----------------------------------------------------------------------
when SLEEP =>
rx_state_bits <= x"1";
got_link_ready_i <= '0';
- if RX_ALLOW_IN = '1' and reg_rx_k_in = '1' and reg_rx_data_in = x"BC" then
+ if reg_rx_k_in = '1' and reg_rx_data_in = x"BC" then
rx_state <= wAIT_1;
end if;
rx_data(15 downto 8)<= reg_rx_data_in;
rx_data(16) <= next_sop;
ct_fifo_write <= '1';
+ rx_state <= FIRST;
else
rx_state <= SLEEP;
end if;
- rx_state <= FIRST;
when GET_DLM =>
rx_state_bits <= x"5";
clk_200_s <= not clk_200_s after 2.501 ns;
+
+tx_dlm_word_m <= x"43";
+tx_dlm_m <= '0', '1' after 4.00 ms, '0' after 4.00001 ms;
+
+
+process begin
+ wait for 3.98 ms;
+ wait until rising_edge(clk_100_m); wait for 1 ns;
+ med_data_in_m <= x"1122";
+ med_packet_num_in_m <= "100";
+ med_dataready_in_m <= '1';
+ wait until rising_edge(clk_100_m); wait for 1 ns;
+ med_data_in_m <= x"3344";
+ med_packet_num_in_m <= "000";
+ med_dataready_in_m <= '1';
+ wait until rising_edge(clk_100_m); wait for 1 ns;
+ med_data_in_m <= x"5566";
+ med_packet_num_in_m <= "001";
+ med_dataready_in_m <= '1';
+ wait until rising_edge(clk_100_m); wait for 1 ns;
+ med_data_in_m <= x"7788";
+ med_packet_num_in_m <= "010";
+ med_dataready_in_m <= '1';
+ wait until rising_edge(clk_100_m); wait for 1 ns;
+ med_data_in_m <= x"9900";
+ med_packet_num_in_m <= "011";
+ med_dataready_in_m <= '1';
+ wait until rising_edge(clk_100_m); wait for 1 ns;
+ med_dataready_in_m <= '0';
+
+end process;
+
+
+
THE_MASTER : med_ecp3_sfp_sync
port map(
CLK => clk_200_m,