From 1510a6acd35dc9102882fcc665c5cb3f4178e5a7 Mon Sep 17 00:00:00 2001 From: hadeshyp Date: Wed, 20 Feb 2013 18:37:20 +0000 Subject: [PATCH] sync media interface --- media_interfaces/med_ecp3_sfp_sync.vhd | 57 +++++++++++++++++-- media_interfaces/sync/med_sync_define.vhd | 3 +- media_interfaces/sync/rx_control.vhd | 23 +++++++- media_interfaces/sync/tb/med_ecp3_sync_tb.vhd | 34 +++++++++++ 4 files changed, 108 insertions(+), 9 deletions(-) diff --git a/media_interfaces/med_ecp3_sfp_sync.vhd b/media_interfaces/med_ecp3_sfp_sync.vhd index 9f8286d..7dd8af3 100644 --- a/media_interfaces/med_ecp3_sfp_sync.vhd +++ b/media_interfaces/med_ecp3_sfp_sync.vhd @@ -12,7 +12,8 @@ use work.med_sync_define.all; 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 @@ -125,6 +126,20 @@ component serdes_sync_0 is 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; @@ -169,6 +184,8 @@ signal wa_position : std_logic_vector(15 downto 0) := x"FFFF"; 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); @@ -188,11 +205,11 @@ 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 : 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; @@ -200,11 +217,37 @@ CLK_RX_FULL_OUT <= clk_rx_full; -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 ------------------------------------------------- @@ -300,6 +343,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); + + PROC_START_TIMER : process begin wait until rising_edge(clk_200_i); if got_link_ready_i = '1' then @@ -503,6 +550,6 @@ STAT_OP(11) <= '0'; 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; diff --git a/media_interfaces/sync/med_sync_define.vhd b/media_interfaces/sync/med_sync_define.vhd index 5f49b0f..d879750 100644 --- a/media_interfaces/sync/med_sync_define.vhd +++ b/media_interfaces/sync/med_sync_define.vhd @@ -129,7 +129,8 @@ end component; 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 diff --git a/media_interfaces/sync/rx_control.vhd b/media_interfaces/sync/rx_control.vhd index ab18a22..94a5ded 100644 --- a/media_interfaces/sync/rx_control.vhd +++ b/media_interfaces/sync/rx_control.vhd @@ -47,6 +47,8 @@ architecture rx_control_arch of rx_control is 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'; @@ -81,13 +83,28 @@ begin --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 ---------------------------------------------------------------------- @@ -123,7 +140,7 @@ PROC_RX_FSM : process begin 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; @@ -170,10 +187,10 @@ PROC_RX_FSM : process begin 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"; diff --git a/media_interfaces/sync/tb/med_ecp3_sync_tb.vhd b/media_interfaces/sync/tb/med_ecp3_sync_tb.vhd index 86c8757..fd3728e 100644 --- a/media_interfaces/sync/tb/med_ecp3_sync_tb.vhd +++ b/media_interfaces/sync/tb/med_ecp3_sync_tb.vhd @@ -125,6 +125,40 @@ clk_100_s <= clk_rxhalf_s; 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, -- 2.43.0