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;
- REFCLK2CORE_OUT : out std_logic := '0';
CLK_RX_HALF_OUT : out std_logic := '0';
CLK_RX_FULL_OUT : out std_logic := '0';
+
+ IS_SLAVE : in std_logic := '0';
+ 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;
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 : std_logic_vector(15 downto 0) := x"FFFF";
-signal tx_allow : std_logic;
-signal rx_allow : std_logic;
-
-signal rx_fsm_state : std_logic_vector(3 downto 0);
-signal tx_fsm_state : std_logic_vector(3 downto 0);
-signal debug_reg : std_logic_vector(63 downto 0);
+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 request_retr_i : std_logic;
+signal start_retr_i : std_logic;
+signal request_retr_position_i : std_logic_vector(7 downto 0);
+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 stat_rx_control_i : std_logic_vector(31 downto 0);
+signal stat_tx_control_i : std_logic_vector(31 downto 0);
+signal debug_rx_control_i : std_logic_vector(31 downto 0);
+signal debug_tx_control_i : std_logic_vector(31 downto 0);
+signal rx_fsm_state : std_logic_vector(3 downto 0);
+signal tx_fsm_state : std_logic_vector(3 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 : unsigned(12 downto 0) := (others => '0');
-
+signal start_timer : unsigned(23 downto 0) := (others => '0');
begin
clk_200_internal <= CLK;
);
-------------------------------------------------
--- Reset FSM
+-- Reset FSM & Link states
-------------------------------------------------
THE_RX_FSM : rx_reset_fsm
port map(
RX_CDR_LOL_CH_S => rx_cdr_lol,
RX_LOS_LOW_CH_S => rx_los_low,
RX_PCS_RST_CH_C => rx_pcs_rst,
- WA_POSITION => wa_position(3 downto 0),
+ WA_POSITION => wa_position_rx(3 downto 0),
STATE_OUT => rx_fsm_state
);
STATE_OUT => tx_fsm_state
);
+wa_position_rx <= wa_position when IS_SLAVE = '1' else x"0000";
PROC_ALLOW : process begin
wait until rising_edge(clk_200_i);
- if rx_fsm_state = x"6" then
+ if rx_fsm_state = x"6" and (IS_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" then --TODO: needs to be comma detection
+ if rx_fsm_state = x"6" and (IS_SLAVE = '1' or start_timer(start_timer'left) = '1') then
tx_allow <= '1';
else
tx_allow <= '0';
end if;
end process;
+
+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;
-------------------------------------------------
TX_DATA_OUT => tx_data,
TX_K_OUT => tx_k,
- REQUEST_RETRANSMIT_IN => open, --TODO
- REQUEST_POSITION_IN => open, --TODO
+ REQUEST_RETRANSMIT_IN => request_retr_i, --TODO
+ REQUEST_POSITION_IN => request_retr_position_i, --TODO
- START_RETRANSMIT_IN => open, --TODO
- START_POSITION_IN => open, --TODO
+ START_RETRANSMIT_IN => start_retr_i, --TODO
+ START_POSITION_IN => request_retr_position_i, --TODO
- SEND_DLM => open, --TODO
- SEND_DLM_WORD => open, --TODO
+ SEND_DLM => TX_DLM,
+ SEND_DLM_WORD => TX_DLM_WORD,
SEND_LINK_RESET_IN => CTRL_OP(15),
TX_ALLOW_IN => tx_allow,
RX_ALLOW_IN => rx_allow,
- DEBUG_OUT => open,
- STAT_REG_OUT => open
+ DEBUG_OUT => debug_tx_control_i,
+ STAT_REG_OUT => stat_tx_control_i
);
+
+-------------------------------------------------
+-- RX Data
+-------------------------------------------------
+THE_RX_CONTROL : rx_control
+ port map(
+ CLK_200 => clk_200_i,
+ CLK_100 => SYSCLK,
+ RESET_IN => CLEAR,
+
+ RX_DATA_OUT => MED_DATA_OUT,
+ RX_PACKET_NUMBER_OUT => MED_PACKET_NUM_OUT,
+ RX_WRITE_OUT => MED_DATAREADY_OUT,
+ RX_READ_IN => MED_READ_IN,
+
+ RX_DATA_IN => rx_data,
+ RX_K_IN => rx_k,
+
+ REQUEST_RETRANSMIT_OUT => request_retr_i,
+ REQUEST_POSITION_OUT => request_retr_position_i,
+
+ START_RETRANSMIT_OUT => start_retr_i,
+ START_POSITION_OUT => start_retr_position_i,
+
+ --send_dlm: 200 MHz, 1 clock strobe, data valid until next DLM
+ RX_DLM => RX_DLM,
+ RX_DLM_WORD => RX_DLM_WORD,
+ SEND_LINK_RESET_OUT => send_link_reset_i,
+ MAKE_RESET_OUT => make_link_reset_i,
+ RX_ALLOW_IN => rx_allow,
+ GOT_LINK_READY => got_link_ready_i,
+
+ DEBUG_OUT => debug_rx_control_i,
+ STAT_REG_OUT => stat_rx_control_i
+ );
-------------------------------------------------
-- SCI
-------------------------------------------------
--- PROC_SCI : process begin
--- wait until rising_edge(SYSCLK);
--- 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;
--- 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;
--- if sci_reg_i = '1' then
--- SCI_DATA_OUT <= debug_reg(8*(to_integer(unsigned(SCI_ADDR(2 downto 0))))+7 downto 8*(to_integer(unsigned(SCI_ADDR(2 downto 0)))));
--- sci_read_shift_i(2) <= '1';
--- else
--- SCI_DATA_OUT <= sci_data_out_i;
--- 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);
-
PROC_SCI_CTRL: process
variable cnt : integer range 0 to 4 := 0;
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_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
debug_reg(5) <= rx_error;
debug_reg(6) <= rx_los_low;
debug_reg(7) <= rx_cdr_lol;
-debug_reg(15 downto 8) <= rx_data;
-debug_reg(16) <= '0';
-debug_reg(17) <= tx_k;
-debug_reg(18) <= tx_pll_lol;
-debug_reg(19) <= lsm_status;
-debug_reg(23 downto 20) <= tx_fsm_state;
-debug_reg(31 downto 24) <= tx_data;
+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(47 downto 32) <= wa_position;
-
-debug_reg(63 downto 48) <= (others => '0');
+debug_reg(35 downto 32) <= wa_position(3 downto 0);
+debug_reg(39 downto 36) <= x"0";
+debug_reg(63 downto 40) <= debug_rx_control_i(23 downto 0);
STAT_DEBUG <= debug_reg;
-STAT_OP(15) <= '0';
+STAT_OP(15) <= send_link_reset_i when rising_edge(SYSCLK);
STAT_OP(14) <= '0';
-STAT_OP(13) <= not rx_allow when rising_edge(SYSCLK); --make trbnet reset
+STAT_OP(13) <= ((make_link_reset_i and IS_SLAVE)) when rising_edge(SYSCLK); --make trbnet reset
STAT_OP(12) <= '0';
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"7";
+STAT_OP(3 downto 0) <= x"0" when rx_allow = '1' and tx_allow = '1' else x"7";
end architecture;
constant K_RST : std_logic_vector(7 downto 0) := x"FE";
constant K_DLM : std_logic_vector(7 downto 0) := x"DC";
+component rx_control is
+ port(
+ CLK_200 : in std_logic;
+ CLK_100 : in std_logic;
+ RESET_IN : in std_logic;
+
+ RX_DATA_OUT : out std_logic_vector(15 downto 0);
+ RX_PACKET_NUMBER_OUT : out std_logic_vector(2 downto 0);
+ RX_WRITE_OUT : out std_logic;
+ RX_READ_IN : in std_logic;
+
+ RX_DATA_IN : in std_logic_vector( 7 downto 0);
+ RX_K_IN : in std_logic;
+
+ REQUEST_RETRANSMIT_OUT : out std_logic := '0';
+ REQUEST_POSITION_OUT : out std_logic_vector( 7 downto 0) := (others => '0');
+
+ START_RETRANSMIT_OUT : out std_logic := '0';
+ START_POSITION_OUT : out std_logic_vector( 7 downto 0) := (others => '0');
+
+ --send_dlm: 200 MHz, 1 clock strobe, data valid until next DLM
+ RX_DLM : out std_logic := '0';
+ RX_DLM_WORD : out std_logic_vector( 7 downto 0) := (others => '0');
+
+ SEND_LINK_RESET_OUT : out std_logic := '0';
+ MAKE_RESET_OUT : out std_logic := '0';
+ RX_ALLOW_IN : in std_logic := '0';
+ GOT_LINK_READY : 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 tx_control is
STATE_OUT : out std_logic_vector(3 downto 0)
);
end component;
-
+
+
+component lattice_ecp3_fifo_18x16_dualport_oreg
+ port (
+ Data: in std_logic_vector(17 downto 0);
+ WrClock: in std_logic;
+ RdClock: in std_logic;
+ WrEn: in std_logic;
+ RdEn: in std_logic;
+ Reset: in std_logic;
+ RPReset: in std_logic;
+ Q: out std_logic_vector(17 downto 0);
+ Empty: out std_logic;
+ Full: out std_logic;
+ AlmostFull: out std_logic
+ );
+end component;
+
+component med_ecp3_sfp_sync is
+ generic(
+ SERDES_NUM : integer range 0 to 3 := 0
+ );
+ port(
+ CLK : in std_logic; -- SerDes clock
+ SYSCLK : in std_logic; -- fabric 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);
+ 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');
+ MED_DATAREADY_OUT : out std_logic := '0';
+ MED_READ_IN : in std_logic;
+ REFCLK2CORE_OUT : out std_logic := '0';
+ CLK_RX_HALF_OUT : out std_logic := '0';
+ CLK_RX_FULL_OUT : out std_logic := '0';
+
+ IS_SLAVE : in std_logic := '0';
+ 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_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);
+ STAT_DEBUG : out std_logic_vector (63 downto 0);
+ CTRL_DEBUG : in std_logic_vector (63 downto 0)
+ );
+end component;
--- /dev/null
+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.med_sync_define.all;
+
+entity rx_control is
+ port(
+ CLK_200 : in std_logic;
+ CLK_100 : in std_logic;
+ RESET_IN : in std_logic;
+
+ RX_DATA_OUT : out std_logic_vector(15 downto 0);
+ RX_PACKET_NUMBER_OUT : out std_logic_vector(2 downto 0);
+ RX_WRITE_OUT : out std_logic;
+ RX_READ_IN : in std_logic;
+
+ RX_DATA_IN : in std_logic_vector( 7 downto 0);
+ RX_K_IN : in std_logic;
+
+ REQUEST_RETRANSMIT_OUT : out std_logic := '0';
+ REQUEST_POSITION_OUT : out std_logic_vector( 7 downto 0) := (others => '0');
+
+ START_RETRANSMIT_OUT : out std_logic := '0';
+ START_POSITION_OUT : out std_logic_vector( 7 downto 0) := (others => '0');
+
+ --send_dlm: 200 MHz, 1 clock strobe, data valid until next DLM
+ RX_DLM : out std_logic := '0';
+ RX_DLM_WORD : out std_logic_vector( 7 downto 0) := (others => '0');
+
+ SEND_LINK_RESET_OUT : out std_logic := '0';
+ MAKE_RESET_OUT : out std_logic := '0';
+ RX_ALLOW_IN : in std_logic := '0';
+ GOT_LINK_READY : out std_logic := '0';
+
+ DEBUG_OUT : out std_logic_vector(31 downto 0);
+ STAT_REG_OUT : out std_logic_vector(31 downto 0)
+ );
+end entity;
+
+
+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_data : std_logic_vector(17 downto 0);
+signal ct_fifo_write : std_logic := '0';
+signal ct_fifo_read : std_logic := '0';
+signal ct_fifo_reset : std_logic := '0';
+signal ct_fifo_data_out : std_logic_vector(17 downto 0);
+signal ct_fifo_empty : std_logic;
+signal ct_fifo_full : std_logic;
+signal ct_fifo_afull : std_logic;
+signal last_ct_fifo_empty : std_logic;
+signal last_ct_fifo_read : std_logic;
+
+signal tmp_link_ready_i : std_logic := '0';
+signal got_link_ready_i : std_logic := '0';
+signal start_retr_i : std_logic;
+signal start_retr_pos_i : std_logic_vector(7 downto 0);
+signal rx_dlm_i : std_logic;
+signal rx_dlm_word_i : std_logic_vector(7 downto 0);
+
+signal send_link_reset_i : std_logic;
+signal make_reset_i : std_logic;
+signal next_sop : std_logic;
+
+signal reg_rx_data_in : std_logic_vector(7 downto 0);
+signal reg_rx_k_in : std_logic;
+
+begin
+
+----------------------------------------------------------------------
+-- Data to Endpoint
+----------------------------------------------------------------------
+--note: no handshaking, read signal can be ignored!
+
+ct_fifo_read <= not ct_fifo_reset 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);
+
+last_ct_fifo_read <= ct_fifo_read when rising_edge(CLK_100);
+last_ct_fifo_empty <= ct_fifo_empty when rising_edge(CLK_100);
+
+----------------------------------------------------------------------
+-- Clock Domain Transfer
+----------------------------------------------------------------------
+THE_CT_FIFO : lattice_ecp3_fifo_18x16_dualport_oreg
+ port map(
+ Data => rx_data,
+ WrClock => CLK_200,
+ RdClock => CLK_100,
+ WrEn => ct_fifo_write,
+ RdEn => ct_fifo_read,
+ Reset => ct_fifo_reset,
+ RPReset => ct_fifo_reset,
+ Q(17 downto 0) => ct_fifo_data_out,
+ Empty => ct_fifo_empty,
+ Full => ct_fifo_full,
+ AlmostFull => ct_fifo_afull
+ );
+
+ct_fifo_reset <= not RX_ALLOW_IN;
+
+
+
+----------------------------------------------------------------------
+-- Read incoming data
+----------------------------------------------------------------------
+PROC_RX_FSM : process begin
+ wait until rising_edge(CLK_200);
+ ct_fifo_write <= '0';
+ start_retr_i <= '0';
+ rx_dlm_i <= '0';
+
+ case rx_state is
+ 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
+ rx_state <= wAIT_1;
+ end if;
+
+ when WAIT_1 =>
+ rx_state <= FIRST;
+
+ when FIRST =>
+ rx_state_bits <= x"2";
+ if reg_rx_k_in = '1' then
+ case reg_rx_data_in is
+ when K_IDLE =>
+ rx_state <= GET_IDLE;
+ when K_RST =>
+ rx_state <= MAKE_RESET;
+ when K_DLM =>
+ rx_state <= GET_DLM;
+ when K_REQ =>
+ rx_state <= START_RETR;
+ when others => null;
+ end case;
+ else
+ rx_data(7 downto 0) <= reg_rx_data_in;
+ rx_state <= GET_DATA;
+ end if;
+
+ when GET_IDLE =>
+ rx_state_bits <= x"3";
+ rx_state <= FIRST;
+ next_sop <= '1';
+ if reg_rx_k_in = '0' and reg_rx_data_in = D_IDLE0 then
+ tmp_link_ready_i <= '0';
+ got_link_ready_i <= tmp_link_ready_i;
+ elsif reg_rx_k_in = '0' and reg_rx_data_in = D_IDLE1 then
+ got_link_ready_i <= '1';
+ tmp_link_ready_i <= '1';
+ else
+ rx_state <= SLEEP;
+ end if;
+
+ when GET_DATA =>
+ rx_state_bits <= x"4";
+ if reg_rx_k_in = '0' then
+ next_sop <= '0';
+ rx_data(15 downto 8)<= reg_rx_data_in;
+ rx_data(16) <= next_sop;
+ ct_fifo_write <= '1';
+ else
+ rx_state <= SLEEP;
+ end if;
+ rx_state <= FIRST;
+
+ when GET_DLM =>
+ rx_state_bits <= x"5";
+ rx_dlm_i <= '1';
+ rx_dlm_word_i <= reg_rx_data_in;
+ rx_state <= FIRST;
+
+ when START_RETR =>
+ rx_state_bits <= x"6";
+ start_retr_i <= '1';
+ start_retr_pos_i <= reg_rx_data_in;
+ rx_state <= FIRST;
+
+ when MAKE_RESET =>
+ rx_state_bits <= x"F";
+ if reg_rx_k_in = '1' and reg_rx_data_in = K_RST then
+ send_link_reset_i <= '1';
+ make_reset_i <= '0';
+ got_link_ready_i <= '0';
+ else
+ send_link_reset_i <= '0';
+ make_reset_i <= '1';
+ rx_state <= SLEEP;
+ end if;
+
+ end case;
+
+ if RESET_IN = '1' then
+ rx_state <= SLEEP;
+ end if;
+end process;
+
+reg_rx_data_in <= RX_DATA_IN when rising_edge(CLK_200);
+reg_rx_k_in <= RX_K_IN when rising_edge(CLK_200);
+
+
+----------------------------------------------------------------------
+-- Signals out
+----------------------------------------------------------------------
+GOT_LINK_READY <= got_link_ready_i;
+
+START_RETRANSMIT_OUT <= start_retr_i;
+START_POSITION_OUT <= start_retr_pos_i;
+
+RX_DLM <= rx_dlm_i;
+RX_DLM_WORD <= rx_dlm_word_i;
+
+REQUEST_RETRANSMIT_OUT <= '0'; --TODO: check incoming data
+REQUEST_POSITION_OUT <= x"00"; --TODO: check incoming data
+
+SEND_LINK_RESET_OUT <= send_link_reset_i;
+MAKE_RESET_OUT <= make_reset_i;
+
+
+----------------------------------------------------------------------
+-- Debug and Status
+----------------------------------------------------------------------
+STAT_REG_OUT(3 downto 0) <= rx_state_bits;
+STAT_REG_OUT(4) <= got_link_ready_i;
+STAT_REG_OUT(5) <= ct_fifo_afull;
+STAT_REG_OUT(6) <= ct_fifo_empty;
+STAT_REG_OUT(7) <= ct_fifo_write;
+STAT_REG_OUT(15 downto 8) <= reg_rx_data_in(7 downto 0);
+STAT_REG_OUT(16) <= rx_data(16);
+STAT_REG_OUT(31 downto 18) <= (others => '0');
+
+
+DEBUG_OUT(3 downto 0) <= rx_state_bits;
+DEBUG_OUT(4) <= got_link_ready_i;
+DEBUG_OUT(5) <= ct_fifo_afull;
+DEBUG_OUT(6) <= ct_fifo_empty;
+DEBUG_OUT(7) <= ct_fifo_write;
+DEBUG_OUT(15 downto 8) <= reg_rx_data_in(7 downto 0);
+DEBUG_OUT(16) <= rx_data(16);
+DEBUG_OUT(31 downto 18) <= (others => '0');
+
+
+
+
+end architecture;
\ No newline at end of file
--- /dev/null
+
+LIBRARY ieee ;
+LIBRARY work ;
+USE ieee.NUMERIC_STD.all ;
+USE ieee.std_logic_1164.all ;
+USE work.med_sync_define.all ;
+USE work.trb_net_components.all ;
+USE work.trb_net_std.all ;
+
+entity med_ecp3_sfp_sync_tb is
+end entity;
+
+architecture arch of med_ecp3_sfp_sync_tb is
+
+
+
+component med_ecp3_sfp_sync is
+ generic(
+ SERDES_NUM : integer range 0 to 3 := 0
+ );
+ port(
+ CLK : in std_logic; -- SerDes clock
+ SYSCLK : in std_logic; -- fabric 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(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(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';
+
+ IS_SLAVE : in std_logic := '0';
+ 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_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;
+
+
+signal clk_100_m, clk_100_s : std_logic := '1';
+signal clk_200_m, clk_200_s : std_logic := '1';
+
+signal reset_m : std_logic := '1';
+signal clear_m : std_logic := '1';
+signal reset_s : std_logic := '1';
+signal clear_s : std_logic := '1';
+
+signal med_data_in_m : std_logic_vector(15 downto 0) := (others => '0');
+signal med_packet_num_in_m : std_logic_vector(2 downto 0) := (others => '0');
+signal med_dataready_in_m : std_logic := '0';
+signal med_read_out_m : std_logic := '0';
+signal med_data_out_m : std_logic_vector(15 downto 0) := (others => '0');
+signal med_packet_num_out_m : std_logic_vector(2 downto 0) := (others => '0');
+signal med_dataready_out_m : std_logic := '0';
+signal med_read_in_m : std_logic := '0';
+
+signal med_data_in_s : std_logic_vector(15 downto 0) := (others => '0');
+signal med_packet_num_in_s : std_logic_vector(2 downto 0) := (others => '0');
+signal med_dataready_in_s : std_logic := '0';
+signal med_read_out_s : std_logic := '0';
+signal med_data_out_s : std_logic_vector(15 downto 0) := (others => '0');
+signal med_packet_num_out_s : std_logic_vector(2 downto 0) := (others => '0');
+signal med_dataready_out_s : std_logic := '0';
+signal med_read_in_s : std_logic := '0';
+
+signal tx_dlm_m : std_logic := '0';
+signal tx_dlm_word_m : std_logic_vector(7 downto 0) := (others => '0');
+signal rx_dlm_s : std_logic := '0';
+signal rx_dlm_word_s : std_logic_vector(7 downto 0) := (others => '0');
+signal tx_dlm_s : std_logic := '0';
+signal tx_dlm_word_s : std_logic_vector(7 downto 0) := (others => '0');
+
+signal RX_P, RX_N, TX_P, TX_N : std_logic;
+signal RX_P_S, RX_N_S, TX_P_S, TX_N_S : std_logic;
+
+signal clk_rxfull_s : std_logic;
+signal clk_rxhalf_s : std_logic;
+
+begin
+
+reset_m <= '0' after 201 ns;
+clear_m <= '0' after 51 ns;
+reset_s <= '0' after 201 ns;
+clear_s <= '0' after 51 ns;
+
+RX_P_S <= transport TX_P after 123 ns;
+RX_N_S <= transport TX_N after 123 ns;
+RX_P <= transport TX_P_S after 123 ns;
+RX_N <= transport TX_N_S after 123 ns;
+
+clk_100_m <= not clk_100_m after 5 ns;
+clk_200_m <= not clk_200_m after 2.5 ns;
+clk_100_s <= clk_rxhalf_s;
+clk_200_s <= not clk_200_s after 2.501 ns;
+
+
+THE_MASTER : med_ecp3_sfp_sync
+ port map(
+ CLK => clk_200_m,
+ SYSCLK => clk_100_m,
+ RESET => reset_m,
+ CLEAR => clear_m,
+ CLK_EN => '1',
+ --Internal Connection
+ MED_DATA_IN => med_data_in_m,
+ MED_PACKET_NUM_IN => med_packet_num_in_m,
+ MED_DATAREADY_IN => med_dataready_in_m,
+ MED_READ_OUT => med_read_out_m,
+ MED_DATA_OUT => med_data_out_m,
+ MED_PACKET_NUM_OUT => med_packet_num_out_m,
+ MED_DATAREADY_OUT => med_dataready_out_m,
+ MED_READ_IN => med_read_in_m,
+ CLK_RX_HALF_OUT => open,
+ CLK_RX_FULL_OUT => open,
+
+ IS_SLAVE => '0',
+ RX_DLM => open,
+ RX_DLM_WORD => open,
+ TX_DLM => tx_dlm_m,
+ TX_DLM_WORD => tx_dlm_word_m,
+ --SFP Connection
+ SD_RXD_P_IN => RX_P,
+ SD_RXD_N_IN => RX_N,
+ SD_TXD_P_OUT => TX_P,
+ SD_TXD_N_OUT => TX_N,
+ SD_REFCLK_P_IN => '0',
+ SD_REFCLK_N_IN => '0',
+ SD_PRSNT_N_IN => '0',
+ SD_LOS_IN => '0',
+ SD_TXDIS_OUT => open,
+ --Control Interface
+ SCI_DATA_IN => (others => '0'),
+ SCI_DATA_OUT => open,
+ SCI_ADDR => (others => '0'),
+ SCI_READ => '0',
+ SCI_WRITE => '0',
+ SCI_ACK => open,
+ SCI_NACK => open,
+ -- Status and control port
+ STAT_OP => open,
+ CTRL_OP => (others => '0'),
+ STAT_DEBUG => open,
+ CTRL_DEBUG => (others => '0')
+ );
+
+
+THE_SLAVE : med_ecp3_sfp_sync
+ port map(
+ CLK => clk_200_s,
+ SYSCLK => clk_100_s,
+ RESET => reset_s,
+ CLEAR => clear_s,
+ CLK_EN => '1',
+ --Internal Connection
+ MED_DATA_IN => med_data_in_s,
+ MED_PACKET_NUM_IN => med_packet_num_in_s,
+ MED_DATAREADY_IN => med_dataready_in_s,
+ MED_READ_OUT => med_read_out_s,
+ MED_DATA_OUT => med_data_out_s,
+ MED_PACKET_NUM_OUT => med_packet_num_out_s,
+ MED_DATAREADY_OUT => med_dataready_out_s,
+ MED_READ_IN => med_read_in_s,
+ CLK_RX_HALF_OUT => clk_rxhalf_s,
+ CLK_RX_FULL_OUT => clk_rxfull_s,
+
+ IS_SLAVE => '1',
+ RX_DLM => rx_dlm_s,
+ RX_DLM_WORD => rx_dlm_word_s,
+ TX_DLM => tx_dlm_s,
+ TX_DLM_WORD => tx_dlm_word_s,
+ --SFP Connection
+ SD_RXD_P_IN => RX_P_S,
+ SD_RXD_N_IN => RX_N_S,
+ SD_TXD_P_OUT => TX_P_S,
+ SD_TXD_N_OUT => TX_N_S,
+ SD_REFCLK_P_IN => '0',
+ SD_REFCLK_N_IN => '0',
+ SD_PRSNT_N_IN => '0',
+ SD_LOS_IN => '0',
+ SD_TXDIS_OUT => open,
+ --Control Interface
+ SCI_DATA_IN => (others => '0'),
+ SCI_DATA_OUT => open,
+ SCI_ADDR => (others => '0'),
+ SCI_READ => '0',
+ SCI_WRITE => '0',
+ SCI_ACK => open,
+ SCI_NACK => open,
+ -- Status and control port
+ STAT_OP => open,
+ CTRL_OP => (others => '0'),
+ STAT_DEBUG => open,
+ CTRL_DEBUG => (others => '0')
+ );
+
+
+end architecture;
\ No newline at end of file
end entity;
architecture tx_control_tb_arch of tx_control_tb is
- signal stat_reg_out : std_logic_vector (31 downto 0) ;
signal start_position_in : std_logic_vector (7 downto 0) := (others => '0') ;
signal clk_100 : std_logic := '1';
signal clk_200 : std_logic := '1';
signal tx_write_in : std_logic := '0';
signal tx_data_out : std_logic_vector (7 downto 0) ;
signal start_retransmit_in : std_logic := '0' ;
- signal debug_out : std_logic_vector (31 downto 0) ;
signal send_link_reset_in : std_logic := '0' ;
signal request_retransmit_in : std_logic := '0' ;
+ signal send_link_reset_out : std_logic := '0' ;
+ signal request_retransmit_out : std_logic := '0' ;
+ signal rx_dlm_word : std_logic_vector (7 downto 0) := (others => '0') ;
+ signal got_link_ready : std_logic := '0' ;
+ signal rx_write_out : std_logic ;
+ signal rx_read_in : std_logic ;
+ signal request_position_out : std_logic_vector (7 downto 0) := (others => '0') ;
+ signal start_retransmit_out : std_logic := '0' ;
+ signal rx_allow_in : std_logic := '0' ;
+ signal rx_packet_number_out : std_logic_vector (2 downto 0) ;
+ signal start_position_out : std_logic_vector (7 downto 0) := (others => '0') ;
+ signal rx_data_in : std_logic_vector (7 downto 0) ;
+ signal rx_data_out : std_logic_vector (15 downto 0) ;
+ signal rx_k_in : std_logic ;
+ signal rx_dlm : std_logic := '0' ;
+ signal make_reset_out : std_logic := '0' ;
+
component tx_control
port (
REQUEST_RETRANSMIT_IN : in STD_LOGIC );
end component ;
+component rx_control is
+ port(
+ CLK_200 : in std_logic;
+ CLK_100 : in std_logic;
+ RESET_IN : in std_logic;
+
+ RX_DATA_OUT : out std_logic_vector(15 downto 0);
+ RX_PACKET_NUMBER_OUT : out std_logic_vector(2 downto 0);
+ RX_WRITE_OUT : out std_logic;
+ RX_READ_IN : in std_logic;
+
+ RX_DATA_IN : in std_logic_vector( 7 downto 0);
+ RX_K_IN : in std_logic;
+
+ REQUEST_RETRANSMIT_OUT : out std_logic := '0';
+ REQUEST_POSITION_OUT : out std_logic_vector( 7 downto 0) := (others => '0');
+
+ START_RETRANSMIT_OUT : out std_logic := '0';
+ START_POSITION_OUT : out std_logic_vector( 7 downto 0) := (others => '0');
+
+ --send_dlm: 200 MHz, 1 clock strobe, data valid until next DLM
+ RX_DLM : out std_logic := '0';
+ RX_DLM_WORD : out std_logic_vector( 7 downto 0) := (others => '0');
+
+ SEND_LINK_RESET_OUT : out std_logic := '0';
+ MAKE_RESET_OUT : out std_logic := '0';
+ RX_ALLOW_IN : in std_logic := '0';
+ GOT_LINK_READY : 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;
begin
- DUT : tx_control
+
+CLK_100 <= not CLK_100 after 5 ns;
+CLK_200 <= not CLK_200 after 2.5 ns;
+
+TX_ALLOW_IN <= '0', '1' after 50 ns;
+RX_ALLOW_IN <= '0', '1' after 40 ns;
+
+ DUTTX : tx_control
port map (
- STAT_REG_OUT => STAT_REG_OUT ,
+ STAT_REG_OUT => open ,
START_POSITION_IN => START_POSITION_IN ,
CLK_100 => CLK_100 ,
CLK_200 => CLK_200 ,
TX_WRITE_IN => TX_WRITE_IN ,
TX_DATA_OUT => TX_DATA_OUT ,
START_RETRANSMIT_IN => START_RETRANSMIT_IN ,
- DEBUG_OUT => DEBUG_OUT ,
+ DEBUG_OUT => open ,
SEND_LINK_RESET_IN => SEND_LINK_RESET_IN ,
REQUEST_RETRANSMIT_IN => REQUEST_RETRANSMIT_IN
);
-CLK_100 <= not CLK_100 after 5 ns;
-CLK_200 <= not CLK_200 after 2.5 ns;
-TX_ALLOW_IN <= '0', '1' after 50 ns;
+ DUTRX : rx_control
+ port map (
+ STAT_REG_OUT => open ,
+ SEND_LINK_RESET_OUT => SEND_LINK_RESET_OUT ,
+ REQUEST_RETRANSMIT_OUT => REQUEST_RETRANSMIT_OUT ,
+ RX_DLM_WORD => RX_DLM_WORD ,
+ CLK_100 => CLK_100 ,
+ GOT_LINK_READY => GOT_LINK_READY ,
+ CLK_200 => CLK_200 ,
+ RX_WRITE_OUT => RX_WRITE_OUT ,
+ RX_READ_IN => RX_READ_IN ,
+ REQUEST_POSITION_OUT => REQUEST_POSITION_OUT ,
+ START_RETRANSMIT_OUT => START_RETRANSMIT_OUT ,
+ RX_ALLOW_IN => RX_ALLOW_IN ,
+ RX_PACKET_NUMBER_OUT => RX_PACKET_NUMBER_OUT ,
+ START_POSITION_OUT => START_POSITION_OUT ,
+ RESET_IN => RESET_IN ,
+ RX_DATA_IN => RX_DATA_IN ,
+ RX_DATA_OUT => RX_DATA_OUT ,
+ RX_K_IN => RX_K_IN ,
+ DEBUG_OUT => open ,
+ RX_DLM => RX_DLM ,
+ MAKE_RESET_OUT => MAKE_RESET_OUT
+ );
+
+
+RX_K_IN <= TX_K_OUT;
+RX_DATA_IN <= TX_DATA_OUT;
process begin
wait for 100 ns;
wait until rising_edge(clk_100); wait for 1 ns;
TX_DATA_IN <= x"0038"; TX_PACKET_NUMBER_IN <= "100"; TX_WRITE_IN <= '1';
wait until rising_edge(clk_100); wait for 1 ns;
- TX_DATA_IN <= x"1111"; TX_PACKET_NUMBER_IN <= "000"; TX_WRITE_IN <= '1';
+ TX_DATA_IN <= x"2211"; TX_PACKET_NUMBER_IN <= "000"; TX_WRITE_IN <= '1';
wait until rising_edge(clk_100); wait for 1 ns;
- TX_DATA_IN <= x"2222"; TX_PACKET_NUMBER_IN <= "001"; TX_WRITE_IN <= '1';
+ TX_DATA_IN <= x"4433"; TX_PACKET_NUMBER_IN <= "001"; TX_WRITE_IN <= '1';
wait until rising_edge(clk_100); wait for 1 ns;
- TX_DATA_IN <= x"3333"; TX_PACKET_NUMBER_IN <= "010"; TX_WRITE_IN <= '1';
+ TX_DATA_IN <= x"6655"; TX_PACKET_NUMBER_IN <= "010"; TX_WRITE_IN <= '1';
wait until rising_edge(clk_100); wait for 1 ns;
- TX_DATA_IN <= x"4444"; TX_PACKET_NUMBER_IN <= "011"; TX_WRITE_IN <= '1';
+ TX_DATA_IN <= x"8877"; TX_PACKET_NUMBER_IN <= "011"; TX_WRITE_IN <= '1';
wait until rising_edge(clk_100); wait for 1 ns;
TX_DATA_IN <= x"0000"; TX_PACKET_NUMBER_IN <= "100"; TX_WRITE_IN <= '0';
end process;
+
+process begin
+ wait for 120 ns;
+ wait until rising_edge(clk_200); wait for 1 ns;
+ SEND_DLM_WORD <= x"85"; SEND_DLM <= '1';
+ wait until rising_edge(clk_200); wait for 1 ns;
+ SEND_DLM_WORD <= x"85"; SEND_DLM <= '0';
+ wait for 15 ns;
+end process;
+
+
end architecture;
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
SEND_DLM : in std_logic := '0';
SEND_DLM_WORD : in std_logic_vector( 7 downto 0) := (others => '0');
architecture arch of tx_control is
--- gk 05.10.10
- component lattice_ecp3_fifo_18x16_dualport_oreg
- port (
- Data: in std_logic_vector(17 downto 0);
- WrClock: in std_logic;
- RdClock: in std_logic;
- WrEn: in std_logic;
- RdEn: in std_logic;
- Reset: in std_logic;
- RPReset: in std_logic;
- Q: out std_logic_vector(17 downto 0);
- Empty: out std_logic;
- Full: out std_logic;
- AlmostFull: out std_logic
- );
- end component;
-
--- gk 05.10.10
-component trb_net_CRC8 is
- port(
- CLK : in std_logic;
- RESET : in std_logic;
- CLK_EN : in std_logic;
- DATA_IN : in std_logic_vector(7 downto 0);
- CRC_OUT : out std_logic_vector(7 downto 0);
- CRC_match : out std_logic
- );
-end component;
type state_t is (SEND_IDLE_L, SEND_IDLE_H, SEND_DATA_L, SEND_DATA_H, SEND_DLM_L, SEND_DLM_H,
SEND_START_L, SEND_START_H, SEND_REQUEST_L, SEND_REQUEST_H,
PULSE_B_OUT => start_retransmit_i
);
- THE_RETRANSMIT_PULSE_SYNC_3 : pulse_sync
- port map(
- CLK_A_IN => CLK_100,
- RESET_A_IN => RESET_IN,
- PULSE_A_IN => SEND_DLM,
- CLK_B_IN => CLK_200,
- RESET_B_IN => RESET_IN,
- PULSE_B_OUT => send_dlm_in_i
- );
+-- THE_RETRANSMIT_PULSE_SYNC_3 : pulse_sync
+-- port map(
+-- CLK_A_IN => CLK_100,
+-- RESET_A_IN => RESET_IN,
+-- PULSE_A_IN => SEND_DLM,
+-- CLK_B_IN => CLK_200,
+-- RESET_B_IN => RESET_IN,
+-- PULSE_B_OUT => send_dlm_in_i
+-- );
+ send_dlm_in_i <= SEND_DLM;
THE_POSITION_REG : process(CLK_100)
begin