From 4b97d976538a30b6854087fb52acb6f08dc9d0e8 Mon Sep 17 00:00:00 2001 From: hadeshyp Date: Tue, 4 Oct 2011 08:24:13 +0000 Subject: [PATCH] *** empty log message *** --- gbe2_ecp3/feeder.vhd | 620 ++++++ gbe2_ecp3/ip_configurator.vhd | 342 +++ gbe2_ecp3/mb_mac_sim.vhd | 331 +++ gbe2_ecp3/slv_mac_memory.vhd | 178 ++ gbe2_ecp3/slv_register.vhd | 177 ++ gbe2_ecp3/tb_feeder.vhd | 300 +++ gbe2_ecp3/tb_frame_receiver.vhd | 1836 +++++++++++++++++ gbe2_ecp3/tb_gbe_buf.vhd | 532 +++++ gbe2_ecp3/tb_ip_configurator.vhd | 145 ++ gbe2_ecp3/tb_ipu2gbe.vhd | 428 ++++ gbe2_ecp3/tb_ipu2gbe_NEW.vhd | 428 ++++ gbe2_ecp3/tb_ipu2gbe_OLD.vhd | 428 ++++ gbe2_ecp3/tb_lsm.vhd | 113 + gbe2_ecp3/tb_pc.vhd | 310 +++ gbe2_ecp3/tb_slv_mac_memory.vhd | 114 + gbe2_ecp3/trb_net16_gbe_buf.vhd | 1614 +++++++++++++++ gbe2_ecp3/trb_net16_gbe_frame_constr.vhd | 568 +++++ gbe2_ecp3/trb_net16_gbe_frame_receiver.vhd | 752 +++++++ gbe2_ecp3/trb_net16_gbe_frame_trans.vhd | 211 ++ gbe2_ecp3/trb_net16_gbe_mac_control.vhd | 290 +++ gbe2_ecp3/trb_net16_gbe_main_control.vhd | 634 ++++++ gbe2_ecp3/trb_net16_gbe_packet_constr.vhd | 1088 ++++++++++ .../trb_net16_gbe_packet_constr_20101006.vhd | 958 +++++++++ .../trb_net16_gbe_packet_constr_nologic.vhd | 1099 ++++++++++ ..._net16_gbe_packet_constr_simple_sender.vhd | 1170 +++++++++++ .../trb_net16_gbe_protocol_prioritizer.vhd | 93 + gbe2_ecp3/trb_net16_gbe_protocol_selector.vhd | 372 ++++ gbe2_ecp3/trb_net16_gbe_receive_control.vhd | 227 ++ ...trb_net16_gbe_response_constructor_ARP.vhd | 287 +++ ...rb_net16_gbe_response_constructor_DHCP.vhd | 659 ++++++ ...net16_gbe_response_constructor_Forward.vhd | 236 +++ ...rb_net16_gbe_response_constructor_Ping.vhd | 299 +++ ...rb_net16_gbe_response_constructor_Test.vhd | 235 +++ ...b_net16_gbe_response_constructor_Test1.vhd | 160 ++ ...b_net16_gbe_response_constructor_Trash.vhd | 153 ++ gbe2_ecp3/trb_net16_gbe_setup.vhd | 605 ++++++ gbe2_ecp3/trb_net16_gbe_setup_simplified.vhd | 595 ++++++ gbe2_ecp3/trb_net16_gbe_transmit_control.vhd | 364 ++++ gbe2_ecp3/trb_net16_gbe_type_validator.vhd | 175 ++ gbe2_ecp3/trb_net16_ipu2gbe.vhd | 1403 +++++++++++++ gbe2_ecp3/trb_net16_ipu2gbe_20101006.vhd | 1316 ++++++++++++ gbe2_ecp3/trb_net16_ipu2gbe_nologic.vhd | 1403 +++++++++++++ gbe2_ecp3/trb_net16_lsm_sfp_gbe.vhd | 236 +++ gbe2_ecp3/trb_net16_med_ecp_sfp_gbe_8b.vhd | 532 +++++ gbe2_ecp3/trb_net_gbe_components.vhd | 861 ++++++++ gbe2_ecp3/trb_net_gbe_protocols.vhd | 324 +++ 46 files changed, 25201 insertions(+) create mode 100755 gbe2_ecp3/feeder.vhd create mode 100755 gbe2_ecp3/ip_configurator.vhd create mode 100755 gbe2_ecp3/mb_mac_sim.vhd create mode 100755 gbe2_ecp3/slv_mac_memory.vhd create mode 100755 gbe2_ecp3/slv_register.vhd create mode 100755 gbe2_ecp3/tb_feeder.vhd create mode 100644 gbe2_ecp3/tb_frame_receiver.vhd create mode 100755 gbe2_ecp3/tb_gbe_buf.vhd create mode 100755 gbe2_ecp3/tb_ip_configurator.vhd create mode 100755 gbe2_ecp3/tb_ipu2gbe.vhd create mode 100755 gbe2_ecp3/tb_ipu2gbe_NEW.vhd create mode 100755 gbe2_ecp3/tb_ipu2gbe_OLD.vhd create mode 100755 gbe2_ecp3/tb_lsm.vhd create mode 100755 gbe2_ecp3/tb_pc.vhd create mode 100755 gbe2_ecp3/tb_slv_mac_memory.vhd create mode 100755 gbe2_ecp3/trb_net16_gbe_buf.vhd create mode 100755 gbe2_ecp3/trb_net16_gbe_frame_constr.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_frame_receiver.vhd create mode 100755 gbe2_ecp3/trb_net16_gbe_frame_trans.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_mac_control.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_main_control.vhd create mode 100755 gbe2_ecp3/trb_net16_gbe_packet_constr.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_packet_constr_20101006.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_packet_constr_nologic.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_packet_constr_simple_sender.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_protocol_prioritizer.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_protocol_selector.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_receive_control.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_response_constructor_ARP.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_response_constructor_DHCP.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_response_constructor_Forward.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_response_constructor_Ping.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_response_constructor_Test.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_response_constructor_Test1.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_response_constructor_Trash.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_setup.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_setup_simplified.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_transmit_control.vhd create mode 100644 gbe2_ecp3/trb_net16_gbe_type_validator.vhd create mode 100755 gbe2_ecp3/trb_net16_ipu2gbe.vhd create mode 100644 gbe2_ecp3/trb_net16_ipu2gbe_20101006.vhd create mode 100644 gbe2_ecp3/trb_net16_ipu2gbe_nologic.vhd create mode 100755 gbe2_ecp3/trb_net16_lsm_sfp_gbe.vhd create mode 100755 gbe2_ecp3/trb_net16_med_ecp_sfp_gbe_8b.vhd create mode 100644 gbe2_ecp3/trb_net_gbe_components.vhd create mode 100644 gbe2_ecp3/trb_net_gbe_protocols.vhd diff --git a/gbe2_ecp3/feeder.vhd b/gbe2_ecp3/feeder.vhd new file mode 100755 index 0000000..57fb2c2 --- /dev/null +++ b/gbe2_ecp3/feeder.vhd @@ -0,0 +1,620 @@ +LIBRARY ieee; +use ieee.std_logic_1164.all; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; +use IEEE.std_logic_arith.all; + +library work; + +entity feeder is +port( CLK : in std_logic; + RESET : in std_logic; + -- IPU interface directed toward the CTS + CTS_NUMBER_IN : in std_logic_vector (15 downto 0); + CTS_CODE_IN : in std_logic_vector (7 downto 0); + CTS_INFORMATION_IN : in std_logic_vector (7 downto 0); + CTS_READOUT_TYPE_IN : in std_logic_vector (3 downto 0); + CTS_START_READOUT_IN : in std_logic; + CTS_READ_IN : in std_logic; + CTS_DATA_OUT : out std_logic_vector (31 downto 0); + CTS_DATAREADY_OUT : out std_logic; + CTS_READOUT_FINISHED_OUT : out std_logic; --no more data, end transfer, send TRM + CTS_LENGTH_OUT : out std_logic_vector (15 downto 0); + CTS_ERROR_PATTERN_OUT : out std_logic_vector (31 downto 0); + -- Data from Frontends + FEE_DATA_IN : in std_logic_vector (15 downto 0); + FEE_DATAREADY_IN : in std_logic; + FEE_READ_OUT : out std_logic; + FEE_BUSY_IN : in std_logic; + FEE_STATUS_BITS_IN : in std_logic_vector (31 downto 0); + -- PacketConstructor interface + PC_WR_EN_OUT : out std_logic; + PC_DATA_OUT : out std_logic_vector (7 downto 0); + PC_READY_IN : in std_logic; + PC_SOS_OUT : out std_logic; + PC_EOD_OUT : out std_logic; + PC_SUB_SIZE_OUT : out std_logic_vector(31 downto 0); + PC_TRIG_NR_OUT : out std_logic_vector(31 downto 0); + PC_PADDING_OUT : out std_logic; + -- Debug + BSM_SAVE_OUT : out std_logic_vector(3 downto 0); + BSM_LOAD_OUT : out std_logic_vector(3 downto 0); + DBG_REM_CTR_OUT : out std_logic_vector(3 downto 0); + DBG_CTS_CTR_OUT : out std_logic_vector(2 downto 0); + DBG_SF_WCNT_OUT : out std_logic_vector(15 downto 0); + DBG_SF_RCNT_OUT : out std_logic_vector(16 downto 0); + DBG_SF_DATA_OUT : out std_logic_vector(15 downto 0); + DBG_SF_RD_EN_OUT : out std_logic; + DBG_SF_WR_EN_OUT : out std_logic; + DBG_SF_EMPTY_OUT : out std_logic; + DBG_SF_FULL_OUT : out std_logic; + DBG_SF_AFULL_OUT : out std_logic; + DEBUG_OUT : out std_logic_vector(31 downto 0) +); +end entity; + +architecture feeder of feeder is + +component fifo_32kx16x8_mb +port( Data : in std_logic_vector(15 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; + AmFullThresh : in std_logic_vector(14 downto 0); + Q : out std_logic_vector(7 downto 0); + WCNT : out std_logic_vector(15 downto 0); + RCNT : out std_logic_vector(16 downto 0); + Empty : out std_logic; + Full : out std_logic; + AlmostFull : out std_logic + ); +end component; + +type saveStates is (SIDLE, WAIT_FOR_DATA, SAVE_DATA, TERMINATE, SCLOSE); +signal saveCurrentState, saveNextState : saveStates; +signal state : std_logic_vector(3 downto 0); +signal data_req_comb : std_logic; +signal data_req : std_logic; -- request data signal, will be used for fee_read generation +signal rst_saved_ctr_comb : std_logic; +signal rst_saved_ctr : std_logic; + +signal fee_read_comb : std_logic; +signal fee_read : std_logic; -- fee_read signal +signal saved_ctr : std_logic_vector(16 downto 0); +signal ce_saved_ctr : std_logic; + +-- header data +signal cts_rnd : std_logic_vector(15 downto 0); +signal cts_rnd_saved : std_logic; +signal cts_trg : std_logic_vector(15 downto 0); +signal cts_trg_saved : std_logic; +signal cts_len : std_logic_vector(16 downto 0); +signal cts_len_saved : std_logic; + +-- CTS interface +signal cts_error_pattern : std_logic_vector(31 downto 0); +signal cts_length : std_logic_vector(15 downto 0); +signal cts_readout_finished : std_logic; +signal cts_dataready : std_logic; +signal cts_data : std_logic_vector(31 downto 0); + +-- Split FIFO signals +signal sf_data : std_logic_vector(15 downto 0); +signal sf_wr_en_comb : std_logic; +signal sf_wr_en : std_logic; -- write signal for FIFO +signal sf_rd_en : std_logic; +signal sf_wcnt : std_logic_vector(15 downto 0); +signal sf_rcnt : std_logic_vector(16 downto 0); +signal sf_empty : std_logic; +signal sf_full : std_logic; +signal sf_afull : std_logic; + +------------------------------------------------------------------- +type loadStates is (LIDLE, INIT, REMOVE, CALCA, CALCB, LOAD, PAD0, PAD1, PAD2, PAD3, WAIT_PC, CLOSE); +signal loadCurrentState, loadNextState : loadStates; +signal state2 : std_logic_vector(3 downto 0); + +signal rem_ctr : std_logic_vector(3 downto 0); -- counter for stripping / storing header data +signal rst_rem_ctr_comb : std_logic; +signal rst_rem_ctr : std_logic; +signal rst_regs_comb : std_logic; +signal rst_regs : std_logic; +signal ce_rem_ctr_comb : std_logic; +signal ce_rem_ctr : std_logic; +signal remove_done_comb : std_logic; +signal remove_done : std_logic; -- end of header stripping process +signal load_done_comb : std_logic; +signal load_done : std_logic; -- end of data transfer into PC +signal calc_pad_comb : std_logic; +signal calc_pad : std_logic; -- add padding bytes, if needed +signal read_data_comb : std_logic; +signal read_data : std_logic; -- fetch data from split fifo +signal data_phase_comb : std_logic; +signal data_phase : std_logic; -- data transport phase from split fifo to PC +signal pc_sos_comb : std_logic; +signal pc_sos : std_logic; -- start of data signal +signal pc_eod_comb : std_logic; +signal pc_eod : std_logic; -- end of data signal +signal pad_data_comb : std_logic; +signal pad_data : std_logic; -- insert padding bytes + +signal pc_data : std_logic_vector(7 downto 0); +signal pc_data_q : std_logic_vector(7 downto 0); +signal pc_trig_nr : std_logic_vector(15 downto 0); +signal pc_sub_size : std_logic_vector(17 downto 0); +signal read_size : std_logic_vector(17 downto 0); -- number of byte to be read from split fifo +signal padding_needed : std_logic; +signal pc_wr_en_q : std_logic; +signal pc_wr_en_qq : std_logic; +signal pc_eod_q : std_logic; + +signal debug : std_logic_vector(31 downto 0); + +begin + +-- CTS interface signals +cts_error_pattern <= (others => '0'); -- FAKE +cts_dataready <= '1'; -- FAKE + +cts_length <= x"0000"; -- length of data payload is always 0 +cts_data <= b"0001" & cts_rnd(11 downto 0) & cts_trg; -- reserved bits = '0', pack bit = '1' + +cts_readout_finished <= '1' when (saveCurrentState = SCLOSE) else '0'; + + +-- Sync all critical pathes +THE_SYNC_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + sf_data <= FEE_DATA_IN; + sf_wr_en <= sf_wr_en_comb; + fee_read <= fee_read_comb; + load_done <= load_done_comb; + pc_eod_q <= pc_eod; + pc_wr_en_qq <= pc_wr_en_q; + pc_wr_en_q <= data_phase; + end if; +end process THE_SYNC_PROC; + +-- combinatorial read signal for the FEE data interface, DO NOT USE DIRECTLY +fee_read_comb <= '1' when ( (sf_afull = '0') and (data_req = '1') ) + else '0'; + +-- combinatorial write signal for the split FIFO, DO NOT USE DIRECTLY +sf_wr_en_comb <= '1' when ( (fee_read = '1') and (FEE_DATAREADY_IN = '1') ) + else '0'; + +-- Counter for header word storage +THE_CTS_SAVED_CTR: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_saved_ctr = '1') ) then + saved_ctr <= (others => '0'); + elsif( ce_saved_ctr = '1' ) then + saved_ctr <= saved_ctr + 1; + end if; + end if; +end process THE_CTS_SAVED_CTR; + +ce_saved_ctr <= sf_wr_en; + +-- Statemachine for reading data payload, handling IPU channel and storing data in the SPLIT_FIFO +saveMachineProc: process( CLK ) +begin + if rising_edge(CLK) then + if RESET = '1' then + saveCurrentState <= SIDLE; + data_req <= '0'; + rst_saved_ctr <= '0'; + else + saveCurrentState <= saveNextState; + data_req <= data_req_comb; + rst_saved_ctr <= rst_saved_ctr_comb; + end if; + end if; +end process saveMachineProc; + +saveMachine: process( saveCurrentState, CTS_START_READOUT_IN, FEE_BUSY_IN, CTS_READ_IN ) +begin + saveNextState <= SIDLE; + data_req_comb <= '0'; + rst_saved_ctr_comb <= '0'; + case saveCurrentState is + when SIDLE => + state <= x"0"; + if (CTS_START_READOUT_IN = '1') then + saveNextState <= WAIT_FOR_DATA; + data_req_comb <= '1'; + rst_saved_ctr_comb <= '1'; + else + saveNextState <= SIDLE; + end if; + when WAIT_FOR_DATA => + state <= x"1"; + if (FEE_BUSY_IN = '1') then + saveNextState <= SAVE_DATA; + data_req_comb <= '1'; + else + saveNextState <= WAIT_FOR_DATA; + data_req_comb <= '1'; + end if; + when SAVE_DATA => + state <= x"2"; + if (FEE_BUSY_IN = '0') then + saveNextState <= TERMINATE; + else + saveNextState <= SAVE_DATA; + data_req_comb <= '1'; + end if; + when TERMINATE => + state <= x"3"; + if (CTS_READ_IN = '1') then + saveNextState <= SCLOSE; + else + saveNextState <= TERMINATE; + end if; + when SCLOSE => + state <= x"4"; + if (CTS_START_READOUT_IN = '0') then + saveNextState <= SIDLE; + else + saveNextState <= SCLOSE; + end if; + when others => + state <= x"f"; + saveNextState <= SIDLE; + end case; +end process saveMachine; + +-- save triggerRnd from incoming data for cts response +CTS_RND_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_saved_ctr = '1') ) then + cts_rnd <= (others => '0'); + cts_rnd_saved <= '0'; + elsif( (saved_ctr(2 downto 0) = b"000") and (sf_wr_en = '1') and (cts_rnd_saved = '0') ) then + cts_rnd <= sf_data; + cts_rnd_saved <= '1'; + end if; + end if; +end process CTS_RND_PROC; + +-- save triggerNr from incoming data for cts response +CTS_TRG_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_saved_ctr = '1') ) then + cts_trg <= (others => '0'); + cts_trg_saved <= '0'; + elsif( (saved_ctr(2 downto 0) = b"001") and (sf_wr_en = '1') and (cts_trg_saved = '0') ) then + cts_trg <= sf_data; + cts_trg_saved <= '1'; + end if; + end if; +end process CTS_TRG_PROC; + +-- save size from incoming data for cts response (future) and to get rid of padding +CTS_SIZE_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_saved_ctr = '1') ) then + cts_len <= (others => '0'); + cts_len_saved <= '0'; + elsif( (saved_ctr(2 downto 0) = b"010") and (sf_wr_en = '1') and (cts_len_saved = '0') ) then + cts_len(16 downto 1) <= sf_data; -- change from 32b words to 16b words + elsif( (saved_ctr(2 downto 0) = b"011") and (cts_len_saved = '0') ) then + cts_len <= cts_len + x"4"; + cts_len_saved <= '1'; + end if; + end if; +end process CTS_SIZE_PROC; + +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ + +-- Split FIFO +THE_SPLIT_FIFO: fifo_32kx16x8_mb +port map( Data => sf_data, + WrClock => CLK, + RdClock => CLK, + WrEn => sf_wr_en, + RdEn => sf_rd_en, + Reset => RESET, + RPReset => RESET, + AmFullThresh => b"111_1111_1110_1111", -- 0x7fef = 32751 + Q => pc_data, --open, + WCNT => sf_wcnt, + RCNT => sf_rcnt, + Empty => sf_empty, + Full => sf_full, + AlmostFull => sf_afull + ); + +sf_rd_en <= read_data; +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ + +-- FIFO data delay process (also forces padding bytes to known value) +THE_DATA_DELAY_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if( pad_data = '1' ) then + pc_data_q <= x"ee"; + else + pc_data_q <= pc_data; + end if; + end if; +end process THE_DATA_DELAY_PROC; + +-- Statemachine for reading the data payload from the SPLIT_FIFO and feeding +-- it into the packet constructor +loadMachineProc : process(CLK) +begin + if rising_edge(CLK) then + if RESET = '1' then + loadCurrentState <= LIDLE; + rst_regs <= '0'; + rst_rem_ctr <= '0'; + ce_rem_ctr <= '0'; + calc_pad <= '0'; + read_data <= '0'; + data_phase <= '0'; + pc_sos <= '0'; + pc_eod <= '0'; + pad_data <= '0'; + else + loadCurrentState <= loadNextState; + rst_regs <= rst_regs_comb; + rst_rem_ctr <= rst_rem_ctr_comb; + ce_rem_ctr <= ce_rem_ctr_comb; + calc_pad <= calc_pad_comb; + read_data <= read_data_comb; + data_phase <= data_phase_comb; + pc_sos <= pc_sos_comb; + pc_eod <= pc_eod_comb; + pad_data <= pad_data_comb; + end if; + end if; +end process loadMachineProc; + +loadMachine : process( loadCurrentState, sf_empty, remove_done, load_done, padding_needed, PC_READY_IN ) +begin + loadNextState <= LIDLE; + rst_regs_comb <= '0'; + rst_rem_ctr_comb <= '0'; + ce_rem_ctr_comb <= '0'; + calc_pad_comb <= '0'; + read_data_comb <= '0'; + data_phase_comb <= '0'; + pc_sos_comb <= '0'; + pc_eod_comb <= '0'; + pad_data_comb <= '0'; + case loadCurrentState is + when LIDLE => + state2 <= x"0"; + if( (sf_empty = '0') and (PC_READY_IN = '1') ) then + loadNextState <= INIT; + rst_regs_comb <= '1'; + rst_rem_ctr_comb <= '1'; + else + loadNextState <= LIDLE; + end if; + when INIT => + state2 <= x"1"; + loadNextState <= REMOVE; + ce_rem_ctr_comb <= '1'; + read_data_comb <= '1'; + when REMOVE => + state2 <= x"2"; + if( remove_done = '1' ) then + loadNextState <= CALCA; + calc_pad_comb <= '1'; + else + loadNextState <= REMOVE; + ce_rem_ctr_comb <= '1'; + read_data_comb <= '1'; + end if; + when CALCA => + state2 <= x"3"; + loadNextState <= CALCB; + when CALCB => + -- we need a branch in case of length "0"!!!! + state2 <= x"4"; + loadNextState <= LOAD; + read_data_comb <= '1'; + data_phase_comb <= '1'; + pc_sos_comb <= '1'; + when LOAD => + state2 <= x"5"; + if ( (load_done = '1') and (padding_needed = '0') ) then + loadNextState <= CLOSE; + elsif( (load_done = '1') and (padding_needed = '1') ) then + loadNextState <= PAD0; + data_phase_comb <= '1'; + else + loadNextState <= LOAD; + read_data_comb <= '1'; + data_phase_comb <= '1'; + end if; + when PAD0 => + state2 <= x"5"; + loadNextState <= PAD1; + data_phase_comb <= '1'; + pad_data_comb <= '1'; + when PAD1 => + state2 <= x"6"; + loadNextState <= PAD2; + data_phase_comb <= '1'; + pad_data_comb <= '1'; + when PAD2 => + state2 <= x"7"; + loadNextState <= PAD3; + data_phase_comb <= '1'; + pad_data_comb <= '1'; + when PAD3 => + state2 <= x"8"; + loadNextState <= CLOSE; + pad_data_comb <= '1'; + when CLOSE => + state2 <= x"9"; + loadNextState <= WAIT_PC; + pc_eod_comb <= '1'; + when WAIT_PC => + state2 <= x"a"; + if( PC_READY_IN = '1' ) then + loadNextState <= LIDLE; + rst_rem_ctr_comb <= '1'; + rst_regs_comb <= '1'; + else + loadNextState <= WAIT_PC; + end if; + when others => + state2 <= x"f"; + loadNextState <= LIDLE; + end case; +end process loadMachine; + +-- Counter for stripping the unneeded parts of the data stream, and saving the important parts +THE_REMOVE_CTR: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_rem_ctr = '1') ) then + rem_ctr <= (others => '0'); + elsif( ce_rem_ctr = '1' ) then + rem_ctr <= rem_ctr + 1; + end if; + end if; +end process THE_REMOVE_CTR; + +remove_done_comb <= '1' when ( rem_ctr = x"6" ) else '0'; + +THE_REM_DONE_SYNC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_rem_ctr = '1') ) then + remove_done <= '0'; + else + remove_done <= remove_done_comb; + end if; + end if; +end process THE_REM_DONE_SYNC; + +-- extract the trigger number from splitfifo data +THE_TRG_NR_PROC: process( CLK ) +begin + if rising_edge(CLK) then + if ( (RESET = '1') or (rst_regs = '1') ) then + pc_trig_nr <= (others => '0'); + elsif( (ce_rem_ctr = '1') and (rem_ctr = x"3") ) then + pc_trig_nr(7 downto 0) <= pc_data; + elsif( (ce_rem_ctr = '1') and (rem_ctr = x"4") ) then + pc_trig_nr(15 downto 8) <= pc_data; + end if; + end if; +end process THE_TRG_NR_PROC; + +-- check for padding +THE_PADDING_NEEDED_PROC: process( CLK ) +begin + if rising_edge(CLK) then + if ( (RESET = '1') or (rst_regs = '1') ) then + padding_needed <= '0'; + elsif( (remove_done = '1') and (pc_sub_size(2) = '1') ) then + padding_needed <= '1'; + elsif( (remove_done = '1') and (pc_sub_size(2) = '0') ) then + padding_needed <= '0'; + end if; + end if; +end process THE_PADDING_NEEDED_PROC; + +-- extract the subevent size from the splitfifo data, convert it from 32b to 8b units, +-- and in case of padding needed increase it accordingly +THE_SUB_SIZE_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_regs = '1') ) then + pc_sub_size <= (others => '0'); + elsif( (ce_rem_ctr = '1') and (rem_ctr = x"5") ) then + pc_sub_size(9 downto 2) <= pc_data; + elsif( (ce_rem_ctr = '1') and (rem_ctr = x"6") ) then + pc_sub_size(17 downto 10) <= pc_data; + elsif( (calc_pad = '1') and (padding_needed = '1') ) then + pc_sub_size <= pc_sub_size + 4; + end if; + end if; +end process THE_SUB_SIZE_PROC; + +-- number of bytes to read from split fifo +THE_READ_SIZE_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_rem_ctr = '1') ) then + read_size <= (others => '0'); + elsif( (ce_rem_ctr = '1') and (rem_ctr = x"5") ) then + read_size(9 downto 2) <= pc_data; + elsif( (ce_rem_ctr = '1') and (rem_ctr = x"6") ) then + read_size(17 downto 10) <= pc_data; + elsif( ((calc_pad = '1') and (load_done = '0')) ) then + read_size <= read_size - 2; + elsif( ((read_data = '1') and (data_phase = '1')) ) then + read_size <= read_size - 1; + end if; + end if; +end process THE_READ_SIZE_PROC; + +load_done_comb <= '1' when (read_size = 0) else '0'; + +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ + +-- Debug signals +debug(31) <= remove_done; +debug(30) <= load_done; +debug(29) <= ce_rem_ctr; +debug(28) <= rst_rem_ctr; +debug(27) <= rst_regs; +debug(26) <= data_phase; +debug(25) <= read_data; +debug(24) <= pad_data; +debug(23 downto 18) <= (others => '0'); +debug(17 downto 0) <= read_size; + +-- Outputs +FEE_READ_OUT <= fee_read; +CTS_ERROR_PATTERN_OUT <= cts_error_pattern; +CTS_DATA_OUT <= cts_data; +CTS_DATAREADY_OUT <= cts_dataready; +CTS_READOUT_FINISHED_OUT <= cts_readout_finished; +CTS_LENGTH_OUT <= cts_length; + +PC_SOS_OUT <= pc_sos; +PC_EOD_OUT <= pc_eod_q; +PC_DATA_OUT <= pc_data_q; +PC_WR_EN_OUT <= pc_wr_en_qq; +PC_TRIG_NR_OUT <= x"0000" & pc_trig_nr; +PC_SUB_SIZE_OUT <= b"0000_0000_0000_00" & pc_sub_size; +PC_PADDING_OUT <= padding_needed; + +BSM_SAVE_OUT <= state; +BSM_LOAD_OUT <= state2; +DBG_CTS_CTR_OUT <= saved_ctr(2 downto 0); +DBG_REM_CTR_OUT <= rem_ctr; +DBG_SF_DATA_OUT <= sf_data; +DBG_SF_WCNT_OUT <= sf_wcnt; +DBG_SF_RCNT_OUT <= sf_rcnt; +DBG_SF_RD_EN_OUT <= sf_rd_en; +DBG_SF_WR_EN_OUT <= sf_wr_en; +DBG_SF_EMPTY_OUT <= sf_empty; +DBG_SF_FULL_OUT <= sf_full; +DBG_SF_AFULL_OUT <= sf_afull; + +DEBUG_OUT <= debug; + +end architecture; \ No newline at end of file diff --git a/gbe2_ecp3/ip_configurator.vhd b/gbe2_ecp3/ip_configurator.vhd new file mode 100755 index 0000000..d6b0778 --- /dev/null +++ b/gbe2_ecp3/ip_configurator.vhd @@ -0,0 +1,342 @@ +LIBRARY ieee; +use ieee.std_logic_1164.all; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; +use IEEE.std_logic_arith.all; + +library work; + +entity ip_configurator is +port( + CLK : in std_logic; + RESET : in std_logic; + -- configuration interface + START_CONFIG_IN : in std_logic; -- start configuration run + BANK_SELECT_IN : in std_logic_vector(3 downto 0); -- selects config bank + CONFIG_DONE_OUT : out std_logic; -- configuration run ended, new values can be used + MEM_ADDR_OUT : out std_logic_vector(7 downto 0); -- address for + MEM_DATA_IN : in std_logic_vector(31 downto 0); -- data from IP memory + MEM_CLK_OUT : out std_logic; -- clock for BlockRAM + -- information for IP cores + DEST_MAC_OUT : out std_logic_vector(47 downto 0); -- destination MAC address + DEST_IP_OUT : out std_logic_vector(31 downto 0); -- destination IP address + DEST_UDP_OUT : out std_logic_vector(15 downto 0); -- destination port + SRC_MAC_OUT : out std_logic_vector(47 downto 0); -- source MAC address + SRC_IP_OUT : out std_logic_vector(31 downto 0); -- source IP address + SRC_UDP_OUT : out std_logic_vector(15 downto 0); -- source port + MTU_OUT : out std_logic_vector(15 downto 0); -- MTU size (max frame size) + -- Debug + DEBUG_OUT : out std_logic_vector(31 downto 0) +); +end entity; + +architecture ip_configurator of ip_configurator is + +-- -- Placer Directives +-- attribute HGROUP : string; +-- -- for whole architecture +-- attribute HGROUP of ip_configurator : architecture is "GBE_conf_group"; + +type STATES is (IDLE, LOAD_REG, DELAY0, DELAY1, DELAY2, LOAD_DONE); +signal CURRENT_STATE, NEXT_STATE : STATES; +signal bsm : std_logic_vector(3 downto 0); +signal ce_ctr_comb : std_logic; +signal ce_ctr : std_logic; +signal rst_ctr_comb : std_logic; +signal rst_ctr : std_logic; +signal cfg_done_comb : std_logic; +signal cfg_done : std_logic; + +signal ctr_done_comb : std_logic; +signal ctr_done : std_logic; + +signal wr_select_comb : std_logic_vector(15 downto 0); +signal wr_select : std_logic_vector(15 downto 0); +signal wr_select_q : std_logic_vector(15 downto 0); + +signal addr_ctr : std_logic_vector(3 downto 0); +signal dest_mac : std_logic_vector(47 downto 0); +signal dest_ip : std_logic_vector(31 downto 0); +signal dest_udp : std_logic_vector(15 downto 0); +signal src_mac : std_logic_vector(47 downto 0); +signal src_ip : std_logic_vector(31 downto 0); +signal src_udp : std_logic_vector(15 downto 0); +signal mtu : std_logic_vector(15 downto 0); + +signal debug : std_logic_vector(31 downto 0); + +begin + + +-- Statemachine for reading data payload, handling IPU channel and storing data in the SPLIT_FIFO +STATE_MACHINE_PROC: process( CLK ) +begin + if rising_edge(CLK) then + if RESET = '1' then + CURRENT_STATE <= IDLE; + ce_ctr <= '0'; + rst_ctr <= '0'; + cfg_done <= '0'; + else + CURRENT_STATE <= NEXT_STATE; + ce_ctr <= ce_ctr_comb; + rst_ctr <= rst_ctr_comb; + cfg_done <= cfg_done_comb; + end if; + end if; +end process STATE_MACHINE_PROC; + +STATE_MACHINE_TRANS: process( CURRENT_STATE, START_CONFIG_IN, ctr_done ) +begin + NEXT_STATE <= IDLE; + ce_ctr_comb <= '0'; + rst_ctr_comb <= '0'; + cfg_done_comb <= '0'; + case CURRENT_STATE is + when IDLE => + bsm <= x"0"; + if( START_CONFIG_IN = '1' ) then + NEXT_STATE <= LOAD_REG; + ce_ctr_comb <= '1'; + else + NEXT_STATE <= IDLE; + end if; + when LOAD_REG => + bsm <= x"1"; + if( ctr_done = '1' ) then + NEXT_STATE <= DELAY0; + rst_ctr_comb <= '1'; + else + NEXT_STATE <= LOAD_REG; + ce_ctr_comb <= '1'; + end if; + when DELAY0 => + bsm <= x"2"; + NEXT_STATE <= DELAY1; + when DELAY1 => + bsm <= x"3"; + NEXT_STATE <= DELAY2; + when DELAY2 => + bsm <= x"4"; + NEXT_STATE <= LOAD_DONE; + cfg_done_comb <= '1'; + when LOAD_DONE => + bsm <= x"2"; + if( START_CONFIG_IN = '0' ) then + NEXT_STATE <= IDLE; + else + NEXT_STATE <= LOAD_DONE; + cfg_done_comb <= '1'; + end if; + when others => + bsm <= x"f"; + NEXT_STATE <= IDLE; + end case; +end process STATE_MACHINE_TRANS; + +-- address counter +THE_ADDR_CTR_PROC: process( CLK ) +begin + if ( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_ctr = '1') ) then + addr_ctr <= (others => '0'); + elsif( ce_ctr = '1' ) then + addr_ctr <= addr_ctr + 1; + end if; + end if; +end process THE_ADDR_CTR_PROC; + +ctr_done_comb <= '1' when (addr_ctr = x"e") else '0'; + +THE_SYNC_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + ctr_done <= ctr_done_comb; + wr_select_q <= wr_select; + wr_select <= wr_select_comb; + end if; +end process THE_SYNC_PROC; + +-- generate combinatorial write select signals, register and delay the (output registers in EBR!) +wr_select_comb(0) <= '1' when ( (ce_ctr = '1') and (addr_ctr = x"0") ) else '0'; -- dest MAC low +wr_select_comb(1) <= '1' when ( (ce_ctr = '1') and (addr_ctr = x"1") ) else '0'; -- dest MAC high +wr_select_comb(2) <= '1' when ( (ce_ctr = '1') and (addr_ctr = x"2") ) else '0'; -- dest IP +wr_select_comb(3) <= '1' when ( (ce_ctr = '1') and (addr_ctr = x"3") ) else '0'; -- dest port +wr_select_comb(4) <= '1' when ( (ce_ctr = '1') and (addr_ctr = x"4") ) else '0'; -- src MAC low +wr_select_comb(5) <= '1' when ( (ce_ctr = '1') and (addr_ctr = x"5") ) else '0'; -- src MAC high +wr_select_comb(6) <= '1' when ( (ce_ctr = '1') and (addr_ctr = x"6") ) else '0'; -- src IP +wr_select_comb(7) <= '1' when ( (ce_ctr = '1') and (addr_ctr = x"7") ) else '0'; -- src port +wr_select_comb(8) <= '1' when ( (ce_ctr = '1') and (addr_ctr = x"8") ) else '0'; -- MTU +wr_select_comb(9) <= '1' when ( (ce_ctr = '1') and (addr_ctr = x"9") ) else '0'; +wr_select_comb(10) <= '1' when ( (ce_ctr = '1') and (addr_ctr = x"a") ) else '0'; +wr_select_comb(11) <= '1' when ( (ce_ctr = '1') and (addr_ctr = x"b") ) else '0'; +wr_select_comb(12) <= '1' when ( (ce_ctr = '1') and (addr_ctr = x"c") ) else '0'; +wr_select_comb(13) <= '1' when ( (ce_ctr = '1') and (addr_ctr = x"d") ) else '0'; +wr_select_comb(14) <= '1' when ( (ce_ctr = '1') and (addr_ctr = x"e") ) else '0'; +wr_select_comb(15) <= '1' when ( (ce_ctr = '1') and (addr_ctr = x"f") ) else '0'; + +-- destination MAC low register +THE_D_MAC_LOW_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( RESET = '1' ) then + dest_mac(31 downto 0) <= (others => '0'); + elsif( wr_select_q(0) = '1') then + dest_mac(31 downto 0) <= mem_data_in; + end if; + end if; +end process THE_D_MAC_LOW_PROC; + +-- destination MAC high register +THE_D_MAC_HIGH_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( RESET = '1' ) then + dest_mac(47 downto 32) <= (others => '0'); + elsif( wr_select_q(1) = '1') then + dest_mac(47 downto 32) <= mem_data_in(15 downto 0); + end if; + end if; +end process THE_D_MAC_HIGH_PROC; + +-- destination IP register +THE_D_IP_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( RESET = '1' ) then + dest_ip <= (others => '0'); + elsif( wr_select_q(2) = '1') then + dest_ip <= mem_data_in; + end if; + end if; +end process THE_D_IP_PROC; + +-- destination PORT register +THE_D_PORT_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( RESET = '1' ) then + dest_udp <= (others => '0'); + elsif( wr_select_q(3) = '1') then + dest_udp <= mem_data_in(15 downto 0); + end if; + end if; +end process THE_D_PORT_PROC; + +-- source MAC low register +THE_S_MAC_LOW_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( RESET = '1' ) then + src_mac(31 downto 0) <= (others => '0'); + elsif( wr_select_q(4) = '1') then + src_mac(31 downto 0) <= mem_data_in; + end if; + end if; +end process THE_S_MAC_LOW_PROC; + +-- source MAC high register +THE_S_MAC_HIGH_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( RESET = '1' ) then + src_mac(47 downto 32) <= (others => '0'); + elsif( wr_select_q(5) = '1') then + src_mac(47 downto 32) <= mem_data_in(15 downto 0); + end if; + end if; +end process THE_S_MAC_HIGH_PROC; + +-- source IP register +THE_S_IP_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( RESET = '1' ) then + src_ip <= (others => '0'); + elsif( wr_select_q(6) = '1') then + src_ip <= mem_data_in; + end if; + end if; +end process THE_S_IP_PROC; + +-- source PORT register +THE_S_PORT_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( RESET = '1' ) then + src_udp <= (others => '0'); + elsif( wr_select_q(7) = '1') then + src_udp <= mem_data_in(15 downto 0); + end if; + end if; +end process THE_S_PORT_PROC; + +-- MTU size register +THE_MTU_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( RESET = '1' ) then + mtu <= (others => '0'); + elsif( wr_select_q(8) = '1') then + mtu <= mem_data_in(15 downto 0); + end if; + end if; +end process THE_MTU_PROC; + + +-- Debug signals +debug(31 downto 12) <= (others => '0'); +debug(11 downto 8) <= addr_ctr; +debug(7) <= '0'; +debug(6) <= ctr_done; +debug(5) <= ce_ctr; +debug(4) <= rst_ctr; +debug(3 downto 0) <= bsm; +-- Outputs +MEM_ADDR_OUT(7 downto 4) <= BANK_SELECT_IN; +MEM_ADDR_OUT(3 downto 0) <= addr_ctr; +MEM_CLK_OUT <= CLK; +CONFIG_DONE_OUT <= cfg_done; + +-- destination MAC address - swap for user convinience +DEST_MAC_OUT(47 downto 40) <= dest_mac(7 downto 0); +DEST_MAC_OUT(39 downto 32) <= dest_mac(15 downto 8); +DEST_MAC_OUT(31 downto 24) <= dest_mac(23 downto 16); +DEST_MAC_OUT(23 downto 16) <= dest_mac(31 downto 24); +DEST_MAC_OUT(15 downto 8) <= dest_mac(39 downto 32); +DEST_MAC_OUT(7 downto 0) <= dest_mac(47 downto 40); + +-- destination IP address - swap for user convinience +DEST_IP_OUT(31 downto 24) <= dest_ip(7 downto 0); +DEST_IP_OUT(23 downto 16) <= dest_ip(15 downto 8); +DEST_IP_OUT(15 downto 8) <= dest_ip(23 downto 16); +DEST_IP_OUT(7 downto 0) <= dest_ip(31 downto 24); + +-- destination port address - swap for user convinience +DEST_UDP_OUT(15 downto 8) <= dest_udp(7 downto 0); +DEST_UDP_OUT(7 downto 0) <= dest_udp(15 downto 8); + +-- source MAC address - swap for user convinience +SRC_MAC_OUT(47 downto 40) <= src_mac(7 downto 0); +SRC_MAC_OUT(39 downto 32) <= src_mac(15 downto 8); +SRC_MAC_OUT(31 downto 24) <= src_mac(23 downto 16); +SRC_MAC_OUT(23 downto 16) <= src_mac(31 downto 24); +SRC_MAC_OUT(15 downto 8) <= src_mac(39 downto 32); +SRC_MAC_OUT(7 downto 0) <= src_mac(47 downto 40); + +-- source IP address - swap for user convinience +SRC_IP_OUT(31 downto 24) <= src_ip(7 downto 0); +SRC_IP_OUT(23 downto 16) <= src_ip(15 downto 8); +SRC_IP_OUT(15 downto 8) <= src_ip(23 downto 16); +SRC_IP_OUT(7 downto 0) <= src_ip(31 downto 24); + +-- source port address - swap for user convinience +SRC_UDP_OUT(15 downto 8) <= src_udp(7 downto 0); +SRC_UDP_OUT(7 downto 0) <= src_udp(15 downto 8); + +-- DO NOT SWAP! +MTU_OUT <= mtu; + +DEBUG_OUT <= debug; + +end architecture; \ No newline at end of file diff --git a/gbe2_ecp3/mb_mac_sim.vhd b/gbe2_ecp3/mb_mac_sim.vhd new file mode 100755 index 0000000..1b1f57e --- /dev/null +++ b/gbe2_ecp3/mb_mac_sim.vhd @@ -0,0 +1,331 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; +use IEEE.std_logic_arith.all; + +library work; +--use work.trb_net_std.all; +--use work.trb_net_components.all; +--use work.trb_net16_hub_func.all; + +entity mb_mac_sim is +port ( + -------------------------------------------------------------------------- + --------------- clock, reset, clock enable ------------------------------- + HCLK : in std_logic; + TX_MAC_CLK : in std_logic; + RX_MAC_CLK : in std_logic; + RESET_N : in std_logic; + TXMAC_CLK_EN : in std_logic; + RXMAC_CLK_EN : in std_logic; + -------------------------------------------------------------------------- + --------------- SGMII receive interface ---------------------------------- + RXD : in std_logic_vector(7 downto 0); + RX_DV : in std_logic; + RX_ER : in std_logic; + COL : in std_logic; + CRS : in std_logic; + -------------------------------------------------------------------------- + --------------- SGMII transmit interface --------------------------------- + TXD : out std_logic_vector(7 downto 0); + TX_EN : out std_logic; + TX_ER : out std_logic; + -------------------------------------------------------------------------- + --------------- CPU configuration interface ------------------------------ + HADDR : in std_logic_vector(7 downto 0); + HDATAIN : in std_logic_vector(7 downto 0); + HCS_N : in std_logic; + HWRITE_N : in std_logic; + HREAD_N : in std_logic; + HDATAOUT : out std_logic_vector(7 downto 0); + HDATAOUT_EN_N : out std_logic; + HREADY_N : out std_logic; + CPU_IF_GBIT_EN : out std_logic; + -------------------------------------------------------------------------- + --------------- Transmit FIFO interface ---------------------------------- + TX_FIFODATA : in std_logic_vector(7 downto 0); + TX_FIFOAVAIL : in std_logic; + TX_FIFOEOF : in std_logic; + TX_FIFOEMPTY : in std_logic; + TX_MACREAD : out std_logic; + TX_DONE : out std_logic; + TX_SNDPAUSTIM : in std_logic_vector(15 downto 0); + TX_SNDPAUSREQ : in std_logic; + TX_FIFOCTRL : in std_logic; + TX_DISCFRM : out std_logic; + TX_STATEN : out std_logic; + TX_STATVEC : out std_logic_vector(30 downto 0); + -------------------------------------------------------------------------- + --------------- Receive FIFO interface ----------------------------------- + RX_DBOUT : out std_logic_vector(7 downto 0); + RX_FIFO_FULL : in std_logic; + IGNORE_PKT : in std_logic; + RX_FIFO_ERROR : out std_logic; + RX_STAT_VECTOR : out std_logic_vector(31 downto 0); + RX_STAT_EN : out std_logic; + RX_WRITE : out std_logic; + RX_EOF : out std_logic; + RX_ERROR : out std_logic +); +end mb_mac_sim; + +architecture mb_mac_sim of mb_mac_sim is + + +-- CPU interface stuff +type HC_STATES is (HC_SLEEP, HC_READ, HC_WRITE, HC_RACK, HC_WACK); +signal HC_CURRENT_STATE, HC_NEXT_STATE: HC_STATES; + +signal hready_n_comb : std_logic; +signal hready_n_buf : std_logic; +signal hdataout_en_n_comb : std_logic; +signal hdataout_en_n_buf : std_logic; + +-- TX stuff +type TX_STATES is (TX_SLEEP, TX_READ, TX_DELAY, TX_TRANS, TX_CHECK); +signal TX_CURRENT_STATE, TX_NEXT_STATE: TX_STATES; + +signal tx_bsm : std_logic_vector(3 downto 0); +signal tx_macread_comb : std_logic; +signal tx_done_comb : std_logic; +signal tx_done_buf : std_logic; + +signal preread_ctr : std_logic_vector(3 downto 0); -- preread counter for TX +signal preread_ce_comb : std_logic; +signal preread_rst_comb : std_logic; +signal preread_done_comb : std_logic; +signal read_on_comb : std_logic; + + +begin + +------------------------------------------------------------------------------ +-- state machine for configuration interface +------------------------------------------------------------------------------ +-- BUG: no register simulated here! + +-- state registers +HC_STATE_MEM: process( HCLK ) +begin + if ( RESET_N = '0' ) then + HC_CURRENT_STATE <= HC_SLEEP; + hready_n_buf <= '1'; + hdataout_en_n_buf <= '1'; + elsif( rising_edge(HCLK) ) then + HC_CURRENT_STATE <= HC_NEXT_STATE; + hready_n_buf <= hready_n_comb; + hdataout_en_n_buf <= hdataout_en_n_comb; + end if; +end process HC_STATE_MEM; + +-- state transitions +HC_STATE_TRANSFORM: process( HC_CURRENT_STATE, HCS_N, HREAD_N, HWRITE_N ) +begin + HC_NEXT_STATE <= HC_SLEEP; -- avoid latches + hready_n_comb <= '1'; + hdataout_en_n_comb <= '1'; + case HC_CURRENT_STATE is + when HC_SLEEP => if ( (HCS_N = '0') and (HREAD_N = '0') ) then + HC_NEXT_STATE <= HC_READ; + elsif( (HCS_N = '0') and (HWRITE_N = '0') ) then + HC_NEXT_STATE <= HC_WRITE; + else + HC_NEXT_STATE <= HC_SLEEP; + end if; + when HC_READ => HC_NEXT_STATE <= HC_RACK; + hdataout_en_n_comb <= '0'; + hready_n_comb <= '0'; + when HC_RACK => HC_NEXT_STATE <= HC_SLEEP; + when HC_WRITE => HC_NEXT_STATE <= HC_WACK; + hready_n_comb <= '0'; + when HC_WACK => HC_NEXT_STATE <= HC_SLEEP; + when others => HC_NEXT_STATE <= HC_SLEEP; + end case; +end process HC_STATE_TRANSFORM; + +HREADY_N <= hready_n_buf; +HDATAOUT_EN_N <= hdataout_en_n_buf; + +------------------------------------------------------------------------------ +-- state machine for "transmission" +------------------------------------------------------------------------------ + +-- preread counter +THE_PREREAD_CTR: process( TX_MAC_CLK ) +begin + if ( RESET_N = '0' ) then + preread_ctr <= (others => '0'); + elsif( rising_edge(TX_MAC_CLK) ) then + if ( preread_rst_comb = '1' ) then + preread_ctr <= (others => '0'); + elsif( preread_ce_comb = '1' ) then + preread_ctr <= preread_ctr + 1; + end if; + end if; +end process THE_PREREAD_CTR; +preread_done_comb <= '1' when (preread_ctr = x"6") + else '0'; + +-- state registers +TX_STATE_MEM: process( TX_MAC_CLK, RESET_N ) +begin + if ( RESET_N = '0' ) then + TX_CURRENT_STATE <= TX_SLEEP; + tx_done_buf <= '0'; + elsif( rising_edge(TX_MAC_CLK) ) then + TX_CURRENT_STATE <= TX_NEXT_STATE; + tx_done_buf <= tx_done_comb; + end if; +end process TX_STATE_MEM; + +tx_macread_comb <= preread_ce_comb or read_on_comb; + +-- state transitions +TX_STATE_TRANSFORM: process( TX_CURRENT_STATE, TX_FIFOEMPTY, TX_FIFOAVAIL, TX_FIFOEOF, preread_done_comb ) +begin + TX_NEXT_STATE <= TX_SLEEP; -- avoid latches + preread_ce_comb <= '0'; + preread_rst_comb <= '0'; + read_on_comb <= '0'; + tx_done_comb <= '0'; + case TX_CURRENT_STATE is + when TX_SLEEP => tx_bsm <= x"0"; + if( TX_FIFOEMPTY = '0' ) then + TX_NEXT_STATE <= TX_READ; + preread_ce_comb <= '1'; + else + TX_NEXT_STATE <= TX_SLEEP; + end if; + when TX_READ => tx_bsm <= x"1"; + if ( TX_FIFOEMPTY = '1' ) then + TX_NEXT_STATE <= TX_DELAY; + preread_rst_comb <= '1'; + elsif( (preread_done_comb = '1') and (TX_FIFOAVAIL = '0') ) then + TX_NEXT_STATE <= TX_DELAY; + preread_rst_comb <= '1'; + elsif( (preread_done_comb = '1') and (TX_FIFOAVAIL = '1') ) then + TX_NEXT_STATE <= TX_TRANS; + preread_rst_comb <= '1'; + read_on_comb <= '1'; + else + TX_NEXT_STATE <= TX_READ; + preread_ce_comb <= '1'; + end if; + when TX_DELAY => tx_bsm <= x"2"; + if( TX_FIFOAVAIL = '1' ) then + TX_NEXT_STATE <= TX_TRANS; + read_on_comb <= '1'; + else + TX_NEXT_STATE <= TX_DELAY; + end if; + when TX_TRANS => tx_bsm <= x"3"; + if( TX_FIFOEOF = '1' ) then + TX_NEXT_STATE <= TX_CHECK; + tx_done_comb <= '1'; -- don't know if this is realistic + else + TX_NEXT_STATE <= TX_TRANS; + read_on_comb <= '1'; + end if; + when TX_CHECK => tx_bsm <= x"4"; + if( (TX_FIFOEMPTY = '0') and (TX_FIFOAVAIL = '1') ) then + TX_NEXT_STATE <= TX_READ; + preread_ce_comb <= '1'; + else + TX_NEXT_STATE <= TX_SLEEP; + end if; + when others => tx_bsm <= x"f"; + TX_NEXT_STATE <= TX_SLEEP; + end case; +end process TX_STATE_TRANSFORM; + + + + +------------------------------------------------------------------------------ +-- Fake signals +------------------------------------------------------------------------------ +RX_DBOUT <= preread_ctr & tx_bsm; -- x"00"; +RX_FIFO_ERROR <= '0'; +RX_STAT_VECTOR <= x"0000_0000"; +RX_STAT_EN <= '0'; +RX_WRITE <= '0'; +RX_EOF <= '0'; +RX_ERROR <= '0'; + +TX_DISCFRM <= '0'; +TX_EN <= '0'; +TX_ER <= '0'; +TX_STATVEC <= (others => '0'); +TX_STATEN <= '0'; +TXD <= x"00"; + +CPU_IF_GBIT_EN <= '0'; + +TX_DONE <= tx_done_buf; +TX_MACREAD <= tx_macread_comb; + +HDATAOUT <= x"00"; + + +end mb_mac_sim; + + +--port map( +-- -------------------------------------------------------------------------- +-- --------------- clock, reset, clock enable ------------------------------- +-- hclk => CLK, -- (in) host clock (100MHz) +-- txmac_clk => TX_MAC_CLK, -- (in) GbE clock (125MHz) +-- rxmac_clk => '0', -- (in) not used (no receiving on GbE) +-- reset_n => GSR_N, -- (in) global set/reset +-- txmac_clk_en => TSM_TX_CLK_EN_IN, -- (in) from SGMII core, '1' for 1GbE operation +-- rxmac_clk_en => TSM_RX_CLK_EN_IN, -- (in) from SGMII core, '1' for 1GbE operation +-- -------------------------------------------------------------------------- +-- --------------- SGMII receive interface ---------------------------------- +-- rxd => x"00", -- (in) receive data from SGMII core +-- rx_dv => '0', -- (in) data valid from SGMII core +-- rx_er => '0', -- (in) receive data error +-- col => TSM_COL_IN, -- (in) collision from SGMII core +-- crs => TSM_CRS_IN, -- (in) carrier sense from SGMII core +-- -------------------------------------------------------------------------- +-- --------------- SGMII transmit interface --------------------------------- +-- txd => CH_TXD_OUT, -- (out) transmit data to SGMII core +-- tx_en => CH_TX_EN_OUT, -- (out) transmit enable +-- tx_er => CH_TX_ER_OUT, -- (out) transmit error +-- -------------------------------------------------------------------------- +-- --------------- CPU configuration interface ------------------------------ +-- haddr => haddr, -- (in) host address bus for configuration +-- hdatain => hdataout, -- (in) host data bus for write accesses +-- hcs_n => hcs, -- (in) host chip select signal +-- hwrite_n => hwrite, -- (in) host write strobe signal +-- hread_n => hread, -- (in) host read strobe signal +-- hdataout => hdatain, -- (out) host data bus for read accesses +-- hdataout_en_n => hdataout_en, -- (out) read data valid signal +-- hready_n => hready, -- (out) data acknowledge signal +-- cpu_if_gbit_en => open, -- (out) status bit +-- -------------------------------------------------------------------------- +-- --------------- Transmit FIFO interface ---------------------------------- +-- tx_fifodata => ft_data(7 downto 0), -- (in) transmit FIFO data bus +-- tx_fifoavail => mac_fifoavail, -- (in) transmit FIFO data available +-- tx_fifoeof => mac_fifoeof, -- (in) transmit FIFO end of frame +-- tx_fifoempty => mac_fifoempty, -- (in) transmit FIFO empty +-- tx_macread => mac_tx_rd_en, -- (out) transmit FIFO read +-- tx_done => mac_tx_done, -- (out) transmit done (without errors) +-- tx_sndpaustim => x"0000", -- (in) PAUSE frame timer +-- tx_sndpausreq => '0', -- (in) PAUSE frame request +-- tx_fifoctrl => '0', -- (in) FIFO control frame ('0' = data, '1' = control) +-- tx_discfrm => open, -- (out) discard frame +-- tx_staten => open, -- (out) transmit statistics vector enable +-- tx_statvec => open, -- (out) transmit statistics vector +-- -------------------------------------------------------------------------- +-- --------------- Receive FIFO interface ----------------------------------- +-- rx_dbout => open, -- (out) receive FIFO data output +-- rx_fifo_full => '0', -- (in) receive FIFO full +-- ignore_pkt => '0', -- (in) ignore next packet +-- rx_fifo_error => open, -- (out) receive FIFO error +-- rx_stat_vector => open, -- (out) receive statistics vector +-- rx_stat_en => open, -- (out) receive statistics vector enable +-- rx_write => open, -- (out) receive FIFO write +-- rx_eof => open, -- (out) end of frame +-- rx_error => open -- (out) receive packet error +--); diff --git a/gbe2_ecp3/slv_mac_memory.vhd b/gbe2_ecp3/slv_mac_memory.vhd new file mode 100755 index 0000000..bd74e03 --- /dev/null +++ b/gbe2_ecp3/slv_mac_memory.vhd @@ -0,0 +1,178 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +library work; + +entity slv_mac_memory is +port( + CLK : in std_logic; + RESET : in std_logic; + BUSY_IN : in std_logic; + -- Slave bus + SLV_ADDR_IN : in std_logic_vector(7 downto 0); + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_BUSY_OUT : out std_logic; + SLV_ACK_OUT : out std_logic; + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + -- I/O to the backend + MEM_CLK_IN : in std_logic; + MEM_ADDR_IN : in std_logic_vector(7 downto 0); + MEM_DATA_OUT : out std_logic_vector(31 downto 0); + -- Status lines + STAT : out std_logic_vector(31 downto 0) -- DEBUG +); +end entity; + +architecture Behavioral of slv_mac_memory is + +component ip_mem is +port( + DataInA : in std_logic_vector(31 downto 0); + DataInB : in std_logic_vector(31 downto 0); + AddressA : in std_logic_vector(7 downto 0); + AddressB : in std_logic_vector(7 downto 0); + ClockA : in std_logic; + ClockB : in std_logic; + ClockEnA : in std_logic; + ClockEnB : in std_logic; + WrA : in std_logic; + WrB : in std_logic; + ResetA : in std_logic; + ResetB : in std_logic; + QA : out std_logic_vector(31 downto 0); + QB : out std_logic_vector(31 downto 0) +); +end component ip_mem; + +-- Signals +type STATES is (SLEEP,RD_BSY,WR_BSY,RD_RDY,WR_RDY,RD_ACK,WR_ACK,DONE); +signal CURRENT_STATE, NEXT_STATE: STATES; + +-- slave bus signals +signal slv_busy_x : std_logic; +signal slv_busy : std_logic; +signal slv_ack_x : std_logic; +signal slv_ack : std_logic; +signal store_wr_x : std_logic; +signal store_wr : std_logic; +signal store_rd_x : std_logic; +signal store_rd : std_logic; + +signal reg_busy : std_logic; + +begin + +-- Fake +reg_busy <= busy_in; +stat <= (others => '0'); + +--------------------------------------------------------- +-- Statemachine -- +--------------------------------------------------------- +-- State memory process +STATE_MEM: process( clk ) +begin + if( rising_edge(clk) ) then + if( reset = '1' ) then + CURRENT_STATE <= SLEEP; + slv_busy <= '0'; + slv_ack <= '0'; + store_wr <= '0'; + store_rd <= '0'; + else + CURRENT_STATE <= NEXT_STATE; + slv_busy <= slv_busy_x; + slv_ack <= slv_ack_x; + store_wr <= store_wr_x; + store_rd <= store_rd_x; + end if; + end if; +end process STATE_MEM; + +-- Transition matrix +TRANSFORM: process(CURRENT_STATE, slv_read_in, slv_write_in, reg_busy ) +begin + NEXT_STATE <= SLEEP; + slv_busy_x <= '0'; + slv_ack_x <= '0'; + store_wr_x <= '0'; + store_rd_x <= '0'; + case CURRENT_STATE is + when SLEEP => if ( (reg_busy = '0') and (slv_read_in = '1') ) then + NEXT_STATE <= RD_RDY; + store_rd_x <= '1'; + elsif( (reg_busy = '0') and (slv_write_in = '1') ) then + NEXT_STATE <= WR_RDY; + store_wr_x <= '1'; + elsif( (reg_busy = '1') and (slv_read_in = '1') ) then + NEXT_STATE <= RD_BSY; + elsif( (reg_busy = '1') and (slv_write_in = '1') ) then + NEXT_STATE <= WR_BSY; + else + NEXT_STATE <= SLEEP; + end if; + when RD_RDY => NEXT_STATE <= RD_ACK; + when WR_RDY => NEXT_STATE <= WR_ACK; + when RD_ACK => if( slv_read_in = '0' ) then + NEXT_STATE <= DONE; + slv_ack_x <= '1'; + else + NEXT_STATE <= RD_ACK; + slv_ack_x <= '1'; + end if; + when WR_ACK => if( slv_write_in = '0' ) then + NEXT_STATE <= DONE; + slv_ack_x <= '1'; + else + NEXT_STATE <= WR_ACK; + slv_ack_x <= '1'; + end if; + when RD_BSY => if( slv_read_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= RD_BSY; + slv_busy_x <= '1'; + end if; + when WR_BSY => if( slv_write_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= WR_BSY; + slv_busy_x <= '1'; + end if; + when DONE => NEXT_STATE <= SLEEP; + + when others => NEXT_STATE <= SLEEP; + end case; +end process TRANSFORM; + +--------------------------------------------------------- +-- data handling -- +--------------------------------------------------------- + +THE_MAC_MEM: ip_mem +port map( + DataInA => slv_data_in, + AddressA => slv_addr_in, + ClockA => clk, + ClockEnA => '1', + QA => slv_data_out, + WrA => store_wr, + ResetA => reset, + DataInB => x"0000_0000", + AddressB => mem_addr_in, + ClockB => mem_clk_in, + ClockEnB => '1', + WrB => '0', -- never write + ResetB => reset, + QB => mem_data_out +); + +-- output signals +slv_ack_out <= slv_ack; +slv_busy_out <= slv_busy; + +end Behavioral; diff --git a/gbe2_ecp3/slv_register.vhd b/gbe2_ecp3/slv_register.vhd new file mode 100755 index 0000000..763550b --- /dev/null +++ b/gbe2_ecp3/slv_register.vhd @@ -0,0 +1,177 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +library work; +--use work.adcmv3_components.all; + + +entity slv_register is +generic( RESET_VALUE : std_logic_vector(31 downto 0) := x"0000_0000" ); +port( CLK_IN : in std_logic; + RESET_IN : in std_logic; + BUSY_IN : in std_logic; + -- Slave bus + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_BUSY_OUT : out std_logic; + SLV_ACK_OUT : out std_logic; + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + -- I/O to the backend + REG_DATA_IN : in std_logic_vector(31 downto 0); + REG_DATA_OUT : out std_logic_vector(31 downto 0); + -- Status lines + STAT : out std_logic_vector(31 downto 0) -- DEBUG + ); +end entity; + +architecture Behavioral of slv_register is + +-- Signals + + type STATES is (SLEEP,RD_BSY,WR_BSY,RD_RDY,WR_RDY,RD_ACK,WR_ACK,DONE); + signal CURRENT_STATE, NEXT_STATE: STATES; + + -- slave bus signals + signal slv_busy_x : std_logic; + signal slv_busy : std_logic; + signal slv_ack_x : std_logic; + signal slv_ack : std_logic; + signal store_wr_x : std_logic; + signal store_wr : std_logic; + signal store_rd_x : std_logic; + signal store_rd : std_logic; + + signal reg_slv_data_in : std_logic_vector(31 downto 0); -- registered data input + signal reg_slv_data_out : std_logic_vector(31 downto 0); -- read back data + signal reg_busy : std_logic; + +begin + +-- Fake +reg_busy <= busy_in; +stat <= (others => '0'); + +--------------------------------------------------------- +-- Statemachine -- +--------------------------------------------------------- +-- State memory process +STATE_MEM: process( clk_in ) +begin + if( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + CURRENT_STATE <= SLEEP; + slv_busy <= '0'; + slv_ack <= '0'; + store_wr <= '0'; + store_rd <= '0'; + else + CURRENT_STATE <= NEXT_STATE; + slv_busy <= slv_busy_x; + slv_ack <= slv_ack_x; + store_wr <= store_wr_x; + store_rd <= store_rd_x; + end if; + end if; +end process STATE_MEM; + +-- Transition matrix +TRANSFORM: process(CURRENT_STATE, slv_read_in, slv_write_in, reg_busy ) +begin + NEXT_STATE <= SLEEP; + slv_busy_x <= '0'; + slv_ack_x <= '0'; + store_wr_x <= '0'; + store_rd_x <= '0'; + case CURRENT_STATE is + when SLEEP => if ( (reg_busy = '0') and (slv_read_in = '1') ) then + NEXT_STATE <= RD_RDY; + store_rd_x <= '1'; + elsif( (reg_busy = '0') and (slv_write_in = '1') ) then + NEXT_STATE <= WR_RDY; + store_wr_x <= '1'; + elsif( (reg_busy = '1') and (slv_read_in = '1') ) then + NEXT_STATE <= RD_BSY; + slv_busy_x <= '1'; -- added 23022009 + elsif( (reg_busy = '1') and (slv_write_in = '1') ) then + NEXT_STATE <= WR_BSY; + slv_busy_x <= '1'; -- added 23022009 + else + NEXT_STATE <= SLEEP; + end if; + when RD_RDY => NEXT_STATE <= RD_ACK; + slv_ack_x <= '1'; + when WR_RDY => NEXT_STATE <= WR_ACK; + slv_ack_x <= '1'; + when RD_ACK => if( slv_read_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= RD_ACK; + slv_ack_x <= '1'; + end if; + when WR_ACK => if( slv_write_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= WR_ACK; + slv_ack_x <= '1'; + end if; + when RD_BSY => if( slv_read_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= RD_BSY; + slv_busy_x <= '1'; + end if; + when WR_BSY => if( slv_write_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= WR_BSY; + slv_busy_x <= '1'; + end if; + when DONE => NEXT_STATE <= SLEEP; + + when others => NEXT_STATE <= SLEEP; + end case; +end process TRANSFORM; + +--------------------------------------------------------- +-- data handling -- +--------------------------------------------------------- + +-- register write +THE_WRITE_REG_PROC: process( clk_in ) +begin + if( rising_edge(clk_in) ) then + if ( reset_in = '1' ) then + reg_slv_data_in <= RESET_VALUE; + elsif( store_wr = '1' ) then + reg_slv_data_in <= slv_data_in; + end if; + end if; +end process THE_WRITE_REG_PROC; + +-- register read +THE_READ_REG_PROC: process( clk_in ) +begin + if( rising_edge(clk_in) ) then + if ( reset_in = '1' ) then + reg_slv_data_out <= (others => '0'); + elsif( store_rd = '1' ) then + reg_slv_data_out <= reg_data_in; + end if; + end if; +end process THE_READ_REG_PROC; + +-- output signals +slv_ack_out <= slv_ack; +slv_busy_out <= slv_busy; +slv_data_out <= reg_slv_data_out; + +--------------------------------------------------------- +-- signals to backend -- +--------------------------------------------------------- + +reg_data_out <= reg_slv_data_in; + +end Behavioral; diff --git a/gbe2_ecp3/tb_feeder.vhd b/gbe2_ecp3/tb_feeder.vhd new file mode 100755 index 0000000..d526404 --- /dev/null +++ b/gbe2_ecp3/tb_feeder.vhd @@ -0,0 +1,300 @@ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY testbench IS +END testbench; + +ARCHITECTURE behavior OF testbench IS + + COMPONENT feeder + PORT( + CLK : IN std_logic; + RESET : IN std_logic; + CTS_NUMBER_IN : IN std_logic_vector(15 downto 0); + CTS_CODE_IN : IN std_logic_vector(7 downto 0); + CTS_INFORMATION_IN : IN std_logic_vector(7 downto 0); + CTS_READOUT_TYPE_IN : IN std_logic_vector(3 downto 0); + CTS_START_READOUT_IN : IN std_logic; + CTS_READ_IN : IN std_logic; + FEE_DATA_IN : IN std_logic_vector(15 downto 0); + FEE_DATAREADY_IN : IN std_logic; + FEE_BUSY_IN : IN std_logic; + FEE_STATUS_BITS_IN : IN std_logic_vector(31 downto 0); + PC_READY_IN : IN std_logic; + CTS_DATA_OUT : OUT std_logic_vector(31 downto 0); + CTS_DATAREADY_OUT : OUT std_logic; + CTS_READOUT_FINISHED_OUT : OUT std_logic; + CTS_LENGTH_OUT : OUT std_logic_vector(15 downto 0); + CTS_ERROR_PATTERN_OUT : OUT std_logic_vector(31 downto 0); + FEE_READ_OUT : OUT std_logic; + PC_WR_EN_OUT : OUT std_logic; + PC_DATA_OUT : OUT std_logic_vector(7 downto 0); + PC_SOS_OUT : OUT std_logic; + PC_EOD_OUT : OUT std_logic; + PC_SUB_SIZE_OUT : OUT std_logic_vector(31 downto 0); + PC_TRIG_NR_OUT : OUT std_logic_vector(31 downto 0); + PC_PADDING_OUT : OUT std_logic; + BSM_SAVE_OUT : OUT std_logic_vector(3 downto 0); + BSM_LOAD_OUT : OUT std_logic_vector(3 downto 0); + DBG_REM_CTR_OUT : OUT std_logic_vector(3 downto 0); + DBG_CTS_CTR_OUT : OUT std_logic_vector(2 downto 0); + DBG_SF_WCNT_OUT : OUT std_logic_vector(15 downto 0); + DBG_SF_RCNT_OUT : OUT std_logic_vector(16 downto 0); + DBG_SF_DATA_OUT : OUT std_logic_vector(15 downto 0); + DBG_SF_RD_EN_OUT : OUT std_logic; + DBG_SF_WR_EN_OUT : OUT std_logic; + DBG_SF_EMPTY_OUT : OUT std_logic; + DBG_SF_FULL_OUT : OUT std_logic; + DBG_SF_AFULL_OUT : OUT std_logic; + DEBUG_OUT : OUT std_logic_vector(31 downto 0) + ); + END COMPONENT; + + SIGNAL CLK : std_logic; + SIGNAL RESET : std_logic; + SIGNAL CTS_NUMBER_IN : std_logic_vector(15 downto 0); + SIGNAL CTS_CODE_IN : std_logic_vector(7 downto 0); + SIGNAL CTS_INFORMATION_IN : std_logic_vector(7 downto 0); + SIGNAL CTS_READOUT_TYPE_IN : std_logic_vector(3 downto 0); + SIGNAL CTS_START_READOUT_IN : std_logic; + SIGNAL CTS_READ_IN : std_logic; + SIGNAL CTS_DATA_OUT : std_logic_vector(31 downto 0); + SIGNAL CTS_DATAREADY_OUT : std_logic; + SIGNAL CTS_READOUT_FINISHED_OUT : std_logic; + SIGNAL CTS_LENGTH_OUT : std_logic_vector(15 downto 0); + SIGNAL CTS_ERROR_PATTERN_OUT : std_logic_vector(31 downto 0); + SIGNAL FEE_DATA_IN : std_logic_vector(15 downto 0); + SIGNAL FEE_DATAREADY_IN : std_logic; + SIGNAL FEE_READ_OUT : std_logic; + SIGNAL FEE_BUSY_IN : std_logic; + SIGNAL FEE_STATUS_BITS_IN : std_logic_vector(31 downto 0); + SIGNAL PC_WR_EN_OUT : std_logic; + SIGNAL PC_DATA_OUT : std_logic_vector(7 downto 0); + SIGNAL PC_READY_IN : std_logic; + SIGNAL PC_SOS_OUT : std_logic; + SIGNAL PC_EOD_OUT : std_logic; + SIGNAL PC_SUB_SIZE_OUT : std_logic_vector(31 downto 0); + SIGNAL PC_TRIG_NR_OUT : std_logic_vector(31 downto 0); + SIGNAL PC_PADDING_OUT : std_logic; + SIGNAL BSM_SAVE_OUT : std_logic_vector(3 downto 0); + SIGNAL BSM_LOAD_OUT : std_logic_vector(3 downto 0); + SIGNAL DBG_REM_CTR_OUT : std_logic_vector(3 downto 0); + SIGNAL DBG_CTS_CTR_OUT : std_logic_vector(2 downto 0); + SIGNAL DBG_SF_WCNT_OUT : std_logic_vector(15 downto 0); + SIGNAL DBG_SF_RCNT_OUT : std_logic_vector(16 downto 0); + SIGNAL DBG_SF_DATA_OUT : std_logic_vector(15 downto 0); + SIGNAL DBG_SF_RD_EN_OUT : std_logic; + SIGNAL DBG_SF_WR_EN_OUT : std_logic; + SIGNAL DBG_SF_EMPTY_OUT : std_logic; + SIGNAL DBG_SF_FULL_OUT : std_logic; + SIGNAL DBG_SF_AFULL_OUT : std_logic; + SIGNAL DEBUG_OUT : std_logic_vector(31 downto 0); + +BEGIN + +-- Please check and add your generic clause manually + uut: feeder PORT MAP( + CLK => CLK, + RESET => RESET, + CTS_NUMBER_IN => CTS_NUMBER_IN, + CTS_CODE_IN => CTS_CODE_IN, + CTS_INFORMATION_IN => CTS_INFORMATION_IN, + CTS_READOUT_TYPE_IN => CTS_READOUT_TYPE_IN, + CTS_START_READOUT_IN => CTS_START_READOUT_IN, + CTS_READ_IN => CTS_READ_IN, + CTS_DATA_OUT => CTS_DATA_OUT, + CTS_DATAREADY_OUT => CTS_DATAREADY_OUT, + CTS_READOUT_FINISHED_OUT => CTS_READOUT_FINISHED_OUT, + CTS_LENGTH_OUT => CTS_LENGTH_OUT, + CTS_ERROR_PATTERN_OUT => CTS_ERROR_PATTERN_OUT, + FEE_DATA_IN => FEE_DATA_IN, + FEE_DATAREADY_IN => FEE_DATAREADY_IN, + FEE_READ_OUT => FEE_READ_OUT, + FEE_BUSY_IN => FEE_BUSY_IN, + FEE_STATUS_BITS_IN => FEE_STATUS_BITS_IN, + PC_WR_EN_OUT => PC_WR_EN_OUT, + PC_DATA_OUT => PC_DATA_OUT, + PC_READY_IN => PC_READY_IN, + PC_SOS_OUT => PC_SOS_OUT, + PC_EOD_OUT => PC_EOD_OUT, + PC_SUB_SIZE_OUT => PC_SUB_SIZE_OUT, + PC_TRIG_NR_OUT => PC_TRIG_NR_OUT, + PC_PADDING_OUT => PC_PADDING_OUT, + BSM_SAVE_OUT => BSM_SAVE_OUT, + BSM_LOAD_OUT => BSM_LOAD_OUT, + DBG_REM_CTR_OUT => DBG_REM_CTR_OUT, + DBG_CTS_CTR_OUT => DBG_CTS_CTR_OUT, + DBG_SF_WCNT_OUT => DBG_SF_WCNT_OUT, + DBG_SF_RCNT_OUT => DBG_SF_RCNT_OUT, + DBG_SF_DATA_OUT => DBG_SF_DATA_OUT, + DBG_SF_RD_EN_OUT => DBG_SF_RD_EN_OUT, + DBG_SF_WR_EN_OUT => DBG_SF_WR_EN_OUT, + DBG_SF_EMPTY_OUT => DBG_SF_EMPTY_OUT, + DBG_SF_FULL_OUT => DBG_SF_FULL_OUT, + DBG_SF_AFULL_OUT => DBG_SF_AFULL_OUT, + DEBUG_OUT => DEBUG_OUT + ); + +CLOCK_GEN: process +begin + clk <= '1'; wait for 5.0 ns; + clk <= '0'; wait for 5.0 ns; +end process CLOCK_GEN; + +-- Testbench +TESTBENCH_PROC: process +variable test_data_len : integer range 0 to 65535 := 49; +variable test_loop_len : integer range 0 to 65535 := 0; +variable test_hdr_len : unsigned(15 downto 0) := x"0000"; +variable test_evt_len : unsigned(15 downto 0) := x"0000"; +variable test_data : unsigned(15 downto 0) := x"ffff"; + +variable trigger_counter : unsigned(15 downto 0) := x"4710"; +variable trigger_loop : integer range 0 to 65535 := 15; +begin + -- Setup signals + reset <= '0'; + cts_number_in <= x"0000"; + cts_code_in <= x"00"; + cts_information_in <= x"00"; + cts_readout_type_in <= x"0"; + cts_start_readout_in <= '0'; + cts_read_in <= '0'; + fee_data_in <= x"0000"; + fee_dataready_in <= '0'; + fee_status_bits_in <= x"0000_0000"; + fee_busy_in <= '0'; + pc_ready_in <= '0'; + + wait for 22 ns; + + -- Reset the whole stuff + wait until rising_edge(clk); + reset <= '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + reset <= '0'; + wait until rising_edge(clk); + wait for 200 ns; + + +------------------------------------------------------------------------------- +-- Loop the transmissions +------------------------------------------------------------------------------- + trigger_counter := x"4710"; + trigger_loop := 9; + test_data_len := 14; + + MY_TRIGGER_LOOP: for J in 0 to trigger_loop loop + -- IPU transmission starts + wait until rising_edge(clk); + cts_number_in <= std_logic_vector( trigger_counter ); + cts_code_in <= x"aa"; + cts_information_in <= x"de"; + cts_readout_type_in <= x"1"; + cts_start_readout_in <= '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + + fee_busy_in <= '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + + -- ONE DATA TRANSMISSION + -- calculate the needed variables +-- test_data_len := 4096; + test_loop_len := 2*(test_data_len - 1) + 1; + test_hdr_len := to_unsigned( test_data_len + 1, 16 ); + test_evt_len := to_unsigned( test_data_len, 16 ); + + -- original data block (trigger 1, random 0xaa, number 0x4711, source 0x21) + fee_dataready_in <= '1'; + fee_data_in <= x"10aa"; + wait until rising_edge(clk); + fee_data_in <= std_logic_vector( trigger_counter ); + wait until rising_edge(clk); + fee_data_in <= std_logic_vector( test_hdr_len ); + wait until rising_edge(clk); + fee_data_in <= x"ff21"; + wait until rising_edge(clk); + fee_data_in <= std_logic_vector( test_evt_len ); + wait until rising_edge(clk); + fee_data_in <= x"ff22"; + + test_data := x"ffff"; + MY_DATA_LOOP: for J in 0 to test_loop_len loop + test_data := test_data + 1; + wait until rising_edge(clk); + fee_data_in <= std_logic_vector(test_data); + end loop MY_DATA_LOOP; + + fee_busy_in <= '0'; -- correct? + wait until rising_edge(clk); + fee_dataready_in <= '0'; + fee_data_in <= x"0000"; + + trigger_loop := trigger_loop + 1; + trigger_counter := trigger_counter + 1; + + wait until rising_edge(clk); + wait until rising_edge(clk); + cts_read_in <= '1'; + wait until rising_edge(clk); + cts_read_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + cts_start_readout_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + end loop MY_TRIGGER_LOOP; +------------------------------------------------------------------------------- +------------------------------------------------------------------------------- +------------------------------------------------------------------------------- + + + wait for 300 ns; + + -- Start packet_constructor + wait until rising_edge(clk); + wait until rising_edge(clk); + pc_ready_in <= '1'; + wait until rising_edge(clk); + + wait; + + wait until rising_edge(clk); + wait until pc_eod_out = '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + pc_ready_in <= '0'; + + -- Stay a while... stay forever!!! + wait; + +end process TESTBENCH_PROC; + + +END; diff --git a/gbe2_ecp3/tb_frame_receiver.vhd b/gbe2_ecp3/tb_frame_receiver.vhd new file mode 100644 index 0000000..9bea054 --- /dev/null +++ b/gbe2_ecp3/tb_frame_receiver.vhd @@ -0,0 +1,1836 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; +USE ieee.math_real.all; + +use work.trb_net_gbe_components.all; +use work.trb_net_gbe_protocols.all; + +entity testbench is +end testbench; + +architecture behavior of testbench is + +signal CLK : std_logic; +signal RESET : std_logic; +signal LINK_OK_IN : std_logic; +signal ALLOW_RX_IN : std_logic; +signal RX_MAC_CLK : std_logic; +signal MAC_RX_EOF_IN : std_logic; +signal MAC_RX_ER_IN : std_logic; +signal MAC_RXD_IN : std_logic_vector(7 downto 0); +signal MAC_RX_EN_IN : std_logic; +signal MAC_RX_FIFO_ERR_IN : std_logic; +signal MAC_RX_FIFO_FULL_OUT : std_logic; +signal MAC_RX_STAT_EN_IN : std_logic; +signal MAC_RX_STAT_VEC_IN : std_logic_vector(31 downto 0); +signal FR_Q_OUT : std_logic_vector(8 downto 0); +signal FR_RD_EN_IN : std_logic; +signal FR_FRAME_VALID_OUT : std_logic; +signal FR_GET_FRAME_IN : std_logic; +signal FR_FRAME_SIZE_OUT : std_logic_vector(15 downto 0); +signal FR_FRAME_PROTO_OUT : std_logic_vector(15 downto 0); +signal DEBUG_OUT : std_logic_vector(95 downto 0); +signal FR_ALLOWED_TYPES_IN : std_logic_vector(31 downto 0); + +signal RC_RD_EN_IN : std_logic; +signal RC_Q_OUT : std_logic_vector(8 downto 0); +signal RC_FRAME_WAITING_OUT : std_logic; +signal RC_LOADING_DONE_IN : std_logic; +signal RC_FRAME_SIZE_OUT : std_logic_vector(15 downto 0); +signal FRAMES_RECEIVED_OUT : std_logic_vector(31 downto 0); +signal BYTES_RECEIVED_OUT : std_logic_vector(31 downto 0); + +signal MC_TRANSMIT_CTRL_OUT : std_logic; +signal MC_TRANSMIT_DATA_OUT : std_logic; +signal MC_DATA_OUT : std_logic_vector(8 downto 0); +signal MC_RD_EN_IN : std_logic; +signal MC_FRAME_SIZE_OUT : std_logic_vector(15 downto 0); +signal MC_BUSY_IN : std_logic; +signal MC_TRANSMIT_DONE_IN : std_logic; +signal RC_FRAME_PROTO_OUT : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); + +signal fc_data : std_logic_vector(7 downto 0); +signal fc_wr_en : std_logic; +signal fc_sod : std_logic; +signal fc_eod : std_logic; +signal fc_h_ready : std_logic; +signal fc_ip_size : std_logic_vector(15 downto 0); +signal fc_udp_size : std_logic_vector(15 downto 0); +signal fc_ready : std_logic; +signal fc_dest_mac : std_logic_vector(47 downto 0); +signal fc_dest_ip : std_logic_vector(31 downto 0); +signal fc_dest_udp : std_logic_vector(15 downto 0); +signal fc_src_mac : std_logic_vector(47 downto 0); +signal fc_src_ip : std_logic_vector(31 downto 0); +signal fc_src_udp : std_logic_vector(15 downto 0); +signal fc_type : std_logic_vector(15 downto 0); +signal mc_type : std_logic_vector(15 downto 0); +signal fc_ihl : std_logic_vector(7 downto 0); +signal fc_tos : std_logic_vector(7 downto 0); +signal fc_ident : std_logic_vector(15 downto 0); +signal fc_flags : std_logic_vector(15 downto 0); +signal fc_ttl : std_logic_vector(7 downto 0); +signal fc_proto : std_logic_vector(7 downto 0); +signal fr_src_mac : std_logic_vector(47 downto 0); +signal fr_dest_mac : std_logic_vector(47 downto 0); +signal fr_src_ip : std_logic_vector(31 downto 0); +signal fr_dest_ip : std_logic_vector(31 downto 0); +signal fr_src_udp : std_logic_vector(15 downto 0); +signal fr_dest_udp : std_logic_vector(15 downto 0); +signal rc_src_mac : std_logic_vector(47 downto 0); +signal rc_dest_mac : std_logic_vector(47 downto 0); +signal rc_src_ip : std_logic_vector(31 downto 0); +signal rc_dest_ip : std_logic_vector(31 downto 0); +signal rc_src_udp : std_logic_vector(15 downto 0); +signal rc_dest_udp : std_logic_vector(15 downto 0); + +signal mc_dest_mac : std_logic_vector(47 downto 0); +signal mc_dest_ip : std_logic_vector(31 downto 0); +signal mc_dest_udp : std_logic_vector(15 downto 0); +signal mc_src_mac : std_logic_vector(47 downto 0); +signal mc_src_ip : std_logic_vector(31 downto 0); +signal mc_src_udp : std_logic_vector(15 downto 0); + +signal fr_allowed_ip : std_logic_vector(31 downto 0); +signal fr_allowed_udp : std_logic_vector(31 downto 0); + +signal fr_ip_proto : std_logic_vector(7 downto 0); +signal mc_ip_proto : std_logic_vector(7 downto 0); + +signal additional_rand_pause : std_logic; + +signal pc_ready, pc_sos, pc_transmit_on, pc_wr_en, pc_sod, pc_eod, pc_fc_h_ready, pc_fc_ready : std_logic; +signal pc_data : std_logic_vector(7 downto 0); +signal pc_ip_size, pc_udp_size : std_logic_vector(15 downto 0); + +begin + +packet_constr : trb_net16_gbe_packet_constr +port map( + RESET => RESET, + CLK => CLK, + MULT_EVT_ENABLE_IN => '0', + -- ports for user logic + PC_WR_EN_IN => '0', + PC_DATA_IN => (others => '0'), + PC_READY_OUT => pc_ready, + PC_START_OF_SUB_IN => pc_sos, + PC_END_OF_SUB_IN => '0', + PC_END_OF_DATA_IN => '0', + PC_TRANSMIT_ON_OUT => pc_transmit_on, + -- queue and subevent layer headers + PC_SUB_SIZE_IN => (others => '0'), + PC_PADDING_IN => '0', + PC_DECODING_IN => (others => '0'), + PC_EVENT_ID_IN => (others => '0'), + PC_TRIG_NR_IN => (others => '0'), + PC_QUEUE_DEC_IN => (others => '0'), + PC_MAX_FRAME_SIZE_IN => (others => '0'), + PC_DELAY_IN => (others => '0'), + -- FrameConstructor ports + TC_WR_EN_OUT => pc_wr_en, + TC_DATA_OUT => pc_data, + TC_H_READY_IN => pc_fc_h_ready, + TC_READY_IN => pc_fc_ready, + TC_IP_SIZE_OUT => pc_ip_size, + TC_UDP_SIZE_OUT => pc_udp_size, + TC_FLAGS_OFFSET_OUT => open, + TC_SOD_OUT => pc_sod, + TC_EOD_OUT => pc_eod, + DEBUG_OUT => open +); + +receiver : trb_net16_gbe_frame_receiver +port map ( + CLK => CLK, + RESET => RESET, + LINK_OK_IN => LINK_OK_IN, + ALLOW_RX_IN => ALLOW_RX_IN, + RX_MAC_CLK => RX_MAC_CLK, + + MAC_RX_EOF_IN => MAC_RX_EOF_IN, + MAC_RX_ER_IN => MAC_RX_ER_IN, + MAC_RXD_IN => MAC_RXD_IN, + MAC_RX_EN_IN => MAC_RX_EN_IN, + MAC_RX_FIFO_ERR_IN => MAC_RX_FIFO_ERR_IN, + MAC_RX_FIFO_FULL_OUT => MAC_RX_FIFO_FULL_OUT, + MAC_RX_STAT_EN_IN => MAC_RX_STAT_EN_IN, + MAC_RX_STAT_VEC_IN => MAC_RX_STAT_VEC_IN, + + FR_Q_OUT => FR_Q_OUT, + FR_RD_EN_IN => FR_RD_EN_IN, + FR_FRAME_VALID_OUT => FR_FRAME_VALID_OUT, + FR_GET_FRAME_IN => FR_GET_FRAME_IN, + FR_FRAME_SIZE_OUT => FR_FRAME_SIZE_OUT, + FR_FRAME_PROTO_OUT => FR_FRAME_PROTO_OUT, + FR_IP_PROTOCOL_OUT => fr_ip_proto, + FR_ALLOWED_TYPES_IN => FR_ALLOWED_TYPES_IN, + FR_ALLOWED_IP_IN => fr_allowed_ip, + FR_ALLOWED_UDP_IN => fr_allowed_udp, + FR_VLAN_ID_IN => x"aabb_0000", + + FR_SRC_MAC_ADDRESS_OUT => fr_src_mac, + FR_DEST_MAC_ADDRESS_OUT => fr_dest_mac, + FR_SRC_IP_ADDRESS_OUT => fr_src_ip, + FR_DEST_IP_ADDRESS_OUT => fr_dest_ip, + FR_SRC_UDP_PORT_OUT => fr_src_udp, + FR_DEST_UDP_PORT_OUT => fr_dest_udp, + + DEBUG_OUT => DEBUG_OUT +); + +receive_controler : trb_net16_gbe_receive_control +port map( + CLK => CLK, + RESET => RESET, + +-- signals to/from frame_receiver + RC_DATA_IN => FR_Q_OUT, + FR_RD_EN_OUT => FR_RD_EN_IN, + FR_FRAME_VALID_IN => FR_FRAME_VALID_OUT, + FR_GET_FRAME_OUT => FR_GET_FRAME_IN, + FR_FRAME_SIZE_IN => FR_FRAME_SIZE_OUT, + FR_FRAME_PROTO_IN => FR_FRAME_PROTO_OUT, + FR_IP_PROTOCOL_IN => fr_ip_proto, + + FR_SRC_MAC_ADDRESS_IN => fr_src_mac, + FR_DEST_MAC_ADDRESS_IN => fr_dest_mac, + FR_SRC_IP_ADDRESS_IN => fr_src_ip, + FR_DEST_IP_ADDRESS_IN => fr_dest_ip, + FR_SRC_UDP_PORT_IN => fr_src_udp, + FR_DEST_UDP_PORT_IN => fr_dest_udp, + +-- signals to/from main controller + RC_RD_EN_IN => RC_RD_EN_IN, + RC_Q_OUT => RC_Q_OUT, + RC_FRAME_WAITING_OUT => RC_FRAME_WAITING_OUT, + RC_LOADING_DONE_IN => RC_LOADING_DONE_IN, + RC_FRAME_SIZE_OUT => RC_FRAME_SIZE_OUT, + RC_FRAME_PROTO_OUT => RC_FRAME_PROTO_OUT, + + RC_SRC_MAC_ADDRESS_OUT => rc_src_mac, + RC_DEST_MAC_ADDRESS_OUT => rc_dest_mac, + RC_SRC_IP_ADDRESS_OUT => rc_src_ip, + RC_DEST_IP_ADDRESS_OUT => rc_dest_ip, + RC_SRC_UDP_PORT_OUT => rc_src_udp, + RC_DEST_UDP_PORT_OUT => rc_dest_udp, + +-- statistics + FRAMES_RECEIVED_OUT => open, + BYTES_RECEIVED_OUT => open, + + DEBUG_OUT => open +); + +main_controller : trb_net16_gbe_main_control +port map ( + CLK => CLK, + CLK_125 => RX_MAC_CLK, + RESET => RESET, + + MC_LINK_OK_OUT => open, + MC_RESET_LINK_IN => '0', + +-- signals to/from receive controller + RC_FRAME_WAITING_IN => RC_FRAME_WAITING_OUT, + RC_LOADING_DONE_OUT => RC_LOADING_DONE_IN, + RC_DATA_IN => RC_Q_OUT, + RC_RD_EN_OUT => RC_RD_EN_IN, + RC_FRAME_SIZE_IN => RC_FRAME_SIZE_OUT, + RC_FRAME_PROTO_IN => RC_FRAME_PROTO_OUT, + + RC_SRC_MAC_ADDRESS_IN => rc_src_mac, + RC_DEST_MAC_ADDRESS_IN => rc_dest_mac, + RC_SRC_IP_ADDRESS_IN => rc_src_ip, + RC_DEST_IP_ADDRESS_IN => rc_dest_ip, + RC_SRC_UDP_PORT_IN => rc_src_udp, + RC_DEST_UDP_PORT_IN => rc_dest_udp, + +-- signals to/from transmit controller + TC_TRANSMIT_CTRL_OUT => MC_TRANSMIT_CTRL_OUT, + TC_TRANSMIT_DATA_OUT => MC_TRANSMIT_DATA_OUT, + TC_DATA_OUT => MC_DATA_OUT, + TC_RD_EN_IN => MC_RD_EN_IN, + TC_FRAME_SIZE_OUT => MC_FRAME_SIZE_OUT, + TC_FRAME_TYPE_OUT => mc_type, + TC_IP_PROTOCOL_OUT => mc_ip_proto, + + TC_DEST_MAC_OUT => mc_dest_mac, + TC_DEST_IP_OUT => mc_dest_ip, + TC_DEST_UDP_OUT => mc_dest_udp, + TC_SRC_MAC_OUT => mc_src_mac, + TC_SRC_IP_OUT => mc_src_ip, + TC_SRC_UDP_OUT => mc_src_udp, + + TC_BUSY_IN => MC_BUSY_IN, + TC_TRANSMIT_DONE_IN => MC_TRANSMIT_DONE_IN, + +-- signals to/from packet constructor + PC_READY_IN => pc_ready, + PC_TRANSMIT_ON_IN => pc_transmit_on, + PC_SOD_IN => pc_sod, + +-- signals to/from sgmii/gbe pcs_an_complete + PCS_AN_COMPLETE_IN => '1', + +-- signals to/from hub + +-- signal to/from Host interface of TriSpeed MAC + TSM_HADDR_OUT => open, + TSM_HDATA_OUT => open, + TSM_HCS_N_OUT => open, + TSM_HWRITE_N_OUT => open, + TSM_HREAD_N_OUT => open, + TSM_HREADY_N_IN => '0', + TSM_HDATA_EN_N_IN => '1', + + DEBUG_OUT => open +); + +transmit_controller : trb_net16_gbe_transmit_control +port map( + CLK => CLK, + RESET => RESET, + +-- signals to/from packet constructor + PC_READY_IN => pc_ready, --'1', + PC_DATA_IN => pc_data, --(others => '0'), + PC_WR_EN_IN => pc_wr_en, --'0', + PC_IP_SIZE_IN => pc_ip_size, + PC_UDP_SIZE_IN => pc_udp_size, + PC_FLAGS_OFFSET_IN => (others => '0'), + PC_SOD_IN => pc_sod, + PC_EOD_IN => pc_eod, + PC_FC_READY_OUT => pc_fc_ready, + PC_FC_H_READY_OUT => pc_fc_h_ready, + PC_TRANSMIT_ON_IN => '0', + + -- signals from ip_configurator used by packet constructor + IC_DEST_MAC_ADDRESS_IN => x"112233445566", + IC_DEST_IP_ADDRESS_IN => x"aabbccdd", + IC_DEST_UDP_PORT_IN => x"0101", + IC_SRC_MAC_ADDRESS_IN => x"665544332211", + IC_SRC_IP_ADDRESS_IN => x"ddccbbaa", + IC_SRC_UDP_PORT_IN => x"0202", + +-- signal to/from main controller + MC_TRANSMIT_CTRL_IN => MC_TRANSMIT_CTRL_OUT, + MC_TRANSMIT_DATA_IN => MC_TRANSMIT_DATA_OUT, + MC_DATA_IN => MC_DATA_OUT, + MC_RD_EN_OUT => MC_RD_EN_IN, + MC_FRAME_SIZE_IN => MC_FRAME_SIZE_OUT, + MC_FRAME_TYPE_IN => mc_type, + MC_IP_PROTOCOL_IN => mc_ip_proto, + + MC_DEST_MAC_IN => mc_dest_mac, + MC_DEST_IP_IN => mc_dest_ip, + MC_DEST_UDP_IN => mc_dest_udp, + MC_SRC_MAC_IN => mc_src_mac, + MC_SRC_IP_IN => mc_src_ip, + MC_SRC_UDP_IN => mc_src_udp, + + MC_BUSY_OUT => MC_BUSY_IN, + MC_TRANSMIT_DONE_OUT => MC_TRANSMIT_DONE_IN, + +-- signal to/from frame constructor + FC_DATA_OUT => fc_data, + FC_WR_EN_OUT => fc_wr_en, + FC_READY_IN => fc_ready, + FC_H_READY_IN => fc_h_ready, + FC_FRAME_TYPE_OUT => fc_type, + FC_IP_SIZE_OUT => fc_ip_size, + FC_UDP_SIZE_OUT => fc_udp_size, + FC_IDENT_OUT => fc_ident, + FC_FLAGS_OFFSET_OUT => fc_flags, + FC_SOD_OUT => fc_sod, + FC_EOD_OUT => fc_eod, + FC_IP_PROTOCOL_OUT => fc_proto, + + DEST_MAC_ADDRESS_OUT => fc_dest_mac, + DEST_IP_ADDRESS_OUT => fc_dest_ip, + DEST_UDP_PORT_OUT => fc_dest_udp, + SRC_MAC_ADDRESS_OUT => fc_src_mac, + SRC_IP_ADDRESS_OUT => fc_src_ip, + SRC_UDP_PORT_OUT => fc_src_udp, + + DEBUG_OUT => open +); + +frame_constructor : trb_net16_gbe_frame_constr +port map( + -- ports for user logic + RESET => RESET, + CLK => CLK, + LINK_OK_IN => '1', + -- + WR_EN_IN => fc_wr_en, + DATA_IN => fc_data, + START_OF_DATA_IN => fc_sod, + END_OF_DATA_IN => fc_eod, + IP_F_SIZE_IN => fc_ip_size, + UDP_P_SIZE_IN => fc_udp_size, + HEADERS_READY_OUT => fc_h_ready, + READY_OUT => fc_ready, + DEST_MAC_ADDRESS_IN => fc_dest_mac, + DEST_IP_ADDRESS_IN => fc_dest_ip, + DEST_UDP_PORT_IN => fc_dest_udp, + SRC_MAC_ADDRESS_IN => fc_src_mac, + SRC_IP_ADDRESS_IN => fc_src_ip, + SRC_UDP_PORT_IN => fc_src_udp, + FRAME_TYPE_IN => fc_type, + IHL_VERSION_IN => fc_ihl, + TOS_IN => fc_tos, + IDENTIFICATION_IN => fc_ident, + FLAGS_OFFSET_IN => fc_flags, + TTL_IN => fc_ttl, + PROTOCOL_IN => fc_proto, + FRAME_DELAY_IN => x"0000_0000", + -- ports for packetTransmitter + RD_CLK => RX_MAC_CLK, + FT_DATA_OUT => open, + FT_TX_EMPTY_OUT => open, + FT_TX_RD_EN_IN => '1', + FT_START_OF_PACKET_OUT => open, + FT_TX_DONE_IN => '1', + FT_TX_DISCFRM_IN => '0', + -- debug ports + BSM_CONSTR_OUT => open, + BSM_TRANS_OUT => open, + DEBUG_OUT => open +); + +-- 100 MHz system clock +CLOCK_GEN_PROC: process +begin + CLK <= '1'; wait for 5.0 ns; + CLK <= '0'; wait for 5.0 ns; +end process CLOCK_GEN_PROC; + +-- 125 MHz MAC clock +CLOCK2_GEN_PROC: process +begin + RX_MAC_CLK <= '1'; wait for 3.0 ns; + RX_MAC_CLK <= '0'; wait for 4.0 ns; +end process CLOCK2_GEN_PROC; + +CHECK_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + assert DEBUG_OUT(1) = '0' and DEBUG_OUT(3) = '0' report "FIFO FULL" severity error; + end if; +end process CHECK_PROC; + +TESTBENCH_PROC : process + +variable seed1 : positive; -- seed for random generator +variable seed2 : positive; -- seed for random generator +variable rand : real; -- random value (0.0 ... 1.0) +variable int_rand : integer; -- random value, scaled to your needs + +begin + + wait for 50 ns; + RESET <= '1'; + + LINK_OK_IN <= '1'; + ALLOW_RX_IN <= '1'; + + MAC_RX_EOF_IN <= '0'; + MAC_RX_ER_IN <= '0'; + MAC_RXD_IN <= x"00"; + MAC_RX_EN_IN <= '0'; + MAC_RX_FIFO_ERR_IN <= '0'; + FR_ALLOWED_TYPES_IN <= x"0000_000f"; + fr_allowed_ip <= x"0000_000f"; + fr_allowed_udp <= x"0000_000f"; + additional_rand_pause <= '0'; + pc_sos <= '0'; + + wait for 10 ns; + RESET <= '0'; + wait for 50 ns; + + wait for 1000 ns; + + --for i in 0 to 1000 loop + + wait for 700 ns; + + + -- FIRST FRAME (ARP Request) + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <= '1'; +-- dest mac + MAC_RXD_IN <= x"ff"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ff"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ff"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ff"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ff"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ff"; + wait until rising_edge(RX_MAC_CLK); +-- src mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ee"; + wait until rising_edge(RX_MAC_CLK); +-- arp frame type + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"06"; + wait until rising_edge(RX_MAC_CLK); +-- hardware type + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); +-- protocol type + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); +-- hardware size + MAC_RXD_IN <= x"06"; + wait until rising_edge(RX_MAC_CLK); +-- protocol size + MAC_RXD_IN <= x"04"; + wait until rising_edge(RX_MAC_CLK); +-- opcode (request) + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); +-- sender mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ee"; + wait until rising_edge(RX_MAC_CLK); +-- sender ip + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a9"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); +-- target mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); +-- target ip + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a8"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"65"; + MAC_RX_EOF_IN <= '1'; + + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <='0'; + MAC_RX_EOF_IN <= '0'; + + + wait; + + + + +-- FIRST FRAME UDP - DHCP Offer + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <= '1'; +-- dest mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"be"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ef"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"be"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ef"; + wait until rising_edge(RX_MAC_CLK); +-- src mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ee"; + wait until rising_edge(RX_MAC_CLK); +-- frame type + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); +-- ip headers + MAC_RXD_IN <= x"45"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"10"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"5a"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"49"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ff"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"11"; -- udp + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a8"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a8"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; +-- udp headers + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"43"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"44"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"2c"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; +-- dhcp data + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"06"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"de"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ad"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"fa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ce"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a8"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"10"; + + for i in 0 to 219 loop + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + end loop; + + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"35"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EOF_IN <= '1'; + + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <='0'; + MAC_RX_EOF_IN <= '0'; + + wait for 100 us; + + + + wait; + + + + + + + + + + + + + + -- FIRST FRAME IP - ICMP Ping request + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <= '1'; +-- dest mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"be"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ef"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"be"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ef"; + wait until rising_edge(RX_MAC_CLK); +-- src mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ee"; + wait until rising_edge(RX_MAC_CLK); +-- frame type + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); +-- ip headers + MAC_RXD_IN <= x"45"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"10"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"5a"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"49"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ff"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ee"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a8"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a8"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; +-- ping headers + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"47"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"d3"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"0d"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"3c"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); +-- ping data + MAC_RXD_IN <= x"8c"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"da"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"e7"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"4d"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"36"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"c4"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"0d"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"09"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"0a"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"0b"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"0c"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"0d"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"0e"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"0f"; + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EOF_IN <= '1'; + MAC_RXD_IN <= x"aa"; + + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <='0'; + MAC_RX_EOF_IN <= '0'; + + wait for 1500 ns; + + + + wait; + + + + + + -- FIRST FRAME IP - ICMP Ping request + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <= '1'; +-- dest mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"be"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ef"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"be"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ef"; + wait until rising_edge(RX_MAC_CLK); +-- src mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ee"; + wait until rising_edge(RX_MAC_CLK); +-- frame type + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); +-- ip headers + MAC_RXD_IN <= x"45"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"10"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"5a"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"49"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ff"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; -- icmp + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a8"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a8"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; +-- ping headers + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"47"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"d3"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"0d"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"3c"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); +-- ping data + MAC_RXD_IN <= x"8c"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"da"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"e7"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"4d"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"36"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"c4"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"0d"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"09"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"0a"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"0b"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"0c"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"0d"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"0e"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"0f"; + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EOF_IN <= '1'; + MAC_RXD_IN <= x"aa"; + + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <='0'; + MAC_RX_EOF_IN <= '0'; + +-- end loop; + + wait for 1500 ns; + + + -- FIRST FRAME (ARP Request) + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <= '1'; +-- dest mac + MAC_RXD_IN <= x"ff"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ff"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ff"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ff"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ff"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ff"; + wait until rising_edge(RX_MAC_CLK); +-- src mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ee"; + wait until rising_edge(RX_MAC_CLK); +-- arp frame type + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"06"; + wait until rising_edge(RX_MAC_CLK); +-- hardware type + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); +-- protocol type + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); +-- hardware size + MAC_RXD_IN <= x"06"; + wait until rising_edge(RX_MAC_CLK); +-- protocol size + MAC_RXD_IN <= x"04"; + wait until rising_edge(RX_MAC_CLK); +-- opcode (request) + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); +-- sender mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ee"; + wait until rising_edge(RX_MAC_CLK); +-- sender ip + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a9"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); +-- target mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); +-- target ip + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a8"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"65"; + MAC_RX_EOF_IN <= '1'; + + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <='0'; + MAC_RX_EOF_IN <= '0'; + + + + + + +-- FIRST FRAME UDP - DHCP Offer + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <= '1'; +-- dest mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"be"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ef"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"be"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ef"; + wait until rising_edge(RX_MAC_CLK); +-- src mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ee"; + wait until rising_edge(RX_MAC_CLK); +-- frame type + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); +-- ip headers + MAC_RXD_IN <= x"45"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"10"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"5a"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"49"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ff"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"11"; -- udp + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a8"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a8"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; +-- udp headers + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"43"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"44"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"2c"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; +-- dhcp data + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"06"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"de"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ad"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"fa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ce"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a8"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"10"; + + for i in 0 to 219 loop + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + end loop; + + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"35"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EOF_IN <= '1'; + + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <='0'; + MAC_RX_EOF_IN <= '0'; + + wait for 100 us; + + +-- FIRST FRAME UDP + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <= '1'; +-- dest mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"11"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"22"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"33"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"44"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"55"; + wait until rising_edge(RX_MAC_CLK); +-- src mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ee"; + wait until rising_edge(RX_MAC_CLK); +-- frame type + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); +-- ip headers + MAC_RXD_IN <= x"45"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"45"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ab"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"40"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"11"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a8"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a8"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; +-- udp headers + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"11"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"11"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"44"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"2c"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); +-- few data words + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"03"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"04"; + MAC_RX_EOF_IN <= '1'; + + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <='0'; + MAC_RX_EOF_IN <= '0'; + + + wait for 100 ns; + + -- FIRST FRAME (ARP Request) + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <= '1'; +-- dest mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"11"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"22"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"33"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"44"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"55"; + wait until rising_edge(RX_MAC_CLK); +-- src mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ee"; + wait until rising_edge(RX_MAC_CLK); +-- arp frame type + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"07"; + wait until rising_edge(RX_MAC_CLK); +-- hardware type + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); +-- protocol type + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); +-- hardware size + MAC_RXD_IN <= x"06"; + wait until rising_edge(RX_MAC_CLK); +-- protocol size + MAC_RXD_IN <= x"04"; + wait until rising_edge(RX_MAC_CLK); +-- opcode (request) + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); +-- sender mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"ee"; + wait until rising_edge(RX_MAC_CLK); +-- sender ip + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a9"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); +-- target mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); +-- target ip + MAC_RXD_IN <= x"c0"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"a9"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; + wait until rising_edge(RX_MAC_CLK); +-- cs + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"03"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"04"; + MAC_RX_EOF_IN <= '1'; + + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <='0'; + MAC_RX_EOF_IN <= '0'; + + + wait for 100 ns; + +-- SECOND FRAME + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <= '1'; +-- dest mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"11"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"22"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"33"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"44"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"55"; + wait until rising_edge(RX_MAC_CLK); +-- src mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"11"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"22"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"33"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"44"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"55"; + wait until rising_edge(RX_MAC_CLK); +-- frame type + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); +-- data + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); +-- cs + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"03"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"04"; + MAC_RX_EOF_IN <= '1'; + + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <='0'; + MAC_RX_EOF_IN <= '0'; + + + wait for 50 ns; + +-- THIRD FRAME + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <= '1'; +-- dest mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"11"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"22"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"33"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"44"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"55"; + wait until rising_edge(RX_MAC_CLK); +-- src mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"11"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"22"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"33"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"44"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"55"; + wait until rising_edge(RX_MAC_CLK); +-- frame type + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); +-- data + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); +-- cs + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"03"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"04"; + MAC_RX_EOF_IN <= '1'; + + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <='0'; + MAC_RX_EOF_IN <= '0'; + + wait for 100 ns; + + + wait; + + FRAMES_LOOP : for i in 0 to 100 loop + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <= '1'; + -- dest mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"11"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"22"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"33"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"44"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"55"; + wait until rising_edge(RX_MAC_CLK); + -- src mac + MAC_RXD_IN <= x"00"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"11"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"22"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"33"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"44"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"55"; + wait until rising_edge(RX_MAC_CLK); + -- frame type + MAC_RXD_IN <= x"08"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + -- data + MAC_RXD_IN <= x"aa"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"bb"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"cc"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"dd"; + wait until rising_edge(RX_MAC_CLK); + -- cs + MAC_RXD_IN <= x"01"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"02"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"03"; + wait until rising_edge(RX_MAC_CLK); + MAC_RXD_IN <= x"04"; + MAC_RX_EOF_IN <= '1'; + + wait until rising_edge(RX_MAC_CLK); + MAC_RX_EN_IN <='0'; + MAC_RX_EOF_IN <= '0'; + + + wait for 100 ns; + end loop FRAMES_LOOP; + + wait for 1000 ns; + +end process; + + +end architecture; diff --git a/gbe2_ecp3/tb_gbe_buf.vhd b/gbe2_ecp3/tb_gbe_buf.vhd new file mode 100755 index 0000000..772ff46 --- /dev/null +++ b/gbe2_ecp3/tb_gbe_buf.vhd @@ -0,0 +1,532 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.math_real.all; +USE ieee.numeric_std.ALL; + +ENTITY testbench IS +END testbench; + +ARCHITECTURE behavior OF testbench IS + component trb_net16_gbe_buf is + generic( + DO_SIMULATION : integer range 0 to 1 := 1; + USE_125MHZ_EXTCLK : integer range 0 to 1 := 1 + ); + port( + CLK : in std_logic; + TEST_CLK : in std_logic; -- only for simulation! + CLK_125_IN : in std_logic; -- gk 28.04.01 used only in internal 125MHz clock mode +RESET : IN std_logic; + GSR_N : IN std_logic; + STAGE_CTRL_REGS_IN : IN std_logic_vector(31 downto 0); + ------------------------ + IP_CFG_START_IN : IN std_logic; + IP_CFG_BANK_SEL_IN : IN std_logic_vector(3 downto 0); + IP_CFG_MEM_DATA_IN : IN std_logic_vector(31 downto 0); + MR_RESET_IN : IN std_logic; + MR_MODE_IN : IN std_logic; + MR_RESTART_IN : IN std_logic; + IP_CFG_MEM_CLK_OUT : OUT std_logic; + IP_CFG_DONE_OUT : OUT std_logic; + IP_CFG_MEM_ADDR_OUT : OUT std_logic_vector(7 downto 0); + -- gk 29.03.10 + SLV_ADDR_IN : in std_logic_vector(7 downto 0); + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_BUSY_OUT : out std_logic; + SLV_ACK_OUT : out std_logic; + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + -- gk 26.04.10 + -- registers setup interface + BUS_ADDR_IN : in std_logic_vector(7 downto 0); + BUS_DATA_IN : in std_logic_vector(31 downto 0); + BUS_DATA_OUT : out std_logic_vector(31 downto 0); -- gk 26.04.10 + BUS_WRITE_EN_IN : in std_logic; -- gk 26.04.10 + BUS_READ_EN_IN : in std_logic; -- gk 26.04.10 + BUS_ACK_OUT : out std_logic; -- gk 26.04.10 + -- gk 23.04.10 + LED_PACKET_SENT_OUT : out std_logic; + LED_AN_DONE_N_OUT : out std_logic; + ------------------------ + CTS_NUMBER_IN : IN std_logic_vector(15 downto 0); + CTS_CODE_IN : IN std_logic_vector(7 downto 0); + CTS_INFORMATION_IN : IN std_logic_vector(7 downto 0); + CTS_READOUT_TYPE_IN : IN std_logic_vector(3 downto 0); + CTS_START_READOUT_IN : IN std_logic; + CTS_READ_IN : IN std_logic; + FEE_DATA_IN : IN std_logic_vector(15 downto 0); + FEE_DATAREADY_IN : IN std_logic; + FEE_STATUS_BITS_IN : IN std_logic_vector(31 downto 0); + FEE_BUSY_IN : IN std_logic; + SFP_RXD_P_IN : IN std_logic; + SFP_RXD_N_IN : IN std_logic; + SFP_REFCLK_P_IN : IN std_logic; + SFP_REFCLK_N_IN : IN std_logic; + SFP_PRSNT_N_IN : IN std_logic; + SFP_LOS_IN : IN std_logic; + STAGE_STAT_REGS_OUT : OUT std_logic_vector(31 downto 0); + CTS_DATA_OUT : OUT std_logic_vector(31 downto 0); + CTS_DATAREADY_OUT : OUT std_logic; + CTS_READOUT_FINISHED_OUT : OUT std_logic; + CTS_LENGTH_OUT : OUT std_logic_vector(15 downto 0); + CTS_ERROR_PATTERN_OUT : OUT std_logic_vector(31 downto 0); + FEE_READ_OUT : OUT std_logic; + SFP_TXD_P_OUT : OUT std_logic; + SFP_TXD_N_OUT : OUT std_logic; + SFP_TXDIS_OUT : OUT std_logic; + -- for simulation of receiving part only + MAC_RX_EOF_IN : in std_logic; + MAC_RXD_IN : in std_logic_vector(7 downto 0); + MAC_RX_EN_IN : in std_logic; + + ANALYZER_DEBUG_OUT : OUT std_logic_vector(63 downto 0) + ); + END COMPONENT; + + SIGNAL CLK : std_logic; + SIGNAL TEST_CLK : std_logic; + SIGNAL RESET : std_logic; + SIGNAL GSR_N : std_logic; + SIGNAL STAGE_STAT_REGS_OUT : std_logic_vector(31 downto 0); + SIGNAL STAGE_CTRL_REGS_IN : std_logic_vector(31 downto 0); + SIGNAL IP_CFG_START_IN : std_logic; + SIGNAL IP_CFG_BANK_SEL_IN : std_logic_vector(3 downto 0); + SIGNAL IP_CFG_MEM_DATA_IN : std_logic_vector(31 downto 0); + SIGNAL MR_RESET_IN : std_logic; + SIGNAL MR_MODE_IN : std_logic; + SIGNAL MR_RESTART_IN : std_logic; + SIGNAL IP_CFG_MEM_CLK_OUT : std_logic; + SIGNAL IP_CFG_DONE_OUT : std_logic; + SIGNAL IP_CFG_MEM_ADDR_OUT : std_logic_vector(7 downto 0); + SIGNAL CTS_NUMBER_IN : std_logic_vector(15 downto 0); + SIGNAL CTS_CODE_IN : std_logic_vector(7 downto 0); + SIGNAL CTS_INFORMATION_IN : std_logic_vector(7 downto 0); + SIGNAL CTS_READOUT_TYPE_IN : std_logic_vector(3 downto 0); + SIGNAL CTS_START_READOUT_IN : std_logic; + SIGNAL CTS_DATA_OUT : std_logic_vector(31 downto 0); + SIGNAL CTS_DATAREADY_OUT : std_logic; + SIGNAL CTS_READOUT_FINISHED_OUT : std_logic; + SIGNAL CTS_READ_IN : std_logic; + SIGNAL CTS_LENGTH_OUT : std_logic_vector(15 downto 0); + SIGNAL CTS_ERROR_PATTERN_OUT : std_logic_vector(31 downto 0); + SIGNAL FEE_DATA_IN : std_logic_vector(15 downto 0); + SIGNAL FEE_DATAREADY_IN : std_logic; + SIGNAL FEE_READ_OUT : std_logic; + SIGNAL FEE_STATUS_BITS_IN : std_logic_vector(31 downto 0); + SIGNAL FEE_BUSY_IN : std_logic; + SIGNAL SFP_RXD_P_IN : std_logic; + SIGNAL SFP_RXD_N_IN : std_logic; + SIGNAL SFP_TXD_P_OUT : std_logic; + SIGNAL SFP_TXD_N_OUT : std_logic; + SIGNAL SFP_REFCLK_P_IN : std_logic; + SIGNAL SFP_REFCLK_N_IN : std_logic; + SIGNAL SFP_PRSNT_N_IN : std_logic; + SIGNAL SFP_LOS_IN : std_logic; + SIGNAL SFP_TXDIS_OUT : std_logic; + SIGNAL ANALYZER_DEBUG_OUT : std_logic_vector(63 downto 0); + --gk 29.03.10 + signal SLV_ADDR_IN : std_logic_vector(7 downto 0); + signal SLV_READ_IN : std_logic; + signal SLV_WRITE_IN : std_logic; + signal SLV_BUSY_OUT : std_logic; + signal SLV_ACK_OUT : std_logic; + signal SLV_DATA_IN : std_logic_vector(31 downto 0); + signal SLV_DATA_OUT : std_logic_vector(31 downto 0); + -- for simulation of receiving part only + signal MAC_RX_EOF_IN : std_logic; + signal MAC_RXD_IN : std_logic_vector(7 downto 0); + signal MAC_RX_EN_IN : std_logic; + +BEGIN + +-- Please check and add your generic clause manually + uut: trb_net16_gbe_buf + GENERIC MAP( DO_SIMULATION => 1, USE_125MHZ_EXTCLK => 1 ) + PORT MAP( + CLK => CLK, + CLK_125_IN => '0', + TEST_CLK => TEST_CLK, + RESET => RESET, + GSR_N => GSR_N, + STAGE_STAT_REGS_OUT => STAGE_STAT_REGS_OUT, + STAGE_CTRL_REGS_IN => STAGE_CTRL_REGS_IN, + IP_CFG_START_IN => IP_CFG_START_IN, + IP_CFG_BANK_SEL_IN => IP_CFG_BANK_SEL_IN, + IP_CFG_MEM_DATA_IN => IP_CFG_MEM_DATA_IN, + MR_RESET_IN => MR_RESET_IN, + MR_MODE_IN => MR_MODE_IN, + MR_RESTART_IN => MR_RESTART_IN, + IP_CFG_MEM_CLK_OUT => IP_CFG_MEM_CLK_OUT, + IP_CFG_DONE_OUT => IP_CFG_DONE_OUT, + IP_CFG_MEM_ADDR_OUT => IP_CFG_MEM_ADDR_OUT, + -- gk 29.03.10 + SLV_ADDR_IN => SLV_ADDR_IN, + SLV_READ_IN => SLV_READ_IN, + SLV_WRITE_IN => SLV_WRITE_IN, + SLV_BUSY_OUT => SLV_BUSY_OUT, + SLV_ACK_OUT => SLV_ACK_OUT, + SLV_DATA_IN => SLV_DATA_IN, + SLV_DATA_OUT => SLV_DATA_OUT, + -- gk 22.04.10 + -- registers setup interface + BUS_ADDR_IN => x"00", + BUS_DATA_IN => x"0000_0000", + BUS_DATA_OUT => open, + BUS_WRITE_EN_IN => '0', + BUS_READ_EN_IN => '0', + BUS_ACK_OUT => open, + -- gk 23.04.10 + LED_PACKET_SENT_OUT => open, + LED_AN_DONE_N_OUT => open, + -------------------------- + CTS_NUMBER_IN => CTS_NUMBER_IN, + CTS_CODE_IN => CTS_CODE_IN, + CTS_INFORMATION_IN => CTS_INFORMATION_IN, + CTS_READOUT_TYPE_IN => CTS_READOUT_TYPE_IN, + CTS_START_READOUT_IN => CTS_START_READOUT_IN, + CTS_DATA_OUT => CTS_DATA_OUT, + CTS_DATAREADY_OUT => CTS_DATAREADY_OUT, + CTS_READOUT_FINISHED_OUT => CTS_READOUT_FINISHED_OUT, + CTS_READ_IN => CTS_READ_IN, + CTS_LENGTH_OUT => CTS_LENGTH_OUT, + CTS_ERROR_PATTERN_OUT => CTS_ERROR_PATTERN_OUT, + FEE_DATA_IN => FEE_DATA_IN, + FEE_DATAREADY_IN => FEE_DATAREADY_IN, + FEE_READ_OUT => FEE_READ_OUT, + FEE_STATUS_BITS_IN => FEE_STATUS_BITS_IN, + FEE_BUSY_IN => FEE_BUSY_IN, + SFP_RXD_P_IN => SFP_RXD_P_IN, + SFP_RXD_N_IN => SFP_RXD_N_IN, + SFP_TXD_P_OUT => SFP_TXD_P_OUT, + SFP_TXD_N_OUT => SFP_TXD_N_OUT, + SFP_REFCLK_P_IN => SFP_REFCLK_P_IN, + SFP_REFCLK_N_IN => SFP_REFCLK_N_IN, + SFP_PRSNT_N_IN => SFP_PRSNT_N_IN, + SFP_LOS_IN => SFP_LOS_IN, + SFP_TXDIS_OUT => SFP_TXDIS_OUT, + -- for simulation of receiving part only + MAC_RX_EOF_IN => MAC_RX_EOF_IN, + MAC_RXD_IN => MAC_RXD_IN, + MAC_RX_EN_IN => MAC_RX_EN_IN, + ANALYZER_DEBUG_OUT => ANALYZER_DEBUG_OUT + ); + + + +-- 100 MHz system clock +CLOCK_GEN_PROC: process +begin + clk <= '1'; wait for 5.0 ns; + clk <= '0'; wait for 5.0 ns; +end process CLOCK_GEN_PROC; + +-- 125 MHz MAC clock +CLOCK2_GEN_PROC: process +begin + test_clk <= '1'; wait for 4.0 ns; + test_clk <= '0'; wait for 3.0 ns; +end process CLOCK2_GEN_PROC; + +-- Testbench +TESTBENCH_PROC: process +-- test data from TRBnet +variable test_data_len : integer range 0 to 65535 := 1; +variable test_loop_len : integer range 0 to 65535 := 0; +variable test_hdr_len : unsigned(15 downto 0) := x"0000"; +variable test_evt_len : unsigned(15 downto 0) := x"0000"; +variable test_data : unsigned(15 downto 0) := x"ffff"; +variable test_data2 : unsigned(7 downto 0) := x"ff"; + +variable trigger_counter : unsigned(15 downto 0) := x"4710"; +variable trigger_loop : integer range 0 to 65535 := 15; + +-- 1400 bytes MTU => 350 as limit for fragmentation +variable max_event_size : real := 512.0; + +variable seed1 : positive; -- seed for random generator +variable seed2 : positive; -- seed for random generator +variable rand : real; -- random value (0.0 ... 1.0) +variable int_rand : integer; -- random value, scaled to your needs +variable cts_random_number : std_logic_vector(7 downto 0); + +variable stim : std_logic_vector(15 downto 0); + +-- RND test +--UNIFORM(seed1, seed2, rand); +--int_rand := INTEGER(TRUNC(rand*65536.0)); +--stim := std_logic_vector(to_unsigned(int_rand, stim'LENGTH)); + +begin + -- Setup signals + reset <= '0'; + gsr_n <= '1'; + + stage_ctrl_regs_in <= x"0000_0000"; + + --ip_cfg_start_in <= '0'; + --ip_cfg_bank_sel_in <= x"0"; + --ip_cfg_mem_data_in <= x"0000_0000"; + mr_reset_in <= '0'; + mr_mode_in <= '0'; + mr_restart_in <= '0'; + SLV_ADDR_IN <= x"00"; + SLV_READ_IN <= '0'; + SLV_WRITE_IN <= '0'; + SLV_DATA_IN <= x"0000_0000"; + + sfp_los_in <= '0'; -- signal from SFP is present + sfp_prsnt_n_in <= '0'; -- SFP itself is present + sfp_refclk_n_in <= '0'; + sfp_refclk_p_in <= '1'; + + cts_number_in <= x"0000"; + cts_code_in <= x"00"; + cts_information_in <= x"00"; + cts_readout_type_in <= x"0"; + cts_start_readout_in <= '0'; + cts_read_in <= '0'; + + fee_data_in <= x"0000"; + fee_dataready_in <= '0'; + fee_status_bits_in <= x"1234_5678"; + fee_busy_in <= '0'; + + MAC_RX_EN_IN <= '0'; + MAC_RX_EOF_IN <= '0'; + MAC_RXD_IN <= (others => '0'); + + + wait for 22 ns; + + -- Reset the whole stuff + wait until rising_edge(clk); + reset <= '1'; + gsr_n <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + reset <= '0'; + gsr_n <= '1'; + wait until rising_edge(clk); + --wait for 100 ns; + + -- Tests may start here +-- wait until ft_bsm_init_tst = x"7"; + + --ip_cfg_start_in <= '1'; + + wait for 500 ns; + + +------------------------------------------------------------------------------- +-- Loop the transmissions +------------------------------------------------------------------------------- + trigger_counter := x"4710"; + trigger_loop := 10; + + RECEIVE_LOOP: for J in 0 to 1 loop + + wait for 200 ns; + + -- IPU transmission starts + wait until rising_edge(test_clk); + + test_data2 := x"ff"; + MY_DATA_LOOP2: for k in 0 to 200 + (J * 10) loop + test_data2 := test_data2 + 1; + wait until rising_edge(test_clk); + MAC_RXD_IN <= std_logic_vector(test_data2); + MAC_RX_EN_IN <= '1'; + end loop MY_DATA_LOOP2; + + MAC_RX_EN_IN <= '0'; + MAC_RXD_IN <= "00000000"; + MAC_RX_EOF_IN <= '1'; + wait until rising_edge(test_clk); + MAC_RX_EOF_IN <= '0'; + + --wait for 3 us; + + end loop RECEIVE_LOOP; + + MY_TRIGGER_LOOP: for J in 0 to trigger_loop loop + -- generate a real random byte for CTS + UNIFORM(seed1, seed2, rand); + int_rand := INTEGER(TRUNC(rand*256.0)); + cts_random_number := std_logic_vector(to_unsigned(int_rand, cts_random_number'LENGTH)); + + -- IPU transmission starts + wait until rising_edge(clk); + cts_number_in <= std_logic_vector( trigger_counter ); + cts_code_in <= cts_random_number; + cts_information_in <= x"d2"; -- cts_information_in <= x"de"; -- gk 29.03.10 + cts_readout_type_in <= x"1"; + cts_start_readout_in <= '1'; + wait until rising_edge(clk); + wait for 400 ns; + + wait until rising_edge(clk); + fee_busy_in <= '1'; + wait for 300 ns; + wait until rising_edge(clk); + + -- ONE DATA TRANSMISSION + -- dice a length + UNIFORM(seed1, seed2, rand); + --test_data_len := INTEGER(TRUNC(rand * 800.0)) + 1; + + --test_data_len := 9685; + test_data_len := 400; + + -- calculate the needed variables + test_loop_len := 2*(test_data_len - 1) + 1; + test_hdr_len := to_unsigned( test_data_len + 1, 16 ); + test_evt_len := to_unsigned( test_data_len, 16 ); + + -- original data block (trigger 1, random 0xaa, number 0x4711, source 0x21) + fee_dataready_in <= '1'; + fee_data_in <= x"10" & cts_random_number; + wait until rising_edge(clk) and (fee_read_out = '1'); -- transfer of first data word + fee_dataready_in <= '0'; + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_dataready_in <= '1'; + fee_data_in <= std_logic_vector( trigger_counter ); + wait until rising_edge(clk) and (fee_read_out = '1'); -- transfer of second data word + fee_dataready_in <= '0'; + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_dataready_in <= '1'; + fee_data_in <= std_logic_vector( test_hdr_len ); + wait until rising_edge(clk) and (fee_read_out = '1'); -- transfer of third data word + fee_data_in <= x"ff21"; + wait until rising_edge(clk) and (fee_read_out = '1'); -- transfer of fourth data word + fee_dataready_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_dataready_in <= '1'; + fee_data_in <= std_logic_vector( test_evt_len ); + wait until rising_edge(clk) and (fee_read_out = '1'); + fee_data_in <= x"ff22"; + wait until rising_edge(clk) and (fee_read_out = '1'); + fee_dataready_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + + test_data := x"ffff"; + MY_DATA_LOOP: for J in 0 to test_loop_len loop + test_data := test_data + 1; + wait until rising_edge(clk); + fee_data_in <= std_logic_vector(test_data); + if( (test_data MOD 5) = 0 ) then + fee_dataready_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_dataready_in <= '1'; + else + fee_dataready_in <= '1'; + end if; + --fee_dataready_in <= '1'; + end loop MY_DATA_LOOP; + -- there must be padding words to get multiple of four LWs + + wait until rising_edge(clk); + fee_dataready_in <= '0'; + fee_data_in <= x"0000"; + + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_busy_in <= '0'; + + + trigger_loop := trigger_loop + 1; + trigger_counter := trigger_counter + 1; + + wait until rising_edge(clk); + wait until rising_edge(clk); + cts_read_in <= '1'; + wait until rising_edge(clk); + cts_read_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + cts_start_readout_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + + --wait for 8 us; + + end loop MY_TRIGGER_LOOP; + + + + + + + + + +-- wait for 8 us; +------------------------------------------------------------------------------- +-- end of loop +------------------------------------------------------------------------------- + -- Stay a while... stay forever!!! + wait; + +end process TESTBENCH_PROC; + +END; + diff --git a/gbe2_ecp3/tb_ip_configurator.vhd b/gbe2_ecp3/tb_ip_configurator.vhd new file mode 100755 index 0000000..6188d42 --- /dev/null +++ b/gbe2_ecp3/tb_ip_configurator.vhd @@ -0,0 +1,145 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY testbench IS +END testbench; + +ARCHITECTURE behavior OF testbench IS + + COMPONENT ip_configurator + PORT( + CLK : IN std_logic; + RESET : IN std_logic; + START_CONFIG_IN : IN std_logic; + BANK_SELECT_IN : IN std_logic_vector(3 downto 0); + MEM_DATA_IN : IN std_logic_vector(31 downto 0); + CONFIG_DONE_OUT : OUT std_logic; + MEM_ADDR_OUT : OUT std_logic_vector(7 downto 0); + MEM_CLK_OUT : OUT std_logic; + DEST_MAC_OUT : OUT std_logic_vector(47 downto 0); + DEST_IP_OUT : OUT std_logic_vector(31 downto 0); + DEST_UDP_OUT : OUT std_logic_vector(15 downto 0); + SRC_MAC_OUT : OUT std_logic_vector(47 downto 0); + SRC_IP_OUT : OUT std_logic_vector(31 downto 0); + SRC_UDP_OUT : OUT std_logic_vector(15 downto 0); + MTU_OUT : OUT std_logic_vector(15 downto 0); + DEBUG_OUT : OUT std_logic_vector(31 downto 0) + ); + END COMPONENT; + + SIGNAL CLK : std_logic; + SIGNAL RESET : std_logic; + SIGNAL START_CONFIG_IN : std_logic; + SIGNAL BANK_SELECT_IN : std_logic_vector(3 downto 0); + SIGNAL CONFIG_DONE_OUT : std_logic; + SIGNAL MEM_ADDR_OUT : std_logic_vector(7 downto 0); + SIGNAL MEM_DATA_IN : std_logic_vector(31 downto 0); + SIGNAL MEM_CLK_OUT : std_logic; + SIGNAL DEST_MAC_OUT : std_logic_vector(47 downto 0); + SIGNAL DEST_IP_OUT : std_logic_vector(31 downto 0); + SIGNAL DEST_UDP_OUT : std_logic_vector(15 downto 0); + SIGNAL SRC_MAC_OUT : std_logic_vector(47 downto 0); + SIGNAL SRC_IP_OUT : std_logic_vector(31 downto 0); + SIGNAL SRC_UDP_OUT : std_logic_vector(15 downto 0); + SIGNAL MTU_OUT : std_logic_vector(15 downto 0); + SIGNAL DEBUG_OUT : std_logic_vector(31 downto 0); + +BEGIN + +-- Please check and add your generic clause manually + uut: ip_configurator PORT MAP( + CLK => CLK, + RESET => RESET, + START_CONFIG_IN => START_CONFIG_IN, + BANK_SELECT_IN => BANK_SELECT_IN, + CONFIG_DONE_OUT => CONFIG_DONE_OUT, + MEM_ADDR_OUT => MEM_ADDR_OUT, + MEM_DATA_IN => MEM_DATA_IN, + MEM_CLK_OUT => MEM_CLK_OUT, + DEST_MAC_OUT => DEST_MAC_OUT, + DEST_IP_OUT => DEST_IP_OUT, + DEST_UDP_OUT => DEST_UDP_OUT, + SRC_MAC_OUT => SRC_MAC_OUT, + SRC_IP_OUT => SRC_IP_OUT, + SRC_UDP_OUT => SRC_UDP_OUT, + MTU_OUT => MTU_OUT, + DEBUG_OUT => DEBUG_OUT + ); + + +CLK_GEN_PROC: process +begin + clk <= '0'; wait for 5.0 ns; + clk <= '1'; wait for 5.0 ns; +end process CLK_GEN_PROC; + +THE_TESTBENCH: process +begin + -- Setup signals + reset <= '0'; + start_config_in <= '0'; + bank_select_in <= x"0"; + mem_data_in <= x"0000_0000"; + + -- Reset the whole stuff + wait until rising_edge(clk); + reset <= '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + reset <= '0'; + wait for 100 ns; + wait until rising_edge(clk); + + -- Tests may start now + wait until rising_edge(clk); + start_config_in <= '1'; + wait until mem_addr_out(3 downto 0) = x"1"; + wait until rising_edge(clk); + mem_data_in <= x"4902d745"; -- dest MAC low + wait until rising_edge(clk); + mem_data_in <= x"00006cf0"; -- dest MAC high + wait until rising_edge(clk); + mem_data_in <= x"c0a80002"; -- dest IP + wait until rising_edge(clk); + mem_data_in <= x"0000c350"; -- dest port + wait until rising_edge(clk); + mem_data_in <= x"eeeeeeee"; -- src MAC low + wait until rising_edge(clk); + mem_data_in <= x"0000eeee"; -- src MAC high + wait until rising_edge(clk); + mem_data_in <= x"c0a80005"; -- src IP + wait until rising_edge(clk); + mem_data_in <= x"0000c350"; -- src port + wait until rising_edge(clk); + mem_data_in <= x"00000578"; -- MTU + wait until rising_edge(clk); + mem_data_in <= x"99999999"; + wait until rising_edge(clk); + mem_data_in <= x"aaaaaaaa"; + wait until rising_edge(clk); + mem_data_in <= x"bbbbbbbb"; + wait until rising_edge(clk); + mem_data_in <= x"cccccccc"; + wait until rising_edge(clk); + mem_data_in <= x"dddddddd"; + wait until rising_edge(clk); + mem_data_in <= x"eeeeeeee"; + wait until rising_edge(clk); + mem_data_in <= x"ffffffff"; + wait until rising_edge(clk); + mem_data_in <= x"00000000"; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + start_config_in <= '0'; + + -- Stay a while... stay forever!!! Muahahaha!!!!! + wait; +end process THE_TESTBENCH; + + +END; diff --git a/gbe2_ecp3/tb_ipu2gbe.vhd b/gbe2_ecp3/tb_ipu2gbe.vhd new file mode 100755 index 0000000..065e674 --- /dev/null +++ b/gbe2_ecp3/tb_ipu2gbe.vhd @@ -0,0 +1,428 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.math_real.all; +USE ieee.numeric_std.ALL; + +ENTITY testbench IS +END testbench; + +ARCHITECTURE behavior OF testbench IS + + COMPONENT trb_net16_ipu2gbe + PORT( + CLK : IN std_logic; + RESET : IN std_logic; + START_CONFIG_OUT : OUT std_logic; + BANK_SELECT_OUT : OUT std_logic_vector(3 downto 0); + CONFIG_DONE_IN : IN std_logic; + DATA_GBE_ENABLE_IN : IN std_logic; + DATA_IPU_ENABLE_IN : IN std_logic; + MULTI_EVT_ENABLE_IN : IN std_logic; + CTS_NUMBER_IN : IN std_logic_vector(15 downto 0); + CTS_CODE_IN : IN std_logic_vector(7 downto 0); + CTS_INFORMATION_IN : IN std_logic_vector(7 downto 0); + CTS_READOUT_TYPE_IN : IN std_logic_vector(3 downto 0); + CTS_START_READOUT_IN : IN std_logic; + CTS_READ_IN : IN std_logic; + FEE_DATA_IN : IN std_logic_vector(15 downto 0); + FEE_DATAREADY_IN : IN std_logic; + FEE_BUSY_IN : IN std_logic; + FEE_STATUS_BITS_IN : IN std_logic_vector(31 downto 0); + PC_READY_IN : IN std_logic; + CTS_DATA_OUT : OUT std_logic_vector(31 downto 0); + CTS_DATAREADY_OUT : OUT std_logic; + CTS_READOUT_FINISHED_OUT : OUT std_logic; + CTS_LENGTH_OUT : OUT std_logic_vector(15 downto 0); + CTS_ERROR_PATTERN_OUT : OUT std_logic_vector(31 downto 0); + FEE_READ_OUT : OUT std_logic; + PC_WR_EN_OUT : OUT std_logic; + PC_DATA_OUT : OUT std_logic_vector(7 downto 0); + PC_SOS_OUT : OUT std_logic; + PC_EOD_OUT : OUT std_logic; + PC_SUB_SIZE_OUT : OUT std_logic_vector(31 downto 0); + PC_TRIG_NR_OUT : OUT std_logic_vector(31 downto 0); + PC_PADDING_OUT : OUT std_logic; + BSM_SAVE_OUT : OUT std_logic_vector(3 downto 0); + BSM_LOAD_OUT : OUT std_logic_vector(3 downto 0); + DBG_REM_CTR_OUT : OUT std_logic_vector(3 downto 0); + DBG_CTS_CTR_OUT : OUT std_logic_vector(2 downto 0); + DBG_SF_WCNT_OUT : OUT std_logic_vector(15 downto 0); + DBG_SF_RCNT_OUT : OUT std_logic_vector(16 downto 0); + DBG_SF_DATA_OUT : OUT std_logic_vector(15 downto 0); + DBG_SF_RD_EN_OUT : OUT std_logic; + DBG_SF_WR_EN_OUT : OUT std_logic; + DBG_SF_EMPTY_OUT : OUT std_logic; + DBG_SF_AEMPTY_OUT : OUT std_logic; + DBG_SF_FULL_OUT : OUT std_logic; + DBG_SF_AFULL_OUT : OUT std_logic; + DEBUG_OUT : OUT std_logic_vector(31 downto 0) + ); + END COMPONENT; + + SIGNAL CLK : std_logic; + SIGNAL RESET : std_logic; + SIGNAL START_CONFIG_OUT : std_logic; + SIGNAL BANK_SELECT_OUT : std_logic_vector(3 downto 0); + SIGNAL CONFIG_DONE_IN : std_logic; + SIGNAL DATA_GBE_ENABLE_IN : std_logic; + SIGNAL DATA_IPU_ENABLE_IN : std_logic; + SIGNAL MULTI_EVT_ENABLE_IN : std_logic; + SIGNAL CTS_NUMBER_IN : std_logic_vector(15 downto 0); + SIGNAL CTS_CODE_IN : std_logic_vector(7 downto 0); + SIGNAL CTS_INFORMATION_IN : std_logic_vector(7 downto 0); + SIGNAL CTS_READOUT_TYPE_IN : std_logic_vector(3 downto 0); + SIGNAL CTS_START_READOUT_IN : std_logic; + SIGNAL CTS_READ_IN : std_logic; + SIGNAL CTS_DATA_OUT : std_logic_vector(31 downto 0); + SIGNAL CTS_DATAREADY_OUT : std_logic; + SIGNAL CTS_READOUT_FINISHED_OUT : std_logic; + SIGNAL CTS_LENGTH_OUT : std_logic_vector(15 downto 0); + SIGNAL CTS_ERROR_PATTERN_OUT : std_logic_vector(31 downto 0); + SIGNAL FEE_DATA_IN : std_logic_vector(15 downto 0); + SIGNAL FEE_DATAREADY_IN : std_logic; + SIGNAL FEE_READ_OUT : std_logic; + SIGNAL FEE_BUSY_IN : std_logic; + SIGNAL FEE_STATUS_BITS_IN : std_logic_vector(31 downto 0); + SIGNAL PC_WR_EN_OUT : std_logic; + SIGNAL PC_DATA_OUT : std_logic_vector(7 downto 0); + SIGNAL PC_READY_IN : std_logic; + SIGNAL PC_SOS_OUT : std_logic; + SIGNAL PC_EOD_OUT : std_logic; + SIGNAL PC_SUB_SIZE_OUT : std_logic_vector(31 downto 0); + SIGNAL PC_TRIG_NR_OUT : std_logic_vector(31 downto 0); + SIGNAL PC_PADDING_OUT : std_logic; + SIGNAL BSM_SAVE_OUT : std_logic_vector(3 downto 0); + SIGNAL BSM_LOAD_OUT : std_logic_vector(3 downto 0); + SIGNAL DBG_REM_CTR_OUT : std_logic_vector(3 downto 0); + SIGNAL DBG_CTS_CTR_OUT : std_logic_vector(2 downto 0); + SIGNAL DBG_SF_WCNT_OUT : std_logic_vector(15 downto 0); + SIGNAL DBG_SF_RCNT_OUT : std_logic_vector(16 downto 0); + SIGNAL DBG_SF_DATA_OUT : std_logic_vector(15 downto 0); + SIGNAL DBG_SF_RD_EN_OUT : std_logic; + SIGNAL DBG_SF_WR_EN_OUT : std_logic; + SIGNAL DBG_SF_EMPTY_OUT : std_logic; + SIGNAL DBG_SF_AEMPTY_OUT : std_logic; + SIGNAL DBG_SF_FULL_OUT : std_logic; + SIGNAL DBG_SF_AFULL_OUT : std_logic; + SIGNAL DEBUG_OUT : std_logic_vector(31 downto 0); + +BEGIN + +-- Please check and add your generic clause manually + uut: trb_net16_ipu2gbe PORT MAP( + CLK => CLK, + RESET => RESET, + START_CONFIG_OUT => START_CONFIG_OUT, + BANK_SELECT_OUT => BANK_SELECT_OUT, + CONFIG_DONE_IN => CONFIG_DONE_IN, + DATA_GBE_ENABLE_IN => DATA_GBE_ENABLE_IN, + DATA_IPU_ENABLE_IN => DATA_IPU_ENABLE_IN, + MULTI_EVT_ENABLE_IN => MULTI_EVT_ENABLE_IN, + CTS_NUMBER_IN => CTS_NUMBER_IN, + CTS_CODE_IN => CTS_CODE_IN, + CTS_INFORMATION_IN => CTS_INFORMATION_IN, + CTS_READOUT_TYPE_IN => CTS_READOUT_TYPE_IN, + CTS_START_READOUT_IN => CTS_START_READOUT_IN, + CTS_READ_IN => CTS_READ_IN, + CTS_DATA_OUT => CTS_DATA_OUT, + CTS_DATAREADY_OUT => CTS_DATAREADY_OUT, + CTS_READOUT_FINISHED_OUT => CTS_READOUT_FINISHED_OUT, + CTS_LENGTH_OUT => CTS_LENGTH_OUT, + CTS_ERROR_PATTERN_OUT => CTS_ERROR_PATTERN_OUT, + FEE_DATA_IN => FEE_DATA_IN, + FEE_DATAREADY_IN => FEE_DATAREADY_IN, + FEE_READ_OUT => FEE_READ_OUT, + FEE_BUSY_IN => FEE_BUSY_IN, + FEE_STATUS_BITS_IN => FEE_STATUS_BITS_IN, + PC_WR_EN_OUT => PC_WR_EN_OUT, + PC_DATA_OUT => PC_DATA_OUT, + PC_READY_IN => PC_READY_IN, + PC_SOS_OUT => PC_SOS_OUT, + PC_EOD_OUT => PC_EOD_OUT, + PC_SUB_SIZE_OUT => PC_SUB_SIZE_OUT, + PC_TRIG_NR_OUT => PC_TRIG_NR_OUT, + PC_PADDING_OUT => PC_PADDING_OUT, + BSM_SAVE_OUT => BSM_SAVE_OUT, + BSM_LOAD_OUT => BSM_LOAD_OUT, + DBG_REM_CTR_OUT => DBG_REM_CTR_OUT, + DBG_CTS_CTR_OUT => DBG_CTS_CTR_OUT, + DBG_SF_WCNT_OUT => DBG_SF_WCNT_OUT, + DBG_SF_RCNT_OUT => DBG_SF_RCNT_OUT, + DBG_SF_DATA_OUT => DBG_SF_DATA_OUT, + DBG_SF_RD_EN_OUT => DBG_SF_RD_EN_OUT, + DBG_SF_WR_EN_OUT => DBG_SF_WR_EN_OUT, + DBG_SF_EMPTY_OUT => DBG_SF_EMPTY_OUT, + DBG_SF_AEMPTY_OUT => DBG_SF_AEMPTY_OUT, + DBG_SF_FULL_OUT => DBG_SF_FULL_OUT, + DBG_SF_AFULL_OUT => DBG_SF_AFULL_OUT, + DEBUG_OUT => DEBUG_OUT + ); + +CLOCK_GEN: process +begin + clk <= '1'; wait for 5.0 ns; + clk <= '0'; wait for 5.0 ns; +end process CLOCK_GEN; + +PC_READY_PROC: process +begin + pc_ready_in <= '0'; + wait for 500 ns; + pc_ready_in <= '1'; + wait for 500 ns; + pc_ready_in <= '0'; + wait for 99 us; +end process PC_READY_PROC; + +-- Testbench +TESTBENCH_PROC: process +-- test data from TRBnet +variable test_data_len : integer range 0 to 65535 := 1; +variable test_loop_len : integer range 0 to 65535 := 0; +variable test_hdr_len : unsigned(15 downto 0) := x"0000"; +variable test_evt_len : unsigned(15 downto 0) := x"0000"; +variable test_data : unsigned(15 downto 0) := x"ffff"; + +variable trigger_counter : unsigned(15 downto 0) := x"4710"; +variable trigger_loop : integer range 0 to 65535 := 15; + +-- 1400 bytes MTU => 350 as limit for fragmentation +--variable max_event_size : real := 512.0; +variable max_event_size : real := 17.0; + +variable seed1 : positive; -- seed for random generator +variable seed2 : positive; -- seed for random generator +variable rand : real; -- random value (0.0 ... 1.0) +variable int_rand : integer; -- random value, scaled to your needs +variable cts_random_number : std_logic_vector(7 downto 0); + +variable stim : std_logic_vector(15 downto 0); + +begin + -- Setup signals + reset <= '0'; + cts_number_in <= x"0000"; + cts_code_in <= x"00"; + cts_information_in <= x"00"; + cts_readout_type_in <= x"0"; + cts_start_readout_in <= '0'; + cts_read_in <= '0'; + fee_data_in <= x"0000"; + fee_dataready_in <= '0'; + fee_status_bits_in <= x"0000_0000"; + fee_busy_in <= '0'; +-- pc_ready_in <= '0'; + + config_done_in <= '1'; + data_gbe_enable_in <= '1'; + data_ipu_enable_in <= '0'; + multi_evt_enable_in <= '0'; + + wait for 22 ns; + + -- Reset the whole stuff + wait until rising_edge(clk); + reset <= '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + reset <= '0'; + wait until rising_edge(clk); + wait for 200 ns; + +--------------------------- + +------------------------------------------------------------------------------- +-- Loop the transmissions +------------------------------------------------------------------------------- + trigger_counter := x"4710"; + trigger_loop := 2; + + MY_TRIGGER_LOOP: for J in 0 to trigger_loop loop + -- generate a real random byte for CTS + UNIFORM(seed1, seed2, rand); + int_rand := INTEGER(TRUNC(rand*256.0)); + cts_random_number := std_logic_vector(to_unsigned(int_rand, cts_random_number'LENGTH)); + + -- IPU transmission starts + wait until rising_edge(clk); + cts_number_in <= std_logic_vector( trigger_counter ); + cts_code_in <= cts_random_number; + cts_information_in <= x"de"; + cts_readout_type_in <= x"1"; + cts_start_readout_in <= '1'; + wait until rising_edge(clk); + wait for 400 ns; + + wait until rising_edge(clk); + fee_busy_in <= '1'; + wait for 300 ns; + wait until rising_edge(clk); + + -- ONE DATA TRANSMISSION + -- dice a length + UNIFORM(seed1, seed2, rand); + test_data_len := INTEGER(TRUNC(rand*max_event_size)) + 1; + +-- test_data_len := 9685; + + -- calculate the needed variables + test_loop_len := 2*(test_data_len - 1) + 1; + test_hdr_len := to_unsigned( test_data_len + 1, 16 ); + test_evt_len := to_unsigned( test_data_len, 16 ); + + -- original data block (trigger 1, random 0xaa, number 0x4711, source 0x21) + fee_dataready_in <= '1'; + fee_data_in <= x"10" & cts_random_number; + wait until rising_edge(clk) and (fee_read_out = '1'); -- transfer of first data word + fee_dataready_in <= '0'; + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_dataready_in <= '1'; + fee_data_in <= std_logic_vector( trigger_counter ); + wait until rising_edge(clk) and (fee_read_out = '1'); -- transfer of second data word + fee_dataready_in <= '0'; + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_dataready_in <= '1'; + fee_data_in <= std_logic_vector( test_hdr_len ); + wait until rising_edge(clk) and (fee_read_out = '1'); -- transfer of third data word + fee_data_in <= x"ff21"; + wait until rising_edge(clk) and (fee_read_out = '1'); -- transfer of fourth data word + fee_dataready_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_dataready_in <= '1'; + fee_data_in <= std_logic_vector( test_evt_len ); + wait until rising_edge(clk) and (fee_read_out = '1'); + fee_data_in <= x"ff22"; + wait until rising_edge(clk) and (fee_read_out = '1'); + fee_dataready_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + + test_data := x"ffff"; + MY_DATA_LOOP: for J in 0 to test_loop_len loop + test_data := test_data + 1; + wait until rising_edge(clk) and (fee_read_out = '1'); -- + fee_data_in <= std_logic_vector(test_data); + if( (test_data MOD 5) = 0 ) then + fee_dataready_in <= '0'; +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_dataready_in <= '1'; + else + fee_dataready_in <= '1'; + end if; + end loop MY_DATA_LOOP; + -- there must be padding words to get multiple of four LWs + + wait until rising_edge(clk); + fee_dataready_in <= '0'; + fee_data_in <= x"0000"; + + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_busy_in <= '0'; + + + trigger_loop := trigger_loop + 1; + trigger_counter := trigger_counter + 1; + + wait until rising_edge(clk); + wait until rising_edge(clk); + cts_read_in <= '1'; + wait until rising_edge(clk); + cts_read_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + cts_start_readout_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + + --wait for 8 us; + + end loop MY_TRIGGER_LOOP; + + + +--------------------------- +--------------------------- + wait for 300 ns; + + wait; + + -- Start packet_constructor + wait until rising_edge(clk); + wait until rising_edge(clk); +-- pc_ready_in <= '1'; + wait until rising_edge(clk); + + wait until rising_edge(clk); + wait until pc_eod_out = '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); +-- pc_ready_in <= '0'; + + -- Stay a while... stay forever!!! + wait; + +end process TESTBENCH_PROC; + + +END; diff --git a/gbe2_ecp3/tb_ipu2gbe_NEW.vhd b/gbe2_ecp3/tb_ipu2gbe_NEW.vhd new file mode 100755 index 0000000..bd8b288 --- /dev/null +++ b/gbe2_ecp3/tb_ipu2gbe_NEW.vhd @@ -0,0 +1,428 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.math_real.all; +USE ieee.numeric_std.ALL; + +ENTITY testbench IS +END testbench; + +ARCHITECTURE behavior OF testbench IS + + COMPONENT trb_net16_ipu2gbe_new + PORT( + CLK : IN std_logic; + RESET : IN std_logic; + START_CONFIG_OUT : OUT std_logic; + BANK_SELECT_OUT : OUT std_logic_vector(3 downto 0); + CONFIG_DONE_IN : IN std_logic; + DATA_GBE_ENABLE_IN : IN std_logic; + DATA_IPU_ENABLE_IN : IN std_logic; + MULTI_EVT_ENABLE_IN : IN std_logic; + CTS_NUMBER_IN : IN std_logic_vector(15 downto 0); + CTS_CODE_IN : IN std_logic_vector(7 downto 0); + CTS_INFORMATION_IN : IN std_logic_vector(7 downto 0); + CTS_READOUT_TYPE_IN : IN std_logic_vector(3 downto 0); + CTS_START_READOUT_IN : IN std_logic; + CTS_READ_IN : IN std_logic; + FEE_DATA_IN : IN std_logic_vector(15 downto 0); + FEE_DATAREADY_IN : IN std_logic; + FEE_BUSY_IN : IN std_logic; + FEE_STATUS_BITS_IN : IN std_logic_vector(31 downto 0); + PC_READY_IN : IN std_logic; + CTS_DATA_OUT : OUT std_logic_vector(31 downto 0); + CTS_DATAREADY_OUT : OUT std_logic; + CTS_READOUT_FINISHED_OUT : OUT std_logic; + CTS_LENGTH_OUT : OUT std_logic_vector(15 downto 0); + CTS_ERROR_PATTERN_OUT : OUT std_logic_vector(31 downto 0); + FEE_READ_OUT : OUT std_logic; + PC_WR_EN_OUT : OUT std_logic; + PC_DATA_OUT : OUT std_logic_vector(7 downto 0); + PC_SOS_OUT : OUT std_logic; + PC_EOD_OUT : OUT std_logic; + PC_SUB_SIZE_OUT : OUT std_logic_vector(31 downto 0); + PC_TRIG_NR_OUT : OUT std_logic_vector(31 downto 0); + PC_PADDING_OUT : OUT std_logic; + BSM_SAVE_OUT : OUT std_logic_vector(3 downto 0); + BSM_LOAD_OUT : OUT std_logic_vector(3 downto 0); + DBG_REM_CTR_OUT : OUT std_logic_vector(3 downto 0); + DBG_CTS_CTR_OUT : OUT std_logic_vector(2 downto 0); + DBG_SF_WCNT_OUT : OUT std_logic_vector(15 downto 0); + DBG_SF_RCNT_OUT : OUT std_logic_vector(16 downto 0); + DBG_SF_DATA_OUT : OUT std_logic_vector(15 downto 0); + DBG_SF_RD_EN_OUT : OUT std_logic; + DBG_SF_WR_EN_OUT : OUT std_logic; + DBG_SF_EMPTY_OUT : OUT std_logic; + DBG_SF_AEMPTY_OUT : OUT std_logic; + DBG_SF_FULL_OUT : OUT std_logic; + DBG_SF_AFULL_OUT : OUT std_logic; + DEBUG_OUT : OUT std_logic_vector(31 downto 0) + ); + END COMPONENT; + + SIGNAL CLK : std_logic; + SIGNAL RESET : std_logic; + SIGNAL START_CONFIG_OUT : std_logic; + SIGNAL BANK_SELECT_OUT : std_logic_vector(3 downto 0); + SIGNAL CONFIG_DONE_IN : std_logic; + SIGNAL DATA_GBE_ENABLE_IN : std_logic; + SIGNAL DATA_IPU_ENABLE_IN : std_logic; + SIGNAL MULTI_EVT_ENABLE_IN : std_logic; + SIGNAL CTS_NUMBER_IN : std_logic_vector(15 downto 0); + SIGNAL CTS_CODE_IN : std_logic_vector(7 downto 0); + SIGNAL CTS_INFORMATION_IN : std_logic_vector(7 downto 0); + SIGNAL CTS_READOUT_TYPE_IN : std_logic_vector(3 downto 0); + SIGNAL CTS_START_READOUT_IN : std_logic; + SIGNAL CTS_READ_IN : std_logic; + SIGNAL CTS_DATA_OUT : std_logic_vector(31 downto 0); + SIGNAL CTS_DATAREADY_OUT : std_logic; + SIGNAL CTS_READOUT_FINISHED_OUT : std_logic; + SIGNAL CTS_LENGTH_OUT : std_logic_vector(15 downto 0); + SIGNAL CTS_ERROR_PATTERN_OUT : std_logic_vector(31 downto 0); + SIGNAL FEE_DATA_IN : std_logic_vector(15 downto 0); + SIGNAL FEE_DATAREADY_IN : std_logic; + SIGNAL FEE_READ_OUT : std_logic; + SIGNAL FEE_BUSY_IN : std_logic; + SIGNAL FEE_STATUS_BITS_IN : std_logic_vector(31 downto 0); + SIGNAL PC_WR_EN_OUT : std_logic; + SIGNAL PC_DATA_OUT : std_logic_vector(7 downto 0); + SIGNAL PC_READY_IN : std_logic; + SIGNAL PC_SOS_OUT : std_logic; + SIGNAL PC_EOD_OUT : std_logic; + SIGNAL PC_SUB_SIZE_OUT : std_logic_vector(31 downto 0); + SIGNAL PC_TRIG_NR_OUT : std_logic_vector(31 downto 0); + SIGNAL PC_PADDING_OUT : std_logic; + SIGNAL BSM_SAVE_OUT : std_logic_vector(3 downto 0); + SIGNAL BSM_LOAD_OUT : std_logic_vector(3 downto 0); + SIGNAL DBG_REM_CTR_OUT : std_logic_vector(3 downto 0); + SIGNAL DBG_CTS_CTR_OUT : std_logic_vector(2 downto 0); + SIGNAL DBG_SF_WCNT_OUT : std_logic_vector(15 downto 0); + SIGNAL DBG_SF_RCNT_OUT : std_logic_vector(16 downto 0); + SIGNAL DBG_SF_DATA_OUT : std_logic_vector(15 downto 0); + SIGNAL DBG_SF_RD_EN_OUT : std_logic; + SIGNAL DBG_SF_WR_EN_OUT : std_logic; + SIGNAL DBG_SF_EMPTY_OUT : std_logic; + SIGNAL DBG_SF_AEMPTY_OUT : std_logic; + SIGNAL DBG_SF_FULL_OUT : std_logic; + SIGNAL DBG_SF_AFULL_OUT : std_logic; + SIGNAL DEBUG_OUT : std_logic_vector(31 downto 0); + +BEGIN + +-- Please check and add your generic clause manually + uut: trb_net16_ipu2gbe_new PORT MAP( + CLK => CLK, + RESET => RESET, + START_CONFIG_OUT => START_CONFIG_OUT, + BANK_SELECT_OUT => BANK_SELECT_OUT, + CONFIG_DONE_IN => CONFIG_DONE_IN, + DATA_GBE_ENABLE_IN => DATA_GBE_ENABLE_IN, + DATA_IPU_ENABLE_IN => DATA_IPU_ENABLE_IN, + MULTI_EVT_ENABLE_IN => MULTI_EVT_ENABLE_IN, + CTS_NUMBER_IN => CTS_NUMBER_IN, + CTS_CODE_IN => CTS_CODE_IN, + CTS_INFORMATION_IN => CTS_INFORMATION_IN, + CTS_READOUT_TYPE_IN => CTS_READOUT_TYPE_IN, + CTS_START_READOUT_IN => CTS_START_READOUT_IN, + CTS_READ_IN => CTS_READ_IN, + CTS_DATA_OUT => CTS_DATA_OUT, + CTS_DATAREADY_OUT => CTS_DATAREADY_OUT, + CTS_READOUT_FINISHED_OUT => CTS_READOUT_FINISHED_OUT, + CTS_LENGTH_OUT => CTS_LENGTH_OUT, + CTS_ERROR_PATTERN_OUT => CTS_ERROR_PATTERN_OUT, + FEE_DATA_IN => FEE_DATA_IN, + FEE_DATAREADY_IN => FEE_DATAREADY_IN, + FEE_READ_OUT => FEE_READ_OUT, + FEE_BUSY_IN => FEE_BUSY_IN, + FEE_STATUS_BITS_IN => FEE_STATUS_BITS_IN, + PC_WR_EN_OUT => PC_WR_EN_OUT, + PC_DATA_OUT => PC_DATA_OUT, + PC_READY_IN => PC_READY_IN, + PC_SOS_OUT => PC_SOS_OUT, + PC_EOD_OUT => PC_EOD_OUT, + PC_SUB_SIZE_OUT => PC_SUB_SIZE_OUT, + PC_TRIG_NR_OUT => PC_TRIG_NR_OUT, + PC_PADDING_OUT => PC_PADDING_OUT, + BSM_SAVE_OUT => BSM_SAVE_OUT, + BSM_LOAD_OUT => BSM_LOAD_OUT, + DBG_REM_CTR_OUT => DBG_REM_CTR_OUT, + DBG_CTS_CTR_OUT => DBG_CTS_CTR_OUT, + DBG_SF_WCNT_OUT => DBG_SF_WCNT_OUT, + DBG_SF_RCNT_OUT => DBG_SF_RCNT_OUT, + DBG_SF_DATA_OUT => DBG_SF_DATA_OUT, + DBG_SF_RD_EN_OUT => DBG_SF_RD_EN_OUT, + DBG_SF_WR_EN_OUT => DBG_SF_WR_EN_OUT, + DBG_SF_EMPTY_OUT => DBG_SF_EMPTY_OUT, + DBG_SF_AEMPTY_OUT => DBG_SF_AEMPTY_OUT, + DBG_SF_FULL_OUT => DBG_SF_FULL_OUT, + DBG_SF_AFULL_OUT => DBG_SF_AFULL_OUT, + DEBUG_OUT => DEBUG_OUT + ); + +CLOCK_GEN: process +begin + clk <= '1'; wait for 5.0 ns; + clk <= '0'; wait for 5.0 ns; +end process CLOCK_GEN; + +PC_READY_PROC: process +begin + pc_ready_in <= '0'; + wait for 500 ns; + pc_ready_in <= '1'; + wait for 500 ns; + pc_ready_in <= '0'; + wait for 99 us; +end process PC_READY_PROC; + +-- Testbench +TESTBENCH_PROC: process +-- test data from TRBnet +variable test_data_len : integer range 0 to 65535 := 1; +variable test_loop_len : integer range 0 to 65535 := 0; +variable test_hdr_len : unsigned(15 downto 0) := x"0000"; +variable test_evt_len : unsigned(15 downto 0) := x"0000"; +variable test_data : unsigned(15 downto 0) := x"ffff"; + +variable trigger_counter : unsigned(15 downto 0) := x"4710"; +variable trigger_loop : integer range 0 to 65535 := 15; + +-- 1400 bytes MTU => 350 as limit for fragmentation +--variable max_event_size : real := 512.0; +variable max_event_size : real := 17.0; + +variable seed1 : positive; -- seed for random generator +variable seed2 : positive; -- seed for random generator +variable rand : real; -- random value (0.0 ... 1.0) +variable int_rand : integer; -- random value, scaled to your needs +variable cts_random_number : std_logic_vector(7 downto 0); + +variable stim : std_logic_vector(15 downto 0); + +begin + -- Setup signals + reset <= '0'; + cts_number_in <= x"0000"; + cts_code_in <= x"00"; + cts_information_in <= x"00"; + cts_readout_type_in <= x"0"; + cts_start_readout_in <= '0'; + cts_read_in <= '0'; + fee_data_in <= x"0000"; + fee_dataready_in <= '0'; + fee_status_bits_in <= x"0000_0000"; + fee_busy_in <= '0'; +-- pc_ready_in <= '0'; + + config_done_in <= '1'; + data_gbe_enable_in <= '1'; + data_ipu_enable_in <= '0'; + multi_evt_enable_in <= '0'; + + wait for 22 ns; + + -- Reset the whole stuff + wait until rising_edge(clk); + reset <= '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + reset <= '0'; + wait until rising_edge(clk); + wait for 200 ns; + +--------------------------- + +------------------------------------------------------------------------------- +-- Loop the transmissions +------------------------------------------------------------------------------- + trigger_counter := x"4710"; + trigger_loop := 2; + + MY_TRIGGER_LOOP: for J in 0 to trigger_loop loop + -- generate a real random byte for CTS + UNIFORM(seed1, seed2, rand); + int_rand := INTEGER(TRUNC(rand*256.0)); + cts_random_number := std_logic_vector(to_unsigned(int_rand, cts_random_number'LENGTH)); + + -- IPU transmission starts + wait until rising_edge(clk); + cts_number_in <= std_logic_vector( trigger_counter ); + cts_code_in <= cts_random_number; + cts_information_in <= x"de"; + cts_readout_type_in <= x"1"; + cts_start_readout_in <= '1'; + wait until rising_edge(clk); + wait for 400 ns; + + wait until rising_edge(clk); + fee_busy_in <= '1'; + wait for 300 ns; + wait until rising_edge(clk); + + -- ONE DATA TRANSMISSION + -- dice a length + UNIFORM(seed1, seed2, rand); + test_data_len := INTEGER(TRUNC(rand*max_event_size)) + 1; + +-- test_data_len := 9685; + + -- calculate the needed variables + test_loop_len := 2*(test_data_len - 1) + 1; + test_hdr_len := to_unsigned( test_data_len + 1, 16 ); + test_evt_len := to_unsigned( test_data_len, 16 ); + + -- original data block (trigger 1, random 0xaa, number 0x4711, source 0x21) + fee_dataready_in <= '1'; + fee_data_in <= x"10" & cts_random_number; + wait until rising_edge(clk) and (fee_read_out = '1'); -- transfer of first data word +-- fee_dataready_in <= '0'; +-- wait until rising_edge(clk); -- BLA +-- wait until rising_edge(clk); -- BLA +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- fee_dataready_in <= '1'; + fee_data_in <= std_logic_vector( trigger_counter ); + wait until rising_edge(clk) and (fee_read_out = '1'); -- transfer of second data word + fee_dataready_in <= '0'; + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_dataready_in <= '1'; + fee_data_in <= std_logic_vector( test_hdr_len ); + wait until rising_edge(clk) and (fee_read_out = '1'); -- transfer of third data word + fee_data_in <= x"ff21"; + wait until rising_edge(clk) and (fee_read_out = '1'); -- transfer of fourth data word + fee_dataready_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_dataready_in <= '1'; + fee_data_in <= std_logic_vector( test_evt_len ); + wait until rising_edge(clk) and (fee_read_out = '1'); + fee_data_in <= x"ff22"; + wait until rising_edge(clk) and (fee_read_out = '1'); + fee_dataready_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + + test_data := x"ffff"; + MY_DATA_LOOP: for J in 0 to test_loop_len loop + test_data := test_data + 1; + wait until rising_edge(clk) and (fee_read_out = '1'); -- + fee_data_in <= std_logic_vector(test_data); + if( (test_data MOD 5) = 0 ) then + fee_dataready_in <= '0'; +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_dataready_in <= '1'; + else + fee_dataready_in <= '1'; + end if; + end loop MY_DATA_LOOP; + -- there must be padding words to get multiple of four LWs + + wait until rising_edge(clk); + fee_dataready_in <= '0'; + fee_data_in <= x"0000"; + + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_busy_in <= '0'; + + + trigger_loop := trigger_loop + 1; + trigger_counter := trigger_counter + 1; + + wait until rising_edge(clk); + wait until rising_edge(clk); + cts_read_in <= '1'; + wait until rising_edge(clk); + cts_read_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + cts_start_readout_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + + --wait for 8 us; + + end loop MY_TRIGGER_LOOP; + + + +--------------------------- +--------------------------- + wait for 300 ns; + + wait; + + -- Start packet_constructor + wait until rising_edge(clk); + wait until rising_edge(clk); +-- pc_ready_in <= '1'; + wait until rising_edge(clk); + + wait until rising_edge(clk); + wait until pc_eod_out = '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); +-- pc_ready_in <= '0'; + + -- Stay a while... stay forever!!! + wait; + +end process TESTBENCH_PROC; + + +END; diff --git a/gbe2_ecp3/tb_ipu2gbe_OLD.vhd b/gbe2_ecp3/tb_ipu2gbe_OLD.vhd new file mode 100755 index 0000000..088bfb2 --- /dev/null +++ b/gbe2_ecp3/tb_ipu2gbe_OLD.vhd @@ -0,0 +1,428 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.math_real.all; +USE ieee.numeric_std.ALL; + +ENTITY testbench IS +END testbench; + +ARCHITECTURE behavior OF testbench IS + + COMPONENT trb_net16_ipu2gbe + PORT( + CLK : IN std_logic; + RESET : IN std_logic; + START_CONFIG_OUT : OUT std_logic; + BANK_SELECT_OUT : OUT std_logic_vector(3 downto 0); + CONFIG_DONE_IN : IN std_logic; + DATA_GBE_ENABLE_IN : IN std_logic; + DATA_IPU_ENABLE_IN : IN std_logic; + MULTI_EVT_ENABLE_IN : IN std_logic; + CTS_NUMBER_IN : IN std_logic_vector(15 downto 0); + CTS_CODE_IN : IN std_logic_vector(7 downto 0); + CTS_INFORMATION_IN : IN std_logic_vector(7 downto 0); + CTS_READOUT_TYPE_IN : IN std_logic_vector(3 downto 0); + CTS_START_READOUT_IN : IN std_logic; + CTS_READ_IN : IN std_logic; + FEE_DATA_IN : IN std_logic_vector(15 downto 0); + FEE_DATAREADY_IN : IN std_logic; + FEE_BUSY_IN : IN std_logic; + FEE_STATUS_BITS_IN : IN std_logic_vector(31 downto 0); + PC_READY_IN : IN std_logic; + CTS_DATA_OUT : OUT std_logic_vector(31 downto 0); + CTS_DATAREADY_OUT : OUT std_logic; + CTS_READOUT_FINISHED_OUT : OUT std_logic; + CTS_LENGTH_OUT : OUT std_logic_vector(15 downto 0); + CTS_ERROR_PATTERN_OUT : OUT std_logic_vector(31 downto 0); + FEE_READ_OUT : OUT std_logic; + PC_WR_EN_OUT : OUT std_logic; + PC_DATA_OUT : OUT std_logic_vector(7 downto 0); + PC_SOS_OUT : OUT std_logic; + PC_EOD_OUT : OUT std_logic; + PC_SUB_SIZE_OUT : OUT std_logic_vector(31 downto 0); + PC_TRIG_NR_OUT : OUT std_logic_vector(31 downto 0); + PC_PADDING_OUT : OUT std_logic; + BSM_SAVE_OUT : OUT std_logic_vector(3 downto 0); + BSM_LOAD_OUT : OUT std_logic_vector(3 downto 0); + DBG_REM_CTR_OUT : OUT std_logic_vector(3 downto 0); + DBG_CTS_CTR_OUT : OUT std_logic_vector(2 downto 0); + DBG_SF_WCNT_OUT : OUT std_logic_vector(15 downto 0); + DBG_SF_RCNT_OUT : OUT std_logic_vector(16 downto 0); + DBG_SF_DATA_OUT : OUT std_logic_vector(15 downto 0); + DBG_SF_RD_EN_OUT : OUT std_logic; + DBG_SF_WR_EN_OUT : OUT std_logic; + DBG_SF_EMPTY_OUT : OUT std_logic; + DBG_SF_AEMPTY_OUT : OUT std_logic; + DBG_SF_FULL_OUT : OUT std_logic; + DBG_SF_AFULL_OUT : OUT std_logic; + DEBUG_OUT : OUT std_logic_vector(31 downto 0) + ); + END COMPONENT; + + SIGNAL CLK : std_logic; + SIGNAL RESET : std_logic; + SIGNAL START_CONFIG_OUT : std_logic; + SIGNAL BANK_SELECT_OUT : std_logic_vector(3 downto 0); + SIGNAL CONFIG_DONE_IN : std_logic; + SIGNAL DATA_GBE_ENABLE_IN : std_logic; + SIGNAL DATA_IPU_ENABLE_IN : std_logic; + SIGNAL MULTI_EVT_ENABLE_IN : std_logic; + SIGNAL CTS_NUMBER_IN : std_logic_vector(15 downto 0); + SIGNAL CTS_CODE_IN : std_logic_vector(7 downto 0); + SIGNAL CTS_INFORMATION_IN : std_logic_vector(7 downto 0); + SIGNAL CTS_READOUT_TYPE_IN : std_logic_vector(3 downto 0); + SIGNAL CTS_START_READOUT_IN : std_logic; + SIGNAL CTS_READ_IN : std_logic; + SIGNAL CTS_DATA_OUT : std_logic_vector(31 downto 0); + SIGNAL CTS_DATAREADY_OUT : std_logic; + SIGNAL CTS_READOUT_FINISHED_OUT : std_logic; + SIGNAL CTS_LENGTH_OUT : std_logic_vector(15 downto 0); + SIGNAL CTS_ERROR_PATTERN_OUT : std_logic_vector(31 downto 0); + SIGNAL FEE_DATA_IN : std_logic_vector(15 downto 0); + SIGNAL FEE_DATAREADY_IN : std_logic; + SIGNAL FEE_READ_OUT : std_logic; + SIGNAL FEE_BUSY_IN : std_logic; + SIGNAL FEE_STATUS_BITS_IN : std_logic_vector(31 downto 0); + SIGNAL PC_WR_EN_OUT : std_logic; + SIGNAL PC_DATA_OUT : std_logic_vector(7 downto 0); + SIGNAL PC_READY_IN : std_logic; + SIGNAL PC_SOS_OUT : std_logic; + SIGNAL PC_EOD_OUT : std_logic; + SIGNAL PC_SUB_SIZE_OUT : std_logic_vector(31 downto 0); + SIGNAL PC_TRIG_NR_OUT : std_logic_vector(31 downto 0); + SIGNAL PC_PADDING_OUT : std_logic; + SIGNAL BSM_SAVE_OUT : std_logic_vector(3 downto 0); + SIGNAL BSM_LOAD_OUT : std_logic_vector(3 downto 0); + SIGNAL DBG_REM_CTR_OUT : std_logic_vector(3 downto 0); + SIGNAL DBG_CTS_CTR_OUT : std_logic_vector(2 downto 0); + SIGNAL DBG_SF_WCNT_OUT : std_logic_vector(15 downto 0); + SIGNAL DBG_SF_RCNT_OUT : std_logic_vector(16 downto 0); + SIGNAL DBG_SF_DATA_OUT : std_logic_vector(15 downto 0); + SIGNAL DBG_SF_RD_EN_OUT : std_logic; + SIGNAL DBG_SF_WR_EN_OUT : std_logic; + SIGNAL DBG_SF_EMPTY_OUT : std_logic; + SIGNAL DBG_SF_AEMPTY_OUT : std_logic; + SIGNAL DBG_SF_FULL_OUT : std_logic; + SIGNAL DBG_SF_AFULL_OUT : std_logic; + SIGNAL DEBUG_OUT : std_logic_vector(31 downto 0); + +BEGIN + +-- Please check and add your generic clause manually + uut: trb_net16_ipu2gbe PORT MAP( + CLK => CLK, + RESET => RESET, + START_CONFIG_OUT => START_CONFIG_OUT, + BANK_SELECT_OUT => BANK_SELECT_OUT, + CONFIG_DONE_IN => CONFIG_DONE_IN, + DATA_GBE_ENABLE_IN => DATA_GBE_ENABLE_IN, + DATA_IPU_ENABLE_IN => DATA_IPU_ENABLE_IN, + MULTI_EVT_ENABLE_IN => MULTI_EVT_ENABLE_IN, + CTS_NUMBER_IN => CTS_NUMBER_IN, + CTS_CODE_IN => CTS_CODE_IN, + CTS_INFORMATION_IN => CTS_INFORMATION_IN, + CTS_READOUT_TYPE_IN => CTS_READOUT_TYPE_IN, + CTS_START_READOUT_IN => CTS_START_READOUT_IN, + CTS_READ_IN => CTS_READ_IN, + CTS_DATA_OUT => CTS_DATA_OUT, + CTS_DATAREADY_OUT => CTS_DATAREADY_OUT, + CTS_READOUT_FINISHED_OUT => CTS_READOUT_FINISHED_OUT, + CTS_LENGTH_OUT => CTS_LENGTH_OUT, + CTS_ERROR_PATTERN_OUT => CTS_ERROR_PATTERN_OUT, + FEE_DATA_IN => FEE_DATA_IN, + FEE_DATAREADY_IN => FEE_DATAREADY_IN, + FEE_READ_OUT => FEE_READ_OUT, + FEE_BUSY_IN => FEE_BUSY_IN, + FEE_STATUS_BITS_IN => FEE_STATUS_BITS_IN, + PC_WR_EN_OUT => PC_WR_EN_OUT, + PC_DATA_OUT => PC_DATA_OUT, + PC_READY_IN => PC_READY_IN, + PC_SOS_OUT => PC_SOS_OUT, + PC_EOD_OUT => PC_EOD_OUT, + PC_SUB_SIZE_OUT => PC_SUB_SIZE_OUT, + PC_TRIG_NR_OUT => PC_TRIG_NR_OUT, + PC_PADDING_OUT => PC_PADDING_OUT, + BSM_SAVE_OUT => BSM_SAVE_OUT, + BSM_LOAD_OUT => BSM_LOAD_OUT, + DBG_REM_CTR_OUT => DBG_REM_CTR_OUT, + DBG_CTS_CTR_OUT => DBG_CTS_CTR_OUT, + DBG_SF_WCNT_OUT => DBG_SF_WCNT_OUT, + DBG_SF_RCNT_OUT => DBG_SF_RCNT_OUT, + DBG_SF_DATA_OUT => DBG_SF_DATA_OUT, + DBG_SF_RD_EN_OUT => DBG_SF_RD_EN_OUT, + DBG_SF_WR_EN_OUT => DBG_SF_WR_EN_OUT, + DBG_SF_EMPTY_OUT => DBG_SF_EMPTY_OUT, + DBG_SF_AEMPTY_OUT => DBG_SF_AEMPTY_OUT, + DBG_SF_FULL_OUT => DBG_SF_FULL_OUT, + DBG_SF_AFULL_OUT => DBG_SF_AFULL_OUT, + DEBUG_OUT => DEBUG_OUT + ); + +CLOCK_GEN: process +begin + clk <= '1'; wait for 5.0 ns; + clk <= '0'; wait for 5.0 ns; +end process CLOCK_GEN; + +PC_READY_PROC: process +begin + pc_ready_in <= '0'; + wait for 500 ns; + pc_ready_in <= '1'; + wait for 500 ns; + pc_ready_in <= '0'; + wait for 99 us; +end process PC_READY_PROC; + +-- Testbench +TESTBENCH_PROC: process +-- test data from TRBnet +variable test_data_len : integer range 0 to 65535 := 1; +variable test_loop_len : integer range 0 to 65535 := 0; +variable test_hdr_len : unsigned(15 downto 0) := x"0000"; +variable test_evt_len : unsigned(15 downto 0) := x"0000"; +variable test_data : unsigned(15 downto 0) := x"ffff"; + +variable trigger_counter : unsigned(15 downto 0) := x"4710"; +variable trigger_loop : integer range 0 to 65535 := 15; + +-- 1400 bytes MTU => 350 as limit for fragmentation +variable max_event_size : real := 512.0; +--variable max_event_size : real := 1024.0; + +variable seed1 : positive; -- seed for random generator +variable seed2 : positive; -- seed for random generator +variable rand : real; -- random value (0.0 ... 1.0) +variable int_rand : integer; -- random value, scaled to your needs +variable cts_random_number : std_logic_vector(7 downto 0); + +variable stim : std_logic_vector(15 downto 0); + +begin + -- Setup signals + reset <= '0'; + cts_number_in <= x"0000"; + cts_code_in <= x"00"; + cts_information_in <= x"00"; + cts_readout_type_in <= x"0"; + cts_start_readout_in <= '0'; + cts_read_in <= '0'; + fee_data_in <= x"0000"; + fee_dataready_in <= '0'; + fee_status_bits_in <= x"0000_0000"; + fee_busy_in <= '0'; +-- pc_ready_in <= '0'; + + config_done_in <= '1'; + data_gbe_enable_in <= '1'; + data_ipu_enable_in <= '0'; + multi_evt_enable_in <= '0'; + + wait for 22 ns; + + -- Reset the whole stuff + wait until rising_edge(clk); + reset <= '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + reset <= '0'; + wait until rising_edge(clk); + wait for 200 ns; + +--------------------------- + +------------------------------------------------------------------------------- +-- Loop the transmissions +------------------------------------------------------------------------------- + trigger_counter := x"4710"; + trigger_loop := 40; + + MY_TRIGGER_LOOP: for J in 0 to trigger_loop loop + -- generate a real random byte for CTS + UNIFORM(seed1, seed2, rand); + int_rand := INTEGER(TRUNC(rand*256.0)); + cts_random_number := std_logic_vector(to_unsigned(int_rand, cts_random_number'LENGTH)); + + -- IPU transmission starts + wait until rising_edge(clk); + cts_number_in <= std_logic_vector( trigger_counter ); + cts_code_in <= cts_random_number; + cts_information_in <= x"de"; + cts_readout_type_in <= x"1"; + cts_start_readout_in <= '1'; + wait until rising_edge(clk); + wait for 400 ns; + + wait until rising_edge(clk); + fee_busy_in <= '1'; + wait for 300 ns; + wait until rising_edge(clk); + + -- ONE DATA TRANSMISSION + -- dice a length + UNIFORM(seed1, seed2, rand); + test_data_len := INTEGER(TRUNC(rand*max_event_size)) + 1; + +-- test_data_len := 9685; + + -- calculate the needed variables + test_loop_len := 2*(test_data_len - 1) + 1; + test_hdr_len := to_unsigned( test_data_len + 1, 16 ); + test_evt_len := to_unsigned( test_data_len, 16 ); + + -- original data block (trigger 1, random 0xaa, number 0x4711, source 0x21) + fee_dataready_in <= '1'; + fee_data_in <= x"10" & cts_random_number; + wait until rising_edge(clk) and (fee_read_out = '1'); -- transfer of first data word + fee_dataready_in <= '0'; + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_dataready_in <= '1'; + fee_data_in <= std_logic_vector( trigger_counter ); + wait until rising_edge(clk) and (fee_read_out = '1'); -- transfer of second data word + fee_dataready_in <= '0'; + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); -- BLA + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_dataready_in <= '1'; + fee_data_in <= std_logic_vector( test_hdr_len ); + wait until rising_edge(clk) and (fee_read_out = '1'); -- transfer of third data word + fee_data_in <= x"ff21"; + wait until rising_edge(clk) and (fee_read_out = '1'); -- transfer of fourth data word + fee_dataready_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_dataready_in <= '1'; + fee_data_in <= std_logic_vector( test_evt_len ); + wait until rising_edge(clk) and (fee_read_out = '1'); + fee_data_in <= x"ff22"; + wait until rising_edge(clk) and (fee_read_out = '1'); + fee_dataready_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + + test_data := x"ffff"; + MY_DATA_LOOP: for J in 0 to test_loop_len loop + test_data := test_data + 1; + wait until rising_edge(clk) and (fee_read_out = '1'); -- + fee_data_in <= std_logic_vector(test_data); + if( (test_data MOD 5) = 0 ) then + fee_dataready_in <= '0'; +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_dataready_in <= '1'; + else + fee_dataready_in <= '1'; + end if; + end loop MY_DATA_LOOP; + -- there must be padding words to get multiple of four LWs + + wait until rising_edge(clk); + fee_dataready_in <= '0'; + fee_data_in <= x"0000"; + + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + fee_busy_in <= '0'; + + + trigger_loop := trigger_loop + 1; + trigger_counter := trigger_counter + 1; + + wait until rising_edge(clk); + wait until rising_edge(clk); + cts_read_in <= '1'; + wait until rising_edge(clk); + cts_read_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + cts_start_readout_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + + --wait for 8 us; + + end loop MY_TRIGGER_LOOP; + + + +--------------------------- +--------------------------- + wait for 300 ns; + + wait; + + -- Start packet_constructor + wait until rising_edge(clk); + wait until rising_edge(clk); +-- pc_ready_in <= '1'; + wait until rising_edge(clk); + + wait until rising_edge(clk); + wait until pc_eod_out = '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); +-- pc_ready_in <= '0'; + + -- Stay a while... stay forever!!! + wait; + +end process TESTBENCH_PROC; + + +END; diff --git a/gbe2_ecp3/tb_lsm.vhd b/gbe2_ecp3/tb_lsm.vhd new file mode 100755 index 0000000..6e86029 --- /dev/null +++ b/gbe2_ecp3/tb_lsm.vhd @@ -0,0 +1,113 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY testbench IS +END testbench; + +ARCHITECTURE behavior OF testbench IS + + COMPONENT trb_net16_lsm_sfp_gbe + PORT( + SYSCLK : IN std_logic; + RESET : IN std_logic; + CLEAR : IN std_logic; + SFP_MISSING_IN : IN std_logic; + SFP_LOS_IN : IN std_logic; + SD_LINK_OK_IN : IN std_logic; + SD_LOS_IN : IN std_logic; + SD_TXCLK_BAD_IN : IN std_logic; + SD_RXCLK_BAD_IN : IN std_logic; + FULL_RESET_OUT : OUT std_logic; + LANE_RESET_OUT : OUT std_logic; + USER_RESET_OUT : OUT std_logic; + TIMING_CTR_OUT : OUT std_logic_vector(18 downto 0); + BSM_OUT : OUT std_logic_vector(3 downto 0); + DEBUG_OUT : OUT std_logic_vector(31 downto 0) + ); + END COMPONENT; + + SIGNAL SYSCLK : std_logic; + SIGNAL RESET : std_logic; + SIGNAL CLEAR : std_logic; + SIGNAL SFP_MISSING_IN : std_logic; + SIGNAL SFP_LOS_IN : std_logic; + SIGNAL SD_LINK_OK_IN : std_logic; + SIGNAL SD_LOS_IN : std_logic; + SIGNAL SD_TXCLK_BAD_IN : std_logic; + SIGNAL SD_RXCLK_BAD_IN : std_logic; + SIGNAL FULL_RESET_OUT : std_logic; + SIGNAL LANE_RESET_OUT : std_logic; + SIGNAL USER_RESET_OUT : std_logic; + SIGNAL TIMING_CTR_OUT : std_logic_vector(18 downto 0); + SIGNAL BSM_OUT : std_logic_vector(3 downto 0); + SIGNAL DEBUG_OUT : std_logic_vector(31 downto 0); + +BEGIN + +-- Please check and add your generic clause manually + uut: trb_net16_lsm_sfp_gbe PORT MAP( + SYSCLK => SYSCLK, + RESET => RESET, + CLEAR => CLEAR, + SFP_MISSING_IN => SFP_MISSING_IN, + SFP_LOS_IN => SFP_LOS_IN, + SD_LINK_OK_IN => SD_LINK_OK_IN, + SD_LOS_IN => SD_LOS_IN, + SD_TXCLK_BAD_IN => SD_TXCLK_BAD_IN, + SD_RXCLK_BAD_IN => SD_RXCLK_BAD_IN, + FULL_RESET_OUT => FULL_RESET_OUT, + LANE_RESET_OUT => LANE_RESET_OUT, + USER_RESET_OUT => USER_RESET_OUT, + TIMING_CTR_OUT => TIMING_CTR_OUT, + BSM_OUT => BSM_OUT, + DEBUG_OUT => DEBUG_OUT + ); + + +CLOCK_GEN: process +begin + sysclk <= '1'; wait for 4.0 ns; + sysclk <= '0'; wait for 4.0 ns; +end process CLOCK_GEN; + +THE_TESTBENCH: process +begin + -- Setup signals + reset <= '0'; + clear <= '0'; + sfp_missing_in <= '0'; + sfp_los_in <= '0'; + sd_link_ok_in <= '0'; + sd_los_in <= '0'; + sd_txclk_bad_in <= '1'; + sd_rxclk_bad_in <= '1'; + wait for 100 ns; + + -- Reset + clear <= '1'; + wait for 100 ns; + clear <= '0'; + wait for 10 ns; + + -- Tests may start now + wait until falling_edge(full_reset_out); + wait for 123 ns; + sd_txclk_bad_in <= '0'; + wait for 433 ns; + sd_rxclk_bad_in <= '0'; + + wait for 1.1 us; + sd_rxclk_bad_in <= '1'; + wait for 33 ns; + sd_rxclk_bad_in <= '0'; + + + wait until rising_edge(sysclk); + + -- Stay a while.... stay forever!!! Muahahaha!!!! + wait; + +end process THE_TESTBENCH; + +END; \ No newline at end of file diff --git a/gbe2_ecp3/tb_pc.vhd b/gbe2_ecp3/tb_pc.vhd new file mode 100755 index 0000000..ac85375 --- /dev/null +++ b/gbe2_ecp3/tb_pc.vhd @@ -0,0 +1,310 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY testbench IS +END testbench; + +ARCHITECTURE behavior OF testbench IS + + COMPONENT trb_net16_gbe_packet_constr + PORT( + RESET : IN std_logic; + CLK : IN std_logic; + PC_WR_EN_IN : IN std_logic; + PC_DATA_IN : IN std_logic_vector(7 downto 0); + PC_START_OF_SUB_IN : IN std_logic; + PC_END_OF_DATA_IN : IN std_logic; + PC_SUB_SIZE_IN : IN std_logic_vector(31 downto 0); + PC_DECODING_IN : IN std_logic_vector(31 downto 0); + PC_EVENT_ID_IN : IN std_logic_vector(31 downto 0); + PC_TRIG_NR_IN : IN std_logic_vector(31 downto 0); + PC_QUEUE_DEC_IN : IN std_logic_vector(31 downto 0); + PC_MAX_FRAME_SIZE_IN : IN std_logic_vector(15 downto 0); + FC_H_READY_IN : IN std_logic; + FC_READY_IN : IN std_logic; + PC_READY_OUT : OUT std_logic; + FC_WR_EN_OUT : OUT std_logic; + FC_DATA_OUT : OUT std_logic_vector(7 downto 0); + FC_IP_SIZE_OUT : OUT std_logic_vector(15 downto 0); + FC_UDP_SIZE_OUT : OUT std_logic_vector(15 downto 0); + FC_IDENT_OUT : OUT std_logic_vector(15 downto 0); + FC_FLAGS_OFFSET_OUT : OUT std_logic_vector(15 downto 0); + FC_SOD_OUT : OUT std_logic; + FC_EOD_OUT : OUT std_logic; + BSM_CONSTR_OUT : OUT std_logic_vector(3 downto 0); + BSM_LOAD_OUT : OUT std_logic_vector(3 downto 0); + BSM_SAVE_OUT : OUT std_logic_vector(3 downto 0); + DBG_SHF_EMPTY : OUT std_logic; + DBG_SHF_FULL : OUT std_logic; + DBG_SHF_WR_EN : OUT std_logic; + DBG_SHF_RD_EN : OUT std_logic; + DBG_DF_EMPTY : OUT std_logic; + DBG_DF_FULL : OUT std_logic; + DBG_DF_WR_EN : OUT std_logic; + DBG_DF_RD_EN : OUT std_logic; + DBG_ALL_CTR : OUT std_logic_vector(4 downto 0); + DBG_SUB_CTR : OUT std_logic_vector(4 downto 0); + DBG_MY_CTR : OUT std_logic_vector(1 downto 0); + DBG_BYTES_LOADED : OUT std_logic_vector(15 downto 0); + DBG_SIZE_LEFT : OUT std_logic_vector(31 downto 0); + DBG_SUB_SIZE_TO_SAVE : OUT std_logic_vector(31 downto 0); + DBG_SUB_SIZE_LOADED : OUT std_logic_vector(31 downto 0); + DBG_SUB_BYTES_LOADED : OUT std_logic_vector(31 downto 0); + DBG_QUEUE_SIZE : OUT std_logic_vector(31 downto 0); + DBG_ACT_QUEUE_SIZE : OUT std_logic_vector(31 downto 0); + DEBUG_OUT : OUT std_logic_vector(31 downto 0) + ); + END COMPONENT; + + SIGNAL RESET : std_logic; + SIGNAL CLK : std_logic; + SIGNAL PC_WR_EN_IN : std_logic; + SIGNAL PC_DATA_IN : std_logic_vector(7 downto 0); + SIGNAL PC_READY_OUT : std_logic; + SIGNAL PC_START_OF_SUB_IN : std_logic; + SIGNAL PC_END_OF_DATA_IN : std_logic; + SIGNAL PC_SUB_SIZE_IN : std_logic_vector(31 downto 0); + SIGNAL PC_DECODING_IN : std_logic_vector(31 downto 0); + SIGNAL PC_EVENT_ID_IN : std_logic_vector(31 downto 0); + SIGNAL PC_TRIG_NR_IN : std_logic_vector(31 downto 0); + SIGNAL PC_QUEUE_DEC_IN : std_logic_vector(31 downto 0); + SIGNAL PC_MAX_FRAME_SIZE_IN : std_logic_vector(15 downto 0); + SIGNAL FC_WR_EN_OUT : std_logic; + SIGNAL FC_DATA_OUT : std_logic_vector(7 downto 0); + SIGNAL FC_H_READY_IN : std_logic; + SIGNAL FC_READY_IN : std_logic; + SIGNAL FC_IP_SIZE_OUT : std_logic_vector(15 downto 0); + SIGNAL FC_UDP_SIZE_OUT : std_logic_vector(15 downto 0); + SIGNAL FC_IDENT_OUT : std_logic_vector(15 downto 0); + SIGNAL FC_FLAGS_OFFSET_OUT : std_logic_vector(15 downto 0); + SIGNAL FC_SOD_OUT : std_logic; + SIGNAL FC_EOD_OUT : std_logic; + SIGNAL BSM_CONSTR_OUT : std_logic_vector(3 downto 0); + SIGNAL BSM_LOAD_OUT : std_logic_vector(3 downto 0); + SIGNAL BSM_SAVE_OUT : std_logic_vector(3 downto 0); + SIGNAL DBG_SHF_EMPTY : std_logic; + SIGNAL DBG_SHF_FULL : std_logic; + SIGNAL DBG_SHF_WR_EN : std_logic; + SIGNAL DBG_SHF_RD_EN : std_logic; + SIGNAL DBG_DF_EMPTY : std_logic; + SIGNAL DBG_DF_FULL : std_logic; + SIGNAL DBG_DF_WR_EN : std_logic; + SIGNAL DBG_DF_RD_EN : std_logic; + SIGNAL DBG_ALL_CTR : std_logic_vector(4 downto 0); + SIGNAL DBG_SUB_CTR : std_logic_vector(4 downto 0); + SIGNAL DBG_MY_CTR : std_logic_vector(1 downto 0); + SIGNAL DBG_BYTES_LOADED : std_logic_vector(15 downto 0); + SIGNAL DBG_SIZE_LEFT : std_logic_vector(31 downto 0); + SIGNAL DBG_SUB_SIZE_TO_SAVE : std_logic_vector(31 downto 0); + SIGNAL DBG_SUB_SIZE_LOADED : std_logic_vector(31 downto 0); + SIGNAL DBG_SUB_BYTES_LOADED : std_logic_vector(31 downto 0); + SIGNAL DBG_QUEUE_SIZE : std_logic_vector(31 downto 0); + SIGNAL DBG_ACT_QUEUE_SIZE : std_logic_vector(31 downto 0); + SIGNAL DEBUG_OUT : std_logic_vector(31 downto 0); + +BEGIN + +-- Please check and add your generic clause manually + uut: trb_net16_gbe_packet_constr PORT MAP( + RESET => RESET, + CLK => CLK, + PC_WR_EN_IN => PC_WR_EN_IN, + PC_DATA_IN => PC_DATA_IN, + PC_READY_OUT => PC_READY_OUT, + PC_START_OF_SUB_IN => PC_START_OF_SUB_IN, + PC_END_OF_DATA_IN => PC_END_OF_DATA_IN, + PC_SUB_SIZE_IN => PC_SUB_SIZE_IN, + PC_DECODING_IN => PC_DECODING_IN, + PC_EVENT_ID_IN => PC_EVENT_ID_IN, + PC_TRIG_NR_IN => PC_TRIG_NR_IN, + PC_QUEUE_DEC_IN => PC_QUEUE_DEC_IN, + PC_MAX_FRAME_SIZE_IN => PC_MAX_FRAME_SIZE_IN, + FC_WR_EN_OUT => FC_WR_EN_OUT, + FC_DATA_OUT => FC_DATA_OUT, + FC_H_READY_IN => FC_H_READY_IN, + FC_READY_IN => FC_READY_IN, + FC_IP_SIZE_OUT => FC_IP_SIZE_OUT, + FC_UDP_SIZE_OUT => FC_UDP_SIZE_OUT, + FC_IDENT_OUT => FC_IDENT_OUT, + FC_FLAGS_OFFSET_OUT => FC_FLAGS_OFFSET_OUT, + FC_SOD_OUT => FC_SOD_OUT, + FC_EOD_OUT => FC_EOD_OUT, + BSM_CONSTR_OUT => BSM_CONSTR_OUT, + BSM_LOAD_OUT => BSM_LOAD_OUT, + BSM_SAVE_OUT => BSM_SAVE_OUT, + DBG_SHF_EMPTY => DBG_SHF_EMPTY, + DBG_SHF_FULL => DBG_SHF_FULL, + DBG_SHF_WR_EN => DBG_SHF_WR_EN, + DBG_SHF_RD_EN => DBG_SHF_RD_EN, + DBG_DF_EMPTY => DBG_DF_EMPTY, + DBG_DF_FULL => DBG_DF_FULL, + DBG_DF_WR_EN => DBG_DF_WR_EN, + DBG_DF_RD_EN => DBG_DF_RD_EN, + DBG_ALL_CTR => DBG_ALL_CTR, + DBG_SUB_CTR => DBG_SUB_CTR, + DBG_MY_CTR => DBG_MY_CTR, + DBG_BYTES_LOADED => DBG_BYTES_LOADED, + DBG_SIZE_LEFT => DBG_SIZE_LEFT, + DBG_SUB_SIZE_TO_SAVE => DBG_SUB_SIZE_TO_SAVE, + DBG_SUB_SIZE_LOADED => DBG_SUB_SIZE_LOADED, + DBG_SUB_BYTES_LOADED => DBG_SUB_BYTES_LOADED, + DBG_QUEUE_SIZE => DBG_QUEUE_SIZE, + DBG_ACT_QUEUE_SIZE => DBG_ACT_QUEUE_SIZE, + DEBUG_OUT => DEBUG_OUT + ); + +CLK_GEN: process +begin + clk <= '1'; wait for 5.0 ns; + clk <= '0'; wait for 5.0 ns; +end process CLK_GEN; + +THE_TESTBENCH: process +variable test_data_len : integer range 0 to 65535 := 1; +variable test_loop_len : integer range 0 to 65535 := 0; +variable test_evt_len : unsigned(15 downto 0) := x"0000"; +variable test_evt_len_vec : std_logic_vector(15 downto 0); +variable test_sub_len : unsigned(15 downto 0) := x"0000"; +variable test_sub_len_vec : std_logic_vector(15 downto 0); +variable test_data : unsigned(15 downto 0) := x"ffff"; +variable test_data_vec : std_logic_vector(15 downto 0); + +variable trigger_counter : unsigned(15 downto 0) := x"4710"; +variable trigger_loop : integer range 0 to 65535 := 15; +begin + -- Set up signals + reset <= '0'; + pc_wr_en_in <= '0'; + pc_data_in <= x"00"; + pc_start_of_sub_in <= '0'; + pc_end_of_data_in <= '0'; + pc_sub_size_in <= x"0000_0000"; + pc_trig_nr_in <= x"0000_0000"; + pc_decoding_in <= x"0002_0001"; -- static + pc_event_id_in <= x"0000_00ca"; -- static + pc_queue_dec_in <= x"0003_0062"; -- static + pc_max_frame_size_in <= x"0578"; -- static + fc_h_ready_in <= '0'; + fc_ready_in <= '0'; + wait until rising_edge(clk); + + -- Reset the whole stuff + wait until rising_edge(clk); + reset <= '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + reset <= '0'; + wait until rising_edge(clk); + wait for 200 ns; + wait until rising_edge(clk); + + -- Tests may start now + +------------------------------------------------------------------------------- +-- Loop the transmissions +------------------------------------------------------------------------------- + trigger_counter := x"4710"; + trigger_loop := 0; + + test_data_len := 14; + + MY_TRIGGER_LOOP: for J in 0 to trigger_loop loop + + -- calculate the needed variables + test_loop_len := 2*(test_data_len - 1) + 1; + test_evt_len := to_unsigned( test_data_len, 16 ); + test_evt_len_vec := std_logic_vector(test_evt_len); + test_sub_len := test_evt_len + 1; + test_sub_len_vec := std_logic_vector(test_sub_len); + + -- start of subevent marker + wait until rising_edge(clk); + wait until rising_edge(clk); + pc_trig_nr_in <= x"0000" & std_logic_vector(trigger_counter); + pc_sub_size_in <= b"0000_0000_0000_00" & test_sub_len_vec & b"00"; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + pc_start_of_sub_in <= '1'; + wait until rising_edge(clk); + pc_start_of_sub_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + pc_data_in <= test_evt_len_vec(15 downto 8); + pc_wr_en_in <= '1'; + wait until rising_edge(clk); + pc_data_in <= test_evt_len_vec(7 downto 0); + pc_wr_en_in <= '1'; + wait until rising_edge(clk); + pc_wr_en_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + pc_data_in <= x"ff"; -- source address high byte + pc_wr_en_in <= '1'; + wait until rising_edge(clk); + pc_data_in <= x"22"; -- source address low byte + pc_wr_en_in <= '1'; + wait until rising_edge(clk); + pc_wr_en_in <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + + test_data := x"ffff"; + MY_DATA_LOOP: for J in 0 to test_loop_len loop + test_data := test_data + 1; + test_data_vec := std_logic_vector(test_data); + wait until rising_edge(clk); + pc_data_in <= test_data_vec(15 downto 8); + pc_wr_en_in <= '1'; + wait until rising_edge(clk); + pc_data_in <= test_data_vec(7 downto 0); + pc_wr_en_in <= '1'; + wait until rising_edge(clk); + pc_wr_en_in <= '0'; +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); + end loop MY_DATA_LOOP; + + -- end of subevent marker +-- wait until rising_edge(clk); + pc_end_of_data_in <= '1'; + wait until rising_edge(clk); + pc_end_of_data_in <= '0'; + pc_sub_size_in <= x"0000_0000"; + pc_trig_nr_in <= x"0000_0000"; + wait until rising_edge(clk); + wait until rising_edge(clk); + + trigger_loop := trigger_loop + 1; + trigger_counter := trigger_counter + 1; + + wait for 500 ns; + wait until rising_edge(clk); + end loop MY_TRIGGER_LOOP; + +-- wait for 8 us; +------------------------------------------------------------------------------- +-- end of loop +------------------------------------------------------------------------------- + + wait until rising_edge(clk); + fc_ready_in <= '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + fc_h_ready_in <= '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + + -- Stay a while... stay forever!!!Muahahah!!! + wait; + +end process THE_TESTBENCH; + +END; \ No newline at end of file diff --git a/gbe2_ecp3/tb_slv_mac_memory.vhd b/gbe2_ecp3/tb_slv_mac_memory.vhd new file mode 100755 index 0000000..00293c3 --- /dev/null +++ b/gbe2_ecp3/tb_slv_mac_memory.vhd @@ -0,0 +1,114 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY testbench IS +END testbench; + +ARCHITECTURE behavior OF testbench IS + + COMPONENT slv_mac_memory + PORT( + CLK : IN std_logic; + RESET : IN std_logic; + BUSY_IN : IN std_logic; + SLV_ADDR_IN : IN std_logic_vector(7 downto 0); + SLV_READ_IN : IN std_logic; + SLV_WRITE_IN : IN std_logic; + SLV_DATA_IN : IN std_logic_vector(31 downto 0); + MEM_CLK_IN : IN std_logic; + MEM_ADDR_IN : IN std_logic_vector(7 downto 0); + SLV_BUSY_OUT : OUT std_logic; + SLV_ACK_OUT : OUT std_logic; + SLV_DATA_OUT : OUT std_logic_vector(31 downto 0); + MEM_DATA_OUT : OUT std_logic_vector(31 downto 0); + STAT : OUT std_logic_vector(31 downto 0) + ); + END COMPONENT; + + SIGNAL CLK : std_logic; + SIGNAL RESET : std_logic; + SIGNAL BUSY_IN : std_logic; + SIGNAL SLV_ADDR_IN : std_logic_vector(7 downto 0); + SIGNAL SLV_READ_IN : std_logic; + SIGNAL SLV_WRITE_IN : std_logic; + SIGNAL SLV_BUSY_OUT : std_logic; + SIGNAL SLV_ACK_OUT : std_logic; + SIGNAL SLV_DATA_IN : std_logic_vector(31 downto 0); + SIGNAL SLV_DATA_OUT : std_logic_vector(31 downto 0); + SIGNAL MEM_CLK_IN : std_logic; + SIGNAL MEM_ADDR_IN : std_logic_vector(7 downto 0); + SIGNAL MEM_DATA_OUT : std_logic_vector(31 downto 0); + SIGNAL STAT : std_logic_vector(31 downto 0); + +BEGIN + +-- Please check and add your generic clause manually + uut: slv_mac_memory PORT MAP( + CLK => CLK, + RESET => RESET, + BUSY_IN => BUSY_IN, + SLV_ADDR_IN => SLV_ADDR_IN, + SLV_READ_IN => SLV_READ_IN, + SLV_WRITE_IN => SLV_WRITE_IN, + SLV_BUSY_OUT => SLV_BUSY_OUT, + SLV_ACK_OUT => SLV_ACK_OUT, + SLV_DATA_IN => SLV_DATA_IN, + SLV_DATA_OUT => SLV_DATA_OUT, + MEM_CLK_IN => MEM_CLK_IN, + MEM_ADDR_IN => MEM_ADDR_IN, + MEM_DATA_OUT => MEM_DATA_OUT, + STAT => STAT + ); + +CLK_GEN_PROC: process +begin + clk <= '0'; mem_clk_in <= '0'; wait for 5.0 ns; + clk <= '1'; mem_clk_in <= '1'; wait for 5.0 ns; +end process CLK_GEN_PROC; + +THE_TESTBENCH: process +begin + -- Setup signals + reset <= '0'; + busy_in <= '0'; + slv_addr_in <= x"00"; + slv_read_in <= '0'; + slv_write_in <= '0'; + slv_data_in <= x"dead_beef"; + mem_addr_in <= x"f0"; + wait until rising_edge(clk); + + -- Reset the whole stuff + wait until rising_edge(clk); + reset <= '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + reset <= '0'; + wait until rising_edge(clk); + + -- Tests may start now + wait until rising_edge(clk); + mem_addr_in <= x"00"; + wait until rising_edge(clk); + mem_addr_in <= x"01"; + wait until rising_edge(clk); + mem_addr_in <= x"02"; + wait until rising_edge(clk); + mem_addr_in <= x"03"; + wait until rising_edge(clk); + mem_addr_in <= x"04"; + wait until rising_edge(clk); + mem_addr_in <= x"05"; + wait until rising_edge(clk); + mem_addr_in <= x"06"; + wait until rising_edge(clk); + mem_addr_in <= x"07"; + wait until rising_edge(clk); + mem_addr_in <= x"08"; + + -- Stay a while... stay forever!!! Muahahaha!!!!! + wait; +end process THE_TESTBENCH; + +END; diff --git a/gbe2_ecp3/trb_net16_gbe_buf.vhd b/gbe2_ecp3/trb_net16_gbe_buf.vhd new file mode 100755 index 0000000..52663cf --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_buf.vhd @@ -0,0 +1,1614 @@ +LIBRARY ieee; +use ieee.std_logic_1164.all; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; +use IEEE.std_logic_arith.all; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +use work.trb_net_gbe_components.all; +use work.trb_net_gbe_protocols.all; +--use work.version.all; + +entity trb_net16_gbe_buf is +generic( + DO_SIMULATION : integer range 0 to 1 := 1; + USE_125MHZ_EXTCLK : integer range 0 to 1 := 1 +); +port( + CLK : in std_logic; + TEST_CLK : in std_logic; -- only for simulation! + CLK_125_IN : in std_logic; -- gk 28.04.01 used only in internal 125MHz clock mode + RESET : in std_logic; + GSR_N : in std_logic; + -- Debug + STAGE_STAT_REGS_OUT : out std_logic_vector(31 downto 0); + STAGE_CTRL_REGS_IN : in std_logic_vector(31 downto 0); + -- configuration interface + IP_CFG_START_IN : in std_logic; + IP_CFG_BANK_SEL_IN : in std_logic_vector(3 downto 0); + IP_CFG_DONE_OUT : out std_logic; + IP_CFG_MEM_ADDR_OUT : out std_logic_vector(7 downto 0); + IP_CFG_MEM_DATA_IN : in std_logic_vector(31 downto 0); + IP_CFG_MEM_CLK_OUT : out std_logic; + MR_RESET_IN : in std_logic; + MR_MODE_IN : in std_logic; + MR_RESTART_IN : in std_logic; + -- gk 29.03.10 + SLV_ADDR_IN : in std_logic_vector(7 downto 0); + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_BUSY_OUT : out std_logic; + SLV_ACK_OUT : out std_logic; + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + -- gk 22.04.10 + -- registers setup interface + BUS_ADDR_IN : in std_logic_vector(7 downto 0); + BUS_DATA_IN : in std_logic_vector(31 downto 0); + BUS_DATA_OUT : out std_logic_vector(31 downto 0); -- gk 26.04.10 + BUS_WRITE_EN_IN : in std_logic; -- gk 26.04.10 + BUS_READ_EN_IN : in std_logic; -- gk 26.04.10 + BUS_ACK_OUT : out std_logic; -- gk 26.04.10 + -- gk 23.04.10 + LED_PACKET_SENT_OUT : out std_logic; + LED_AN_DONE_N_OUT : out std_logic; + -- CTS interface + CTS_NUMBER_IN : in std_logic_vector (15 downto 0); + CTS_CODE_IN : in std_logic_vector (7 downto 0); + CTS_INFORMATION_IN : in std_logic_vector (7 downto 0); + CTS_READOUT_TYPE_IN : in std_logic_vector (3 downto 0); + CTS_START_READOUT_IN : in std_logic; + CTS_DATA_OUT : out std_logic_vector (31 downto 0); + CTS_DATAREADY_OUT : out std_logic; + CTS_READOUT_FINISHED_OUT : out std_logic; + CTS_READ_IN : in std_logic; + CTS_LENGTH_OUT : out std_logic_vector (15 downto 0); + CTS_ERROR_PATTERN_OUT : out std_logic_vector (31 downto 0); + -- Data payload interface + FEE_DATA_IN : in std_logic_vector (15 downto 0); + FEE_DATAREADY_IN : in std_logic; + FEE_READ_OUT : out std_logic; + FEE_STATUS_BITS_IN : in std_logic_vector (31 downto 0); + FEE_BUSY_IN : in std_logic; + --SFP Connection + SFP_RXD_P_IN : in std_logic; + SFP_RXD_N_IN : in std_logic; + SFP_TXD_P_OUT : out std_logic; + SFP_TXD_N_OUT : out std_logic; + SFP_REFCLK_P_IN : in std_logic; + SFP_REFCLK_N_IN : in std_logic; + SFP_PRSNT_N_IN : in std_logic; -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) + SFP_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) + SFP_TXDIS_OUT : out std_logic; -- SFP disable + + -- for simulation of receiving part only + MAC_RX_EOF_IN : in std_logic; + MAC_RXD_IN : in std_logic_vector(7 downto 0); + MAC_RX_EN_IN : in std_logic; + + + -- debug ports + ANALYZER_DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end entity trb_net16_gbe_buf; + +architecture trb_net16_gbe_buf of trb_net16_gbe_buf is + +-- Placer Directives +--attribute HGROUP : string; +-- for whole architecture +--attribute HGROUP of trb_net16_gbe_buf : architecture is "GBE_BUF_group"; + + +component tsmac34 +port( + --------------- clock and reset port declarations ------------------ + hclk : in std_logic; + txmac_clk : in std_logic; + rxmac_clk : in std_logic; + reset_n : in std_logic; + txmac_clk_en : in std_logic; + rxmac_clk_en : in std_logic; + ------------------- Input signals to the GMII ---------------- + rxd : in std_logic_vector(7 downto 0); + rx_dv : in std_logic; + rx_er : in std_logic; + col : in std_logic; + crs : in std_logic; + -------------------- Input signals to the CPU I/F ------------------- + haddr : in std_logic_vector(7 downto 0); + hdatain : in std_logic_vector(7 downto 0); + hcs_n : in std_logic; + hwrite_n : in std_logic; + hread_n : in std_logic; + ---------------- Input signals to the Tx MAC FIFO I/F --------------- + tx_fifodata : in std_logic_vector(7 downto 0); + tx_fifoavail : in std_logic; + tx_fifoeof : in std_logic; + tx_fifoempty : in std_logic; + tx_sndpaustim : in std_logic_vector(15 downto 0); + tx_sndpausreq : in std_logic; + tx_fifoctrl : in std_logic; + ---------------- Input signals to the Rx MAC FIFO I/F --------------- + rx_fifo_full : in std_logic; + ignore_pkt : in std_logic; + -------------------- Output signals from the GMII ----------------------- + txd : out std_logic_vector(7 downto 0); + tx_en : out std_logic; + tx_er : out std_logic; + -------------------- Output signals from the CPU I/F ------------------- + hdataout : out std_logic_vector(7 downto 0); + hdataout_en_n : out std_logic; + hready_n : out std_logic; + cpu_if_gbit_en : out std_logic; + ---------------- Output signals from the Tx MAC FIFO I/F --------------- + tx_macread : out std_logic; + tx_discfrm : out std_logic; + tx_staten : out std_logic; + tx_done : out std_logic; + tx_statvec : out std_logic_vector(30 downto 0); + ---------------- Output signals from the Rx MAC FIFO I/F --------------- + rx_fifo_error : out std_logic; + rx_stat_vector : out std_logic_vector(31 downto 0); + rx_dbout : out std_logic_vector(7 downto 0); + rx_write : out std_logic; + rx_stat_en : out std_logic; + rx_eof : out std_logic; + rx_error : out std_logic +); +end component; + +component mb_mac_sim is +port ( + -------------------------------------------------------------------------- + --------------- clock, reset, clock enable ------------------------------- + HCLK : in std_logic; + TX_MAC_CLK : in std_logic; + RX_MAC_CLK : in std_logic; + RESET_N : in std_logic; + TXMAC_CLK_EN : in std_logic; + RXMAC_CLK_EN : in std_logic; + -------------------------------------------------------------------------- + --------------- SGMII receive interface ---------------------------------- + RXD : in std_logic_vector(7 downto 0); + RX_DV : in std_logic; + RX_ER : in std_logic; + COL : in std_logic; + CRS : in std_logic; + -------------------------------------------------------------------------- + --------------- SGMII transmit interface --------------------------------- + TXD : out std_logic_vector(7 downto 0); + TX_EN : out std_logic; + TX_ER : out std_logic; + -------------------------------------------------------------------------- + --------------- CPU configuration interface ------------------------------ + HADDR : in std_logic_vector(7 downto 0); + HDATAIN : in std_logic_vector(7 downto 0); + HCS_N : in std_logic; + HWRITE_N : in std_logic; + HREAD_N : in std_logic; + HDATAOUT : out std_logic_vector(7 downto 0); + HDATAOUT_EN_N : out std_logic; + HREADY_N : out std_logic; + CPU_IF_GBIT_EN : out std_logic; + -------------------------------------------------------------------------- + --------------- Transmit FIFO interface ---------------------------------- + TX_FIFODATA : in std_logic_vector(7 downto 0); + TX_FIFOAVAIL : in std_logic; + TX_FIFOEOF : in std_logic; + TX_FIFOEMPTY : in std_logic; + TX_MACREAD : out std_logic; + TX_DONE : out std_logic; + TX_SNDPAUSTIM : in std_logic_vector(15 downto 0); + TX_SNDPAUSREQ : in std_logic; + TX_FIFOCTRL : in std_logic; + TX_DISCFRM : out std_logic; + TX_STATEN : out std_logic; + TX_STATVEC : out std_logic_vector(30 downto 0); + -------------------------------------------------------------------------- + --------------- Receive FIFO interface ----------------------------------- + RX_DBOUT : out std_logic_vector(7 downto 0); + RX_FIFO_FULL : in std_logic; + IGNORE_PKT : in std_logic; + RX_FIFO_ERROR : out std_logic; + RX_STAT_VECTOR : out std_logic_vector(31 downto 0); + RX_STAT_EN : out std_logic; + RX_WRITE : out std_logic; + RX_EOF : out std_logic; + RX_ERROR : out std_logic +); +end component; + +component slv_mac_memory is +port( + CLK : in std_logic; + RESET : in std_logic; + BUSY_IN : in std_logic; + -- Slave bus + SLV_ADDR_IN : in std_logic_vector(7 downto 0); + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_BUSY_OUT : out std_logic; + SLV_ACK_OUT : out std_logic; + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + -- I/O to the backend + MEM_CLK_IN : in std_logic; + MEM_ADDR_IN : in std_logic_vector(7 downto 0); + MEM_DATA_OUT : out std_logic_vector(31 downto 0); + -- Status lines + STAT : out std_logic_vector(31 downto 0) -- DEBUG +); +end component; + +component fifo_4096x9 is +port( + Data : in std_logic_vector(8 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(8 downto 0); + Empty : out std_logic; + Full : out std_logic +); +end component; + +signal ig_bsm_save : std_logic_vector(3 downto 0); +signal ig_bsm_load : std_logic_vector(3 downto 0); +signal ig_cts_ctr : std_logic_vector(2 downto 0); +signal ig_rem_ctr : std_logic_vector(3 downto 0); +signal ig_debug : std_logic_vector(31 downto 0); +signal ig_data : std_logic_vector(15 downto 0); +signal ig_wcnt : std_logic_vector(15 downto 0); +signal ig_rcnt : std_logic_vector(16 downto 0); +signal ig_rd_en : std_logic; +signal ig_wr_en : std_logic; +signal ig_empty : std_logic; +signal ig_aempty : std_logic; +signal ig_full : std_logic; +signal ig_afull : std_logic; + +signal pc_wr_en : std_logic; +signal pc_data : std_logic_vector(7 downto 0); +signal pc_eod : std_logic; +signal pc_sos : std_logic; +signal pc_ready : std_logic; +signal pc_padding : std_logic; +signal pc_decoding : std_logic_vector(31 downto 0); +signal pc_event_id : std_logic_vector(31 downto 0); +signal pc_queue_dec : std_logic_vector(31 downto 0); +signal pc_max_frame_size : std_logic_vector(15 downto 0); +signal pc_bsm_constr : std_logic_vector(3 downto 0); +signal pc_bsm_load : std_logic_vector(3 downto 0); +signal pc_bsm_save : std_logic_vector(3 downto 0); +signal pc_shf_empty : std_logic; +signal pc_shf_full : std_logic; +signal pc_shf_wr_en : std_logic; +signal pc_shf_rd_en : std_logic; +signal pc_shf_q : std_logic_vector(7 downto 0); +signal pc_df_empty : std_logic; +signal pc_df_full : std_logic; +signal pc_df_wr_en : std_logic; +signal pc_df_rd_en : std_logic; +signal pc_df_q : std_logic_vector(7 downto 0); +signal pc_all_ctr : std_logic_vector(4 downto 0); +signal pc_sub_ctr : std_logic_vector(4 downto 0); +signal pc_bytes_loaded : std_logic_vector(15 downto 0); +signal pc_size_left : std_logic_vector(31 downto 0); +signal pc_sub_size_to_save : std_logic_vector(31 downto 0); +signal pc_sub_size_loaded : std_logic_vector(31 downto 0); +signal pc_sub_bytes_loaded : std_logic_vector(31 downto 0); +signal pc_queue_size : std_logic_vector(31 downto 0); +signal pc_act_queue_size : std_logic_vector(31 downto 0); + +signal fee_read : std_logic; +signal cts_readout_finished : std_logic; +signal cts_dataready : std_logic; +signal cts_length : std_logic_vector(15 downto 0); +signal cts_data : std_logic_vector(31 downto 0); -- DHDR of rest packet +signal cts_error_pattern : std_logic_vector(31 downto 0); + +signal pc_sub_size : std_logic_vector(31 downto 0); +signal pc_trig_nr : std_logic_vector(31 downto 0); + +signal tc_wr_en : std_logic; +signal tc_data : std_logic_vector(7 downto 0); +signal tc_ip_size : std_logic_vector(15 downto 0); +signal tc_udp_size : std_logic_vector(15 downto 0); +signal tc_ident : std_logic_vector(15 downto 0); +signal tc_flags_offset : std_logic_vector(15 downto 0); +signal tc_sod : std_logic; +signal tc_eod : std_logic; +signal tc_h_ready : std_logic; +signal tc_ready : std_logic; +signal fc_dest_mac : std_logic_vector(47 downto 0); +signal fc_dest_ip : std_logic_vector(31 downto 0); +signal fc_dest_udp : std_logic_vector(15 downto 0); +signal fc_src_mac : std_logic_vector(47 downto 0); +signal fc_src_ip : std_logic_vector(31 downto 0); +signal fc_src_udp : std_logic_vector(15 downto 0); +signal fc_type : std_logic_vector(15 downto 0); +signal fc_ihl_version : std_logic_vector(7 downto 0); +signal fc_tos : std_logic_vector(7 downto 0); +signal fc_ttl : std_logic_vector(7 downto 0); +signal fc_protocol : std_logic_vector(7 downto 0); +signal fc_bsm_constr : std_logic_vector(7 downto 0); +signal fc_bsm_trans : std_logic_vector(3 downto 0); + +signal ft_data : std_logic_vector(8 downto 0);-- gk 04.05.10 +signal ft_tx_empty : std_logic; +signal ft_start_of_packet : std_logic; +signal ft_bsm_init : std_logic_vector(3 downto 0); +signal ft_bsm_mac : std_logic_vector(3 downto 0); +signal ft_bsm_trans : std_logic_vector(3 downto 0); + +signal mac_haddr : std_logic_vector(7 downto 0); +signal mac_hdataout : std_logic_vector(7 downto 0); +signal mac_hcs : std_logic; +signal mac_hwrite : std_logic; +signal mac_hread : std_logic; +signal mac_fifoavail : std_logic; +signal mac_fifoempty : std_logic; +signal mac_fifoeof : std_logic; +signal mac_hready : std_logic; +signal mac_hdata_en : std_logic; +signal mac_tx_done : std_logic; +signal mac_tx_read : std_logic; + +signal serdes_clk_125 : std_logic; +signal mac_tx_clk_en : std_logic; +signal mac_rx_clk_en : std_logic; +signal mac_col : std_logic; +signal mac_crs : std_logic; +signal pcs_txd : std_logic_vector(7 downto 0); +signal pcs_tx_en : std_logic; +signal pcs_tx_er : std_logic; +signal pcs_an_lp_ability : std_logic_vector(15 downto 0); +signal pcs_an_complete : std_logic; +signal pcs_an_page_rx : std_logic; + +signal pcs_stat_debug : std_logic_vector(63 downto 0); + +signal stage_stat_regs : std_logic_vector(31 downto 0); +signal stage_ctrl_regs : std_logic_vector(31 downto 0); + +signal analyzer_debug : std_logic_vector(63 downto 0); + +signal ip_cfg_start : std_logic; +signal ip_cfg_bank : std_logic_vector(3 downto 0); +signal ip_cfg_done : std_logic; + +signal ip_cfg_mem_addr : std_logic_vector(7 downto 0); +signal ip_cfg_mem_data : std_logic_vector(31 downto 0); +signal ip_cfg_mem_clk : std_logic; + +-- gk 22.04.10 +signal max_packet : std_logic_vector(31 downto 0); +signal min_packet : std_logic_vector(31 downto 0); +signal use_gbe : std_logic; +signal use_trbnet : std_logic; +signal use_multievents : std_logic; +-- gk 26.04.10 +signal readout_ctr : std_logic_vector(23 downto 0); +signal readout_ctr_valid : std_logic; +signal gbe_trig_nr : std_logic_vector(31 downto 0); +-- gk 28.04.10 +signal pc_delay : std_logic_vector(31 downto 0); +-- gk 04.05.10 +signal ft_eod : std_logic; +-- gk 01.06.10 +signal dbg_ipu2gbe1 : std_logic_vector(31 downto 0); +signal dbg_ipu2gbe2 : std_logic_vector(31 downto 0); +signal dbg_ipu2gbe3 : std_logic_vector(31 downto 0); +signal dbg_ipu2gbe4 : std_logic_vector(31 downto 0); +signal dbg_ipu2gbe5 : std_logic_vector(31 downto 0); +signal dbg_ipu2gbe6 : std_logic_vector(31 downto 0); +signal dbg_ipu2gbe7 : std_logic_vector(31 downto 0); +signal dbg_ipu2gbe8 : std_logic_vector(31 downto 0); +signal dbg_ipu2gbe9 : std_logic_vector(31 downto 0); +signal dbg_ipu2gbe10 : std_logic_vector(31 downto 0); +signal dbg_ipu2gbe11 : std_logic_vector(31 downto 0); +signal dbg_ipu2gbe12 : std_logic_vector(31 downto 0); +signal dbg_pc1 : std_logic_vector(31 downto 0); +signal dbg_pc2 : std_logic_vector(31 downto 0); +signal dbg_fc1 : std_logic_vector(31 downto 0); +signal dbg_fc2 : std_logic_vector(31 downto 0); +signal dbg_ft1 : std_logic_vector(31 downto 0); +-- gk 08.06.10 +signal mac_tx_staten : std_logic; +signal mac_tx_statevec : std_logic_vector(30 downto 0); +signal mac_tx_discfrm : std_logic; + +signal dbg_rd_en : std_logic; +signal dbg_q : std_logic_vector(15 downto 0); + +-- gk 21.07.10 +signal allow_large : std_logic; + +-- gk 28.07.10 +signal bytes_sent_ctr : std_logic_vector(31 downto 0); +signal monitor_sent : std_logic_vector(31 downto 0); +signal monitor_dropped : std_logic_vector(31 downto 0); +signal monitor_sm : std_logic_vector(31 downto 0); +signal monitor_lr : std_logic_vector(31 downto 0); +signal monitor_hr : std_logic_vector(31 downto 0); +signal monitor_fifos : std_logic_vector(31 downto 0); +signal monitor_fifos_q : std_logic_vector(31 downto 0); +signal monitor_discfrm : std_logic_vector(31 downto 0); + +-- gk 02.08.10 +signal discfrm_ctr : std_logic_vector(31 downto 0); + +-- gk 28.09.10 +signal dbg_reset_fifo : std_logic; + +-- gk 30.09.10 +signal fc_rd_en : std_logic; +signal link_ok : std_logic; +signal link_ok_timeout_ctr : std_logic_vector(15 downto 0); + +type linkStates is (ACTIVE, INACTIVE, TIMEOUT, FINALIZE); +signal link_current_state, link_next_state : linkStates; + +signal link_down_ctr : std_logic_vector(15 downto 0); +signal link_down_ctr_lock : std_logic; + +signal link_state : std_logic_vector(3 downto 0); + +signal monitor_empty : std_logic_vector(31 downto 0); + +-- gk 07.10.10 +signal pc_eos : std_logic; + +-- gk 09.12.10 +signal frame_delay : std_logic_vector(31 downto 0); + +-- gk 13.02.11 +signal pcs_rxd : std_logic_vector(7 downto 0); +signal pcs_rx_en : std_logic; +signal pcs_rx_er : std_logic; +signal mac_rx_eof : std_logic; +signal mac_rx_er : std_logic; +signal mac_rxd : std_logic_vector(7 downto 0); +signal mac_rx_fifo_err : std_logic; +signal mac_rx_fifo_full : std_logic; +signal mac_rx_en : std_logic; +signal mac_rx_stat_en : std_logic; +signal mac_rx_stat_vec : std_logic_vector(31 downto 0); +signal fr_q : std_logic_vector(8 downto 0); +signal fr_rd_en : std_logic; +signal fr_frame_valid : std_logic; +signal rc_rd_en : std_logic; +signal rc_q : std_logic_vector(8 downto 0); +signal rc_frames_rec_ctr : std_logic_vector(31 downto 0); +signal tc_pc_ready : std_logic; +signal tc_pc_h_ready : std_logic; +signal mc_ctrl_frame_req : std_logic; +signal mc_data : std_logic_vector(8 downto 0); +signal mc_rd_en : std_logic; +signal fc_wr_en : std_logic; +signal fc_data : std_logic_vector(7 downto 0); +signal fc_ip_size : std_logic_vector(15 downto 0); +signal fc_udp_size : std_logic_vector(15 downto 0); +signal fc_ident : std_logic_vector(15 downto 0); +signal fc_flags_offset : std_logic_vector(15 downto 0); +signal fc_sod : std_logic; +signal fc_eod : std_logic; +signal fc_h_ready : std_logic; +signal fc_ready : std_logic; +signal rc_frame_ready : std_logic; +signal allow_rx : std_logic; +signal fr_frame_size : std_logic_vector(15 downto 0); +signal rc_frame_size : std_logic_vector(15 downto 0); +signal mc_frame_size : std_logic_vector(15 downto 0); +signal ic_dest_mac : std_logic_vector(47 downto 0); +signal ic_dest_ip : std_logic_vector(31 downto 0); +signal ic_dest_udp : std_logic_vector(15 downto 0); +signal ic_src_mac : std_logic_vector(47 downto 0); +signal ic_src_ip : std_logic_vector(31 downto 0); +signal ic_src_udp : std_logic_vector(15 downto 0); +signal pc_transmit_on : std_logic; +signal rc_bytes_rec : std_logic_vector(31 downto 0); +signal rc_debug : std_logic_vector(63 downto 0); +signal mc_busy : std_logic; +signal tsmac_gbit_en : std_logic; +signal mc_transmit_ctrl : std_logic; +signal mc_transmit_data : std_logic; +signal rc_loading_done : std_logic; +signal fr_get_frame : std_logic; +signal mc_transmit_done : std_logic; + +signal dbg_fr : std_logic_vector(95 downto 0); +signal dbg_rc : std_logic_vector(63 downto 0); +signal dbg_mc : std_logic_vector(63 downto 0); +signal dbg_tc : std_logic_vector(63 downto 0); + +signal fr_allowed_types : std_logic_vector(31 downto 0); +signal fr_allowed_ip : std_logic_vector(31 downto 0); +signal fr_allowed_udp : std_logic_vector(31 downto 0); + +signal fr_frame_proto : std_logic_vector(15 downto 0); +signal rc_frame_proto : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); + +signal dbg_select_rec : std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); +signal dbg_select_sent : std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); +signal dbg_select_protos : std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0); + +signal serdes_rx_clk : std_logic; + +signal vlan_id : std_logic_vector(31 downto 0); +signal mc_type : std_logic_vector(15 downto 0); +signal fr_src_mac : std_logic_vector(47 downto 0); +signal fr_dest_mac : std_logic_vector(47 downto 0); +signal fr_src_ip : std_logic_vector(31 downto 0); +signal fr_dest_ip : std_logic_vector(31 downto 0); +signal fr_src_udp : std_logic_vector(15 downto 0); +signal fr_dest_udp : std_logic_vector(15 downto 0); +signal rc_src_mac : std_logic_vector(47 downto 0); +signal rc_dest_mac : std_logic_vector(47 downto 0); +signal rc_src_ip : std_logic_vector(31 downto 0); +signal rc_dest_ip : std_logic_vector(31 downto 0); +signal rc_src_udp : std_logic_vector(15 downto 0); +signal rc_dest_udp : std_logic_vector(15 downto 0); + +signal mc_dest_mac : std_logic_vector(47 downto 0); +signal mc_dest_ip : std_logic_vector(31 downto 0); +signal mc_dest_udp : std_logic_vector(15 downto 0); +signal mc_src_mac : std_logic_vector(47 downto 0); +signal mc_src_ip : std_logic_vector(31 downto 0); +signal mc_src_udp : std_logic_vector(15 downto 0); + +signal dbg_ft : std_logic_vector(63 downto 0); + +signal fr_ip_proto : std_logic_vector(7 downto 0); +signal mc_ip_proto : std_logic_vector(7 downto 0); + +begin + +--my_mac <= x"efbeefbe0000"; -- temporary + +stage_ctrl_regs <= STAGE_CTRL_REGS_IN; + +-- gk 23.04.10 +LED_PACKET_SENT_OUT <= pc_ready; +LED_AN_DONE_N_OUT <= not link_ok; --not pcs_an_complete; + +-- FrameConstructor fixed magic values +--fc_type <= x"0008"; +fc_ihl_version <= x"45"; +fc_tos <= x"10"; +fc_ttl <= x"ff"; +--fc_protocol <= x"11"; + +-- +-- MAIN_CONTROL : trb_net16_gbe_main_control +-- port map( +-- CLK => CLK, +-- CLK_125 => serdes_clk_125, +-- RESET => RESET, +-- +-- MC_LINK_OK_OUT => link_ok, +-- MC_RESET_LINK_IN => MR_RESTART_IN, +-- +-- -- signals to/from receive controller +-- RC_FRAME_WAITING_IN => rc_frame_ready, +-- RC_LOADING_DONE_OUT => rc_loading_done, +-- RC_DATA_IN => rc_q, +-- RC_RD_EN_OUT => rc_rd_en, +-- RC_FRAME_SIZE_IN => rc_frame_size, +-- RC_FRAME_PROTO_IN => rc_frame_proto, +-- +-- RC_SRC_MAC_ADDRESS_IN => rc_src_mac, +-- RC_DEST_MAC_ADDRESS_IN => rc_dest_mac, +-- RC_SRC_IP_ADDRESS_IN => rc_src_ip, +-- RC_DEST_IP_ADDRESS_IN => rc_dest_ip, +-- RC_SRC_UDP_PORT_IN => rc_src_udp, +-- RC_DEST_UDP_PORT_IN => rc_dest_udp, +-- +-- -- signals to/from transmit controller +-- TC_TRANSMIT_CTRL_OUT => mc_transmit_ctrl, +-- TC_TRANSMIT_DATA_OUT => mc_transmit_data, +-- TC_DATA_OUT => mc_data, +-- TC_RD_EN_IN => mc_rd_en, +-- TC_FRAME_SIZE_OUT => mc_frame_size, +-- TC_FRAME_TYPE_OUT => mc_type, +-- TC_IP_PROTOCOL_OUT => mc_ip_proto, +-- +-- TC_DEST_MAC_OUT => mc_dest_mac, +-- TC_DEST_IP_OUT => mc_dest_ip, +-- TC_DEST_UDP_OUT => mc_dest_udp, +-- TC_SRC_MAC_OUT => mc_src_mac, +-- TC_SRC_IP_OUT => mc_src_ip, +-- TC_SRC_UDP_OUT => mc_src_udp, +-- +-- TC_BUSY_IN => mc_busy, +-- TC_TRANSMIT_DONE_IN => mc_transmit_done, +-- +-- -- signals to/from packet constructor +-- PC_READY_IN => pc_ready, +-- PC_TRANSMIT_ON_IN => pc_transmit_on, +-- PC_SOD_IN => tc_sod, +-- +-- -- signals to/from sgmii/gbe pcs_an_complete +-- PCS_AN_COMPLETE_IN => pcs_an_complete, +-- +-- -- signals to/from hub +-- +-- +-- -- signal to/from Host interface of TriSpeed MAC +-- TSM_HADDR_OUT => mac_haddr, +-- TSM_HDATA_OUT => mac_hdataout, +-- TSM_HCS_N_OUT => mac_hcs, +-- TSM_HWRITE_N_OUT => mac_hwrite, +-- TSM_HREAD_N_OUT => mac_hread, +-- TSM_HREADY_N_IN => mac_hready, +-- TSM_HDATA_EN_N_IN => mac_hdata_en, +-- +-- SELECT_REC_FRAMES_OUT => dbg_select_rec, +-- SELECT_SENT_FRAMES_OUT => dbg_select_sent, +-- SELECT_PROTOS_DEBUG_OUT => dbg_select_protos, +-- +-- DEBUG_OUT => dbg_mc +-- ); +-- +-- +-- TRANSMIT_CONTROLLER : trb_net16_gbe_transmit_control +-- port map( +-- CLK => CLK, +-- RESET => RESET, +-- +-- -- signals to/from packet constructor +-- PC_READY_IN => pc_ready, +-- PC_DATA_IN => tc_data, +-- PC_WR_EN_IN => tc_wr_en, +-- PC_IP_SIZE_IN => tc_ip_size, +-- PC_UDP_SIZE_IN => tc_udp_size, +-- PC_FLAGS_OFFSET_IN => tc_flags_offset, +-- PC_SOD_IN => tc_sod, +-- PC_EOD_IN => tc_eod, +-- PC_FC_READY_OUT => tc_pc_ready, +-- PC_FC_H_READY_OUT => tc_pc_h_ready, +-- PC_TRANSMIT_ON_IN => pc_transmit_on, +-- +-- -- signals from ip_configurator used by packet constructor +-- IC_DEST_MAC_ADDRESS_IN => ic_dest_mac, +-- IC_DEST_IP_ADDRESS_IN => ic_dest_ip, +-- IC_DEST_UDP_PORT_IN => ic_dest_udp, +-- IC_SRC_MAC_ADDRESS_IN => ic_src_mac, +-- IC_SRC_IP_ADDRESS_IN => ic_src_ip, +-- IC_SRC_UDP_PORT_IN => ic_src_udp, +-- +-- -- signal to/from main controller +-- MC_TRANSMIT_CTRL_IN => mc_transmit_ctrl, +-- MC_TRANSMIT_DATA_IN => mc_transmit_data, +-- MC_DATA_IN => mc_data, +-- MC_RD_EN_OUT => mc_rd_en, +-- MC_FRAME_SIZE_IN => mc_frame_size, +-- MC_FRAME_TYPE_IN => mc_type, +-- MC_IP_PROTOCOL_IN => mc_ip_proto, +-- +-- MC_DEST_MAC_IN => mc_dest_mac, +-- MC_DEST_IP_IN => mc_dest_ip, +-- MC_DEST_UDP_IN => mc_dest_udp, +-- MC_SRC_MAC_IN => mc_src_mac, +-- MC_SRC_IP_IN => mc_src_ip, +-- MC_SRC_UDP_IN => mc_src_udp, +-- +-- MC_BUSY_OUT => mc_busy, +-- MC_TRANSMIT_DONE_OUT => mc_transmit_done, +-- +-- -- signal to/from frame constructor +-- FC_DATA_OUT => fc_data, +-- FC_WR_EN_OUT => fc_wr_en, +-- FC_READY_IN => fc_ready, +-- FC_H_READY_IN => fc_h_ready, +-- FC_FRAME_TYPE_OUT => fc_type, +-- FC_IP_SIZE_OUT => fc_ip_size, +-- FC_UDP_SIZE_OUT => fc_udp_size, +-- FC_IDENT_OUT => fc_ident, +-- FC_FLAGS_OFFSET_OUT => fc_flags_offset, +-- FC_SOD_OUT => fc_sod, +-- FC_EOD_OUT => fc_eod, +-- FC_IP_PROTOCOL_OUT => fc_protocol, +-- +-- DEST_MAC_ADDRESS_OUT => fc_dest_mac, +-- DEST_IP_ADDRESS_OUT => fc_dest_ip, +-- DEST_UDP_PORT_OUT => fc_dest_udp, +-- SRC_MAC_ADDRESS_OUT => fc_src_mac, +-- SRC_IP_ADDRESS_OUT => fc_src_ip, +-- SRC_UDP_PORT_OUT => fc_src_udp, +-- +-- +-- -- debug +-- DEBUG_OUT => dbg_tc +-- ); +-- +-- +-- setup_imp_gen : if (DO_SIMULATION = 0) generate +-- -- gk 22.04.10 new entity to set values via slow control +-- SETUP : gbe_setup +-- port map( +-- CLK => CLK, +-- RESET => RESET, +-- +-- -- gk 26.04.10 +-- -- interface to regio bus +-- BUS_ADDR_IN => BUS_ADDR_IN, +-- BUS_DATA_IN => BUS_DATA_IN, +-- BUS_DATA_OUT => BUS_DATA_OUT, +-- BUS_WRITE_EN_IN => BUS_WRITE_EN_IN, +-- BUS_READ_EN_IN => BUS_READ_EN_IN, +-- BUS_ACK_OUT => BUS_ACK_OUT, +-- +-- GBE_TRIG_NR_IN => pc_trig_nr, -- gk 26.04.10 +-- +-- -- output to gbe_buf +-- GBE_SUBEVENT_ID_OUT => pc_event_id, +-- GBE_SUBEVENT_DEC_OUT => pc_decoding, +-- GBE_QUEUE_DEC_OUT => pc_queue_dec, +-- GBE_MAX_PACKET_OUT => max_packet, +-- GBE_MIN_PACKET_OUT => min_packet, -- gk 20.07.10 +-- GBE_MAX_FRAME_OUT => pc_max_frame_size, +-- GBE_USE_GBE_OUT => use_gbe, +-- GBE_USE_TRBNET_OUT => use_trbnet, +-- GBE_USE_MULTIEVENTS_OUT => use_multievents, +-- GBE_READOUT_CTR_OUT => readout_ctr, -- gk 26.04.10 +-- GBE_READOUT_CTR_VALID_OUT => readout_ctr_valid, -- gk 26.04.10 +-- GBE_DELAY_OUT => pc_delay, +-- GBE_ALLOW_LARGE_OUT => allow_large, -- gk 21.07.10 +-- GBE_ALLOW_RX_OUT => allow_rx, +-- GBE_FRAME_DELAY_OUT => frame_delay, -- gk 09.12.10 +-- GBE_ALLOWED_TYPES_OUT => fr_allowed_types, +-- GBE_ALLOWED_IP_OUT => fr_allowed_ip, +-- GBE_ALLOWED_UDP_OUT => fr_allowed_udp, +-- GBE_VLAN_ID_OUT => vlan_id, +-- -- gk 28.07.10 +-- MONITOR_BYTES_IN => bytes_sent_ctr, +-- MONITOR_SENT_IN => monitor_sent, +-- MONITOR_DROPPED_IN => monitor_dropped, +-- MONITOR_SM_IN => monitor_sm, +-- MONITOR_LR_IN => monitor_lr, +-- MONITOR_HDR_IN => monitor_hr, +-- MONITOR_FIFOS_IN => monitor_fifos_q, +-- MONITOR_DISCFRM_IN => monitor_discfrm, +-- MONITOR_EMPTY_IN => monitor_empty, +-- MONITOR_LINK_DWN_IN(15 downto 0) => link_down_ctr, -- gk 30.09.10 +-- MONITOR_LINK_DWN_IN(19 downto 16) => link_state, +-- MONITOR_LINK_DWN_IN(23 downto 20) => ft_bsm_trans, +-- MONITOR_LINK_DWN_IN(27 downto 24) => fc_bsm_trans, +-- MONITOR_LINK_DWN_IN(31 downto 28) => (others => '0'), +-- MONITOR_RX_FRAMES_IN => rc_frames_rec_ctr, +-- MONITOR_RX_BYTES_IN => rc_bytes_rec, +-- MONITOR_RX_BYTES_R_IN => rc_debug(31 downto 0), +-- -- gk 01.06.10 +-- DBG_IPU2GBE1_IN => dbg_ipu2gbe1, +-- DBG_IPU2GBE2_IN => dbg_ipu2gbe2, +-- DBG_IPU2GBE3_IN => dbg_ipu2gbe3, +-- DBG_IPU2GBE4_IN => dbg_ipu2gbe4, +-- DBG_IPU2GBE5_IN => dbg_ipu2gbe5, +-- DBG_IPU2GBE6_IN => dbg_ipu2gbe6, +-- DBG_IPU2GBE7_IN => dbg_ipu2gbe7, +-- DBG_IPU2GBE8_IN => dbg_ipu2gbe8, +-- DBG_IPU2GBE9_IN => dbg_ipu2gbe9, +-- DBG_IPU2GBE10_IN => dbg_ipu2gbe10, +-- DBG_IPU2GBE11_IN => dbg_ipu2gbe11, +-- DBG_IPU2GBE12_IN => dbg_ipu2gbe12, +-- DBG_PC1_IN => dbg_pc1, +-- DBG_PC2_IN => dbg_pc2, +-- DBG_FC1_IN => dbg_fc1, +-- DBG_FC2_IN => dbg_fc2, +-- DBG_FT1_IN => dbg_ft1, +-- DBG_FT2_IN => dbg_ft(31 downto 0), +-- DBG_FR_IN => dbg_fr, +-- DBG_RC_IN => dbg_rc, +-- DBG_MC_IN => dbg_mc, +-- DBG_TC_IN => dbg_tc(31 downto 0), +-- DBG_FIFO_RD_EN_OUT => dbg_rd_en, +-- +-- DBG_SELECT_REC_IN => dbg_select_rec, +-- DBG_SELECT_SENT_IN => dbg_select_sent, +-- DBG_SELECT_PROTOS_IN => dbg_select_protos, +-- +-- DBG_FIFO_Q_IN => dbg_q +-- +-- --DBG_FIFO_RESET_OUT => dbg_reset_fifo -- gk 28.09.10 +-- ); +-- end generate; +-- +-- setup_sim_gen : if (DO_SIMULATION = 1) generate +-- -- gk 22.04.10 new entity to set values via slow control +-- SETUP : gbe_setup +-- port map( +-- CLK => CLK, +-- RESET => RESET, +-- +-- -- gk 26.04.10 +-- -- interface to regio bus +-- BUS_ADDR_IN => BUS_ADDR_IN, +-- BUS_DATA_IN => BUS_DATA_IN, +-- BUS_DATA_OUT => BUS_DATA_OUT, +-- BUS_WRITE_EN_IN => BUS_WRITE_EN_IN, +-- BUS_READ_EN_IN => BUS_READ_EN_IN, +-- BUS_ACK_OUT => BUS_ACK_OUT, +-- +-- GBE_TRIG_NR_IN => pc_trig_nr, -- gk 26.04.10 +-- +-- -- output to gbe_buf +-- GBE_SUBEVENT_ID_OUT => pc_event_id, +-- GBE_SUBEVENT_DEC_OUT => pc_decoding, +-- GBE_QUEUE_DEC_OUT => pc_queue_dec, +-- GBE_MAX_PACKET_OUT => max_packet, +-- GBE_MIN_PACKET_OUT => min_packet, -- gk 20.07.10 +-- GBE_MAX_FRAME_OUT => pc_max_frame_size, +-- GBE_USE_GBE_OUT => use_gbe, +-- GBE_USE_TRBNET_OUT => use_trbnet, +-- GBE_USE_MULTIEVENTS_OUT => use_multievents, +-- GBE_READOUT_CTR_OUT => readout_ctr, -- gk 26.04.10 +-- GBE_READOUT_CTR_VALID_OUT => readout_ctr_valid, -- gk 26.04.10 +-- GBE_DELAY_OUT => pc_delay, +-- GBE_ALLOW_LARGE_OUT => open, +-- GBE_ALLOW_RX_OUT => open, +-- GBE_FRAME_DELAY_OUT => frame_delay, -- gk 09.12.10 +-- GBE_ALLOWED_TYPES_OUT => fr_allowed_types, +-- GBE_ALLOWED_IP_OUT => fr_allowed_ip, +-- GBE_ALLOWED_UDP_OUT => fr_allowed_udp, +-- GBE_VLAN_ID_OUT => vlan_id, +-- -- gk 28.07.10 +-- MONITOR_BYTES_IN => bytes_sent_ctr, +-- MONITOR_SENT_IN => monitor_sent, +-- MONITOR_DROPPED_IN => monitor_dropped, +-- MONITOR_SM_IN => monitor_sm, +-- MONITOR_LR_IN => monitor_lr, +-- MONITOR_HDR_IN => monitor_hr, +-- MONITOR_FIFOS_IN => monitor_fifos_q, +-- MONITOR_DISCFRM_IN => monitor_discfrm, +-- MONITOR_EMPTY_IN => monitor_empty, +-- MONITOR_LINK_DWN_IN(15 downto 0) => link_down_ctr, -- gk 30.09.10 +-- MONITOR_LINK_DWN_IN(19 downto 16) => link_state, +-- MONITOR_LINK_DWN_IN(23 downto 20) => ft_bsm_trans, +-- MONITOR_LINK_DWN_IN(27 downto 24) => fc_bsm_trans, +-- MONITOR_LINK_DWN_IN(31 downto 28) => (others => '0'), +-- MONITOR_RX_FRAMES_IN => rc_frames_rec_ctr, +-- MONITOR_RX_BYTES_IN => rc_bytes_rec, +-- MONITOR_RX_BYTES_R_IN => rc_debug(31 downto 0), +-- -- gk 01.06.10 +-- DBG_IPU2GBE1_IN => dbg_ipu2gbe1, +-- DBG_IPU2GBE2_IN => dbg_ipu2gbe2, +-- DBG_IPU2GBE3_IN => dbg_ipu2gbe3, +-- DBG_IPU2GBE4_IN => dbg_ipu2gbe4, +-- DBG_IPU2GBE5_IN => dbg_ipu2gbe5, +-- DBG_IPU2GBE6_IN => dbg_ipu2gbe6, +-- DBG_IPU2GBE7_IN => dbg_ipu2gbe7, +-- DBG_IPU2GBE8_IN => dbg_ipu2gbe8, +-- DBG_IPU2GBE9_IN => dbg_ipu2gbe9, +-- DBG_IPU2GBE10_IN => dbg_ipu2gbe10, +-- DBG_IPU2GBE11_IN => dbg_ipu2gbe11, +-- DBG_IPU2GBE12_IN => dbg_ipu2gbe12, +-- DBG_PC1_IN => dbg_pc1, +-- DBG_PC2_IN => dbg_pc2, +-- DBG_FC1_IN => dbg_fc1, +-- DBG_FC2_IN => dbg_fc2, +-- DBG_FT1_IN => dbg_ft1, +-- DBG_FT2_IN => dbg_ft(31 downto 0), +-- DBG_FR_IN => dbg_fr, +-- DBG_RC_IN => dbg_rc(31 downto 0), +-- DBG_MC_IN => dbg_mc, +-- DBG_TC_IN => dbg_tc(31 downto 0), +-- DBG_FIFO_RD_EN_OUT => dbg_rd_en, +-- +-- DBG_SELECT_REC_IN => dbg_select_rec, +-- DBG_SELECT_SENT_IN => dbg_select_sent, +-- DBG_SELECT_PROTOS_IN => dbg_select_protos, +-- +-- DBG_FIFO_Q_IN => dbg_q +-- --DBG_FIFO_RESET_OUT => dbg_reset_fifo -- gk 28.09.10 +-- ); +-- +-- allow_rx <= '1'; +-- allow_large <= '0'; +-- +-- end generate; +-- +-- +-- -- IP configurator: allows IP config to change for each event builder +-- THE_IP_CONFIGURATOR: ip_configurator +-- port map( +-- CLK => CLK, +-- RESET => RESET, +-- -- configuration interface +-- START_CONFIG_IN => ip_cfg_start, --IP_CFG_START_IN, -- new -- gk 7.03.10 +-- BANK_SELECT_IN => ip_cfg_bank, --IP_CFG_BANK_SEL_IN, -- new -- gk 27.03.10 +-- CONFIG_DONE_OUT => ip_cfg_done, --IP_CFG_DONE_OUT, -- new -- gk 27.03.10 +-- MEM_ADDR_OUT => ip_cfg_mem_addr, --IP_CFG_MEM_ADDR_OUT, -- new -- gk 27.03.10 +-- MEM_DATA_IN => ip_cfg_mem_data, --IP_CFG_MEM_DATA_IN, -- new -- gk 27.03.10 +-- MEM_CLK_OUT => ip_cfg_mem_clk, --IP_CFG_MEM_CLK_OUT, -- new -- gk 27.03.10 +-- -- information for IP cores +-- DEST_MAC_OUT => ic_dest_mac, +-- DEST_IP_OUT => ic_dest_ip, +-- DEST_UDP_OUT => ic_dest_udp, +-- SRC_MAC_OUT => ic_src_mac, +-- SRC_IP_OUT => ic_src_ip, +-- SRC_UDP_OUT => ic_src_udp, +-- MTU_OUT => open, --pc_max_frame_size, -- gk 22.04.10 +-- -- Debug +-- DEBUG_OUT => open +-- ); +-- +-- -- gk 27.03.01 +-- MB_IP_CONFIG: slv_mac_memory +-- port map( +-- CLK => CLK, -- clk_100, +-- RESET => RESET, --reset_i, +-- BUSY_IN => '0', +-- -- Slave bus +-- SLV_ADDR_IN => SLV_ADDR_IN, --x"00", --mb_ip_mem_addr(7 downto 0), +-- SLV_READ_IN => SLV_READ_IN, --'0', --mb_ip_mem_read, +-- SLV_WRITE_IN => SLV_WRITE_IN, --mb_ip_mem_write, +-- SLV_BUSY_OUT => SLV_BUSY_OUT, +-- SLV_ACK_OUT => SLV_ACK_OUT, --mb_ip_mem_ack, +-- SLV_DATA_IN => SLV_DATA_IN, --mb_ip_mem_data_wr, +-- SLV_DATA_OUT => SLV_DATA_OUT, --mb_ip_mem_data_rd, +-- -- I/O to the backend +-- MEM_CLK_IN => ip_cfg_mem_clk, +-- MEM_ADDR_IN => ip_cfg_mem_addr, +-- MEM_DATA_OUT => ip_cfg_mem_data, +-- -- Status lines +-- STAT => open +-- ); +-- +-- -- First stage: get data from IPU channel, buffer it and terminate the IPU transmission to CTS +-- THE_IPU_INTERFACE: trb_net16_ipu2gbe +-- port map( +-- CLK => CLK, +-- RESET => RESET, +-- --Event information coming from CTS +-- CTS_NUMBER_IN => CTS_NUMBER_IN, +-- CTS_CODE_IN => CTS_CODE_IN, +-- CTS_INFORMATION_IN => CTS_INFORMATION_IN, +-- CTS_READOUT_TYPE_IN => CTS_READOUT_TYPE_IN, +-- CTS_START_READOUT_IN => CTS_START_READOUT_IN, +-- --Information sent to CTS +-- --status data, equipped with DHDR +-- CTS_DATA_OUT => cts_data, +-- CTS_DATAREADY_OUT => cts_dataready, +-- CTS_READOUT_FINISHED_OUT => cts_readout_finished, +-- CTS_READ_IN => CTS_READ_IN, +-- CTS_LENGTH_OUT => cts_length, +-- CTS_ERROR_PATTERN_OUT => cts_error_pattern, +-- -- Data from Frontends +-- FEE_DATA_IN => FEE_DATA_IN, +-- FEE_DATAREADY_IN => FEE_DATAREADY_IN, +-- FEE_READ_OUT => fee_read, +-- FEE_STATUS_BITS_IN => FEE_STATUS_BITS_IN, +-- FEE_BUSY_IN => FEE_BUSY_IN, +-- -- slow control interface +-- START_CONFIG_OUT => ip_cfg_start, --open, --: out std_logic; -- reconfigure MACs/IPs/ports/packet size -- gk 27.03.10 +-- BANK_SELECT_OUT => ip_cfg_bank, --open, --: out std_logic_vector(3 downto 0); -- configuration page address -- gk 27.03.10 +-- CONFIG_DONE_IN => ip_cfg_done, --'1', --: in std_logic; -- configuration finished -- gk 27.03.10 +-- DATA_GBE_ENABLE_IN => use_gbe, --'1', --: in std_logic; -- IPU data is forwarded to GbE -- gk 22.04.10 +-- DATA_IPU_ENABLE_IN => use_trbnet, --'0', --: in std_logic; -- IPU data is forwarded to CTS / TRBnet -- gk 22.04.10 +-- MULT_EVT_ENABLE_IN => use_multievents, +-- MAX_MESSAGE_SIZE_IN => max_packet, --x"0000_FDE8", -- gk 08.04.10 -- temporarily fixed here, to be set by slow ctrl -- gk 22.04.10 +-- MIN_MESSAGE_SIZE_IN => min_packet, -- gk 20.07.10 +-- READOUT_CTR_IN => readout_ctr, -- gk 26.04.10 +-- READOUT_CTR_VALID_IN => readout_ctr_valid, -- gk 26.04.10 +-- ALLOW_LARGE_IN => allow_large, -- gk 21.07.10 +-- -- PacketConstructor interface +-- PC_WR_EN_OUT => pc_wr_en, +-- PC_DATA_OUT => pc_data, +-- PC_READY_IN => pc_ready, +-- PC_SOS_OUT => pc_sos, +-- PC_EOS_OUT => pc_eos, -- gk 07.10.10 +-- PC_EOD_OUT => pc_eod, +-- PC_SUB_SIZE_OUT => pc_sub_size, +-- PC_TRIG_NR_OUT => pc_trig_nr, +-- PC_PADDING_OUT => pc_padding, +-- MONITOR_OUT(31 downto 0) => monitor_sent, +-- MONITOR_OUT(63 downto 32) => monitor_dropped, +-- MONITOR_OUT(95 downto 64) => monitor_hr, +-- MONITOR_OUT(127 downto 96) => monitor_sm, +-- MONITOR_OUT(159 downto 128) => monitor_lr, +-- MONITOR_OUT(191 downto 160) => monitor_fifos, +-- MONITOR_OUT(223 downto 192) => monitor_empty, +-- DEBUG_OUT(31 downto 0) => dbg_ipu2gbe1, +-- DEBUG_OUT(63 downto 32) => dbg_ipu2gbe2, +-- DEBUG_OUT(95 downto 64) => dbg_ipu2gbe3, +-- DEBUG_OUT(127 downto 96) => dbg_ipu2gbe4, +-- DEBUG_OUT(159 downto 128) => dbg_ipu2gbe5, +-- DEBUG_OUT(191 downto 160) => dbg_ipu2gbe6, +-- DEBUG_OUT(223 downto 192) => dbg_ipu2gbe7, +-- DEBUG_OUT(255 downto 224) => dbg_ipu2gbe8, +-- DEBUG_OUT(287 downto 256) => dbg_ipu2gbe9, +-- DEBUG_OUT(319 downto 288) => dbg_ipu2gbe10, +-- DEBUG_OUT(351 downto 320) => dbg_ipu2gbe11, +-- DEBUG_OUT(383 downto 352) => dbg_ipu2gbe12 +-- ); +-- +-- -- Second stage: Packet constructor +-- PACKET_CONSTRUCTOR : trb_net16_gbe_packet_constr +-- port map( +-- -- ports for user logic +-- RESET => RESET, +-- CLK => CLK, +-- MULT_EVT_ENABLE_IN => use_multievents, -- gk 06.10.10 +-- PC_WR_EN_IN => pc_wr_en, +-- PC_DATA_IN => pc_data, +-- PC_READY_OUT => pc_ready, +-- PC_START_OF_SUB_IN => dbg_rd_en, -- pc_sos, CHANGED TO SLOW CONTROL PULSE +-- PC_END_OF_SUB_IN => pc_eos, -- gk 07.10.10 +-- PC_END_OF_DATA_IN => pc_eod, +-- PC_TRANSMIT_ON_OUT => pc_transmit_on, +-- -- queue and subevent layer headers +-- PC_SUB_SIZE_IN => pc_sub_size, +-- PC_PADDING_IN => pc_padding, -- gk 29.03.10 +-- PC_DECODING_IN => pc_decoding, +-- PC_EVENT_ID_IN => pc_event_id, +-- PC_TRIG_NR_IN => pc_trig_nr, +-- PC_QUEUE_DEC_IN => pc_queue_dec, +-- PC_MAX_FRAME_SIZE_IN => pc_max_frame_size, +-- PC_DELAY_IN => pc_delay, -- gk 28.04.10 +-- -- NEW PORTS +-- TC_WR_EN_OUT => tc_wr_en, +-- TC_DATA_OUT => tc_data, +-- TC_H_READY_IN => tc_pc_h_ready, +-- TC_READY_IN => tc_pc_ready, +-- TC_IP_SIZE_OUT => tc_ip_size, +-- TC_UDP_SIZE_OUT => tc_udp_size, +-- --FC_IDENT_OUT => fc_ident, +-- TC_FLAGS_OFFSET_OUT => tc_flags_offset, +-- TC_SOD_OUT => tc_sod, +-- TC_EOD_OUT => tc_eod, +-- DEBUG_OUT(31 downto 0) => dbg_pc1, +-- DEBUG_OUT(63 downto 32) => dbg_pc2 +-- ); +-- +-- -- Third stage: Frame Constructor +-- FRAME_CONSTRUCTOR: trb_net16_gbe_frame_constr +-- port map( +-- -- ports for user logic +-- RESET => RESET, +-- CLK => CLK, +-- LINK_OK_IN => link_ok, --pcs_an_complete, -- gk 03.08.10 -- gk 30.09.10 +-- -- +-- WR_EN_IN => fc_wr_en, +-- DATA_IN => fc_data, +-- START_OF_DATA_IN => fc_sod, +-- END_OF_DATA_IN => fc_eod, +-- IP_F_SIZE_IN => fc_ip_size, +-- UDP_P_SIZE_IN => fc_udp_size, +-- HEADERS_READY_OUT => fc_h_ready, +-- READY_OUT => fc_ready, +-- DEST_MAC_ADDRESS_IN => fc_dest_mac, +-- DEST_IP_ADDRESS_IN => fc_dest_ip, +-- DEST_UDP_PORT_IN => fc_dest_udp, +-- SRC_MAC_ADDRESS_IN => fc_src_mac, +-- SRC_IP_ADDRESS_IN => fc_src_ip, +-- SRC_UDP_PORT_IN => fc_src_udp, +-- FRAME_TYPE_IN => fc_type, +-- IHL_VERSION_IN => fc_ihl_version, +-- TOS_IN => fc_tos, +-- IDENTIFICATION_IN => fc_ident, +-- FLAGS_OFFSET_IN => fc_flags_offset, +-- TTL_IN => fc_ttl, +-- PROTOCOL_IN => fc_protocol, +-- FRAME_DELAY_IN => frame_delay, -- gk 09.12.10 +-- -- ports for packetTransmitter +-- RD_CLK => serdes_clk_125, +-- FT_DATA_OUT => ft_data, +-- --FT_EOD_OUT => ft_eod, -- gk 04.05.10 +-- FT_TX_EMPTY_OUT => ft_tx_empty, +-- FT_TX_RD_EN_IN => mac_tx_read, +-- FT_START_OF_PACKET_OUT => ft_start_of_packet, +-- FT_TX_DONE_IN => mac_tx_done, +-- FT_TX_DISCFRM_IN => mac_tx_discfrm, +-- -- debug ports +-- BSM_CONSTR_OUT => fc_bsm_constr, +-- BSM_TRANS_OUT => fc_bsm_trans, +-- DEBUG_OUT(31 downto 0) => dbg_fc1, +-- DEBUG_OUT(63 downto 32) => dbg_fc2 +-- ); +-- +-- +-- +-- RECEIVE_CONTROLLER : trb_net16_gbe_receive_control +-- port map( +-- CLK => CLK, +-- RESET => RESET, +-- +-- -- signals to/from frame_receiver +-- RC_DATA_IN => fr_q, +-- FR_RD_EN_OUT => fr_rd_en, +-- FR_FRAME_VALID_IN => fr_frame_valid, +-- FR_GET_FRAME_OUT => fr_get_frame, +-- FR_FRAME_SIZE_IN => fr_frame_size, +-- FR_FRAME_PROTO_IN => fr_frame_proto, +-- FR_IP_PROTOCOL_IN => fr_ip_proto, +-- +-- FR_SRC_MAC_ADDRESS_IN => fr_src_mac, +-- FR_DEST_MAC_ADDRESS_IN => fr_dest_mac, +-- FR_SRC_IP_ADDRESS_IN => fr_src_ip, +-- FR_DEST_IP_ADDRESS_IN => fr_dest_ip, +-- FR_SRC_UDP_PORT_IN => fr_src_udp, +-- FR_DEST_UDP_PORT_IN => fr_dest_udp, +-- +-- -- signals to/from main controller +-- RC_RD_EN_IN => rc_rd_en, +-- RC_Q_OUT => rc_q, +-- RC_FRAME_WAITING_OUT => rc_frame_ready, +-- RC_LOADING_DONE_IN => rc_loading_done, +-- RC_FRAME_SIZE_OUT => rc_frame_size, +-- RC_FRAME_PROTO_OUT => rc_frame_proto, +-- +-- RC_SRC_MAC_ADDRESS_OUT => rc_src_mac, +-- RC_DEST_MAC_ADDRESS_OUT => rc_dest_mac, +-- RC_SRC_IP_ADDRESS_OUT => rc_src_ip, +-- RC_DEST_IP_ADDRESS_OUT => rc_dest_ip, +-- RC_SRC_UDP_PORT_OUT => rc_src_udp, +-- RC_DEST_UDP_PORT_OUT => rc_dest_udp, +-- +-- -- statistics +-- FRAMES_RECEIVED_OUT => rc_frames_rec_ctr, +-- BYTES_RECEIVED_OUT => rc_bytes_rec, +-- +-- +-- DEBUG_OUT => rc_debug +-- ); +-- dbg_q(15 downto 9) <= (others => '0'); +-- +-- +-- FRAME_TRANSMITTER: trb_net16_gbe_frame_trans +-- port map( +-- CLK => CLK, +-- RESET => RESET, +-- LINK_OK_IN => link_ok, --pcs_an_complete, -- gk 03.08.10 -- gk 30.09.10 +-- TX_MAC_CLK => serdes_clk_125, +-- TX_EMPTY_IN => ft_tx_empty, +-- START_OF_PACKET_IN => ft_start_of_packet, +-- DATA_ENDFLAG_IN => ft_data(8), -- ft_eod -- gk 04.05.10 +-- +-- TX_FIFOAVAIL_OUT => mac_fifoavail, +-- TX_FIFOEOF_OUT => mac_fifoeof, +-- TX_FIFOEMPTY_OUT => mac_fifoempty, +-- TX_DONE_IN => mac_tx_done, +-- TX_STAT_EN_IN => mac_tx_staten, +-- TX_STATVEC_IN => mac_tx_statevec, +-- TX_DISCFRM_IN => mac_tx_discfrm, +-- -- Debug +-- BSM_INIT_OUT => ft_bsm_init, +-- BSM_MAC_OUT => ft_bsm_mac, +-- BSM_TRANS_OUT => ft_bsm_trans, +-- DBG_RD_DONE_OUT => open, +-- DBG_INIT_DONE_OUT => open, +-- DBG_ENABLED_OUT => open, +-- DEBUG_OUT => dbg_ft +-- --DEBUG_OUT(31 downto 0) => open, +-- --DEBUG_OUT(63 downto 32) => open +-- ); +-- +-- +-- FRAME_RECEIVER : trb_net16_gbe_frame_receiver +-- port map( +-- CLK => CLK, +-- RESET => RESET, +-- LINK_OK_IN => link_ok, +-- ALLOW_RX_IN => allow_rx, +-- RX_MAC_CLK => serdes_clk_125, +-- +-- -- input signals from TS_MAC +-- MAC_RX_EOF_IN => mac_rx_eof, +-- MAC_RX_ER_IN => mac_rx_er, +-- MAC_RXD_IN => mac_rxd, +-- MAC_RX_EN_IN => mac_rx_en, +-- MAC_RX_FIFO_ERR_IN => mac_rx_fifo_err, +-- MAC_RX_FIFO_FULL_OUT => mac_rx_fifo_full, +-- MAC_RX_STAT_EN_IN => mac_rx_stat_en, +-- MAC_RX_STAT_VEC_IN => mac_rx_stat_vec, +-- -- output signal to control logic +-- FR_Q_OUT => fr_q, +-- FR_RD_EN_IN => fr_rd_en, +-- FR_FRAME_VALID_OUT => fr_frame_valid, +-- FR_GET_FRAME_IN => fr_get_frame, +-- FR_FRAME_SIZE_OUT => fr_frame_size, +-- FR_FRAME_PROTO_OUT => fr_frame_proto, +-- FR_IP_PROTOCOL_OUT => fr_ip_proto, +-- FR_ALLOWED_TYPES_IN => fr_allowed_types, +-- FR_ALLOWED_IP_IN => fr_allowed_ip, +-- FR_ALLOWED_UDP_IN => fr_allowed_udp, +-- FR_VLAN_ID_IN => vlan_id, +-- +-- FR_SRC_MAC_ADDRESS_OUT => fr_src_mac, +-- FR_DEST_MAC_ADDRESS_OUT => fr_dest_mac, +-- FR_SRC_IP_ADDRESS_OUT => fr_src_ip, +-- FR_DEST_IP_ADDRESS_OUT => fr_dest_ip, +-- FR_SRC_UDP_PORT_OUT => fr_src_udp, +-- FR_DEST_UDP_PORT_OUT => fr_dest_udp, +-- +-- DEBUG_OUT => dbg_fr +-- ); +-- + +-- in case of real hardware, we use the IP cores for MAC and PHY, and also put a SerDes in +imp_gen: if (DO_SIMULATION = 0) generate + -------------------------------------------------------------------------------------------- + -------------------------------------------------------------------------------------------- + -- Implementation + -------------------------------------------------------------------------------------------- + -------------------------------------------------------------------------------------------- + + -- MAC part + MAC: tsmac34 + port map( + ----------------- clock and reset port declarations ------------------ + hclk => CLK, + txmac_clk => serdes_clk_125, + rxmac_clk => serdes_clk_125, + reset_n => GSR_N, + txmac_clk_en => mac_tx_clk_en, + rxmac_clk_en => mac_rx_clk_en, + ------------------- Input signals to the GMII ---------------- NOT USED + rxd => pcs_txd, --pcs_rxd, --x"00", + rx_dv => pcs_tx_en, --pcs_rx_en, --'0', + rx_er => pcs_tx_er, --pcs_rx_er, --'0', + col => mac_col, + crs => mac_crs, + -------------------- Input signals to the CPU I/F ------------------- + haddr => mac_haddr, + hdatain => mac_hdataout, + hcs_n => mac_hcs, + hwrite_n => mac_hwrite, + hread_n => mac_hread, + ---------------- Input signals to the Tx MAC FIFO I/F --------------- + tx_fifodata => ft_data(7 downto 0), + tx_fifoavail => mac_fifoavail, + tx_fifoeof => mac_fifoeof, + tx_fifoempty => mac_fifoempty, + tx_sndpaustim => x"0000", + tx_sndpausreq => '0', + tx_fifoctrl => '0', -- always data frame + ---------------- Input signals to the Rx MAC FIFO I/F --------------- + rx_fifo_full => mac_rx_fifo_full, --'0', + ignore_pkt => '0', + ---------------- Output signals from the GMII ----------------------- + txd => pcs_txd, + tx_en => pcs_tx_en, + tx_er => pcs_tx_er, + ----------------- Output signals from the CPU I/F ------------------- + hdataout => open, + hdataout_en_n => mac_hdata_en, + hready_n => mac_hready, + cpu_if_gbit_en => tsmac_gbit_en, + ------------- Output signals from the Tx MAC FIFO I/F --------------- + tx_macread => mac_tx_read, + tx_discfrm => mac_tx_discfrm, + tx_staten => mac_tx_staten, -- gk 08.06.10 + tx_statvec => mac_tx_statevec, -- gk 08.06.10 + tx_done => mac_tx_done, + ------------- Output signals from the Rx MAC FIFO I/F --------------- + rx_fifo_error => mac_rx_fifo_err, --open, + rx_stat_vector => mac_rx_stat_vec, --open, + rx_dbout => mac_rxd, --open, + rx_write => mac_rx_en, --open, + rx_stat_en => mac_rx_stat_en, --open, + rx_eof => mac_rx_eof, --open, + rx_error => mac_rx_er --open + ); + + -- gk 08.06.10 + dbg_statevec_proc : process(serdes_clk_125) + begin + if rising_edge(serdes_clk_125) then + if (RESET = '1') then + dbg_ft1 <= (others => '0'); + elsif (mac_tx_staten = '1') then + dbg_ft1(30 downto 0) <= mac_tx_statevec; + dbg_ft1(31) <= mac_tx_discfrm; + end if; + end if; + end process dbg_statevec_proc; + + serdes_intclk_gen: if (USE_125MHZ_EXTCLK = 0) generate + -- PHY part + PCS_SERDES : trb_net16_med_ecp_sfp_gbe_8b + generic map( + USE_125MHZ_EXTCLK => 0 + ) + port map( + RESET => RESET, + GSR_N => GSR_N, + CLK_125_OUT => serdes_clk_125, + CLK_125_RX_OUT => open, + CLK_125_IN => CLK_125_IN, + FT_TX_CLK_EN_OUT => mac_tx_clk_en, + FT_RX_CLK_EN_OUT => mac_rx_clk_en, + --connection to frame transmitter (tsmac) + FT_COL_OUT => mac_col, + FT_CRS_OUT => mac_crs, + FT_TXD_IN => pcs_txd, + FT_TX_EN_IN => pcs_tx_en, + FT_TX_ER_IN => pcs_tx_er, + FT_RXD_OUT => pcs_rxd, + FT_RX_EN_OUT => pcs_rx_en, + FT_RX_ER_OUT => pcs_rx_er, + --SFP Connection + SD_RXD_P_IN => SFP_RXD_P_IN, + SD_RXD_N_IN => SFP_RXD_N_IN, + SD_TXD_P_OUT => SFP_TXD_P_OUT, + SD_TXD_N_OUT => SFP_TXD_N_OUT, + SD_REFCLK_P_IN => SFP_REFCLK_P_IN, + SD_REFCLK_N_IN => SFP_REFCLK_N_IN, + SD_PRSNT_N_IN => SFP_PRSNT_N_IN, + SD_LOS_IN => SFP_LOS_IN, + SD_TXDIS_OUT => SFP_TXDIS_OUT, + -- Autonegotiation stuff + MR_ADV_ABILITY_IN => x"0020", -- full duplex only + MR_AN_LP_ABILITY_OUT => pcs_an_lp_ability, + MR_AN_PAGE_RX_OUT => pcs_an_page_rx, + MR_AN_COMPLETE_OUT => pcs_an_complete, + MR_RESET_IN => RESET, --MR_RESET_IN, + MR_MODE_IN => '0', --MR_MODE_IN, + MR_AN_ENABLE_IN => '1', -- do autonegotiation + MR_RESTART_AN_IN => RESET, --MR_RESTART_IN, + -- Status and control port + STAT_OP => open, + CTRL_OP => x"0000", + STAT_DEBUG => pcs_stat_debug, --open, + CTRL_DEBUG => x"0000_0000_0000_0000" + ); + end generate serdes_intclk_gen; + + serdes_extclk_gen: if (USE_125MHZ_EXTCLK = 1) generate + -- PHY part + PCS_SERDES : trb_net16_med_ecp_sfp_gbe_8b + generic map( + USE_125MHZ_EXTCLK => 1 + ) + port map( + RESET => RESET, + GSR_N => GSR_N, + CLK_125_OUT => serdes_clk_125, + CLK_125_RX_OUT => serdes_rx_clk, + CLK_125_IN => '0', -- not used + FT_TX_CLK_EN_OUT => mac_tx_clk_en, + FT_RX_CLK_EN_OUT => mac_rx_clk_en, + --connection to frame transmitter (tsmac) + FT_COL_OUT => mac_col, + FT_CRS_OUT => mac_crs, + FT_TXD_IN => pcs_txd, + FT_TX_EN_IN => pcs_tx_en, + FT_TX_ER_IN => pcs_tx_er, + FT_RXD_OUT => pcs_rxd, + FT_RX_EN_OUT => pcs_rx_en, + FT_RX_ER_OUT => pcs_rx_er, + --SFP Connection + SD_RXD_P_IN => SFP_RXD_P_IN, + SD_RXD_N_IN => SFP_RXD_N_IN, + SD_TXD_P_OUT => SFP_TXD_P_OUT, + SD_TXD_N_OUT => SFP_TXD_N_OUT, + SD_REFCLK_P_IN => SFP_REFCLK_P_IN, + SD_REFCLK_N_IN => SFP_REFCLK_N_IN, + SD_PRSNT_N_IN => SFP_PRSNT_N_IN, + SD_LOS_IN => SFP_LOS_IN, + SD_TXDIS_OUT => SFP_TXDIS_OUT, + -- Autonegotiation stuff + MR_ADV_ABILITY_IN => x"0020", -- full duplex only + MR_AN_LP_ABILITY_OUT => pcs_an_lp_ability, + MR_AN_PAGE_RX_OUT => pcs_an_page_rx, + MR_AN_COMPLETE_OUT => pcs_an_complete, + MR_RESET_IN => MR_RESET_IN, + MR_MODE_IN => MR_MODE_IN, + MR_AN_ENABLE_IN => '1', -- do autonegotiation + MR_RESTART_AN_IN => MR_RESTART_IN, + -- Status and control port + STAT_OP => open, + CTRL_OP => x"0000", + STAT_DEBUG => pcs_stat_debug, --open, + CTRL_DEBUG => x"0000_0000_0000_0000" + ); + end generate serdes_extclk_gen; + + stage_stat_regs(31 downto 28) <= x"e"; + stage_stat_regs(27 downto 24) <= pcs_stat_debug(25 downto 22); -- link s-tatus + stage_stat_regs(23 downto 20) <= pcs_stat_debug(35 downto 32); -- reset bsm + stage_stat_regs(19) <= '0'; + stage_stat_regs(18) <= link_ok; -- gk 30.09.10 + stage_stat_regs(17) <= pcs_an_complete; + stage_stat_regs(16) <= pcs_an_page_rx; + stage_stat_regs(15 downto 0) <= pcs_an_lp_ability; + +end generate imp_gen; + +-- in case of simulation we include a fake MAC and no PHY/SerDes. +sim_gen: if (DO_SIMULATION = 1) generate + -------------------------------------------------------------------------------------------- + -------------------------------------------------------------------------------------------- + -- Simulation + -------------------------------------------------------------------------------------------- + -------------------------------------------------------------------------------------------- + MAC: mb_mac_sim + port map( -------------------------------------------------------------------------- + --------------- clock, reset, clock enable ------------------------------- + HCLK => CLK, + TX_MAC_CLK => serdes_clk_125, + RX_MAC_CLK => serdes_rx_clk, --serdes_clk_125, + RESET_N => GSR_N, + TXMAC_CLK_EN => mac_tx_clk_en, + RXMAC_CLK_EN => mac_rx_clk_en, + -------------------------------------------------------------------------- + --------------- SGMII receive interface ---------------------------------- + RXD => x"00", + RX_DV => '0', + RX_ER => '0', + COL => mac_col, + CRS => mac_crs, + -------------------------------------------------------------------------- + --------------- SGMII transmit interface --------------------------------- + TXD => pcs_txd, + TX_EN => pcs_tx_en, + TX_ER => pcs_tx_er, + -------------------------------------------------------------------------- + --------------- CPU configuration interface ------------------------------ + HADDR => mac_haddr, + HDATAIN => mac_hdataout, + HCS_N => mac_hcs, + HWRITE_N => mac_hwrite, + HREAD_N => mac_hread, + HDATAOUT => open, + HDATAOUT_EN_N => mac_hdata_en, + HREADY_N => mac_hready, + CPU_IF_GBIT_EN => open, + -------------------------------------------------------------------------- + --------------- Transmit FIFO interface ---------------------------------- + TX_FIFODATA => ft_data(7 downto 0), + TX_FIFOAVAIL => mac_fifoavail, + TX_FIFOEOF => mac_fifoeof, + TX_FIFOEMPTY => mac_fifoempty, + TX_MACREAD => mac_tx_read, + TX_DONE => mac_tx_done, + TX_SNDPAUSTIM => x"0000", + TX_SNDPAUSREQ => '0', + TX_FIFOCTRL => '0', + TX_DISCFRM => open, + TX_STATEN => open, + TX_STATVEC => open, + -------------------------------------------------------------------------- + --------------- Receive FIFO interface ----------------------------------- + RX_DBOUT => open, + RX_FIFO_FULL => '0', + IGNORE_PKT => '0', + RX_FIFO_ERROR => open, + RX_STAT_VECTOR => open, + RX_STAT_EN => open, + RX_WRITE => open, + RX_EOF => open, + RX_ERROR => open + ); + + -- add external test clock for the MAC part + serdes_clk_125 <= TEST_CLK; + + -- fake signals + pcs_an_lp_ability <= x"4060"; + pcs_an_page_rx <= '0'; + pcs_an_complete <= '1'; + mac_tx_clk_en <= '1'; + mac_rx_clk_en <= '1'; + + stage_stat_regs(31 downto 0) <= (others => '0'); + + pcs_stat_debug(63 downto 0) <= (others => '0'); + + SFP_TXD_P_OUT <= '1'; + SFP_TXD_N_OUT <= '0'; + SFP_TXDIS_OUT <= '0'; + +end generate sim_gen; + + +--*********************** +-- MONITORING & DEBUG +--*********************** + + +-- gk 04.08.10 +MON_PROC : process(CLK) +begin + if rising_edge(CLK) then + monitor_fifos_q(3 downto 0) <= monitor_fifos(3 downto 0); + if (dbg_pc1(28) = '1') then + monitor_fifos_q(5 downto 4) <= b"11"; + else + monitor_fifos_q(5 downto 4) <= b"00"; + end if; + if (dbg_pc1(30) = '1') then + monitor_fifos_q(7 downto 6) <= b"11"; + else + monitor_fifos_q(7 downto 6) <= b"00"; + end if; + if (dbg_fc1(28) = '1') then + monitor_fifos_q(11 downto 8) <= b"1111"; + else + monitor_fifos_q(11 downto 8) <= b"0000"; + end if; + if (pcs_an_complete = '0') then + monitor_fifos_q(15 downto 12) <= b"1111"; + else + monitor_fifos_q(15 downto 12) <= b"0000"; + end if; + end if; +end process MON_PROC; + +-- gk 28.07.10 +BYTES_SENT_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + bytes_sent_ctr <= (others => '0'); + elsif (fc_wr_en = '1') then + bytes_sent_ctr <= bytes_sent_ctr + x"1"; + end if; + end if; +end process BYTES_SENT_CTR_PROC; + +-- gk 02.08.10 +DISCFRM_PROC : process(serdes_clk_125) +begin + if rising_edge(serdes_clk_125) then + if (RESET = '1') then + discfrm_ctr <= (others => '0'); + elsif (mac_tx_discfrm = '1') then + discfrm_ctr <= discfrm_ctr + x"1"; + end if; + end if; +end process DISCFRM_PROC; + +discfrm_sync : signal_sync + generic map( + DEPTH => 2, + WIDTH => 32 + ) + port map( + RESET => RESET, + D_IN => discfrm_ctr, + CLK0 => serdes_clk_125, + CLK1 => CLK, + D_OUT => monitor_discfrm + ); + + +------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------ + +--*************** +-- LOGIC ANALYZER SIGNALS +--*************** +--analyzer_debug <= pcs_stat_debug; + +-- Outputs +FEE_READ_OUT <= fee_read; + +CTS_READOUT_FINISHED_OUT <= cts_readout_finished; +CTS_DATAREADY_OUT <= cts_dataready; +CTS_DATA_OUT <= cts_data; +CTS_LENGTH_OUT <= cts_length; +CTS_ERROR_PATTERN_OUT <= cts_error_pattern; + +STAGE_STAT_REGS_OUT <= stage_stat_regs; + +ANALYZER_DEBUG_OUT <= analyzer_debug; +analyzer_debug(0) <= '0'; --serdes_clk_125; +analyzer_debug(1) <= not pcs_stat_debug(22); +analyzer_debug(2) <= SFP_PRSNT_N_IN; +analyzer_debug(3) <= SFP_LOS_IN; +analyzer_debug(63 downto 4) <= (others => '0'); + + +end architecture; diff --git a/gbe2_ecp3/trb_net16_gbe_frame_constr.vhd b/gbe2_ecp3/trb_net16_gbe_frame_constr.vhd new file mode 100755 index 0000000..6b88e61 --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_frame_constr.vhd @@ -0,0 +1,568 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +entity trb_net16_gbe_frame_constr is +port( + -- ports for user logic + RESET : in std_logic; + CLK : in std_logic; + LINK_OK_IN : in std_logic; -- gk 03.08.10 + -- + WR_EN_IN : in std_logic; + DATA_IN : in std_logic_vector(7 downto 0); + START_OF_DATA_IN : in std_logic; + END_OF_DATA_IN : in std_logic; + IP_F_SIZE_IN : in std_logic_vector(15 downto 0); + UDP_P_SIZE_IN : in std_logic_vector(15 downto 0); -- needed for fragmentation + HEADERS_READY_OUT : out std_logic; + READY_OUT : out std_logic; + DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + FRAME_TYPE_IN : in std_logic_vector(15 downto 0); + IHL_VERSION_IN : in std_logic_vector(7 downto 0); + TOS_IN : in std_logic_vector(7 downto 0); + IDENTIFICATION_IN : in std_logic_vector(15 downto 0); + FLAGS_OFFSET_IN : in std_logic_vector(15 downto 0); + TTL_IN : in std_logic_vector(7 downto 0); + PROTOCOL_IN : in std_logic_vector(7 downto 0); + FRAME_DELAY_IN : in std_logic_vector(31 downto 0); -- gk 09.12.10 + -- ports for packetTransmitter + RD_CLK : in std_logic; -- 125MHz clock!!! + FT_DATA_OUT : out std_logic_vector(8 downto 0); + FT_TX_EMPTY_OUT : out std_logic; + FT_TX_RD_EN_IN : in std_logic; + FT_START_OF_PACKET_OUT : out std_logic; + FT_TX_DONE_IN : in std_logic; + FT_TX_DISCFRM_IN : in std_logic; + -- debug ports + BSM_CONSTR_OUT : out std_logic_vector(7 downto 0); + BSM_TRANS_OUT : out std_logic_vector(3 downto 0); + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end trb_net16_gbe_frame_constr; + +architecture trb_net16_gbe_frame_constr of trb_net16_gbe_frame_constr is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_frame_constr : architecture is "GBE_LINK_group"; + +component fifo_4096x9 is +port( + Data : in std_logic_vector(8 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(8 downto 0); + Empty : out std_logic; + Full : out std_logic +); +end component; + +attribute sys_encoding : string; + +type constructStates is (IDLE, DEST_MAC_ADDR, SRC_MAC_ADDR, FRAME_TYPE_S, VERSION, + TOS_S, IP_LENGTH, IDENT, FLAGS, TTL_S, PROTO, HEADER_CS, + SRC_IP_ADDR, DEST_IP_ADDR, SRC_PORT, DEST_PORT, UDP_LENGTH, + UDP_CS, SAVE_DATA, CLEANUP, DELAY); +signal constructCurrentState, constructNextState : constructStates; +signal bsm_constr : std_logic_vector(7 downto 0); +attribute sys_encoding of constructCurrentState: signal is "safe,gray"; + +type transmitStates is (T_IDLE, T_LOAD, T_TRANSMIT, T_PAUSE, T_CLEANUP); +signal transmitCurrentState, transmitNextState : transmitStates; +signal bsm_trans : std_logic_vector(3 downto 0); + +signal headers_int_counter : integer range 0 to 6; +signal fpf_data : std_logic_vector(7 downto 0); +signal fpf_empty : std_logic; +signal fpf_full : std_logic; +signal fpf_wr_en : std_logic; +signal fpf_rd_en : std_logic; +signal fpf_q : std_logic_vector(8 downto 0); +signal ip_size : std_logic_vector(15 downto 0); +signal ip_checksum : std_logic_vector(31 downto 0); +signal udp_size : std_logic_vector(15 downto 0); +signal udp_checksum : std_logic_vector(15 downto 0); +signal ft_sop : std_logic; +signal put_udp_headers : std_logic; +signal ready_frames_ctr : std_logic_vector(15 downto 0); +signal sent_frames_ctr : std_logic_vector(15 downto 0); +signal debug : std_logic_vector(63 downto 0); +signal ready : std_logic; +signal headers_ready : std_logic; + +signal cur_max : integer range 0 to 10; + +signal ready_frames_ctr_q : std_logic_vector(15 downto 0); +signal ip_cs_temp_right : std_logic_vector(15 downto 0); -- gk 29.03.10 + +signal fpf_reset : std_logic; -- gk 01.01.01 + +-- gk 09.12.10 +signal delay_ctr : std_logic_vector(31 downto 0); +signal frame_delay_reg : std_logic_vector(31 downto 0); + +begin + +-- Fakes +udp_checksum <= x"0000"; -- no checksum test needed +--debug <= (others => '0'); + +ready <= '1' when (constructCurrentState = IDLE) + else '0'; +headers_ready <= '1' when (constructCurrentState = SAVE_DATA) + else '0'; + +sizeProc: process( put_udp_headers, IP_F_SIZE_IN, UDP_P_SIZE_IN, DEST_UDP_PORT_IN) +begin + if( put_udp_headers = '1' ) and (DEST_UDP_PORT_IN /= x"0000") then + ip_size <= IP_F_SIZE_IN + x"14" + x"8"; + udp_size <= UDP_P_SIZE_IN + x"8"; + else + ip_size <= IP_F_SIZE_IN + x"14"; + udp_size <= UDP_P_SIZE_IN; + end if; +end process sizeProc; + +ipCsProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (constructCurrentState = IDLE) then + ip_checksum <= x"00000000"; + else + case constructCurrentState is + when DEST_MAC_ADDR => + case headers_int_counter is + when 0 => + ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + SRC_IP_ADDRESS_IN(7 downto 0); + when 1 => + ip_checksum <= ip_checksum + SRC_IP_ADDRESS_IN(15 downto 8); + when 2 => + ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + SRC_IP_ADDRESS_IN(23 downto 16); + when 3 => + ip_checksum <= ip_checksum + SRC_IP_ADDRESS_IN(31 downto 24); + when 4 => + ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + DEST_IP_ADDRESS_IN(7 downto 0); + when 5 => + ip_checksum <= ip_checksum + DEST_IP_ADDRESS_IN(15 downto 8); + when others => null; + end case; + when SRC_MAC_ADDR => + case headers_int_counter is + when 0 => + ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + DEST_IP_ADDRESS_IN(23 downto 16); + when 1 => + ip_checksum <= ip_checksum + DEST_IP_ADDRESS_IN(31 downto 24); + when 2 => + ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + IHL_VERSION_IN; + when 3 => + ip_checksum <= ip_checksum + TOS_IN; + when 4 => + ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + ip_size(15 downto 8); + when 5 => + ip_checksum <= ip_checksum + ip_size(7 downto 0); + when others => null; + end case; + when VERSION => + if headers_int_counter = 0 then + ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + IDENTIFICATION_IN(7 downto 0); + end if; + when TOS_S => + if headers_int_counter = 0 then + ip_checksum <= ip_checksum + IDENTIFICATION_IN(15 downto 8); + end if; + when IP_LENGTH => + if headers_int_counter = 0 then + ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + FLAGS_OFFSET_IN(15 downto 8); + elsif headers_int_counter = 1 then + ip_checksum <= ip_checksum + FLAGS_OFFSET_IN(7 downto 0); + end if; + when IDENT => + if headers_int_counter = 0 then + ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + TTL_IN; + elsif headers_int_counter = 1 then + ip_checksum <= ip_checksum + PROTOCOL_IN; + end if; + -- gk 29.03.10 corrected the bug with bad checksums when sum larger than 16b + when FLAGS => + if headers_int_counter = 0 then + ip_cs_temp_right <= ip_checksum(31 downto 16); + elsif headers_int_counter = 1 then + ip_checksum(31 downto 16) <= (others => '0'); + end if; + when TTL_S => + if headers_int_counter = 0 then + ip_checksum <= ip_checksum + ip_cs_temp_right; + end if; + when PROTO => + if headers_int_counter = 0 then + ip_checksum(15 downto 0) <= ip_checksum(15 downto 0) + ip_checksum(31 downto 16); + end if; + when others => null; + end case; + end if; + end if; +end process ipCsProc; + + +constructMachineProc: process( CLK ) +begin + if( rising_edge(CLK) ) then + if( RESET = '1' ) then + constructCurrentState <= IDLE; + else + constructCurrentState <= constructNextState; + end if; + end if; +end process constructMachineProc; + +--find next state of construct machine +constructMachine: process( constructCurrentState, delay_ctr, FRAME_DELAY_IN, START_OF_DATA_IN, END_OF_DATA_IN, headers_int_counter, put_udp_headers, CUR_MAX, FRAME_TYPE_IN, DEST_IP_ADDRESS_IN, DEST_UDP_PORT_IN) +begin + constructNextState <= constructCurrentState; + if( headers_int_counter = cur_max ) then --can be checked everytime - if not in use, counter and cur_max are 0 + case constructCurrentState is + when IDLE => + if( START_OF_DATA_IN = '1' ) then + constructNextState <= DEST_MAC_ADDR; + end if; + when DEST_MAC_ADDR => + constructNextState <= SRC_MAC_ADDR; + when SRC_MAC_ADDR => + constructNextState <= FRAME_TYPE_S; + when FRAME_TYPE_S => + if (DEST_IP_ADDRESS_IN /= x"0000_0000") then -- in case of ip frame continue with ip/udp headers + constructNextState <= VERSION; + else -- otherwise transmit data as pure ethernet frame + constructNextState <= SAVE_DATA; + end if; + when VERSION => + constructNextState <= TOS_S; + when TOS_S => + constructNextState <= IP_LENGTH; + when IP_LENGTH => + constructNextState <= IDENT; + when IDENT => + constructNextState <= FLAGS; + when FLAGS => + constructNextState <= TTL_S; + when TTL_S => + constructNextState <= PROTO; + when PROTO => + constructNextState <= HEADER_CS; + when HEADER_CS => + constructNextState <= SRC_IP_ADDR; + when SRC_IP_ADDR => + constructNextState <= DEST_IP_ADDR; + when DEST_IP_ADDR => + if (put_udp_headers = '1') and (DEST_UDP_PORT_IN /= x"0000") then + constructNextState <= SRC_PORT; + else + constructNextState <= SAVE_DATA; + end if; + when SRC_PORT => + constructNextState <= DEST_PORT; + when DEST_PORT => + constructNextState <= UDP_LENGTH; + when UDP_LENGTH => + constructNextState <= UDP_CS; + when UDP_CS => + constructNextState <= SAVE_DATA; + when SAVE_DATA => + if (END_OF_DATA_IN = '1') then + constructNextState <= CLEANUP; + end if; + when CLEANUP => + --constructNextState <= IDLE; + constructNextState <= DELAY; -- gk 10.12.10 IDLE; + -- gk 09.12.10 + when DELAY => + if (delay_ctr = FRAME_DELAY_IN) then + constructNextState <= IDLE; + else + constructNextState <= DELAY; + end if; + + when others => + constructNextState <= IDLE; + end case; + end if; +end process constructMachine; + +-- gk 09.12.10 +delayCtrProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (constructCurrentState = IDLE) or (constructCurrentState = CLEANUP) then + delay_ctr <= (others => '0'); + elsif (constructCurrentState = DELAY) then + delay_ctr <= delay_ctr + x"1"; + end if; + + frame_delay_reg <= FRAME_DELAY_IN; + end if; +end process delayCtrProc; + + +bsmConstrProc : process(constructCurrentState) +begin +--find maximum time in each state & set state bits + case constructCurrentState is + when IDLE => cur_max <= 0; bsm_constr <= x"01"; + when DEST_MAC_ADDR => cur_max <= 5; bsm_constr <= x"02"; + when SRC_MAC_ADDR => cur_max <= 5; bsm_constr <= x"03"; + when FRAME_TYPE_S => cur_max <= 1; bsm_constr <= x"04"; + when VERSION => cur_max <= 0; bsm_constr <= x"05"; + when TOS_S => cur_max <= 0; bsm_constr <= x"06"; + when IP_LENGTH => cur_max <= 1; bsm_constr <= x"07"; + when IDENT => cur_max <= 1; bsm_constr <= x"08"; + when FLAGS => cur_max <= 1; bsm_constr <= x"09"; + when TTL_S => cur_max <= 0; bsm_constr <= x"0a"; + when PROTO => cur_max <= 0; bsm_constr <= x"0b"; + when HEADER_CS => cur_max <= 1; bsm_constr <= x"0c"; + when SRC_IP_ADDR => cur_max <= 3; bsm_constr <= x"0d"; + when DEST_IP_ADDR => cur_max <= 3; bsm_constr <= x"0e"; + when SRC_PORT => cur_max <= 1; bsm_constr <= x"0f"; + when DEST_PORT => cur_max <= 1; bsm_constr <= x"10"; + when UDP_LENGTH => cur_max <= 1; bsm_constr <= x"11"; + when UDP_CS => cur_max <= 1; bsm_constr <= x"12"; + when SAVE_DATA => cur_max <= 0; bsm_constr <= x"13"; + when CLEANUP => cur_max <= 0; bsm_constr <= x"14"; + when DELAY => cur_max <= 0; bsm_constr <= x"15"; + when others => cur_max <= 0; bsm_constr <= x"1f"; + end case; +end process; + + +headersIntProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (constructCurrentState = IDLE) then + headers_int_counter <= 0; + else + if (headers_int_counter = cur_max) then + headers_int_counter <= 0; + else + headers_int_counter <= headers_int_counter + 1; + end if; + end if; + end if; +end process headersIntProc; + + + +putUdpHeadersProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (FLAGS_OFFSET_IN(12 downto 0) = "0000000000000") then + put_udp_headers <= '1'; + else + put_udp_headers <= '0'; + end if; + end if; +end process putUdpHeadersProc; + + +fpfWrEnProc : process(constructCurrentState, WR_EN_IN, RESET, LINK_OK_IN) +begin + if (RESET = '1') or (LINK_OK_IN = '0') then -- gk 01.10.10 + fpf_wr_en <= '0'; + elsif (constructCurrentState /= IDLE) and (constructCurrentState /= CLEANUP) and (constructCurrentState /= SAVE_DATA) and (constructCurrentState /= DELAY) then + fpf_wr_en <= '1'; + elsif (constructCurrentState = SAVE_DATA) and (WR_EN_IN = '1') then + fpf_wr_en <= '1'; + else + fpf_wr_en <= '0'; + end if; +end process fpfWrEnProc; + +fpfDataProc : process(constructCurrentState, DEST_MAC_ADDRESS_IN, SRC_MAC_ADDRESS_IN, FRAME_TYPE_IN, IHL_VERSION_IN, + TOS_IN, ip_size, IDENTIFICATION_IN, FLAGS_OFFSET_IN, TTL_IN, PROTOCOL_IN, + ip_checksum, SRC_IP_ADDRESS_IN, DEST_IP_ADDRESS_IN, + SRC_UDP_PORT_IN, DEST_UDP_PORT_IN, udp_size, udp_checksum, headers_int_counter, DATA_IN) +begin + case constructCurrentState is + when IDLE => fpf_data <= DEST_MAC_ADDRESS_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8); + when DEST_MAC_ADDR => fpf_data <= DEST_MAC_ADDRESS_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8); + when SRC_MAC_ADDR => fpf_data <= SRC_MAC_ADDRESS_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8); + when FRAME_TYPE_S => fpf_data <= FRAME_TYPE_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8); + when VERSION => fpf_data <= IHL_VERSION_IN; + when TOS_S => fpf_data <= TOS_IN; + when IP_LENGTH => fpf_data <= ip_size(15 - headers_int_counter * 8 downto 8 - headers_int_counter * 8); + when IDENT => fpf_data <= IDENTIFICATION_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8); + when FLAGS => fpf_data <= FLAGS_OFFSET_IN(15 - headers_int_counter * 8 downto 8 - headers_int_counter * 8); + when TTL_S => fpf_data <= TTL_IN; + when PROTO => fpf_data <= PROTOCOL_IN; + when HEADER_CS => fpf_data <= x"ff" - ip_checksum(15 - headers_int_counter * 8 downto 8 - headers_int_counter * 8); + when SRC_IP_ADDR => fpf_data <= SRC_IP_ADDRESS_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8); + when DEST_IP_ADDR => fpf_data <= DEST_IP_ADDRESS_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8); + when SRC_PORT => fpf_data <= SRC_UDP_PORT_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8); + when DEST_PORT => fpf_data <= DEST_UDP_PORT_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8); + when UDP_LENGTH => fpf_data <= udp_size(15 - headers_int_counter * 8 downto 8 - headers_int_counter * 8); + when UDP_CS => fpf_data <= udp_checksum(15 - headers_int_counter * 8 downto 8 - headers_int_counter * 8); + when SAVE_DATA => fpf_data <= DATA_IN; + when CLEANUP => fpf_data <= x"ab"; + when DELAY => fpf_data <= x"ac"; + when others => fpf_data <= x"00"; + end case; +end process fpfDataProc; + + +readyFramesCtrProc: process( CLK ) +begin + if rising_edge(CLK) then + if (RESET = '1') or (LINK_OK_IN = '0') then -- gk 01.10.10 + ready_frames_ctr <= (others => '0'); + elsif (constructCurrentState = CLEANUP) then + ready_frames_ctr <= ready_frames_ctr + 1; + end if; + end if; +end process readyFramesCtrProc; + +fpf_reset <= '1' when (RESET = '1') or (LINK_OK_IN = '0') else '0'; -- gk 01.10.10 + +FINAL_PACKET_FIFO: fifo_4096x9 +port map( + Data(7 downto 0) => fpf_data, + Data(8) => END_OF_DATA_IN, + WrClock => CLK, + RdClock => RD_CLK, + WrEn => fpf_wr_en, + RdEn => fpf_rd_en, --FT_TX_RD_EN_IN, + Reset => fpf_reset, + RPReset => fpf_reset, + Q => fpf_q, + Empty => fpf_empty, + Full => fpf_full +); + +fpf_rd_en <= '1' when ((LINK_OK_IN = '1') and (FT_TX_RD_EN_IN = '1')) + or (LINK_OK_IN = '0') -- clear the fifo if link is down + else '0'; + +transferToRdClock : signal_sync + generic map( + DEPTH => 2, + WIDTH => 16 + ) + port map( + RESET => RESET, + D_IN => ready_frames_ctr, + CLK0 => RD_CLK, --CLK, + CLK1 => RD_CLK, + D_OUT => ready_frames_ctr_q + ); + +transmitMachineProc: process( RD_CLK ) +begin + if( rising_edge(RD_CLK) ) then + if( RESET = '1' ) or (LINK_OK_IN = '0') then -- gk 01.10.10 + transmitCurrentState <= T_IDLE; + else + transmitCurrentState <= transmitNextState; + end if; + end if; +end process transmitMachineProc; + +transmitMachine: process( transmitCurrentState, fpf_q, FT_TX_DONE_IN, sent_frames_ctr, ready_frames_ctr_q, FT_TX_DISCFRM_IN ) +begin + case transmitCurrentState is + when T_IDLE => + bsm_trans <= x"0"; + if( (sent_frames_ctr /= ready_frames_ctr_q) ) then + transmitNextState <= T_LOAD; + else + transmitNextState <= T_IDLE; + end if; + when T_LOAD => + bsm_trans <= x"1"; + if( fpf_q(8) = '1' ) then + transmitNextState <= T_TRANSMIT; + else + transmitNextState <= T_LOAD; + end if; + when T_TRANSMIT => + bsm_trans <= x"2"; + -- gk 03.08.10 + if ((LINK_OK_IN = '1') and ((FT_TX_DONE_IN = '1') or (FT_TX_DISCFRM_IN = '1')))then + transmitNextState <= T_CLEANUP; + elsif (LINK_OK_IN = '0') then + transmitNextState <= T_PAUSE; + else + transmitNextState <= T_TRANSMIT; + end if; + when T_PAUSE => + transmitNextState <= T_CLEANUP; + when T_CLEANUP => + bsm_trans <= x"3"; + transmitNextState <= T_IDLE; + when others => + bsm_trans <= x"f"; + transmitNextState <= T_IDLE; + end case; +end process transmitMachine; + + + +sopProc: process( RD_CLK ) +begin + if rising_edge(RD_CLK) then + if ( RESET = '1' ) or (LINK_OK_IN = '0') then -- gk 01.10.10 + ft_sop <= '0'; + elsif ((transmitCurrentState = T_IDLE) and (sent_frames_ctr /= ready_frames_ctr_q)) then + ft_sop <= '1'; + else + ft_sop <= '0'; + end if; + end if; +end process sopProc; + +sentFramesCtrProc: process( RD_CLK ) +begin + if rising_edge(RD_CLK) then + if ( RESET = '1' ) or (LINK_OK_IN = '0') then -- gk 01.10.10 + sent_frames_ctr <= (others => '0'); + -- gk 03.08.10 + elsif( FT_TX_DONE_IN = '1' ) or (FT_TX_DISCFRM_IN = '1') then + sent_frames_ctr <= sent_frames_ctr + 1; + end if; + end if; +end process sentFramesCtrProc; + +debug(7 downto 0) <= bsm_constr; +debug(11 downto 8) <= bsm_trans; +debug(27 downto 12) <= sent_frames_ctr; +debug(28) <= fpf_full; +debug(29) <= fpf_empty; +debug(30) <= ready; +debug(31) <= headers_ready; +debug(47 downto 32) <= ready_frames_ctr_q; +debug(48) <= '0'; + + +-- Output +FT_DATA_OUT <= fpf_q; +FT_TX_EMPTY_OUT <= fpf_empty; +FT_START_OF_PACKET_OUT <= ft_sop; +READY_OUT <= ready; +HEADERS_READY_OUT <= headers_ready; + +BSM_CONSTR_OUT <= bsm_constr; +BSM_TRANS_OUT <= bsm_trans; +DEBUG_OUT <= debug; + +end trb_net16_gbe_frame_constr; \ No newline at end of file diff --git a/gbe2_ecp3/trb_net16_gbe_frame_receiver.vhd b/gbe2_ecp3/trb_net16_gbe_frame_receiver.vhd new file mode 100644 index 0000000..6c10c5d --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_frame_receiver.vhd @@ -0,0 +1,752 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; +use work.trb_net_gbe_components.all; +use work.trb_net_gbe_protocols.all; + +--******** +-- here all frame checking has to be done, if the frame fits into protocol standards +-- if so FR_FRAME_VALID_OUT is asserted after having received all bytes of a frame +-- otherwise, after receiving all bytes, FR_FRAME_VALID_OUT keeps low and the fifo is cleared +-- also a part of addresses assignemt has to be done here + +entity trb_net16_gbe_frame_receiver is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + LINK_OK_IN : in std_logic; + ALLOW_RX_IN : in std_logic; + RX_MAC_CLK : in std_logic; -- receiver serdes clock + +-- input signals from TS_MAC + MAC_RX_EOF_IN : in std_logic; + MAC_RX_ER_IN : in std_logic; + MAC_RXD_IN : in std_logic_vector(7 downto 0); + MAC_RX_EN_IN : in std_logic; + MAC_RX_FIFO_ERR_IN : in std_logic; + MAC_RX_FIFO_FULL_OUT : out std_logic; + MAC_RX_STAT_EN_IN : in std_logic; + MAC_RX_STAT_VEC_IN : in std_logic_vector(31 downto 0); + +-- output signal to control logic + FR_Q_OUT : out std_logic_vector(8 downto 0); + FR_RD_EN_IN : in std_logic; + FR_FRAME_VALID_OUT : out std_logic; + FR_GET_FRAME_IN : in std_logic; + FR_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + FR_FRAME_PROTO_OUT : out std_logic_vector(15 downto 0); + FR_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + FR_ALLOWED_TYPES_IN : in std_logic_vector(31 downto 0); + FR_ALLOWED_IP_IN : in std_logic_vector(31 downto 0); + FR_ALLOWED_UDP_IN : in std_logic_vector(31 downto 0); + FR_VLAN_ID_IN : in std_logic_vector(31 downto 0); + + FR_SRC_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0); + FR_DEST_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0); + FR_SRC_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0); + FR_DEST_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0); + FR_SRC_UDP_PORT_OUT : out std_logic_vector(15 downto 0); + FR_DEST_UDP_PORT_OUT : out std_logic_vector(15 downto 0); + + DEBUG_OUT : out std_logic_vector(95 downto 0) +); +end trb_net16_gbe_frame_receiver; + + +architecture trb_net16_gbe_frame_receiver of trb_net16_gbe_frame_receiver is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_frame_receiver : architecture is "GBE_LINK_group"; + +attribute syn_encoding : string; +type filter_states is (IDLE, REMOVE_DEST, REMOVE_SRC, REMOVE_TYPE, SAVE_FRAME, DROP_FRAME, REMOVE_VID, REMOVE_VTYPE, REMOVE_IP, REMOVE_UDP, DECIDE, CLEANUP); +signal filter_current_state, filter_next_state : filter_states; +attribute syn_encoding of filter_current_state : signal is "safe,gray"; + +signal fifo_wr_en : std_logic; +signal rx_bytes_ctr : std_logic_vector(15 downto 0); +signal frame_valid_q : std_logic; +signal delayed_frame_valid : std_logic; +signal delayed_frame_valid_q : std_logic; + +signal rec_fifo_empty : std_logic; +signal rec_fifo_full : std_logic; +signal sizes_fifo_full : std_logic; +signal sizes_fifo_empty : std_logic; + +signal remove_ctr : std_logic_vector(7 downto 0); +signal new_frame : std_logic; +signal new_frame_lock : std_logic; +signal saved_frame_type : std_logic_vector(15 downto 0); +signal saved_vid : std_logic_vector(15 downto 0); +signal saved_src_mac : std_logic_vector(47 downto 0); +signal saved_dest_mac : std_logic_vector(47 downto 0); +signal frame_type_valid : std_logic; +signal saved_proto : std_logic_vector(7 downto 0); +signal saved_src_ip : std_logic_vector(31 downto 0); +signal saved_dest_ip : std_logic_vector(31 downto 0); +signal saved_src_udp : std_logic_vector(15 downto 0); +signal saved_dest_udp : std_logic_vector(15 downto 0); + +signal dump : std_logic_vector(7 downto 0); +signal dump2 : std_logic_vector(7 downto 0); + +signal error_frames_ctr : std_logic_vector(15 downto 0); + +-- debug signals +signal dbg_rec_frames : std_logic_vector(15 downto 0); +signal dbg_ack_frames : std_logic_vector(15 downto 0); +signal dbg_drp_frames : std_logic_vector(15 downto 0); +signal state : std_logic_vector(3 downto 0); +signal parsed_frames_ctr : std_logic_vector(15 downto 0); +signal ok_frames_ctr : std_logic_vector(15 downto 0); + +begin + +DEBUG_OUT(0) <= rec_fifo_empty; +DEBUG_OUT(1) <= rec_fifo_full; +DEBUG_OUT(2) <= sizes_fifo_empty; +DEBUG_OUT(3) <= sizes_fifo_full; +DEBUG_OUT(7 downto 4) <= state; +-- DEBUG_OUT(19 downto 8) <= dbg_rec_frames(11 downto 0); +-- DEBUG_OUT(31 downto 20) <= parsed_frames_ctr(11 downto 0); +-- +-- DEBUG_OUT(47 downto 32) <= dbg_ack_frames; +-- DEBUG_OUT(63 downto 48) <= dbg_drp_frames; +-- DEBUG_OUT(79 downto 64) <= error_frames_ctr; +-- DEBUG_OUT(95 downto 80) <= ok_frames_ctr; + + +-- new_frame is asserted when first byte of the frame arrives +NEW_FRAME_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') or (MAC_RX_EOF_IN = '1') then + new_frame <= '0'; + new_frame_lock <= '0'; + elsif (new_frame_lock = '0') and (MAC_RX_EN_IN = '1') then + new_frame <= '1'; + new_frame_lock <= '1'; + else + new_frame <= '0'; + end if; + end if; +end process NEW_FRAME_PROC; + + +FILTER_MACHINE_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') then + filter_current_state <= IDLE; + else + filter_current_state <= filter_next_state; + end if; + end if; +end process FILTER_MACHINE_PROC; + +FILTER_MACHINE : process(filter_current_state, saved_frame_type, saved_proto, g_MY_MAC, saved_dest_mac, remove_ctr, new_frame, MAC_RX_EOF_IN, frame_type_valid, ALLOW_RX_IN) +begin + + case filter_current_state is + + when IDLE => + state <= x"1"; + if (new_frame = '1') and (ALLOW_RX_IN = '1') then + filter_next_state <= REMOVE_DEST; + else + filter_next_state <= IDLE; + end if; + + -- frames arrive without preamble! + when REMOVE_DEST => + state <= x"3"; + if (remove_ctr = x"03") then -- counter starts with a delay that's why only 3 + -- destination MAC address filtering here + if (saved_dest_mac = g_MY_MAC) or (saved_dest_mac = x"ffffffffffff") then + filter_next_state <= REMOVE_SRC; + else + filter_next_state <= DECIDE; + end if; + else + filter_next_state <= REMOVE_DEST; + end if; + + when REMOVE_SRC => + state <= x"4"; + if (remove_ctr = x"09") then + filter_next_state <= REMOVE_TYPE; + else + filter_next_state <= REMOVE_SRC; + end if; + + when REMOVE_TYPE => + state <= x"5"; + if (remove_ctr = x"0b") then + if (saved_frame_type = x"8100") then -- VLAN tagged frame + filter_next_state <= REMOVE_VID; + else -- no VLAN tag + if (saved_frame_type = x"0800") then -- in case of IP continue removing headers + filter_next_state <= REMOVE_IP; + else + filter_next_state <= DECIDE; + end if; + end if; + else + filter_next_state <= REMOVE_TYPE; + end if; + + when REMOVE_VID => + state <= x"a"; + if (remove_ctr = x"0d") then + filter_next_state <= REMOVE_VTYPE; + else + filter_next_state <= REMOVE_VID; + end if; + + when REMOVE_VTYPE => + state <= x"b"; + if (remove_ctr = x"0f") then + if (saved_frame_type = x"0800") then -- in case of IP continue removing headers + filter_next_state <= REMOVE_IP; + else + filter_next_state <= DECIDE; + end if; + else + filter_next_state <= REMOVE_VTYPE; + end if; + + when REMOVE_IP => + state <= x"c"; + if (remove_ctr = x"11") then + if (saved_proto = x"11") then -- forced to recognize udp only, TODO check all protocols + filter_next_state <= REMOVE_UDP; + else + filter_next_state <= DECIDE; -- changed from drop + end if; + else + filter_next_state <= REMOVE_IP; + end if; + + when REMOVE_UDP => + state <= x"d"; + if (remove_ctr = x"19") then + filter_next_state <= DECIDE; + else + filter_next_state <= REMOVE_UDP; + end if; + + when DECIDE => + state <= x"6"; + if (frame_type_valid = '1') then + filter_next_state <= SAVE_FRAME; + else + filter_next_state <= DROP_FRAME; + end if; + + when SAVE_FRAME => + state <= x"7"; + if (MAC_RX_EOF_IN = '1') then + filter_next_state <= CLEANUP; + else + filter_next_state <= SAVE_FRAME; + end if; + + when DROP_FRAME => + state <= x"8"; + if (MAC_RX_EOF_IN = '1') then + filter_next_state <= CLEANUP; + else + filter_next_state <= DROP_FRAME; + end if; + + when CLEANUP => + state <= x"9"; + filter_next_state <= IDLE; + + when others => null; + + end case; +end process; + +-- counts the bytes to be removed from the ethernet headers fields +REMOVE_CTR_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') or (filter_current_state = IDLE) or + (filter_current_state = REMOVE_VTYPE and remove_ctr = x"0f") or + (filter_current_state = REMOVE_TYPE and remove_ctr = x"0b") then + + remove_ctr <= (others => '1'); + elsif (MAC_RX_EN_IN = '1') and (filter_current_state /= IDLE) then --and (filter_current_state /= CLEANUP) then + remove_ctr <= remove_ctr + x"1"; + end if; + end if; +end process REMOVE_CTR_PROC; + +SAVED_PROTO_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') or (filter_current_state = CLEANUP) then + saved_proto <= (others => '0'); + elsif (filter_current_state = REMOVE_IP) and (remove_ctr = x"07") then + saved_proto <= MAC_RXD_IN; + end if; + end if; +end process SAVED_PROTO_PROC; + +SAVED_SRC_IP_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') or (filter_current_state = CLEANUP) then + saved_src_ip <= (others => '0'); + elsif (filter_current_state = REMOVE_IP) and (remove_ctr = x"0a") then + saved_src_ip(7 downto 0) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_IP) and (remove_ctr = x"0b") then + saved_src_ip(15 downto 8) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_IP) and (remove_ctr = x"0c") then + saved_src_ip(23 downto 16) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_IP) and (remove_ctr = x"0d") then + saved_src_ip(31 downto 24) <= MAC_RXD_IN; + end if; + end if; +end process SAVED_SRC_IP_PROC; + +SAVED_DEST_IP_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') or (filter_current_state = CLEANUP) then + saved_dest_ip <= (others => '0'); + elsif (filter_current_state = REMOVE_IP) and (remove_ctr = x"0e") then + saved_dest_ip(7 downto 0) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_IP) and (remove_ctr = x"0f") then + saved_dest_ip(15 downto 8) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_IP) and (remove_ctr = x"10") then + saved_dest_ip(23 downto 16) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_IP) and (remove_ctr = x"11") then + saved_dest_ip(31 downto 24) <= MAC_RXD_IN; + end if; + end if; +end process SAVED_DEST_IP_PROC; + +SAVED_SRC_UDP_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') or (filter_current_state = CLEANUP) then + saved_src_udp <= (others => '0'); + elsif (filter_current_state = REMOVE_UDP) and (remove_ctr = x"12") then + saved_src_udp(15 downto 8) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_UDP) and (remove_ctr = x"13") then + saved_src_udp(7 downto 0) <= MAC_RXD_IN; + end if; + end if; +end process SAVED_SRC_UDP_PROC; + +SAVED_DEST_UDP_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') or (filter_current_state = CLEANUP) then + saved_dest_udp <= (others => '0'); + elsif (filter_current_state = REMOVE_UDP) and (remove_ctr = x"14") then + saved_dest_udp(15 downto 8) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_UDP) and (remove_ctr = x"15") then + saved_dest_udp(7 downto 0) <= MAC_RXD_IN; + end if; + end if; +end process SAVED_DEST_UDP_PROC; + +-- saves the destination mac address of the incoming frame +SAVED_DEST_MAC_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') or (filter_current_state = CLEANUP) then + saved_dest_mac <= (others => '0'); + elsif (filter_current_state = IDLE) and (MAC_RX_EN_IN = '1') and (new_frame = '0') then + saved_dest_mac(7 downto 0) <= MAC_RXD_IN; + elsif (filter_current_state = IDLE) and (new_frame = '1') and (ALLOW_RX_IN = '1') then + saved_dest_mac(15 downto 8) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_DEST) and (remove_ctr = x"FF") then + saved_dest_mac(23 downto 16) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_DEST) and (remove_ctr = x"00") then + saved_dest_mac(31 downto 24) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_DEST) and (remove_ctr = x"01") then + saved_dest_mac(39 downto 32) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_DEST) and (remove_ctr = x"02") then + saved_dest_mac(47 downto 40) <= MAC_RXD_IN; + end if; + end if; +end process SAVED_DEST_MAC_PROC; + +-- saves the source mac address of the incoming frame +SAVED_SRC_MAC_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') or (filter_current_state = CLEANUP) then + saved_src_mac <= (others => '0'); + elsif (filter_current_state = REMOVE_DEST) and (remove_ctr = x"03") then + saved_src_mac(7 downto 0) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_SRC) and (remove_ctr = x"04") then + saved_src_mac(15 downto 8) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_SRC) and (remove_ctr = x"05") then + saved_src_mac(23 downto 16) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_SRC) and (remove_ctr = x"06") then + saved_src_mac(31 downto 24) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_SRC) and (remove_ctr = x"07") then + saved_src_mac(39 downto 32) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_SRC) and (remove_ctr = x"08") then + saved_src_mac(47 downto 40) <= MAC_RXD_IN; + end if; + end if; +end process SAVED_SRC_MAC_PROC; + +-- saves the frame type of the incoming frame for futher check +SAVED_FRAME_TYPE_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') or (filter_current_state = CLEANUP) then + saved_frame_type <= (others => '0'); + elsif (filter_current_state = REMOVE_SRC) and (remove_ctr = x"09") then + saved_frame_type(15 downto 8) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_TYPE) and (remove_ctr = x"0a") then + saved_frame_type(7 downto 0) <= MAC_RXD_IN; + -- two more cases for VLAN tagged frame + elsif (filter_current_state = REMOVE_VID) and (remove_ctr = x"0d") then + saved_frame_type(15 downto 8) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_VTYPE) and (remove_ctr = x"0e") then + saved_frame_type(7 downto 0) <= MAC_RXD_IN; + end if; + end if; +end process SAVED_FRAME_TYPE_PROC; + +-- saves VLAN id when tagged frame spotted +SAVED_VID_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') or (filter_current_state = CLEANUP) then + saved_vid <= (others => '0'); + elsif (filter_current_state = REMOVE_TYPE and remove_ctr = x"0b" and saved_frame_type = x"8100") then + saved_vid(15 downto 8) <= MAC_RXD_IN; + elsif (filter_current_state = REMOVE_VID and remove_ctr = x"0c") then + saved_vid(7 downto 0) <= MAC_RXD_IN; + end if; + end if; +end process SAVED_VID_PROC; + +type_validator : trb_net16_gbe_type_validator +port map( + CLK => RX_MAC_CLK, + RESET => RESET, + FRAME_TYPE_IN => saved_frame_type, + SAVED_VLAN_ID_IN => saved_vid, + ALLOWED_TYPES_IN => FR_ALLOWED_TYPES_IN, + VLAN_ID_IN => FR_VLAN_ID_IN, + + -- IP level + IP_PROTOCOLS_IN => saved_proto, + ALLOWED_IP_PROTOCOLS_IN => FR_ALLOWED_IP_IN, + + -- UDP level + UDP_PROTOCOL_IN => saved_dest_udp, + ALLOWED_UDP_PROTOCOLS_IN => FR_ALLOWED_UDP_IN, + + VALID_OUT => frame_type_valid +); + +--TODO put here a larger fifo maybe (for sure!) +receive_fifo : fifo_4096x9 +port map( + Data(7 downto 0) => MAC_RXD_IN, + Data(8) => MAC_RX_EOF_IN, + WrClock => RX_MAC_CLK, + RdClock => CLK, + WrEn => fifo_wr_en, + RdEn => FR_RD_EN_IN, + Reset => RESET, + RPReset => RESET, + Q => FR_Q_OUT, + Empty => rec_fifo_empty, + Full => rec_fifo_full +); + +fifo_wr_en <= '1' when (MAC_RX_EN_IN = '1') and ((filter_current_state = SAVE_FRAME) or + ( (filter_current_state = REMOVE_TYPE and remove_ctr = x"b" and saved_frame_type /= x"8100" and saved_frame_type /= x"0800") or + (filter_current_state = REMOVE_VTYPE and remove_ctr = x"f") or + (filter_current_state = DECIDE and frame_type_valid = '1'))) + else '0'; + + +MAC_RX_FIFO_FULL_OUT <= rec_fifo_full; + +sizes_fifo : fifo_512x32 +port map( + Data(15 downto 0) => rx_bytes_ctr, + Data(31 downto 16) => saved_frame_type, + WrClock => RX_MAC_CLK, + RdClock => CLK, + WrEn => frame_valid_q, + RdEn => FR_GET_FRAME_IN, + Reset => RESET, + RPReset => RESET, + Q(15 downto 0) => FR_FRAME_SIZE_OUT, + Q(31 downto 16) => FR_FRAME_PROTO_OUT, + Empty => sizes_fifo_empty, + Full => sizes_fifo_full +); + +macs_fifo : fifo_512x72 +port map( + Data(47 downto 0) => saved_src_mac, + Data(63 downto 48) => saved_src_udp, + Data(71 downto 64) => (others => '0'), + WrClock => RX_MAC_CLK, + RdClock => CLK, + WrEn => frame_valid_q, + RdEn => FR_GET_FRAME_IN, + Reset => RESET, + RPReset => RESET, + Q(47 downto 0) => FR_SRC_MAC_ADDRESS_OUT, + Q(63 downto 48) => FR_SRC_UDP_PORT_OUT, + Q(71 downto 64) => dump2, + Empty => open, + Full => open +); + +macd_fifo : fifo_512x72 +port map( + Data(47 downto 0) => saved_dest_mac, + Data(63 downto 48) => saved_dest_udp, + Data(71 downto 64) => (others => '0'), + WrClock => RX_MAC_CLK, + RdClock => CLK, + WrEn => frame_valid_q, + RdEn => FR_GET_FRAME_IN, + Reset => RESET, + RPReset => RESET, + Q(47 downto 0) => FR_DEST_MAC_ADDRESS_OUT, + Q(63 downto 48) => FR_DEST_UDP_PORT_OUT, + Q(71 downto 64) => dump, + Empty => open, + Full => open +); + +ip_fifo : fifo_512x72 +port map( + Data(31 downto 0) => saved_src_ip, + Data(63 downto 32) => saved_dest_ip, + Data(71 downto 64) => saved_proto, + WrClock => RX_MAC_CLK, + RdClock => CLK, + WrEn => frame_valid_q, + RdEn => FR_GET_FRAME_IN, + Reset => RESET, + RPReset => RESET, + Q(31 downto 0) => FR_SRC_IP_ADDRESS_OUT, + Q(63 downto 32) => FR_DEST_IP_ADDRESS_OUT, + Q(71 downto 64) => FR_IP_PROTOCOL_OUT, + Empty => open, + Full => open +); + +FRAME_VALID_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (MAC_RX_EOF_IN = '1' and ALLOW_RX_IN = '1' and frame_type_valid = '1') then + frame_valid_q <= '1'; + else + frame_valid_q <= '0'; + end if; + end if; +end process FRAME_VALID_PROC; + +RX_BYTES_CTR_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') or (delayed_frame_valid_q = '1') then + --if (RESET = '1') or (frame_valid_q = '1') then + rx_bytes_ctr <= (others => '0'); + elsif (fifo_wr_en = '1') then + rx_bytes_ctr <= rx_bytes_ctr + x"1"; + end if; + end if; +end process; + +PARSED_FRAMES_CTR_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') then + parsed_frames_ctr <= (others => '0'); + elsif (filter_current_state = IDLE and new_frame = '1' and ALLOW_RX_IN = '1') then + parsed_frames_ctr <= parsed_frames_ctr + x"1"; + end if; + end if; +end process PARSED_FRAMES_CTR_PROC; + +FRAMEOK_FRAMES_CTR_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') then + ok_frames_ctr <= (others => '0'); + elsif (MAC_RX_STAT_EN_IN = '1' and MAC_RX_STAT_VEC_IN(23) = '1') then + ok_frames_ctr <= ok_frames_ctr + x"1"; + end if; + end if; +end process FRAMEOK_FRAMES_CTR_PROC; + +ERROR_FRAMES_CTR_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') then + error_frames_ctr <= (others => '0'); + elsif (MAC_RX_ER_IN = '1') then + error_frames_ctr <= error_frames_ctr + x"1"; + end if; + end if; +end process ERROR_FRAMES_CTR_PROC; + + +SYNC_PROC : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + delayed_frame_valid <= MAC_RX_EOF_IN; + delayed_frame_valid_q <= delayed_frame_valid; + end if; +end process SYNC_PROC; + +--***************** +-- synchronization between 125MHz receive clock and 100MHz system clock +FRAME_VALID_SYNC : pulse_sync +port map( + CLK_A_IN => RX_MAC_CLK, + RESET_A_IN => RESET, + PULSE_A_IN => frame_valid_q, + CLK_B_IN => CLK, + RESET_B_IN => RESET, + PULSE_B_OUT => FR_FRAME_VALID_OUT +); + + +-- **** +-- debug counters, to be removed later +RECEIVED_FRAMES_CTR : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') then + dbg_rec_frames <= (others => '0'); + elsif (MAC_RX_EOF_IN = '1') then + dbg_rec_frames <= dbg_rec_frames + x"1"; + end if; + end if; +end process RECEIVED_FRAMES_CTR; + +ACK_FRAMES_CTR : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') then + dbg_ack_frames <= (others => '0'); + elsif (filter_current_state = DECIDE and frame_type_valid = '1') then + dbg_ack_frames <= dbg_ack_frames + x"1"; + end if; + end if; +end process ACK_FRAMES_CTR; + +DROPPED_FRAMES_CTR : process(RX_MAC_CLK) +begin + if rising_edge(RX_MAC_CLK) then + if (RESET = '1') then + dbg_drp_frames <= (others => '0'); + elsif (filter_current_state = DECIDE and frame_type_valid = '0') then + dbg_drp_frames <= dbg_drp_frames + x"1"; + end if; + end if; +end process DROPPED_FRAMES_CTR; + +sync1 : signal_sync +generic map ( + WIDTH => 16, + DEPTH => 2 +) +port map ( + RESET => RESET, + CLK0 => CLK, + CLK1 => CLK, + D_IN => dbg_drp_frames, + D_OUT => DEBUG_OUT(63 downto 48) +); + +sync2 : signal_sync +generic map ( + WIDTH => 16, + DEPTH => 2 +) +port map ( + RESET => RESET, + CLK0 => CLK, + CLK1 => CLK, + D_IN => dbg_ack_frames, + D_OUT => DEBUG_OUT(47 downto 32) +); + +sync3 : signal_sync +generic map ( + WIDTH => 12, + DEPTH => 2 +) +port map ( + RESET => RESET, + CLK0 => CLK, + CLK1 => CLK, + D_IN => dbg_rec_frames(11 downto 0), + D_OUT => DEBUG_OUT(19 downto 8) +); + +sync4 : signal_sync +generic map ( + WIDTH => 12, + DEPTH => 2 +) +port map ( + RESET => RESET, + CLK0 => CLK, + CLK1 => CLK, + D_IN => parsed_frames_ctr(11 downto 0), + D_OUT => DEBUG_OUT(31 downto 20) +); + +sync5 : signal_sync +generic map ( + WIDTH => 16, + DEPTH => 2 +) +port map ( + RESET => RESET, + CLK0 => CLK, + CLK1 => CLK, + D_IN => error_frames_ctr, + D_OUT => DEBUG_OUT(79 downto 64) +); + +sync6 : signal_sync +generic map ( + WIDTH => 16, + DEPTH => 2 +) +port map ( + RESET => RESET, + CLK0 => CLK, + CLK1 => CLK, + D_IN => ok_frames_ctr, + D_OUT => DEBUG_OUT(95 downto 80) +); + +-- end of debug counters +-- **** + +end trb_net16_gbe_frame_receiver; + + diff --git a/gbe2_ecp3/trb_net16_gbe_frame_trans.vhd b/gbe2_ecp3/trb_net16_gbe_frame_trans.vhd new file mode 100755 index 0000000..eddaf7f --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_frame_trans.vhd @@ -0,0 +1,211 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +entity trb_net16_gbe_frame_trans is +port ( + CLK : in std_logic; + RESET : in std_logic; + LINK_OK_IN : in std_logic; -- gk 03.08.10 + TX_MAC_CLK : in std_logic; + TX_EMPTY_IN : in std_logic; + START_OF_PACKET_IN : in std_logic; + DATA_ENDFLAG_IN : in std_logic; -- (8) is end flag, rest is only for TSMAC + + TX_FIFOAVAIL_OUT : out std_logic; + TX_FIFOEOF_OUT : out std_logic; + TX_FIFOEMPTY_OUT : out std_logic; + TX_DONE_IN : in std_logic; + TX_STAT_EN_IN : in std_logic; + TX_STATVEC_IN : in std_logic_vector(30 downto 0); + TX_DISCFRM_IN : in std_logic; + -- Debug + BSM_INIT_OUT : out std_logic_vector(3 downto 0); + BSM_MAC_OUT : out std_logic_vector(3 downto 0); + BSM_TRANS_OUT : out std_logic_vector(3 downto 0); + DBG_RD_DONE_OUT : out std_logic; + DBG_INIT_DONE_OUT : out std_logic; + DBG_ENABLED_OUT : out std_logic; + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end trb_net16_gbe_frame_trans; + +-- FifoRd ?!? + +architecture trb_net16_gbe_frame_trans of trb_net16_gbe_frame_trans is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_frame_trans : architecture is "GBE_BUF_group"; + +component mac_init_mem is +port ( + Address : in std_logic_vector(5 downto 0); + OutClock : in std_logic; + OutClockEn : in std_logic; + Reset : in std_logic; + Q : out std_logic_vector(7 downto 0) +); +end component; + +attribute syn_encoding : string; + +type macInitStates is (I_IDLE, I_INCRADDRESS, I_PAUSE, I_WRITE, I_PAUSE2, I_READ, I_PAUSE3, I_ENDED); +signal macInitState, macInitNextState : macInitStates; +attribute syn_encoding of macInitState: signal is "safe,gray"; +signal bsm_init : std_logic_vector(3 downto 0); + +type macStates is (M_RESETING, M_IDLE, M_INIT); +signal macCurrentState, macNextState : macStates; +signal bsm_mac : std_logic_vector(3 downto 0); + +type transmitStates is (T_IDLE, T_TRANSMIT, T_WAITFORFIFO); +signal transmitCurrentState, transmitNextState : transmitStates; +attribute syn_encoding of transmitCurrentState: signal is "safe,gray"; +signal bsm_trans : std_logic_vector(3 downto 0); + +signal tx_fifoavail_i : std_logic; +signal tx_fifoeof_i : std_logic; + +-- host interface signals +signal hcs_n_i : std_logic; +signal hwrite_n_i : std_logic; +signal hread_n_i : std_logic; + +-- MAC INITIALIZATION signals +signal macInitMemAddr : std_logic_vector(5 downto 0); +signal macInitMemQ : std_logic_vector(7 downto 0); +signal macInitMemEn : std_logic; +signal reading_done : std_logic; +signal init_done : std_logic; +signal enabled : std_logic; +signal addrSig : std_logic_vector(5 downto 0); +signal addr2 : std_logic_vector(5 downto 0); +signal resetAddr : std_logic; + +signal FifoEmpty : std_logic; +signal debug : std_logic_vector(63 downto 0); +signal sent_ctr : std_logic_vector(31 downto 0); + +begin + +-- Fakes +debug(63 downto 32) <= (others => '0'); +--debug(31 downto 0) <= sent_ctr; + + +TransmitStateMachineProc : process (TX_MAC_CLK) +begin + if rising_edge(TX_MAC_CLK) then + if (RESET = '1') or (LINK_OK_IN = '0') then -- gk 01.10.10 + transmitCurrentState <= T_IDLE; + else + transmitCurrentState <= transmitNextState; + end if; + end if; +end process TransmitStatemachineProc; + +--TransmitStateMachine : process (transmitCurrentState, macCurrentState, START_OF_PACKET_IN, DATA_ENDFLAG_IN, TX_DONE_IN) +TransmitStateMachine : process (transmitCurrentState, START_OF_PACKET_IN, DATA_ENDFLAG_IN, TX_DONE_IN) +begin + case transmitCurrentState is + when T_IDLE => + bsm_trans <= x"0"; + if (START_OF_PACKET_IN = '1') then --and (macCurrentState = M_IDLE)) then + transmitNextState <= T_TRANSMIT; + else + transmitNextState <= T_IDLE; + end if; + when T_TRANSMIT => + bsm_trans <= x"1"; + if (DATA_ENDFLAG_IN = '1') then + transmitNextState <= T_WAITFORFIFO; + else + transmitNextState <= T_TRANSMIT; + end if; + when T_WAITFORFIFO => + bsm_trans <= x"2"; + if (TX_DONE_IN = '1') then --or (TX_DISCFRM_IN = '1') then + transmitNextState <= T_IDLE; + else + transmitNextState <= T_WAITFORFIFO; + end if; + when others => + bsm_trans <= x"f"; + transmitNextState <= T_IDLE; + end case; +end process TransmitStateMachine; + +FifoAvailProc : process (TX_MAC_CLK) +begin + if rising_edge(TX_MAC_CLK) then + if (RESET = '1') or (LINK_OK_IN = '0') then -- gk 01.10.10 + tx_fifoavail_i <= '0'; + elsif (transmitCurrentState = T_TRANSMIT) then + tx_fifoavail_i <= '1'; + else + tx_fifoavail_i <= '0'; + end if; + end if; +end process FifoAvailProc; + +FifoEmptyProc : process(transmitCurrentState, START_OF_PACKET_IN, TX_EMPTY_IN, RESET) +begin + if (RESET = '1') or (LINK_OK_IN = '0') then -- gk 01.10.10 + FifoEmpty <= '1'; + elsif (transmitCurrentState = T_WAITFORFIFO) then + FifoEmpty <= '1'; + elsif (transmitCurrentState = T_TRANSMIT) then + FifoEmpty <= TX_EMPTY_IN; + elsif (((transmitCurrentState = T_IDLE) or (transmitCurrentState = T_WAITFORFIFO)) and (START_OF_PACKET_IN = '1')) then + FifoEmpty <= '0'; + else + FifoEmpty <= '1'; + end if; +end process FifoEmptyProc; + +tx_fifoeof_i <= '1' when ((DATA_ENDFLAG_IN = '1') and (transmitCurrentState = T_TRANSMIT)) + else '0'; + +SENT_CTR_PROC : process(TX_MAC_CLK) +begin + if rising_edge(TX_MAC_CLK) then + if (RESET = '1') then + sent_ctr <= (others => '0'); + elsif (TX_DONE_IN = '1') and (TX_STAT_EN_IN = '1') and (TX_STATVEC_IN(0) = '1') then + sent_ctr <= sent_ctr + x"1"; + end if; + end if; +end process SENT_CTR_PROC; + +sync1 : signal_sync +generic map( + WIDTH => 32, + DEPTH => 2 +) +port map ( + RESET => RESET, + CLK0 => CLK, + CLK1 => CLK, + D_IN => sent_ctr, + D_OUT => debug(31 downto 0) +); + +TX_FIFOAVAIL_OUT <= tx_fifoavail_i; +TX_FIFOEOF_OUT <= tx_fifoeof_i; +TX_FIFOEMPTY_OUT <= FifoEmpty; + +BSM_INIT_OUT <= bsm_init; +BSM_MAC_OUT <= bsm_mac; +BSM_TRANS_OUT <= bsm_trans; +DBG_RD_DONE_OUT <= reading_done; +DBG_INIT_DONE_OUT <= init_done; +DBG_ENABLED_OUT <= enabled; +DEBUG_OUT <= debug; + +end trb_net16_gbe_frame_trans; diff --git a/gbe2_ecp3/trb_net16_gbe_mac_control.vhd b/gbe2_ecp3/trb_net16_gbe_mac_control.vhd new file mode 100644 index 0000000..29196e7 --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_mac_control.vhd @@ -0,0 +1,290 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +--******** +-- configures TriSpeed MAC and signalizes when it's ready +-- used also to filter out frames with different addresses +-- after main configuration (by setting TsMAC filtering accordingly) + + + +entity trb_net16_gbe_mac_control is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- signals to/from main controller + MC_TSMAC_READY_OUT : out std_logic; + MC_RECONF_IN : in std_logic; + MC_GBE_EN_IN : in std_logic; + MC_RX_DISCARD_FCS : in std_logic; + MC_PROMISC_IN : in std_logic; + MC_MAC_ADDR_IN : in std_logic_vector(47 downto 0); + +-- signal to/from Host interface of TriSpeed MAC + TSM_HADDR_OUT : out std_logic_vector(7 downto 0); + TSM_HDATA_OUT : out std_logic_vector(7 downto 0); + TSM_HCS_N_OUT : out std_logic; + TSM_HWRITE_N_OUT : out std_logic; + TSM_HREAD_N_OUT : out std_logic; + TSM_HREADY_N_IN : in std_logic; + TSM_HDATA_EN_N_IN : in std_logic; + + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end trb_net16_gbe_mac_control; + + +architecture trb_net16_gbe_mac_control of trb_net16_gbe_mac_control is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_mac_control : architecture is "GBE_BUF_group"; + +type mac_conf_states is (IDLE, DISABLE, WRITE_TX_RX_CTRL, WRITE_MAX_PKT_SIZE, SKIP, WRITE_IPG, + WRITE_MAC0, WRITE_MAC1, WRITE_MAC2, ENABLE, READY); +signal mac_conf_current_state, mac_conf_next_state : mac_conf_states; + +signal tsmac_ready : std_logic; +signal reg_mode : std_logic_vector(15 downto 0); +signal reg_tx_rx_ctrl : std_logic_vector(15 downto 0); +signal reg_max_pkt_size : std_logic_vector(15 downto 0); +signal reg_ipg : std_logic_vector(15 downto 0); +signal reg_mac0 : std_logic_vector(15 downto 0); +signal reg_mac1 : std_logic_vector(15 downto 0); +signal reg_mac2 : std_logic_vector(15 downto 0); + +signal haddr : std_logic_vector(7 downto 0); +signal hcs_n : std_logic; +signal hwrite_n : std_logic; +signal hdata_pointer : integer range 0 to 1; +signal state : std_logic_vector(3 downto 0); +signal hready_n_q : std_logic; + +begin + +DEBUG_OUT(3 downto 0) <= state; +DEBUG_OUT(7 downto 4) <= haddr(3 downto 0); +DEBUG_OUT(8) <= hcs_n; +DEBUG_OUT(9) <= hwrite_n; +DEBUG_OUT(63 downto 11) <= (others => '0'); + +reg_mode(15 downto 4) <= (others => '0'); -- reserved +reg_mode(3) <= '1'; -- tx_en +reg_mode(2) <= '1'; -- rx_en +reg_mode(1) <= '1'; -- flow_control en +reg_mode(0) <= MC_GBE_EN_IN; -- gbe en + +reg_tx_rx_ctrl(15 downto 9) <= (others => '0'); -- reserved +reg_tx_rx_ctrl(8) <= '1'; -- receive short +reg_tx_rx_ctrl(7) <= '1'; -- receive broadcast +reg_tx_rx_ctrl(6) <= '1'; -- drop control +reg_tx_rx_ctrl(5) <= '0'; -- half_duplex en +reg_tx_rx_ctrl(4) <= '1'; -- receive multicast +reg_tx_rx_ctrl(3) <= '1'; -- receive pause +reg_tx_rx_ctrl(2) <= '0'; -- transmit disable FCS +reg_tx_rx_ctrl(1) <= '1'; -- receive discard FCS and padding +reg_tx_rx_ctrl(0) <= MC_PROMISC_IN; -- promiscuous mode + +reg_max_pkt_size(15 downto 0) <= x"05EE"; -- 1518 default value + +reg_ipg(15 downto 5) <= (others => '0'); +reg_ipg(4 downto 0) <= "01100"; -- default value inter-packet-gap in byte time + +reg_mac0(7 downto 0) <= MC_MAC_ADDR_IN(7 downto 0); +reg_mac0(15 downto 8) <= MC_MAC_ADDR_IN(15 downto 8); +reg_mac1(7 downto 0) <= MC_MAC_ADDR_IN(23 downto 16); +reg_mac1(15 downto 8) <= MC_MAC_ADDR_IN(31 downto 24); +reg_mac2(7 downto 0) <= MC_MAC_ADDR_IN(39 downto 32); +reg_mac2(15 downto 8) <= MC_MAC_ADDR_IN(47 downto 40); + + +MAC_CONF_MACHINE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (MC_RECONF_IN = '1') then + mac_conf_current_state <= IDLE; + else + mac_conf_current_state <= mac_conf_next_state; + end if; + end if; +end process MAC_CONF_MACHINE_PROC; + +MAC_CONF_MACHINE : process(mac_conf_current_state, tsmac_ready, haddr) +begin + + case mac_conf_current_state is + + when IDLE => + state <= x"1"; + if (tsmac_ready = '0') then + mac_conf_next_state <= DISABLE; + else + mac_conf_next_state <= IDLE; + end if; + + when DISABLE => + state <= x"2"; + if (haddr = x"01") then + mac_conf_next_state <= WRITE_TX_RX_CTRL; + else + mac_conf_next_state <= DISABLE; + end if; + + when WRITE_TX_RX_CTRL => + state <= x"3"; + if (haddr = x"03") then + mac_conf_next_state <= WRITE_MAX_PKT_SIZE; + else + mac_conf_next_state <= WRITE_TX_RX_CTRL; + end if; + + when WRITE_MAX_PKT_SIZE => + state <= x"4"; + if (haddr = x"05") then + mac_conf_next_state <= SKIP; + else + mac_conf_next_state <= WRITE_MAX_PKT_SIZE; + end if; + + when SKIP => + state <= x"5"; + if (haddr = x"07") then + mac_conf_next_state <= WRITE_IPG; + else + mac_conf_next_state <= SKIP; + end if; + + when WRITE_IPG => + state <= x"6"; + if (haddr = x"09") then + mac_conf_next_state <= WRITE_MAC0; + else + mac_conf_next_state <= WRITE_IPG; + end if; + + when WRITE_MAC0 => + state <= x"7"; + if (haddr = x"0B") then + mac_conf_next_state <= WRITE_MAC1; + else + mac_conf_next_state <= WRITE_MAC0; + end if; + + when WRITE_MAC1 => + state <= x"8"; + if (haddr = x"0D") then + mac_conf_next_state <= WRITE_MAC2; + else + mac_conf_next_state <= WRITE_MAC1; + end if; + + when WRITE_MAC2 => + state <= x"9"; + if (haddr = x"0F") then + mac_conf_next_state <= ENABLE; + else + mac_conf_next_state <= WRITE_MAC2; + end if; + + when ENABLE => + state <= x"a"; + if (haddr = x"01") then + mac_conf_next_state <= READY; + else + mac_conf_next_state <= ENABLE; + end if; + + when READY => + state <= x"b"; + if (MC_RECONF_IN = '1') then + mac_conf_next_state <= IDLE; + else + mac_conf_next_state <= READY; + end if; + + end case; + +end process MAC_CONF_MACHINE; + +HADDR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (mac_conf_current_state = IDLE) then + haddr <= (others => '0'); + elsif (mac_conf_current_state /= IDLE) and (hcs_n = '0') and (TSM_HREADY_N_IN = '0') then + haddr <= haddr + x"1"; + elsif (mac_conf_current_state = SKIP) then + haddr <= haddr + x"1"; + elsif (mac_conf_current_state = WRITE_MAC2) and (haddr = x"0F") and (TSM_HREADY_N_IN = '0') then + haddr <= (others => '0'); + end if; + end if; +end process HADDR_PROC; + +HDATA_PROC : process(mac_conf_current_state) +begin + + case mac_conf_current_state is + + when WRITE_TX_RX_CTRL => + TSM_HDATA_OUT <= reg_tx_rx_ctrl(7 + 8 * hdata_pointer downto 8 * hdata_pointer); + + when WRITE_MAX_PKT_SIZE => + TSM_HDATA_OUT <= reg_max_pkt_size(7 + 8 * hdata_pointer downto 8 * hdata_pointer); + + when WRITE_IPG => + TSM_HDATA_OUT <= reg_ipg(7 + 8 * hdata_pointer downto 8 * hdata_pointer); + + when WRITE_MAC0 => + TSM_HDATA_OUT <= reg_mac0(7 + 8 * hdata_pointer downto 8 * hdata_pointer); + + when WRITE_MAC1 => + TSM_HDATA_OUT <= reg_mac1(7 + 8 * hdata_pointer downto 8 * hdata_pointer); + + when WRITE_MAC2 => + TSM_HDATA_OUT <= reg_mac2(7 + 8 * hdata_pointer downto 8 * hdata_pointer); + + when ENABLE => + TSM_HDATA_OUT <= reg_mode(7 + 8 * hdata_pointer downto 8 * hdata_pointer); + + when others => + TSM_HDATA_OUT <= (others => '0'); + + end case; + +end process HDATA_PROC; + +-- delay hready by one clock cycle to keep hcs and hwrite active during hready +HREADY_Q_PROC : process(CLK) +begin + if rising_edge(CLK) then + hready_n_q <= TSM_HREADY_N_IN; + end if; +end process HREADY_Q_PROC; + +hdata_pointer <= 1 when haddr(0) = '1' else 0; + +hcs_n <= '0' when (mac_conf_current_state /= IDLE) and (mac_conf_current_state /= SKIP) and (mac_conf_current_state /= READY) and (hready_n_q = '1') + else '1'; -- should also support reading + +hwrite_n <= hcs_n when (mac_conf_current_state /= IDLE) else '1'; -- active only during writing + +tsmac_ready <= '1' when (mac_conf_current_state = READY) else '0'; + +TSM_HADDR_OUT <= haddr; +TSM_HCS_N_OUT <= hcs_n; +TSM_HWRITE_N_OUT <= hwrite_n; +TSM_HREAD_N_OUT <= '1'; -- for the moment no reading +MC_TSMAC_READY_OUT <= tsmac_ready; + + +end trb_net16_gbe_mac_control; + + diff --git a/gbe2_ecp3/trb_net16_gbe_main_control.vhd b/gbe2_ecp3/trb_net16_gbe_main_control.vhd new file mode 100644 index 0000000..077e2d8 --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_main_control.vhd @@ -0,0 +1,634 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +use work.trb_net_gbe_components.all; +use work.trb_net_gbe_protocols.all; + +--******** +-- controls the work of the whole gbe in both directions +-- multiplexes the output between data stream and output slow control packets based on priority +-- reacts to incoming gbe slow control commands +-- + + +entity trb_net16_gbe_main_control is +port ( + CLK : in std_logic; -- system clock + CLK_125 : in std_logic; + RESET : in std_logic; + + MC_LINK_OK_OUT : out std_logic; + MC_RESET_LINK_IN : in std_logic; + +-- signals to/from receive controller + RC_FRAME_WAITING_IN : in std_logic; + RC_LOADING_DONE_OUT : out std_logic; + RC_DATA_IN : in std_logic_vector(8 downto 0); + RC_RD_EN_OUT : out std_logic; + RC_FRAME_SIZE_IN : in std_logic_vector(15 downto 0); + RC_FRAME_PROTO_IN : in std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); + + RC_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + RC_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + RC_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + RC_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + RC_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + RC_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + +-- signals to/from transmit controller + TC_TRANSMIT_CTRL_OUT : out std_logic; -- slow control frame is waiting to be built and sent + TC_TRANSMIT_DATA_OUT : out std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_RD_EN_IN : in std_logic; + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + + TC_BUSY_IN : in std_logic; + TC_TRANSMIT_DONE_IN : in std_logic; + +-- signals to/from packet constructor + PC_READY_IN : in std_logic; + PC_TRANSMIT_ON_IN : in std_logic; + PC_SOD_IN : in std_logic; + +-- signals to/from sgmii/gbe pcs_an_complete + PCS_AN_COMPLETE_IN : in std_logic; + +-- signals to/from hub + +-- signal to/from Host interface of TriSpeed MAC + TSM_HADDR_OUT : out std_logic_vector(7 downto 0); + TSM_HDATA_OUT : out std_logic_vector(7 downto 0); + TSM_HCS_N_OUT : out std_logic; + TSM_HWRITE_N_OUT : out std_logic; + TSM_HREAD_N_OUT : out std_logic; + TSM_HREADY_N_IN : in std_logic; + TSM_HDATA_EN_N_IN : in std_logic; + + SELECT_REC_FRAMES_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); + SELECT_SENT_FRAMES_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); + SELECT_PROTOS_DEBUG_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0); + + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end trb_net16_gbe_main_control; + + +architecture trb_net16_gbe_main_control of trb_net16_gbe_main_control is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_main_control : architecture is "GBE_MAIN_group"; + +signal saved_frame_req : std_logic; +signal saved_frame_req_q : std_logic; +signal saved_frame_req_t : std_logic; + +signal tsm_ready : std_logic; +signal tsm_reconf : std_logic; +signal tsm_haddr : std_logic_vector(7 downto 0); +signal tsm_hdata : std_logic_vector(7 downto 0); +signal tsm_hcs_n : std_logic; +signal tsm_hwrite_n : std_logic; +signal tsm_hread_n : std_logic; + +type link_states is (ACTIVE, INACTIVE, ENABLE_MAC, TIMEOUT, FINALIZE, WAIT_FOR_BOOT, GET_ADDRESS); +signal link_current_state, link_next_state : link_states; + +signal link_down_ctr : std_logic_vector(15 downto 0); +signal link_down_ctr_lock : std_logic; +signal link_ok : std_logic; +signal link_ok_timeout_ctr : std_logic_vector(15 downto 0); + +signal mac_control_debug : std_logic_vector(63 downto 0); + +type flow_states is (IDLE, TRANSMIT_DATA, TRANSMIT_CTRL, CLEANUP); +signal flow_current_state, flow_next_state : flow_states; + +signal state : std_logic_vector(3 downto 0); +signal link_state : std_logic_vector(3 downto 0); +signal redirect_state : std_logic_vector(3 downto 0); + +signal ps_wr_en : std_logic; +signal ps_response_ready : std_logic; +signal ps_busy : std_logic_vector(c_MAX_PROTOCOLS -1 downto 0); +signal rc_rd_en : std_logic; +signal first_byte : std_logic; +signal first_byte_q : std_logic; +signal first_byte_qq : std_logic; +signal proto_select : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); +signal loaded_bytes_ctr : std_Logic_vector(15 downto 0); + +signal dhcp_start : std_logic; +signal dhcp_done : std_logic; +signal wait_ctr : std_logic_vector(31 downto 0); + +signal rc_data_local : std_logic_vector(8 downto 0); + +-- debug +signal frame_waiting_ctr : std_logic_vector(15 downto 0); +signal ps_busy_q : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); +signal rc_frame_proto_q : std_Logic_vector(c_MAX_PROTOCOLS - 1 downto 0); + +type redirect_states is (IDLE, CHECK_BUSY, LOAD, BUSY, FINISH, CLEANUP); +signal redirect_current_state, redirect_next_state : redirect_states; + +signal frame_type : std_logic_vector(15 downto 0); + +begin + +protocol_selector : trb_net16_gbe_protocol_selector +port map( + CLK => CLK, + RESET => RESET, + + PS_DATA_IN => rc_data_local, -- RC_DATA_IN, + PS_WR_EN_IN => ps_wr_en, + PS_PROTO_SELECT_IN => proto_select, + PS_BUSY_OUT => ps_busy, + PS_FRAME_SIZE_IN => RC_FRAME_SIZE_IN, + PS_RESPONSE_READY_OUT => ps_response_ready, + + PS_SRC_MAC_ADDRESS_IN => RC_SRC_MAC_ADDRESS_IN, + PS_DEST_MAC_ADDRESS_IN => RC_DEST_MAC_ADDRESS_IN, + PS_SRC_IP_ADDRESS_IN => RC_SRC_IP_ADDRESS_IN, + PS_DEST_IP_ADDRESS_IN => RC_DEST_IP_ADDRESS_IN, + PS_SRC_UDP_PORT_IN => RC_SRC_UDP_PORT_IN, + PS_DEST_UDP_PORT_IN => RC_DEST_UDP_PORT_IN, + + TC_DATA_OUT => TC_DATA_OUT, + TC_RD_EN_IN => TC_RD_EN_IN, + TC_FRAME_SIZE_OUT => TC_FRAME_SIZE_OUT, + TC_FRAME_TYPE_OUT => frame_type, --TC_FRAME_TYPE_OUT, + TC_IP_PROTOCOL_OUT => TC_IP_PROTOCOL_OUT, + + TC_DEST_MAC_OUT => TC_DEST_MAC_OUT, + TC_DEST_IP_OUT => TC_DEST_IP_OUT, + TC_DEST_UDP_OUT => TC_DEST_UDP_OUT, + TC_SRC_MAC_OUT => TC_SRC_MAC_OUT, + TC_SRC_IP_OUT => TC_SRC_IP_OUT, + TC_SRC_UDP_OUT => TC_SRC_UDP_OUT, + + TC_BUSY_IN => TC_BUSY_IN, + + RECEIVED_FRAMES_OUT => SELECT_REC_FRAMES_OUT, + SENT_FRAMES_OUT => SELECT_SENT_FRAMES_OUT, + PROTOS_DEBUG_OUT => SELECT_PROTOS_DEBUG_OUT, + + DHCP_START_IN => dhcp_start, + DHCP_DONE_OUT => dhcp_done, + + DEBUG_OUT => open +); + +TC_FRAME_TYPE_OUT <= frame_type when flow_current_state = TRANSMIT_CTRL else x"0008"; + +proto_select <= RC_FRAME_PROTO_IN; +--proto_select <= (others => '0') when (redirect_current_state = IDLE and RC_FRAME_WAITING_IN = '0') +-- else RC_FRAME_PROTO_IN; + +SYNC_PROC : process(CLK) +begin + if rising_edge(CLK) then + rc_data_local <= RC_DATA_IN; + end if; +end process SYNC_PROC; + +REDIRECT_MACHINE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + redirect_current_state <= IDLE; + else + redirect_current_state <= redirect_next_state; + end if; + end if; +end process REDIRECT_MACHINE_PROC; + +REDIRECT_MACHINE : process(redirect_current_state, link_current_state, RC_FRAME_WAITING_IN, RC_DATA_IN, ps_busy, RC_FRAME_PROTO_IN, ps_wr_en, loaded_bytes_ctr, RC_FRAME_SIZE_IN) +begin + case redirect_current_state is + + when IDLE => + redirect_state <= x"1"; + if (RC_FRAME_WAITING_IN = '1') and (link_current_state = ACTIVE or link_current_state = GET_ADDRESS) then + -- if (or_all(ps_busy and RC_FRAME_PROTO_IN) = '0') then + -- redirect_next_state <= LOAD; + -- else + -- redirect_next_state <= BUSY; + -- end if; + redirect_next_state <= CHECK_BUSY; + else + redirect_next_state <= IDLE; + end if; + + when CHECK_BUSY => + redirect_state <= x"6"; + if (or_all(ps_busy and RC_FRAME_PROTO_IN) = '0') then + redirect_next_state <= LOAD; + else + redirect_next_state <= BUSY; + end if; + + when LOAD => + redirect_state <= x"2"; + --if (RC_DATA_IN(8) = '1') and (ps_wr_en = '1') then + if (loaded_bytes_ctr = RC_FRAME_SIZE_IN - x"1") then + redirect_next_state <= FINISH; + else + redirect_next_state <= LOAD; + end if; + + when BUSY => + redirect_state <= x"3"; + if (or_all(ps_busy and RC_FRAME_PROTO_IN) = '0') then + redirect_next_state <= LOAD; + else + redirect_next_state <= BUSY; + end if; + + when FINISH => + redirect_state <= x"4"; + redirect_next_state <= CLEANUP; + + when CLEANUP => + redirect_state <= x"5"; + redirect_next_state <= IDLE; + + end case; +end process REDIRECT_MACHINE; + +rc_rd_en <= '1' when redirect_current_state = LOAD else '0'; +RC_RD_EN_OUT <= rc_rd_en; + +--RC_RD_EN_PROC : process(CLK) +--begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- rc_rd_en <= '0'; +-- elsif (redirect_current_state = LOAD) then +-- rc_rd_en <= '1'; +-- else +-- rc_rd_en <= '0'; +-- end if; +-- end if; +--end process; + +LOADING_DONE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + RC_LOADING_DONE_OUT <= '0'; + elsif (RC_DATA_IN(8) = '1' and ps_wr_en = '1') then + RC_LOADING_DONE_OUT <= '1'; + else + RC_LOADING_DONE_OUT <= '0'; + end if; + end if; +end process LOADING_DONE_PROC; +--RC_LOADING_DONE_OUT <= '1' when (RC_DATA_IN(8) = '1') and (ps_wr_en = '1') else '0'; + +PS_WR_EN_PROC : process(CLK) +begin + if rising_edge(CLK) then + ps_wr_en <= rc_rd_en; + end if; +end process PS_WR_EN_PROC; + +LOADED_BYTES_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (redirect_current_state = IDLE) then + loaded_bytes_ctr <= (others => '0'); + elsif (redirect_current_state = LOAD) and (rc_rd_en = '1') then + loaded_bytes_ctr <= loaded_bytes_ctr + x"1"; + end if; + end if; +end process LOADED_BYTES_CTR_PROC; + +FIRST_BYTE_PROC : process(CLK) +begin + if rising_edge(CLK) then + first_byte_q <= first_byte; + first_byte_qq <= first_byte_q; + + if (RESET = '1') then + first_byte <= '0'; + elsif (redirect_current_state = IDLE) then + first_byte <= '1'; + else + first_byte <= '0'; + end if; + end if; +end process FIRST_BYTE_PROC; + +--********************* +-- DATA FLOW CONTROL + +FLOW_MACHINE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + flow_current_state <= IDLE; + else + flow_current_state <= flow_next_state; + end if; + end if; +end process FLOW_MACHINE_PROC; + +FLOW_MACHINE : process(flow_current_state, PC_TRANSMIT_ON_IN, PC_SOD_IN, TC_TRANSMIT_DONE_IN, ps_response_ready) +begin + case flow_current_state is + + when IDLE => + state <= x"1"; + --if (RC_FRAME_WAITING_IN = '1') and (PC_TRANSMIT_ON_IN = '0') then + if (ps_response_ready = '1') and (PC_TRANSMIT_ON_IN = '0') then + flow_next_state <= TRANSMIT_CTRL; + elsif (PC_SOD_IN = '1') then -- pottential loss of frames + flow_next_state <= TRANSMIT_DATA; + else + flow_next_state <= IDLE; + end if; + + when TRANSMIT_DATA => + state <= x"2"; + if (TC_TRANSMIT_DONE_IN = '1') then + flow_next_state <= CLEANUP; + else + flow_next_state <= TRANSMIT_DATA; + end if; + + when TRANSMIT_CTRL => + state <= x"3"; + if (TC_TRANSMIT_DONE_IN = '1') then + flow_next_state <= CLEANUP; + else + flow_next_state <= TRANSMIT_CTRL; + end if; + + when CLEANUP => + state <= x"4"; + flow_next_state <= IDLE; + + end case; +end process FLOW_MACHINE; + +TC_TRANSMIT_DATA_OUT <= '1' when (flow_current_state = TRANSMIT_DATA) else '0'; +TC_TRANSMIT_CTRL_OUT <= '1' when (flow_current_state = TRANSMIT_CTRL) else '0'; + + + +--RC_LOADING_DONE_OUT <= '1' when (flow_current_state = TRANSMIT_CTRL) and (TC_TRANSMIT_DONE_IN = '1') else '0'; + +--*********************** +-- LINK STATE CONTROL + +LINK_STATE_MACHINE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + link_current_state <= INACTIVE; + --link_current_state <= ACTIVE; -- for simulation only + else + link_current_state <= link_next_state; + end if; + end if; +end process; + +LINK_STATE_MACHINE : process(link_current_state, dhcp_done, wait_ctr, PCS_AN_COMPLETE_IN, tsm_ready, link_ok_timeout_ctr, PC_READY_IN) +begin + case link_current_state is + + when ACTIVE => + link_state <= x"1"; + if (PCS_AN_COMPLETE_IN = '0') then + link_next_state <= INACTIVE; --ENABLE_MAC; + else + link_next_state <= ACTIVE; + end if; + + when INACTIVE => + link_state <= x"2"; + if (PCS_AN_COMPLETE_IN = '1') then + link_next_state <= TIMEOUT; + --link_next_state <= GET_ADDRESS; -- for simulation only + else + link_next_state <= INACTIVE; + end if; + + when TIMEOUT => + link_state <= x"3"; + if (PCS_AN_COMPLETE_IN = '0') then + link_next_state <= INACTIVE; + else + if (link_ok_timeout_ctr = x"ffff") then + link_next_state <= ENABLE_MAC; --FINALIZE; + else + link_next_state <= TIMEOUT; + end if; + end if; + + when ENABLE_MAC => + link_state <= x"4"; + if (PCS_AN_COMPLETE_IN = '0') then + link_next_state <= INACTIVE; + elsif (tsm_ready = '1') then + link_next_state <= FINALIZE; --INACTIVE; + else + link_next_state <= ENABLE_MAC; + end if; + + when FINALIZE => + link_state <= x"5"; + if (PCS_AN_COMPLETE_IN = '0') then + link_next_state <= INACTIVE; + else + if (PC_READY_IN = '1') then + link_next_state <= WAIT_FOR_BOOT; --ACTIVE; + else + link_next_state <= FINALIZE; + end if; + end if; + + when WAIT_FOR_BOOT => + link_state <= x"6"; + if (PCS_AN_COMPLETE_IN = '0') then + link_next_state <= INACTIVE; + else + if (wait_ctr = x"3baa_ca00") then + --if (wait_ctr = x"0000_0010") then -- for simulation + link_next_state <= GET_ADDRESS; + else + link_next_state <= WAIT_FOR_BOOT; + end if; + end if; + + when GET_ADDRESS => + link_state <= x"7"; + if (PCS_AN_COMPLETE_IN = '0') then + link_next_state <= INACTIVE; + else + if (dhcp_done = '1') then + link_next_state <= ACTIVE; + else + link_next_state <= GET_ADDRESS; + end if; + end if; + + end case; +end process LINK_STATE_MACHINE; + +LINK_OK_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (link_current_state /= TIMEOUT) then + link_ok_timeout_ctr <= (others => '0'); + elsif (link_current_state = TIMEOUT) then + link_ok_timeout_ctr <= link_ok_timeout_ctr + x"1"; + end if; + end if; +end process LINK_OK_CTR_PROC; + +link_ok <= '1' when (link_current_state = ACTIVE) or (link_current_state = GET_ADDRESS) or (link_current_state = WAIT_FOR_BOOT) else '0'; + +WAIT_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (link_current_state = INACTIVE) then + wait_ctr <= (others => '0'); + elsif (link_current_state = WAIT_FOR_BOOT) then + wait_ctr <= wait_ctr + x"1"; + end if; + end if; +end process WAIT_CTR_PROC; + +dhcp_start <= '1' when link_current_state = GET_ADDRESS else '0'; + +LINK_DOWN_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + link_down_ctr <= (others => '0'); + link_down_ctr_lock <= '0'; + elsif (PCS_AN_COMPLETE_IN = '1') then + link_down_ctr_lock <= '0'; + elsif ((PCS_AN_COMPLETE_IN = '0') and (link_down_ctr_lock = '0')) then + link_down_ctr <= link_down_ctr + x"1"; + link_down_ctr_lock <= '1'; + end if; + end if; +end process LINK_DOWN_CTR_PROC; + +MC_LINK_OK_OUT <= link_ok; + +-- END OF LINK STATE CONTROL +--************* + +--************* +-- GENERATE MAC_ADDRESS +--TODO: take the unique id from regio and generate a mac address +g_MY_MAC <= x"efbeefbe0000"; +-- +--************* + +--**************** +-- TRI SPEED MAC CONTROLLER + +TSMAC_CONTROLLER : trb_net16_gbe_mac_control +port map( + CLK => CLK, + RESET => RESET, + +-- signals to/from main controller + MC_TSMAC_READY_OUT => tsm_ready, + MC_RECONF_IN => tsm_reconf, + MC_GBE_EN_IN => '1', + MC_RX_DISCARD_FCS => '0', + MC_PROMISC_IN => '1', + MC_MAC_ADDR_IN => g_MY_MAC, --x"001122334455", + +-- signal to/from Host interface of TriSpeed MAC + TSM_HADDR_OUT => tsm_haddr, + TSM_HDATA_OUT => tsm_hdata, + TSM_HCS_N_OUT => tsm_hcs_n, + TSM_HWRITE_N_OUT => tsm_hwrite_n, + TSM_HREAD_N_OUT => tsm_hread_n, + TSM_HREADY_N_IN => TSM_HREADY_N_IN, + TSM_HDATA_EN_N_IN => TSM_HDATA_EN_N_IN, + + DEBUG_OUT => mac_control_debug +); + +--DEBUG_OUT <= mac_control_debug; + +tsm_reconf <= '1' when (link_current_state = INACTIVE) and (PCS_AN_COMPLETE_IN = '1') else '0'; + +TSM_HADDR_OUT <= tsm_haddr; +TSM_HCS_N_OUT <= tsm_hcs_n; +TSM_HDATA_OUT <= tsm_hdata; +TSM_HREAD_N_OUT <= tsm_hread_n; +TSM_HWRITE_N_OUT <= tsm_hwrite_n; + +-- END OF TRI SPEED MAC CONTROLLER +--*************** + + +-- **** debug +FRAME_WAITING_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + frame_waiting_ctr <= (others => '0'); + elsif (RC_FRAME_WAITING_IN = '1') then + frame_waiting_ctr <= frame_waiting_ctr + x"1"; + end if; + end if; +end process FRAME_WAITING_CTR_PROC; + +SAVE_VALUES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + ps_busy_q <= (others => '0'); + rc_frame_proto_q <= (others => '0'); + elsif (redirect_current_state = IDLE and RC_FRAME_WAITING_IN = '1') then + ps_busy_q <= ps_busy; + rc_frame_proto_q <= RC_FRAME_PROTO_IN; + end if; + end if; +end process SAVE_VALUES_PROC; + + +DEBUG_OUT(3 downto 0) <= mac_control_debug(3 downto 0); +DEBUG_OUT(7 downto 4) <= state; +DEBUG_OUT(11 downto 8) <= redirect_state; +DEBUG_OUT(15 downto 12) <= link_state; +DEBUG_OUT(23 downto 16) <= frame_waiting_ctr(7 downto 0); +DEBUG_OUT(27 downto 24) <= (others => '0'); --ps_busy_q; +DEBUG_OUT(31 downto 28) <= (others => '0'); --rc_frame_proto_q; +DEBUG_OUT(63 downto 32) <= (others => '0'); + + +-- **** + + + +end trb_net16_gbe_main_control; + + diff --git a/gbe2_ecp3/trb_net16_gbe_packet_constr.vhd b/gbe2_ecp3/trb_net16_gbe_packet_constr.vhd new file mode 100755 index 0000000..2f03435 --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_packet_constr.vhd @@ -0,0 +1,1088 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; +use IEEE.std_logic_arith.all; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +entity trb_net16_gbe_packet_constr is +port( + RESET : in std_logic; + CLK : in std_logic; + MULT_EVT_ENABLE_IN : in std_logic; -- gk 06.10.10 + -- ports for user logic + PC_WR_EN_IN : in std_logic; -- write into queueConstr from userLogic + PC_DATA_IN : in std_logic_vector(7 downto 0); + PC_READY_OUT : out std_logic; + PC_START_OF_SUB_IN : in std_logic; + PC_END_OF_SUB_IN : in std_logic; -- gk 07.10.10 + PC_END_OF_DATA_IN : in std_logic; + PC_TRANSMIT_ON_OUT : out std_logic; + -- queue and subevent layer headers + PC_SUB_SIZE_IN : in std_logic_vector(31 downto 0); -- store and swap + PC_PADDING_IN : in std_logic; -- gk 29.03.10 + PC_DECODING_IN : in std_logic_vector(31 downto 0); -- swap + PC_EVENT_ID_IN : in std_logic_vector(31 downto 0); -- swap + PC_TRIG_NR_IN : in std_logic_vector(31 downto 0); -- store and swap! + PC_QUEUE_DEC_IN : in std_logic_vector(31 downto 0); -- swap + PC_MAX_FRAME_SIZE_IN : in std_logic_vector(15 downto 0); -- DO NOT SWAP + PC_DELAY_IN : in std_logic_vector(31 downto 0); -- gk 28.04.10 + -- FrameConstructor ports + TC_WR_EN_OUT : out std_logic; + TC_DATA_OUT : out std_logic_vector(7 downto 0); + TC_H_READY_IN : in std_logic; + TC_READY_IN : in std_logic; + TC_IP_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_UDP_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FLAGS_OFFSET_OUT : out std_logic_vector(15 downto 0); + TC_SOD_OUT : out std_logic; + TC_EOD_OUT : out std_logic; + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end trb_net16_gbe_packet_constr; + +architecture trb_net16_gbe_packet_constr of trb_net16_gbe_packet_constr is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_packet_constr : architecture is "GBE_GBE_group"; + +component fifo_64kx9 +port ( + Data : in std_logic_vector(8 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(8 downto 0); + Empty : out std_logic; + Full : out std_logic +); +end component; + +-- FIFO for SubEventHeader information +component fifo_16kx8 is +port ( + Data : in std_logic_vector(7 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(7 downto 0); + Empty : out std_logic; + Full : out std_logic +); +end component; + +signal df_wr_en : std_logic; +signal df_rd_en : std_logic; +signal df_q : std_logic_vector(7 downto 0); +signal df_q_reg : std_logic_vector(7 downto 0); +signal df_empty : std_logic; +signal df_full : std_logic; + +signal fc_data : std_logic_vector(7 downto 0); +signal fc_wr_en : std_logic; +signal fc_sod : std_logic; +signal fc_eod : std_logic; +signal fc_ident : std_logic_vector(15 downto 0); -- change this to own counter! +signal fc_flags_offset : std_logic_vector(15 downto 0); + +signal shf_data : std_logic_vector(7 downto 0); +signal shf_wr_en : std_logic; +signal shf_rd_en : std_logic; +signal shf_q : std_logic_vector(7 downto 0); +signal shf_empty : std_logic; +signal shf_full : std_logic; + +type constructStates is (CIDLE, SAVE_DATA, WAIT_FOR_LOAD); +signal constructCurrentState, constructNextState : constructStates; +signal constr_state : std_logic_vector(3 downto 0); +signal all_int_ctr : integer range 0 to 31; +signal all_ctr : std_logic_vector(4 downto 0); + +type saveSubStates is (SIDLE, SAVE_SIZE, SAVE_DECODING, SAVE_ID, SAVE_TRIG_NR, SAVE_TERM); +signal saveSubCurrentState, saveSubNextState : saveSubStates; +signal save_state : std_logic_vector(3 downto 0); +signal sub_int_ctr : integer range 0 to 31; +signal sub_ctr : std_logic_vector(4 downto 0); +signal my_int_ctr : integer range 0 to 3; +signal my_ctr : std_logic_vector(1 downto 0); + +type loadStates is (LIDLE, WAIT_FOR_FC, PUT_Q_LEN, PUT_Q_DEC, LOAD_SUB, PREP_DATA, LOAD_DATA, DIVIDE, LOAD_TERM, CLEANUP, DELAY); +signal loadCurrentState, loadNextState: loadStates; +signal load_state : std_logic_vector(3 downto 0); + +signal queue_size : std_logic_vector(31 downto 0); -- sum of all subevents sizes plus their headers and queue headers and termination +signal queue_size_temp : std_logic_vector(31 downto 0); +signal actual_queue_size : std_logic_vector(31 downto 0); -- queue size used during loading process when queue_size is no more valid +signal bytes_loaded : std_logic_vector(15 downto 0); -- size of actual constructing frame +signal sub_size_to_save : std_logic_vector(31 downto 0); -- size of subevent to save to shf +signal sub_size_loaded : std_logic_vector(31 downto 0); -- size of subevent actually being transmitted +signal sub_bytes_loaded : std_logic_vector(31 downto 0); -- amount of bytes of actual subevent sent +signal actual_packet_size : std_logic_vector(15 downto 0); -- actual size of whole udp packet +signal size_left : std_logic_vector(31 downto 0); +signal fc_ip_size : std_logic_vector(15 downto 0); +signal fc_udp_size : std_logic_vector(15 downto 0); +signal max_frame_size : std_logic_vector(15 downto 0); +signal divide_position : std_logic_vector(1 downto 0); -- 00->data, 01->sub, 11->term +signal debug : std_logic_vector(63 downto 0); +signal pc_ready : std_logic; + +signal pc_sub_size : std_logic_vector(31 downto 0); +signal pc_trig_nr : std_logic_vector(31 downto 0); +signal rst_after_sub_comb : std_logic; -- gk 08.04.10 +signal rst_after_sub : std_logic; -- gk 08.04.10 +signal load_int_ctr : integer range 0 to 3; -- gk 08.04.10 +signal delay_ctr : std_logic_vector(31 downto 0); -- gk 28.04.10 +signal ticks_ctr : std_logic_vector(7 downto 0); -- gk 28.04.10 + +-- gk 26.07.10 +signal load_eod : std_logic; +signal load_eod_q : std_logic; + +-- gk 07.10.10 +signal df_eod : std_logic; + +-- gk 04.12.10 +signal first_sub_in_multi : std_logic; +signal from_divide_state : std_logic; +signal disable_prep : std_logic; + +begin + + +PC_TRANSMIT_ON_OUT <= '1' when constructCurrentState = WAIT_FOR_LOAD else '0'; + +my_int_ctr <= (3 - to_integer(to_unsigned(sub_int_ctr, 2))); -- reverse byte order +load_int_ctr <= (3 - to_integer(to_unsigned(all_int_ctr, 2))); -- gk 08.04.10 + +all_ctr <= std_logic_vector(to_unsigned(all_int_ctr, all_ctr'length)); -- for debugging +sub_ctr <= std_logic_vector(to_unsigned(sub_int_ctr, sub_ctr'length)); -- for debugging +my_ctr <= std_logic_vector(to_unsigned(my_int_ctr, my_ctr'length)); -- for debugging + +max_frame_size <= PC_MAX_FRAME_SIZE_IN; + +-- Ready signal for PacketConstructor +pc_ready <= '1' when (constructCurrentState = CIDLE) and (df_empty = '1') else '0'; + +-- store event information on Start_of_Subevent +THE_EVT_INFO_STORE_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if (RESET = '1') then -- gk 31.05.10 + pc_sub_size <= (others => '0'); + pc_trig_nr <= (others => '0'); + elsif( PC_START_OF_SUB_IN = '1' ) then + pc_sub_size <= PC_SUB_SIZE_IN; + pc_trig_nr <= PC_TRIG_NR_IN; + end if; + end if; +end process; + +-- gk 07.10.10 +df_eod <= '1' when ((MULT_EVT_ENABLE_IN = '0') and (PC_END_OF_DATA_IN = '1')) + or ((MULT_EVT_ENABLE_IN = '1') and (PC_END_OF_SUB_IN = '1')) + else '0'; + +-- Data FIFO for incoming packet data from IPU buffer +-- gk 26.07.10 +DATA_FIFO : fifo_64kx9 +port map( + Data(7 downto 0) => PC_DATA_IN, + Data(8) => df_eod, --PC_END_OF_DATA_IN, -- gk 07.10.10 + WrClock => CLK, + RdClock => CLK, + WrEn => df_wr_en, + RdEn => df_rd_en, + Reset => RESET, + RPReset => RESET, + Q(7 downto 0) => df_q, + Q(8) => load_eod, + Empty => df_empty, + Full => df_full +); + +LOAD_EOD_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + load_eod_q <= '0'; + else + load_eod_q <= load_eod; + end if; + end if; +end process LOAD_EOD_PROC; + +-- Write enable for the data FIFO +-- !!!combinatorial signal!!! +-- could be avoided as IPU2GBE does only send data in case of PC_READY. +df_wr_en <= '1' when ((PC_WR_EN_IN = '1') and (constructCurrentState /= WAIT_FOR_LOAD)) + else '0'; + +-- Output register for data FIFO +dfQProc : process(CLK) +begin + if rising_edge(CLK) then + df_q_reg <= df_q; + end if; +end process dfQProc; + +-- Construction state machine +constructMachineProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + constructCurrentState <= CIDLE; + else + constructCurrentState <= constructNextState; + end if; + end if; +end process constructMachineProc; + +constructMachine : process(constructCurrentState, PC_START_OF_SUB_IN, PC_WR_EN_IN, PC_END_OF_DATA_IN, loadCurrentState, saveSubCurrentState, sub_int_ctr) +begin + case constructCurrentState is + when CIDLE => + constr_state <= x"0"; + --if( PC_WR_EN_IN = '1' ) then + -- gk 04.12.10 + if (PC_START_OF_SUB_IN = '1') then + + constructNextState <= SAVE_DATA; + else + constructNextState <= CIDLE; + end if; + when SAVE_DATA => + constr_state <= x"1"; + if( PC_END_OF_DATA_IN = '1' ) then + constructNextState <= WAIT_FOR_LOAD; + else + constructNextState <= SAVE_DATA; + end if; + when WAIT_FOR_LOAD => + constr_state <= x"2"; + if( (df_empty = '1') and (loadCurrentState = LIDLE) ) then -- waits until the whole packet is transmitted + constructNextState <= CIDLE; + else + constructNextState <= WAIT_FOR_LOAD; + end if; + when others => + constr_state <= x"f"; + constructNextState <= CIDLE; + end case; +end process constructMachine; + +--*********************** +-- SIZE COUNTERS FOR SAVING SIDE +--*********************** + +-- gk 29.03.10 the subevent size saved to its headers cannot contain padding bytes but they are included in pc_sub_size +-- that's why they are removed if pc_padding flag is asserted +sub_size_to_save <= (x"10" + pc_sub_size) when (PC_PADDING_IN = '0') + else (x"c" + pc_sub_size); -- subevent headers + data + +-- BUG HERE BUG HERE BUG HERE BUG HERE +-- gk 29.03.10 no changes here because the queue size should contain the padding bytes of subevents +queueSizeProc : process(CLK) +begin + if rising_edge(CLK) then + --if (RESET = '1') or (loadCurrentState = PUT_Q_DEC) then -- gk 07.10.10 -- (loadCurrentState = CLEANUP) then + if (RESET = '1') or (loadCurrentState = CLEANUP) then + queue_size <= x"00000028"; -- + 8B for queue headers and 32B for termination + elsif (saveSubCurrentState = SAVE_SIZE) and (sub_int_ctr = 3) then + queue_size <= queue_size + pc_sub_size + x"10"; -- + 16B for each subevent headers + end if; + end if; +end process queueSizeProc; + + +--*********************** +-- LOAD DATA COMBINED WITH HEADERS INTO FC, QUEUE TRANSMISSION +--*********************** + +loadMachineProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + loadCurrentState <= LIDLE; + else + loadCurrentState <= loadNextState; + end if; + end if; +end process loadMachineProc; + +loadMachine : process(loadCurrentState, constructCurrentState, all_int_ctr, df_empty, + sub_bytes_loaded, sub_size_loaded, size_left, TC_H_READY_IN, + max_frame_size, bytes_loaded, divide_position, PC_DELAY_IN, + delay_ctr, load_eod_q, MULT_EVT_ENABLE_IN) +begin + case loadCurrentState is + when LIDLE => + load_state <= x"0"; + if ((constructCurrentState = WAIT_FOR_LOAD) and (df_empty = '0')) then + loadNextState <= WAIT_FOR_FC; + else + loadNextState <= LIDLE; + end if; + when WAIT_FOR_FC => + load_state <= x"1"; + if (TC_H_READY_IN = '1') then + loadNextState <= PUT_Q_LEN; + else + loadNextState <= WAIT_FOR_FC; + end if; + when PUT_Q_LEN => + load_state <= x"2"; + if (all_int_ctr = 3) then + loadNextState <= PUT_Q_DEC; + else + loadNextState <= PUT_Q_LEN; + end if; + when PUT_Q_DEC => + load_state <= x"3"; + if (all_int_ctr = 3) then + loadNextState <= LOAD_SUB; + else + loadNextState <= PUT_Q_DEC; + end if; + when LOAD_SUB => + load_state <= x"4"; + if (bytes_loaded = max_frame_size - 1) then + loadNextState <= DIVIDE; + elsif (all_int_ctr = 15) then + loadNextState <= PREP_DATA; + else + loadNextState <= LOAD_SUB; + end if; + when PREP_DATA => + load_state <= x"5"; + loadNextState <= LOAD_DATA; + when LOAD_DATA => + load_state <= x"6"; +-- if (bytes_loaded = max_frame_size - 1) then +-- loadNextState <= DIVIDE; +-- -- gk 07.10.10 +-- elsif (MULT_EVT_ENABLE_IN = '1') then +-- if (size_left = x"0000_0023") then +-- loadNextState <= LOAD_TERM; +-- elsif (load_eod_q = '1') then +-- loadNextState <= LOAD_SUB; +-- else +-- loadNextState <= LOAD_DATA; +-- end if; +-- else +-- if (load_eod_q = '1') then +-- loadNextState <= LOAD_TERM; +-- else +-- loadNextState <= LOAD_DATA; +-- end if; +-- end if; + if (bytes_loaded = max_frame_size - 1) then + loadNextState <= DIVIDE; + -- gk 07.10.10 + elsif (load_eod_q = '1') then + if (MULT_EVT_ENABLE_IN = '1') then + if (size_left < x"0000_0030") then + loadNextState <= LOAD_TERM; + else + loadNextState <= LOAD_SUB; + end if; + else + loadNextState <= LOAD_TERM; + end if; + else + loadNextState <= LOAD_DATA; + end if; + when DIVIDE => + load_state <= x"7"; + if (TC_H_READY_IN = '1') then + if (divide_position = "00") then + loadNextState <= PREP_DATA; + elsif (divide_position = "01") then + loadNextState <= LOAD_SUB; + else + loadNextState <= LOAD_TERM; + end if; + else + loadNextState <= DIVIDE; + end if; + when LOAD_TERM => + load_state <= x"8"; + if (bytes_loaded = max_frame_size - 1) and (all_int_ctr /= 31) then + loadNextState <= DIVIDE; + elsif (all_int_ctr = 31) then + loadNextState <= CLEANUP; + else + loadNextState <= LOAD_TERM; + end if; + -- gk 28.04.10 + when CLEANUP => + load_state <= x"9"; + if (PC_DELAY_IN = x"0000_0000") then + loadNextState <= LIDLE; + else + loadNextState <= DELAY; + end if; + -- gk 28.04.10 + when DELAY => + load_state <= x"a"; + if (delay_ctr = x"0000_0000") then + loadNextState <= LIDLE; + else + loadNextState <= DELAY; + end if; + when others => + load_state <= x"f"; + loadNextState <= LIDLE; + end case; +end process loadMachine; + +-- gk 04.12.10 +firstSubInMultiProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = LOAD_TERM) then + first_sub_in_multi <= '1'; + elsif (loadCurrentState = LOAD_DATA) then + first_sub_in_multi <= '0'; + end if; + end if; +end process; + +-- gk 04.12.10 +fromDivideStateProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + from_divide_state <= '0'; + elsif (loadCurrentState = DIVIDE) then + from_divide_state <= '1'; + elsif (loadCurrentState = PREP_DATA) then + from_divide_state <= '0'; + end if; + end if; +end process fromDivideStateProc; + + +dividePositionProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + divide_position <= "00"; +-- elsif (bytes_loaded = max_frame_size - 1) then +-- if (loadCurrentState = LIDLE) then +-- divide_position <= "00"; +-- elsif (loadCurrentState = LOAD_DATA) then +-- -- gk 07.10.10 +-- if (MULT_EVT_ENABLE_IN = '1') and (size_left = x"0000_003a") then +-- divide_position <= "11"; +-- -- gk 07.10.10 +-- elsif (MULT_EVT_ENABLE_IN = '1') and (load_eod_q = '1') then +-- divide_position <= "01"; +-- -- gk 26.07.10 +-- elsif (MULT_EVT_ENABLE_IN = '0') and (load_eod_q = '1') then -- if termination is about to be loaded divide on term +-- divide_position <= "11"; +-- else +-- divide_position <= "00"; -- still data loaded divide on data +-- end if; +-- elsif (loadCurrentState = LOAD_SUB) then +-- if (all_int_ctr = 15) then +-- divide_position <= "00"; +-- else +-- divide_position <= "01"; +-- end if; +-- elsif (loadCurrentState = LOAD_TERM) then +-- divide_position <= "11"; +-- end if; +-- end if; + elsif (bytes_loaded = max_frame_size - 1) then + if (loadCurrentState = LIDLE) then + divide_position <= "00"; + disable_prep <= '0'; -- gk 05.12.10 + elsif (loadCurrentState = LOAD_DATA) then + -- gk 05.12.10 + -- gk 26.07.10 + if (MULT_EVT_ENABLE_IN = '0') and (load_eod_q = '1') then -- if termination is about to be loaded divide on term + divide_position <= "11"; + disable_prep <= '0'; -- gk 05.12.10 + elsif (MULT_EVT_ENABLE_IN = '1') and (load_eod_q = '1') then + if (size_left > x"0000_0028") then + divide_position <= "01"; + disable_prep <= '0'; -- gk 05.12.10 + else + divide_position <= "11"; + disable_prep <= '0'; -- gk 05.12.10 + end if; + else + divide_position <= "00"; -- still data loaded divide on data + disable_prep <= '1'; -- gk 05.12.10 + end if; + elsif (loadCurrentState = LOAD_SUB) then + if (all_int_ctr = 15) then + divide_position <= "00"; + disable_prep <= '1'; -- gk 05.12.10 + else + divide_position <= "01"; + disable_prep <= '0'; -- gk 05.12.10 + end if; + elsif (loadCurrentState = LOAD_TERM) then + divide_position <= "11"; + disable_prep <= '0'; -- gk 05.12.10 + end if; + elsif (loadCurrentState = PREP_DATA) then -- gk 06.12.10 reset disable_prep + disable_prep <= '0'; + end if; + + end if; +end process dividePositionProc; + +allIntCtrProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then -- gk 31.05.10 + all_int_ctr <= 0; + else + case loadCurrentState is + + when LIDLE => all_int_ctr <= 0; + + when WAIT_FOR_FC => all_int_ctr <= 0; + + when PUT_Q_LEN => + if (all_int_ctr = 3) then + all_int_ctr <= 0; + else + all_int_ctr <= all_int_ctr + 1; + end if; + + when PUT_Q_DEC => + if (all_int_ctr = 3) then + all_int_ctr <= 0; + else + all_int_ctr <= all_int_ctr + 1; + end if; + + when LOAD_SUB => + if (all_int_ctr = 15) then + all_int_ctr <= 0; + else + all_int_ctr <= all_int_ctr + 1; + end if; + + when LOAD_DATA => all_int_ctr <= 0; + + when LOAD_TERM => + if (all_int_ctr = 31) then + all_int_ctr <= 0; + else + all_int_ctr <= all_int_ctr + 1; + end if; + + when DIVIDE => null; + + when CLEANUP => all_int_ctr <= 0; + + when PREP_DATA => all_int_ctr <= 0; + + when DELAY => all_int_ctr <= 0; + end case; + end if; + end if; +end process allIntCtrProc; + +dfRdEnProc : process(loadCurrentState, bytes_loaded, max_frame_size, sub_bytes_loaded, + sub_size_loaded, all_int_ctr, RESET, size_left, load_eod_q) +begin + if (RESET = '1') then + df_rd_en <= '0'; + elsif (loadCurrentState = LOAD_DATA) then +-- if (bytes_loaded = max_frame_size - x"1") then +-- df_rd_en <= '0'; +-- -- gk 07.10.10 +-- elsif (MULT_EVT_ENABLE_IN = '0') and (load_eod_q = '1') then +-- df_rd_en <= '0'; +-- -- gk 07.10.10 +-- elsif (MULT_EVT_ENABLE_IN = '1') and (size_left = x"0000_003a") then +-- df_rd_en <= '0'; +-- else +-- df_rd_en <= '1'; +-- end if; + if (bytes_loaded = max_frame_size - x"1") then + df_rd_en <= '0'; + -- gk 26.07.10 + --elsif (load_eod = '1') or (load_eod_q = '1') then + elsif (load_eod_q = '1') then + df_rd_en <= '0'; +-- elsif (sub_bytes_loaded = sub_size_loaded) then +-- df_rd_en <= '0'; + else + df_rd_en <= '1'; + end if; + + elsif (loadCurrentState = LOAD_SUB) and (all_int_ctr = 15) and (bytes_loaded /= max_frame_size - x"1") then + df_rd_en <= '1'; + elsif (loadCurrentState = PREP_DATA) then + df_rd_en <= '1'; + else + df_rd_en <= '0'; + end if; +end process dfRdEnProc; + +shfRdEnProc : process(loadCurrentState, all_int_ctr, RESET) +begin + if (RESET = '1') then -- gk 31.05.10 + shf_rd_en <= '0'; + elsif (loadCurrentState = LOAD_SUB) then + shf_rd_en <= '1'; + elsif (loadCurrentState = LOAD_TERM) and (all_int_ctr < 31) then + shf_rd_en <= '1'; + elsif (loadCurrentState = PUT_Q_DEC) and (all_int_ctr = 3) then + shf_rd_en <= '1'; + else + shf_rd_en <= '0'; + end if; +end process shfRdEnProc; + + +-- fcWrEnProc : process(loadCurrentState, RESET) +-- begin +-- if (RESET = '1') then -- gk 31.05.10 +-- fc_wr_en <= '0'; +-- elsif (loadCurrentState = PUT_Q_LEN) or (loadCurrentState = PUT_Q_DEC) then +-- fc_wr_en <= '1'; +-- elsif (loadCurrentState = LOAD_SUB) or (loadCurrentState = LOAD_DATA) or (loadCurrentState = LOAD_TERM) then +-- fc_wr_en <= '1'; +-- else +-- fc_wr_en <= '0'; +-- end if; +-- end process fcWrEnProc; +fcWrEnProc : process(loadCurrentState, RESET, first_sub_in_multi, from_divide_state, MULT_EVT_ENABLE_IN, divide_position, disable_prep) +begin + if (RESET = '1') then -- gk 31.05.10 + fc_wr_en <= '0'; + elsif (loadCurrentState = PUT_Q_LEN) or (loadCurrentState = PUT_Q_DEC) then + fc_wr_en <= '1'; + elsif (loadCurrentState = LOAD_SUB) or (loadCurrentState = LOAD_DATA) or (loadCurrentState = LOAD_TERM) then + fc_wr_en <= '1'; + -- gk 04.12.10 + elsif (MULT_EVT_ENABLE_IN = '1') and (loadCurrentState = PREP_DATA) and (first_sub_in_multi = '0') and (from_divide_state = '0') and (disable_prep = '0') then + fc_wr_en <= '1'; + elsif (MULT_EVT_ENABLE_IN = '1') and (loadCurrentState = PREP_DATA) and (from_divide_state = '1') and ((divide_position = "00") or (divide_position = "01")) and (disable_prep = '0') then + fc_wr_en <= '1'; + else + fc_wr_en <= '0'; + end if; +end process fcWrEnProc; + + +-- was all_int_ctr +fcDataProc : process(loadCurrentState, queue_size_temp, PC_QUEUE_DEC_IN, shf_q, df_q_reg, load_int_ctr) +begin + case loadCurrentState is + when LIDLE => fc_data <= x"af"; + when WAIT_FOR_FC => fc_data <= x"bf"; + -- gk 08.04.10 my_int_ctr changed to load_int_ctr + when PUT_Q_LEN => fc_data <= queue_size_temp(load_int_ctr * 8 + 7 downto load_int_ctr * 8); + when PUT_Q_DEC => fc_data <= PC_QUEUE_DEC_IN(load_int_ctr * 8 + 7 downto load_int_ctr * 8); + when LOAD_SUB => fc_data <= shf_q; + when PREP_DATA => fc_data <= df_q_reg; + when LOAD_DATA => fc_data <= df_q_reg; + when LOAD_TERM => fc_data <= shf_q; + when DIVIDE => fc_data <= x"cf"; + when CLEANUP => fc_data <= x"df"; + when others => fc_data <= x"00"; + end case; +end process fcDataProc; + +-- delay counters +-- gk 28.04.10 +DELAY_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if ((RESET = '1') or (loadCurrentState = LIDLE)) then + delay_ctr <= PC_DELAY_IN; + elsif ((loadCurrentState = DELAY) and (ticks_ctr(7) = '1')) then + delay_ctr <= delay_ctr - x"1"; + end if; + end if; +end process DELAY_CTR_PROC; + +-- gk 28.04.10 +TICKS_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if ((RESET = '1') or (loadCurrentState = LIDLE) or (ticks_ctr(7) = '1')) then + ticks_ctr <= x"00"; + elsif (loadCurrentState = DELAY) then + ticks_ctr <= ticks_ctr + x"1"; + end if; + end if; +end process TICKS_CTR_PROC; + + +--*********************** +-- SIZE COUNTERS FOR LOADING SIDE +--*********************** + +queue_size_temp <= queue_size - x"20"; -- size of data without termination + +-- gk 08.04.10 +rst_after_sub_comb <= '1' when (loadCurrentState = LIDLE) or + ((loadCurrentState = LOAD_DATA) and (size_left /= x"00000021")) -- gk 26.07.10 -- and (sub_bytes_loaded = sub_size_loaded) + else '0'; + +-- gk 08.04.10 +RST_AFTER_SUB_PROC : process(CLK) +begin + if(rising_edge(CLK)) then + if(RESET = '1') then + rst_after_sub <= '0'; + else + rst_after_sub <= rst_after_sub_comb; + end if; + end if; +end process RST_AFTER_SUB_PROC; + +-- counts all bytes loaded to divide data into frames +bytesLoadedProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = DIVIDE) or (loadCurrentState = CLEANUP) then + bytes_loaded <= x"0000"; + elsif (loadCurrentState = PUT_Q_LEN) or (loadCurrentState = PUT_Q_DEC) or (loadCurrentState = LOAD_DATA) or (loadCurrentState = LOAD_SUB) or (loadCurrentState = LOAD_TERM) then + bytes_loaded <= bytes_loaded + x"1"; + -- gk 05.12.10 +-- elsif (MULT_EVT_ENABLE_IN = '1') and (loadCurrentState = PREP_DATA) and (first_sub_in_multi = '0') and (from_divide_state = '0') then +-- bytes_loaded <= bytes_loaded + x"1"; + elsif (MULT_EVT_ENABLE_IN = '1') and (loadCurrentState = PREP_DATA) and (first_sub_in_multi = '0') and (from_divide_state = '0') and (disable_prep = '0') then + bytes_loaded <= bytes_loaded + x"1"; + elsif (MULT_EVT_ENABLE_IN = '1') and (loadCurrentState = PREP_DATA) and (from_divide_state = '1') and ((divide_position = "00") or (divide_position = "01")) and (disable_prep = '0') then + bytes_loaded <= bytes_loaded + x"1"; + end if; + end if; +end process bytesLoadedProc; + +-- size of subevent loaded from memory +subSizeLoadedProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) or (rst_after_sub = '1') then -- gk 08.04.10 + sub_size_loaded <= x"00000000"; + elsif (loadCurrentState = LOAD_SUB) and (all_int_ctr < 4) then + -- was all_int_ctr + -- gk 08.04.10 my_int_ctr changed to load_int_ctr + sub_size_loaded(7 + load_int_ctr * 8 downto load_int_ctr * 8) <= shf_q; + -- gk 29.03.10 here the padding bytes have to be added to the loadedSize in order to load the correct amount of bytes from fifo + elsif (loadCurrentState = LOAD_SUB) and (all_int_ctr = 5) and (sub_size_loaded(2) = '1') then + sub_size_loaded <= sub_size_loaded + x"4"; + end if; + end if; +end process subSizeLoadedProc; + +-- counts only raw data bytes being loaded +subBytesLoadedProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) or (rst_after_sub = '1') then -- gk 26.07.10 --or (sub_bytes_loaded = sub_size_loaded) -- gk 08.04.10 + sub_bytes_loaded <= x"00000011"; -- subevent headers doesnt count + elsif (loadCurrentState = LOAD_DATA) then + sub_bytes_loaded <= sub_bytes_loaded + x"1"; + end if; + end if; +end process subBytesLoadedProc; + +-- counts the size of the large udp packet +actualPacketProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) then + actual_packet_size <= x"0008"; + elsif (fc_wr_en = '1') then + actual_packet_size <= actual_packet_size + x"1"; + end if; + end if; +end process actualPacketProc; + +actualQueueSizeProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = CLEANUP) then + actual_queue_size <= (others => '0'); + elsif (loadCurrentState = LIDLE) then + actual_queue_size <= queue_size; + end if; + end if; +end process actualQueueSizeProc; + +-- amount of bytes left to send in current packet +sizeLeftProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = CLEANUP) then + size_left <= (others => '0'); + elsif (loadCurrentState = LIDLE) then + size_left <= queue_size; + elsif (fc_wr_en = '1') then + size_left <= size_left - 1; + end if; + end if; +end process sizeLeftProc; + +-- HOT FIX: don't rely on CTS information, count the packets on your own. +-- In this case, we increment the fragmented packet ID with EOD from ipu2gbe. +THE_FC_IDENT_COUNTER_PROC: process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + fc_ident <= (others => '0'); + elsif (PC_END_OF_DATA_IN = '1') then + fc_ident <= fc_ident + 1; + end if; + end if; +end process THE_FC_IDENT_COUNTER_PROC; + +fc_flags_offset(15 downto 14) <= "00"; + +moreFragmentsProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) then + fc_flags_offset(13) <= '0'; + elsif ((loadCurrentState = DIVIDE) and (TC_READY_IN = '1')) or ((loadCurrentState = WAIT_FOR_FC) and (TC_READY_IN = '1')) then + if ((actual_queue_size - actual_packet_size) < max_frame_size) then + fc_flags_offset(13) <= '0'; -- no more fragments + else + fc_flags_offset(13) <= '1'; -- more fragments + end if; + end if; + end if; +end process moreFragmentsProc; + +eodProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + fc_eod <= '0'; + elsif (loadCurrentState = LOAD_DATA) and (bytes_loaded = max_frame_size - 2) then + fc_eod <= '1'; + elsif (loadCurrentState = LOAD_SUB) and (bytes_loaded = max_frame_size - 2) then + fc_eod <= '1'; + elsif (loadCurrentState = LOAD_TERM) and ((bytes_loaded = max_frame_size - 2) or (all_int_ctr = 30)) then + fc_eod <= '1'; + else + fc_eod <= '0'; + end if; + end if; +end process eodProc; + +sodProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + fc_sod <= '0'; + elsif (loadCurrentState = WAIT_FOR_FC) and (TC_READY_IN = '1') then + fc_sod <= '1'; + elsif (loadCurrentState = DIVIDE) and (TC_READY_IN = '1') then + fc_sod <= '1'; + else + fc_sod <= '0'; + end if; + end if; +end process sodProc; + +offsetProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) then + fc_flags_offset(12 downto 0) <= (others => '0'); + elsif ((loadCurrentState = DIVIDE) and (TC_READY_IN = '1')) then + fc_flags_offset(12 downto 0) <= actual_packet_size(15 downto 3); + end if; + end if; +end process offsetProc; + +fcIPSizeProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET= '1') then + fc_ip_size <= (others => '0'); + elsif ((loadCurrentState = DIVIDE) and (TC_READY_IN = '1')) or ((loadCurrentState = WAIT_FOR_FC) and (TC_READY_IN = '1')) then + if (size_left >= max_frame_size) then + fc_ip_size <= max_frame_size; + else + fc_ip_size <= size_left(15 downto 0); + end if; + end if; + end if; +end process fcIPSizeProc; + +fcUDPSizeProc : process(CLK) + begin + if rising_edge(CLK) then + if (RESET = '1') then + fc_udp_size <= (others => '0'); + elsif (loadCurrentState = WAIT_FOR_FC) and (TC_READY_IN = '1') then + fc_udp_size <= queue_size(15 downto 0); + end if; + end if; +end process fcUDPSizeProc; + + +--*********************** +-- SUBEVENT HEADERS WRITE AND READ +--*********************** + +SUBEVENT_HEADERS_FIFO : fifo_16kx8 +port map( + Data => shf_data, + WrClock => CLK, + RdClock => CLK, + WrEn => shf_wr_en, + RdEn => shf_rd_en, + Reset => RESET, + RPReset => RESET, + Q => shf_q, + Empty => shf_empty, + Full => shf_full +); + +-- write enable for SHF +shf_wr_en <= '1' when ((saveSubCurrentState /= SIDLE) and (loadCurrentState /= PREP_DATA)) + else '0'; + +-- data multiplexing for SHF (convert 32bit LWs to 8bit) +-- CHANGED. +-- The SubEventHeader (4x 32bit is stored in [MSB:LSB] now, same byte order as data from PC. +shfDataProc : process(saveSubCurrentState, sub_size_to_save, PC_DECODING_IN, PC_EVENT_ID_IN, + pc_trig_nr, my_int_ctr, fc_data) +begin + case saveSubCurrentState is + when SIDLE => shf_data <= x"ac"; + when SAVE_SIZE => shf_data <= sub_size_to_save(my_int_ctr * 8 + 7 downto my_int_ctr * 8); + when SAVE_DECODING => shf_data <= PC_DECODING_IN(my_int_ctr * 8 + 7 downto my_int_ctr * 8); + when SAVE_ID => shf_data <= PC_EVENT_ID_IN(my_int_ctr * 8 + 7 downto my_int_ctr * 8); + when SAVE_TRIG_NR => shf_data <= pc_trig_nr(my_int_ctr * 8 + 7 downto my_int_ctr * 8); + when SAVE_TERM => shf_data <= fc_data; + when others => shf_data <= x"00"; + end case; +end process shfDataProc; + +saveSubMachineProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + saveSubCurrentState <= SIDLE; + else + saveSubCurrentState <= saveSubNextState; + end if; + end if; +end process saveSubMachineProc; + +saveSubMachine : process(saveSubCurrentState, PC_START_OF_SUB_IN, sub_int_ctr, loadCurrentState, TC_H_READY_IN) +begin + case saveSubCurrentState is + when SIDLE => + save_state <= x"0"; + if (PC_START_OF_SUB_IN = '1') then + saveSubNextState <= SAVE_SIZE; + -- this branch is dangerous! + elsif (loadCurrentState = WAIT_FOR_FC) and (TC_H_READY_IN = '1') then -- means that loadCurrentState is put_q_len + saveSubNextState <= SAVE_TERM; + else + saveSubNextState <= SIDLE; + end if; + when SAVE_SIZE => + save_state <= x"1"; + if (sub_int_ctr = 3) then + saveSubNextState <= SAVE_DECODING; + else + saveSubNextState <= SAVE_SIZE; + end if; + when SAVE_DECODING => + save_state <= x"2"; + if (sub_int_ctr = 3) then + saveSubNextState <= SAVE_ID; + else + saveSubNextState <= SAVE_DECODING; + end if; + when SAVE_ID => + save_state <= x"3"; + if (sub_int_ctr = 3) then + saveSubNextState <= SAVE_TRIG_NR; + else + saveSubNextState <= SAVE_ID; + end if; + when SAVE_TRIG_NR => + save_state <= x"4"; + if (sub_int_ctr = 3) then + saveSubNextState <= SIDLE; + else + saveSubNextState <= SAVE_TRIG_NR; + end if; + when SAVE_TERM => + save_state <= x"5"; + if (sub_int_ctr = 31) then + saveSubNextState <= SIDLE; + else + saveSubNextState <= SAVE_TERM; + end if; + when others => + save_state <= x"f"; + saveSubNextState <= SIDLE; + end case; +end process; + +-- This counter is used for breaking down 32bit information words into 8bit bytes for +-- storing them in the SHF. +-- It is also used for the termination 32byte sequence. +subIntProc: process( CLK ) +begin + if rising_edge(CLK) then + if (RESET = '1') or (saveSubCurrentState = SIDLE) then + sub_int_ctr <= 0; + elsif (sub_int_ctr = 3) and (saveSubCurrentState /= SAVE_TERM) then + sub_int_ctr <= 0; + elsif (sub_int_ctr = 31) and (saveSubCurrentState = SAVE_TERM) then + sub_int_ctr <= 0; + elsif (saveSubCurrentState /= SIDLE) and (loadCurrentState /= PREP_DATA) then + sub_int_ctr <= sub_int_ctr + 1; + end if; + end if; +end process subIntProc; + +debug(3 downto 0) <= constr_state; +debug(7 downto 4) <= save_state; +debug(11 downto 8) <= load_state; +debug(27 downto 12) <= queue_size(15 downto 0); +debug(28) <= df_full; +debug(29) <= df_empty; +debug(30) <= shf_full; +debug(31) <= shf_empty; + +debug(47 downto 32) <= size_left(15 downto 0); +debug(52 downto 48) <= all_ctr; +debug(53) <= pc_ready; + +-- outputs +PC_READY_OUT <= pc_ready; +TC_WR_EN_OUT <= fc_wr_en; +TC_DATA_OUT <= fc_data; +TC_IP_SIZE_OUT <= fc_ip_size; +TC_UDP_SIZE_OUT <= fc_udp_size; +-- FC_IDENT_OUT(15 downto 8) <= fc_ident(7 downto 0); +-- FC_IDENT_OUT(7 downto 0) <= fc_ident(15 downto 8); +TC_FLAGS_OFFSET_OUT <= fc_flags_offset; +TC_SOD_OUT <= fc_sod; +TC_EOD_OUT <= fc_eod; + +DEBUG_OUT <= debug; + +end trb_net16_gbe_packet_constr; \ No newline at end of file diff --git a/gbe2_ecp3/trb_net16_gbe_packet_constr_20101006.vhd b/gbe2_ecp3/trb_net16_gbe_packet_constr_20101006.vhd new file mode 100644 index 0000000..1102f44 --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_packet_constr_20101006.vhd @@ -0,0 +1,958 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; +use IEEE.std_logic_arith.all; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +entity trb_net16_gbe_packet_constr is +port( + RESET : in std_logic; + CLK : in std_logic; + -- ports for user logic + PC_WR_EN_IN : in std_logic; -- write into queueConstr from userLogic + PC_DATA_IN : in std_logic_vector(7 downto 0); + PC_READY_OUT : out std_logic; + PC_START_OF_SUB_IN : in std_logic; + PC_END_OF_DATA_IN : in std_logic; + -- queue and subevent layer headers + PC_SUB_SIZE_IN : in std_logic_vector(31 downto 0); -- store and swap + PC_PADDING_IN : in std_logic; -- gk 29.03.10 + PC_DECODING_IN : in std_logic_vector(31 downto 0); -- swap + PC_EVENT_ID_IN : in std_logic_vector(31 downto 0); -- swap + PC_TRIG_NR_IN : in std_logic_vector(31 downto 0); -- store and swap! + PC_QUEUE_DEC_IN : in std_logic_vector(31 downto 0); -- swap + PC_MAX_FRAME_SIZE_IN : in std_logic_vector(15 downto 0); -- DO NOT SWAP + PC_DELAY_IN : in std_logic_vector(31 downto 0); -- gk 28.04.10 + -- FrameConstructor ports + FC_WR_EN_OUT : out std_logic; + FC_DATA_OUT : out std_logic_vector(7 downto 0); + FC_H_READY_IN : in std_logic; + FC_READY_IN : in std_logic; + FC_IP_SIZE_OUT : out std_logic_vector(15 downto 0); + FC_UDP_SIZE_OUT : out std_logic_vector(15 downto 0); + FC_IDENT_OUT : out std_logic_vector(15 downto 0); + FC_FLAGS_OFFSET_OUT : out std_logic_vector(15 downto 0); + FC_SOD_OUT : out std_logic; + FC_EOD_OUT : out std_logic; + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end trb_net16_gbe_packet_constr; + +architecture trb_net16_gbe_packet_constr of trb_net16_gbe_packet_constr is + +-- -- Placer Directives +-- attribute HGROUP : string; +-- -- for whole architecture +-- attribute HGROUP of trb_net16_gbe_packet_constr : architecture is "GBE_packet_constr_group"; + +component fifo_64kx9 +port ( + Data : in std_logic_vector(8 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(8 downto 0); + Empty : out std_logic; + Full : out std_logic +); +end component; + +-- FIFO for SubEventHeader information +component fifo_2048x8 is +port ( + Data : in std_logic_vector(7 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(7 downto 0); + Empty : out std_logic; + Full : out std_logic +); +end component; + +signal df_wr_en : std_logic; +signal df_rd_en : std_logic; +signal df_q : std_logic_vector(7 downto 0); +signal df_q_reg : std_logic_vector(7 downto 0); +signal df_empty : std_logic; +signal df_full : std_logic; + +signal fc_data : std_logic_vector(7 downto 0); +signal fc_wr_en : std_logic; +signal fc_sod : std_logic; +signal fc_eod : std_logic; +signal fc_ident : std_logic_vector(15 downto 0); -- change this to own counter! +signal fc_flags_offset : std_logic_vector(15 downto 0); + +signal shf_data : std_logic_vector(7 downto 0); +signal shf_wr_en : std_logic; +signal shf_rd_en : std_logic; +signal shf_q : std_logic_vector(7 downto 0); +signal shf_empty : std_logic; +signal shf_full : std_logic; + +type constructStates is (CIDLE, SAVE_DATA, WAIT_FOR_LOAD); +signal constructCurrentState, constructNextState : constructStates; +signal constr_state : std_logic_vector(3 downto 0); +signal all_int_ctr : integer range 0 to 31; +signal all_ctr : std_logic_vector(4 downto 0); + +type saveSubStates is (SIDLE, SAVE_SIZE, SAVE_DECODING, SAVE_ID, SAVE_TRIG_NR, SAVE_TERM); +signal saveSubCurrentState, saveSubNextState : saveSubStates; +signal save_state : std_logic_vector(3 downto 0); +signal sub_int_ctr : integer range 0 to 31; +signal sub_ctr : std_logic_vector(4 downto 0); +signal my_int_ctr : integer range 0 to 3; +signal my_ctr : std_logic_vector(1 downto 0); + +type loadStates is (LIDLE, WAIT_FOR_FC, PUT_Q_LEN, PUT_Q_DEC, LOAD_SUB, PREP_DATA, LOAD_DATA, DIVIDE, LOAD_TERM, CLEANUP, DELAY); +signal loadCurrentState, loadNextState: loadStates; +signal load_state : std_logic_vector(3 downto 0); + +signal queue_size : std_logic_vector(31 downto 0); -- sum of all subevents sizes plus their headers and queue headers and termination +signal queue_size_temp : std_logic_vector(31 downto 0); +signal actual_queue_size : std_logic_vector(31 downto 0); -- queue size used during loading process when queue_size is no more valid +signal bytes_loaded : std_logic_vector(15 downto 0); -- size of actual constructing frame +signal sub_size_to_save : std_logic_vector(31 downto 0); -- size of subevent to save to shf +signal sub_size_loaded : std_logic_vector(31 downto 0); -- size of subevent actually being transmitted +signal sub_bytes_loaded : std_logic_vector(31 downto 0); -- amount of bytes of actual subevent sent +signal actual_packet_size : std_logic_vector(15 downto 0); -- actual size of whole udp packet +signal size_left : std_logic_vector(31 downto 0); +signal fc_ip_size : std_logic_vector(15 downto 0); +signal fc_udp_size : std_logic_vector(15 downto 0); +signal max_frame_size : std_logic_vector(15 downto 0); +signal divide_position : std_logic_vector(1 downto 0); -- 00->data, 01->sub, 11->term +signal debug : std_logic_vector(63 downto 0); +signal pc_ready : std_logic; + +signal pc_sub_size : std_logic_vector(31 downto 0); +signal pc_trig_nr : std_logic_vector(31 downto 0); +signal rst_after_sub_comb : std_logic; -- gk 08.04.10 +signal rst_after_sub : std_logic; -- gk 08.04.10 +signal load_int_ctr : integer range 0 to 3; -- gk 08.04.10 +signal delay_ctr : std_logic_vector(31 downto 0); -- gk 28.04.10 +signal ticks_ctr : std_logic_vector(7 downto 0); -- gk 28.04.10 + +-- gk 26.07.10 +signal load_eod : std_logic; +signal load_eod_q : std_logic; + +begin + +-- Fakes +--debug <= (others => '0'); + +my_int_ctr <= (3 - to_integer(to_unsigned(sub_int_ctr, 2))); -- reverse byte order +load_int_ctr <= (3 - to_integer(to_unsigned(all_int_ctr, 2))); -- gk 08.04.10 + +all_ctr <= std_logic_vector(to_unsigned(all_int_ctr, all_ctr'length)); -- for debugging +sub_ctr <= std_logic_vector(to_unsigned(sub_int_ctr, sub_ctr'length)); -- for debugging +my_ctr <= std_logic_vector(to_unsigned(my_int_ctr, my_ctr'length)); -- for debugging + +max_frame_size <= PC_MAX_FRAME_SIZE_IN; + +-- Ready signal for PacketConstructor +pc_ready <= '1' when (constructCurrentState = CIDLE) and (df_empty = '1') else '0'; + +-- store event information on Start_of_Subevent +THE_EVT_INFO_STORE_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if (RESET = '1') then -- gk 31.05.10 + pc_sub_size <= (others => '0'); + pc_trig_nr <= (others => '0'); + elsif( PC_START_OF_SUB_IN = '1' ) then + pc_sub_size <= PC_SUB_SIZE_IN; + pc_trig_nr <= PC_TRIG_NR_IN; + end if; + end if; +end process; + +-- Data FIFO for incoming packet data from IPU buffer +-- gk 26.07.10 +DATA_FIFO : fifo_64kx9 +port map( + Data(7 downto 0) => PC_DATA_IN, + Data(8) => PC_END_OF_DATA_IN, + WrClock => CLK, + RdClock => CLK, + WrEn => df_wr_en, + RdEn => df_rd_en, + Reset => RESET, + RPReset => RESET, + Q(7 downto 0) => df_q, + Q(8) => load_eod, + Empty => df_empty, + Full => df_full +); + +LOAD_EOD_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + load_eod_q <= '0'; + else + load_eod_q <= load_eod; + end if; + end if; +end process LOAD_EOD_PROC; + +-- Write enable for the data FIFO +-- !!!combinatorial signal!!! +-- could be avoided as IPU2GBE does only send data in case of PC_READY. +df_wr_en <= '1' when ((PC_WR_EN_IN = '1') and (constructCurrentState /= WAIT_FOR_LOAD)) + else '0'; + +-- Output register for data FIFO +dfQProc : process(CLK) +begin + if rising_edge(CLK) then + df_q_reg <= df_q; + end if; +end process dfQProc; + +-- Construction state machine +constructMachineProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + constructCurrentState <= CIDLE; + else + constructCurrentState <= constructNextState; + end if; + end if; +end process constructMachineProc; + +constructMachine : process(constructCurrentState, PC_WR_EN_IN, PC_END_OF_DATA_IN, loadCurrentState, saveSubCurrentState, sub_int_ctr) +begin + case constructCurrentState is + when CIDLE => + constr_state <= x"0"; + if( PC_WR_EN_IN = '1' ) then + constructNextState <= SAVE_DATA; + else + constructNextState <= CIDLE; + end if; + when SAVE_DATA => + constr_state <= x"1"; + if( PC_END_OF_DATA_IN = '1' ) then + constructNextState <= WAIT_FOR_LOAD; + else + constructNextState <= SAVE_DATA; + end if; + when WAIT_FOR_LOAD => + constr_state <= x"2"; + if( (df_empty = '1') and (loadCurrentState = LIDLE) ) then -- waits until the whole packet is transmitted + constructNextState <= CIDLE; + else + constructNextState <= WAIT_FOR_LOAD; + end if; + when others => + constr_state <= x"f"; + constructNextState <= CIDLE; + end case; +end process constructMachine; + +--*********************** +-- SIZE COUNTERS FOR SAVING SIDE +--*********************** + +-- gk 29.03.10 the subevent size saved to its headers cannot contain padding bytes but they are included in pc_sub_size +-- that's why they are removed if pc_padding flag is asserted +sub_size_to_save <= (x"10" + pc_sub_size) when (PC_PADDING_IN = '0') + else (x"c" + pc_sub_size); -- subevent headers + data + +-- BUG HERE BUG HERE BUG HERE BUG HERE +-- gk 29.03.10 no changes here because the queue size should contain the padding bytes of subevents +queueSizeProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = CLEANUP) then + queue_size <= x"00000028"; -- + 8B for queue headers and 32B for termination + elsif (saveSubCurrentState = SAVE_SIZE) and (sub_int_ctr = 3) then + queue_size <= queue_size + pc_sub_size + x"10"; -- + 16B for each subevent headers + end if; + end if; +end process queueSizeProc; + + +--*********************** +-- LOAD DATA COMBINED WITH HEADERS INTO FC, QUEUE TRANSMISSION +--*********************** + +loadMachineProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + loadCurrentState <= LIDLE; + else + loadCurrentState <= loadNextState; + end if; + end if; +end process loadMachineProc; + +loadMachine : process(loadCurrentState, constructCurrentState, all_int_ctr, df_empty, + sub_bytes_loaded, sub_size_loaded, size_left, FC_H_READY_IN, max_frame_size, + bytes_loaded, divide_position, PC_DELAY_IN, delay_ctr, load_eod_q) +begin + case loadCurrentState is + when LIDLE => + load_state <= x"0"; + if ((constructCurrentState = WAIT_FOR_LOAD) and (df_empty = '0')) then + loadNextState <= WAIT_FOR_FC; + else + loadNextState <= LIDLE; + end if; + when WAIT_FOR_FC => + load_state <= x"1"; + if (FC_H_READY_IN = '1') then + loadNextState <= PUT_Q_LEN; + else + loadNextState <= WAIT_FOR_FC; + end if; + when PUT_Q_LEN => + load_state <= x"2"; + if (all_int_ctr = 3) then + loadNextState <= PUT_Q_DEC; + else + loadNextState <= PUT_Q_LEN; + end if; + when PUT_Q_DEC => + load_state <= x"3"; + if (all_int_ctr = 3) then + loadNextState <= LOAD_SUB; + else + loadNextState <= PUT_Q_DEC; + end if; + when LOAD_SUB => + load_state <= x"4"; + if (bytes_loaded = max_frame_size - 1) then + loadNextState <= DIVIDE; + elsif (all_int_ctr = 15) then + loadNextState <= PREP_DATA; + else + loadNextState <= LOAD_SUB; + end if; + when PREP_DATA => + load_state <= x"5"; + loadNextState <= LOAD_DATA; + when LOAD_DATA => + load_state <= x"6"; + if (bytes_loaded = max_frame_size - 1) then + loadNextState <= DIVIDE; + -- gk 26.07.10 + -- close packet after one event loaded + elsif (load_eod_q = '1') then + loadNextState <= LOAD_TERM; +-- elsif (sub_bytes_loaded = sub_size_loaded) then -- if all subevent bytes are loaded +-- if (size_left = x"00000021") then -- and there is no more data, only termination left +-- -- gk 21.07.10 +-- if (PC_SKIP_TERM_IN = '0') then +-- loadNextState <= LOAD_TERM; -- add termination and close packet +-- else +-- loadNextState <= CLEANUP; +-- end if; +-- else -- there is more data in fifo +-- loadNextState <= LOAD_SUB; -- add another subevent +-- end if; + else + loadNextState <= LOAD_DATA; + end if; + when DIVIDE => + load_state <= x"7"; + if (FC_H_READY_IN = '1') then + if (divide_position = "00") then + loadNextState <= PREP_DATA; + elsif (divide_position = "01") then + loadNextState <= LOAD_SUB; + else + loadNextState <= LOAD_TERM; + end if; + else + loadNextState <= DIVIDE; + end if; + when LOAD_TERM => + load_state <= x"8"; + if (bytes_loaded = max_frame_size - 1) and (all_int_ctr /= 31) then + loadNextState <= DIVIDE; + elsif (all_int_ctr = 31) then + loadNextState <= CLEANUP; + else + loadNextState <= LOAD_TERM; + end if; + -- gk 28.04.10 + when CLEANUP => + load_state <= x"9"; + if (PC_DELAY_IN = x"0000_0000") then + loadNextState <= LIDLE; + else + loadNextState <= DELAY; + end if; + -- gk 28.04.10 + when DELAY => + load_state <= x"a"; + if (delay_ctr = x"0000_0000") then + loadNextState <= LIDLE; + else + loadNextState <= DELAY; + end if; + when others => + load_state <= x"f"; + loadNextState <= LIDLE; + end case; +end process loadMachine; + +dividePositionProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + divide_position <= "00"; + elsif (bytes_loaded = max_frame_size - 1) then + if (loadCurrentState = LIDLE) then + divide_position <= "00"; + elsif (loadCurrentState = LOAD_DATA) then + -- gk 26.07.10 + if (load_eod_q = '1') then -- if termination is about to be loaded divide on term + divide_position <= "11"; + else + divide_position <= "00"; -- still data loaded divide on data +-- if (sub_bytes_loaded = sub_size_loaded) and (size_left = x"00000021") then +-- divide_position <= "11"; +-- elsif (sub_bytes_loaded = sub_size_loaded) and (size_left /= x"00000021") then +-- divide_position <= "01"; +-- else +-- divide_position <= "00"; + end if; + elsif (loadCurrentState = LOAD_SUB) then + if (all_int_ctr = 15) then + divide_position <= "00"; + else + divide_position <= "01"; + end if; + elsif (loadCurrentState = LOAD_TERM) then + divide_position <= "11"; + end if; + end if; + end if; +end process dividePositionProc; + +allIntCtrProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then -- gk 31.05.10 + all_int_ctr <= 0; + else + case loadCurrentState is + + when LIDLE => all_int_ctr <= 0; + + when WAIT_FOR_FC => all_int_ctr <= 0; + + when PUT_Q_LEN => + if (all_int_ctr = 3) then + all_int_ctr <= 0; + else + all_int_ctr <= all_int_ctr + 1; + end if; + + when PUT_Q_DEC => + if (all_int_ctr = 3) then + all_int_ctr <= 0; + else + all_int_ctr <= all_int_ctr + 1; + end if; + + when LOAD_SUB => + if (all_int_ctr = 15) then + all_int_ctr <= 0; + else + all_int_ctr <= all_int_ctr + 1; + end if; + + when LOAD_DATA => all_int_ctr <= 0; + + when LOAD_TERM => + if (all_int_ctr = 31) then + all_int_ctr <= 0; + else + all_int_ctr <= all_int_ctr + 1; + end if; + + when DIVIDE => null; --all_int_ctr <= all_int_ctr; + + when CLEANUP => all_int_ctr <= 0; + + when PREP_DATA => all_int_ctr <= 0; + + when DELAY => all_int_ctr <= 0; + end case; + end if; + end if; +end process allIntCtrProc; + +dfRdEnProc : process(loadCurrentState, bytes_loaded, max_frame_size, sub_bytes_loaded, + sub_size_loaded, all_int_ctr, RESET, load_eod, load_eod_q) +begin + if (RESET = '1') then -- gk 31.05.10 + df_rd_en <= '0'; + elsif (loadCurrentState = LOAD_DATA) then +-- if (bytes_loaded >= max_frame_size - x"1") then +-- df_rd_en <= '0'; +-- elsif (sub_bytes_loaded >= sub_size_loaded) then +-- df_rd_en <= '0'; + if (bytes_loaded = max_frame_size - x"1") then + df_rd_en <= '0'; + -- gk 26.07.10 + --elsif (load_eod = '1') or (load_eod_q = '1') then + elsif (load_eod_q = '1') then + df_rd_en <= '0'; +-- elsif (sub_bytes_loaded = sub_size_loaded) then +-- df_rd_en <= '0'; + else + df_rd_en <= '1'; + end if; + elsif (loadCurrentState = LOAD_SUB) and (all_int_ctr = 15) and (bytes_loaded /= max_frame_size - x"1") then + df_rd_en <= '1'; + elsif (loadCurrentState = PREP_DATA) then + df_rd_en <= '1'; + else + df_rd_en <= '0'; + end if; +end process dfRdEnProc; + +shfRdEnProc : process(loadCurrentState, all_int_ctr, RESET) +begin + if (RESET = '1') then -- gk 31.05.10 + shf_rd_en <= '0'; + elsif (loadCurrentState = LOAD_SUB) then + shf_rd_en <= '1'; + elsif (loadCurrentState = LOAD_TERM) and (all_int_ctr < 31) then + shf_rd_en <= '1'; + elsif (loadCurrentState = PUT_Q_DEC) and (all_int_ctr = 3) then + shf_rd_en <= '1'; + else + shf_rd_en <= '0'; + end if; +end process shfRdEnProc; + + +fcWrEnProc : process(loadCurrentState, RESET) +begin + if (RESET = '1') then -- gk 31.05.10 + fc_wr_en <= '0'; + elsif (loadCurrentState = PUT_Q_LEN) or (loadCurrentState = PUT_Q_DEC) then + fc_wr_en <= '1'; + elsif (loadCurrentState = LOAD_SUB) or (loadCurrentState = LOAD_DATA) or (loadCurrentState = LOAD_TERM) then + fc_wr_en <= '1'; + else + fc_wr_en <= '0'; + end if; +end process fcWrEnProc; + +-- was all_int_ctr +fcDataProc : process(loadCurrentState, queue_size_temp, PC_QUEUE_DEC_IN, shf_q, df_q_reg, load_int_ctr) +begin + case loadCurrentState is + when LIDLE => fc_data <= x"af"; + when WAIT_FOR_FC => fc_data <= x"bf"; + -- gk 08.04.10 my_int_ctr changed to load_int_ctr + when PUT_Q_LEN => fc_data <= queue_size_temp(load_int_ctr * 8 + 7 downto load_int_ctr * 8); + when PUT_Q_DEC => fc_data <= PC_QUEUE_DEC_IN(load_int_ctr * 8 + 7 downto load_int_ctr * 8); + when LOAD_SUB => fc_data <= shf_q; + when PREP_DATA => fc_data <= df_q_reg; + when LOAD_DATA => fc_data <= df_q_reg; + when LOAD_TERM => fc_data <= shf_q; + when DIVIDE => fc_data <= x"cf"; + when CLEANUP => fc_data <= x"df"; + when others => fc_data <= x"00"; + end case; +end process fcDataProc; + +-- delay counters +-- gk 28.04.10 +DELAY_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if ((RESET = '1') or (loadCurrentState = LIDLE)) then + delay_ctr <= PC_DELAY_IN; + elsif ((loadCurrentState = DELAY) and (ticks_ctr(7) = '1')) then + delay_ctr <= delay_ctr - x"1"; + end if; + end if; +end process DELAY_CTR_PROC; + +-- gk 28.04.10 +TICKS_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if ((RESET = '1') or (loadCurrentState = LIDLE) or (ticks_ctr(7) = '1')) then + ticks_ctr <= x"00"; + elsif (loadCurrentState = DELAY) then + ticks_ctr <= ticks_ctr + x"1"; + end if; + end if; +end process TICKS_CTR_PROC; + + +--*********************** +-- SIZE COUNTERS FOR LOADING SIDE +--*********************** + +queue_size_temp <= queue_size - x"20"; -- size of data without termination + +-- gk 08.04.10 +rst_after_sub_comb <= '1' when (loadCurrentState = LIDLE) or + ((loadCurrentState = LOAD_DATA) and (size_left /= x"00000021")) -- gk 26.07.10 -- and (sub_bytes_loaded = sub_size_loaded) + else '0'; + +-- gk 08.04.10 +RST_AFTER_SUB_PROC : process(CLK) +begin + if(rising_edge(CLK)) then + if(RESET = '1') then + rst_after_sub <= '0'; + else + rst_after_sub <= rst_after_sub_comb; + end if; + end if; +end process RST_AFTER_SUB_PROC; + +-- counts all bytes loaded to divide data into frames +bytesLoadedProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = DIVIDE) or (loadCurrentState = CLEANUP) then + bytes_loaded <= x"0000"; + elsif (loadCurrentState = PUT_Q_LEN) or (loadCurrentState = PUT_Q_DEC) or (loadCurrentState = LOAD_DATA) or (loadCurrentState = LOAD_SUB) or (loadCurrentState = LOAD_TERM) then + bytes_loaded <= bytes_loaded + x"1"; + end if; + end if; +end process bytesLoadedProc; + +-- size of subevent loaded from memory +subSizeLoadedProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) or (rst_after_sub = '1') then -- gk 08.04.10 + sub_size_loaded <= x"00000000"; + elsif (loadCurrentState = LOAD_SUB) and (all_int_ctr < 4) then + -- was all_int_ctr + -- gk 08.04.10 my_int_ctr changed to load_int_ctr + sub_size_loaded(7 + load_int_ctr * 8 downto load_int_ctr * 8) <= shf_q; + -- gk 29.03.10 here the padding bytes have to be added to the loadedSize in order to load the correct amount of bytes from fifo + elsif (loadCurrentState = LOAD_SUB) and (all_int_ctr = 5) and (sub_size_loaded(2) = '1') then + sub_size_loaded <= sub_size_loaded + x"4"; + end if; + end if; +end process subSizeLoadedProc; + +-- counts only raw data bytes being loaded +subBytesLoadedProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) or (rst_after_sub = '1') then -- gk 26.07.10 --or (sub_bytes_loaded = sub_size_loaded) -- gk 08.04.10 + sub_bytes_loaded <= x"00000011"; -- subevent headers doesnt count + elsif (loadCurrentState = LOAD_DATA) then + sub_bytes_loaded <= sub_bytes_loaded + x"1"; + end if; + end if; +end process subBytesLoadedProc; + +-- counts the size of the large udp packet +actualPacketProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) then + actual_packet_size <= x"0008"; + elsif (fc_wr_en = '1') then + actual_packet_size <= actual_packet_size + x"1"; + end if; + end if; +end process actualPacketProc; + +actualQueueSizeProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = CLEANUP) then + actual_queue_size <= (others => '0'); + elsif (loadCurrentState = LIDLE) then + actual_queue_size <= queue_size; + end if; + end if; +end process actualQueueSizeProc; + +-- amount of bytes left to send in current packet +sizeLeftProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = CLEANUP) then + size_left <= (others => '0'); + elsif (loadCurrentState = LIDLE) then + size_left <= queue_size; + elsif (fc_wr_en = '1') then + size_left <= size_left - 1; + end if; + end if; +end process sizeLeftProc; + +-- HOT FIX: don't rely on CTS information, count the packets on your own. +-- In this case, we increment the fragmented packet ID with EOD from ipu2gbe. +THE_FC_IDENT_COUNTER_PROC: process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + fc_ident <= (others => '0'); + elsif (PC_END_OF_DATA_IN = '1') then + fc_ident <= fc_ident + 1; + end if; + end if; +end process THE_FC_IDENT_COUNTER_PROC; + +fc_flags_offset(15 downto 14) <= "00"; + +moreFragmentsProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) then + fc_flags_offset(13) <= '0'; + elsif ((loadCurrentState = DIVIDE) and (FC_READY_IN = '1')) or ((loadCurrentState = WAIT_FOR_FC) and (FC_READY_IN = '1')) then + if ((actual_queue_size - actual_packet_size) < max_frame_size) then + fc_flags_offset(13) <= '0'; -- no more fragments + else + fc_flags_offset(13) <= '1'; -- more fragments + end if; + end if; + end if; +end process moreFragmentsProc; + +eodProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + fc_eod <= '0'; + elsif (loadCurrentState = LOAD_DATA) and (bytes_loaded = max_frame_size - 2) then + fc_eod <= '1'; + elsif (loadCurrentState = LOAD_SUB) and (bytes_loaded = max_frame_size - 2) then + fc_eod <= '1'; + elsif (loadCurrentState = LOAD_TERM) and ((bytes_loaded = max_frame_size - 2) or (all_int_ctr = 30)) then + fc_eod <= '1'; + else + fc_eod <= '0'; + end if; + end if; +end process eodProc; + +sodProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + fc_sod <= '0'; + elsif (loadCurrentState = WAIT_FOR_FC) and (FC_READY_IN = '1') then + fc_sod <= '1'; + elsif (loadCurrentState = DIVIDE) and (FC_READY_IN = '1') then + fc_sod <= '1'; + else + fc_sod <= '0'; + end if; + end if; +end process sodProc; + +offsetProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) then + fc_flags_offset(12 downto 0) <= (others => '0'); + elsif ((loadCurrentState = DIVIDE) and (FC_READY_IN = '1')) then + fc_flags_offset(12 downto 0) <= actual_packet_size(15 downto 3); + end if; + end if; +end process offsetProc; + +fcIPSizeProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET= '1') then + fc_ip_size <= (others => '0'); + elsif ((loadCurrentState = DIVIDE) and (FC_READY_IN = '1')) or ((loadCurrentState = WAIT_FOR_FC) and (FC_READY_IN = '1')) then + if (size_left >= max_frame_size) then + fc_ip_size <= max_frame_size; + else + fc_ip_size <= size_left(15 downto 0); + end if; + end if; + end if; +end process fcIPSizeProc; + +fcUDPSizeProc : process(CLK) + begin + if rising_edge(CLK) then + if (RESET = '1') then + fc_udp_size <= (others => '0'); + elsif (loadCurrentState = WAIT_FOR_FC) and (FC_READY_IN = '1') then + fc_udp_size <= queue_size(15 downto 0); + end if; + end if; +end process fcUDPSizeProc; + + +--*********************** +-- SUBEVENT HEADERS WRITE AND READ +--*********************** + +SUBEVENT_HEADERS_FIFO : fifo_2048x8 +port map( + Data => shf_data, + WrClock => CLK, + RdClock => CLK, + WrEn => shf_wr_en, + RdEn => shf_rd_en, + Reset => RESET, + RPReset => RESET, + Q => shf_q, + Empty => shf_empty, + Full => shf_full +); + +-- write enable for SHF +shf_wr_en <= '1' when ((saveSubCurrentState /= SIDLE) and (loadCurrentState /= PREP_DATA)) + else '0'; + +-- data multiplexing for SHF (convert 32bit LWs to 8bit) +-- CHANGED. +-- The SubEventHeader (4x 32bit is stored in [MSB:LSB] now, same byte order as data from PC. +shfDataProc : process(saveSubCurrentState, sub_size_to_save, PC_DECODING_IN, PC_EVENT_ID_IN, + pc_trig_nr, my_int_ctr, fc_data) +begin + case saveSubCurrentState is + when SIDLE => shf_data <= x"ac"; + when SAVE_SIZE => shf_data <= sub_size_to_save(my_int_ctr * 8 + 7 downto my_int_ctr * 8); + when SAVE_DECODING => shf_data <= PC_DECODING_IN(my_int_ctr * 8 + 7 downto my_int_ctr * 8); + when SAVE_ID => shf_data <= PC_EVENT_ID_IN(my_int_ctr * 8 + 7 downto my_int_ctr * 8); + when SAVE_TRIG_NR => shf_data <= pc_trig_nr(my_int_ctr * 8 + 7 downto my_int_ctr * 8); + when SAVE_TERM => shf_data <= fc_data; + when others => shf_data <= x"00"; + end case; +end process shfDataProc; + +saveSubMachineProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + saveSubCurrentState <= SIDLE; + else + saveSubCurrentState <= saveSubNextState; + end if; + end if; +end process saveSubMachineProc; + +saveSubMachine : process(saveSubCurrentState, PC_START_OF_SUB_IN, sub_int_ctr, loadCurrentState, FC_H_READY_IN) +begin + case saveSubCurrentState is + when SIDLE => + save_state <= x"0"; + if (PC_START_OF_SUB_IN = '1') then + saveSubNextState <= SAVE_SIZE; + -- this branch is dangerous! + elsif (loadCurrentState = WAIT_FOR_FC) and (FC_H_READY_IN = '1') then -- means that loadCurrentState is put_q_len + saveSubNextState <= SAVE_TERM; + else + saveSubNextState <= SIDLE; + end if; + when SAVE_SIZE => + save_state <= x"1"; + if (sub_int_ctr = 3) then + saveSubNextState <= SAVE_DECODING; + else + saveSubNextState <= SAVE_SIZE; + end if; + when SAVE_DECODING => + save_state <= x"2"; + if (sub_int_ctr = 3) then + saveSubNextState <= SAVE_ID; + else + saveSubNextState <= SAVE_DECODING; + end if; + when SAVE_ID => + save_state <= x"3"; + if (sub_int_ctr = 3) then + saveSubNextState <= SAVE_TRIG_NR; + else + saveSubNextState <= SAVE_ID; + end if; + when SAVE_TRIG_NR => + save_state <= x"4"; + if (sub_int_ctr = 3) then + saveSubNextState <= SIDLE; + else + saveSubNextState <= SAVE_TRIG_NR; + end if; + when SAVE_TERM => + save_state <= x"5"; + if (sub_int_ctr = 31) then + saveSubNextState <= SIDLE; + else + saveSubNextState <= SAVE_TERM; + end if; + when others => + save_state <= x"f"; + saveSubNextState <= SIDLE; + end case; +end process; + +-- This counter is used for breaking down 32bit information words into 8bit bytes for +-- storing them in the SHF. +-- It is also used for the termination 32byte sequence. +subIntProc: process( CLK ) +begin + if rising_edge(CLK) then + if (RESET = '1') or (saveSubCurrentState = SIDLE) then + sub_int_ctr <= 0; + elsif (sub_int_ctr = 3) and (saveSubCurrentState /= SAVE_TERM) then + sub_int_ctr <= 0; + elsif (sub_int_ctr = 31) and (saveSubCurrentState = SAVE_TERM) then + sub_int_ctr <= 0; + elsif (saveSubCurrentState /= SIDLE) and (loadCurrentState /= PREP_DATA) then + sub_int_ctr <= sub_int_ctr + 1; + end if; + end if; +end process subIntProc; + +debug(3 downto 0) <= constr_state; +debug(7 downto 4) <= save_state; +debug(11 downto 8) <= load_state; +debug(27 downto 12) <= queue_size(15 downto 0); +debug(28) <= df_full; +debug(29) <= df_empty; +debug(30) <= shf_full; +debug(31) <= shf_empty; + +debug(47 downto 32) <= size_left(15 downto 0); +debug(52 downto 48) <= all_ctr; +debug(53) <= pc_ready; + +-- outputs +PC_READY_OUT <= pc_ready; +FC_WR_EN_OUT <= fc_wr_en; +FC_DATA_OUT <= fc_data; +FC_IP_SIZE_OUT <= fc_ip_size; +FC_UDP_SIZE_OUT <= fc_udp_size; +FC_IDENT_OUT(15 downto 8) <= fc_ident(7 downto 0); +FC_IDENT_OUT(7 downto 0) <= fc_ident(15 downto 8); +FC_FLAGS_OFFSET_OUT <= fc_flags_offset; +FC_SOD_OUT <= fc_sod; +FC_EOD_OUT <= fc_eod; + +DEBUG_OUT <= debug; + +end trb_net16_gbe_packet_constr; \ No newline at end of file diff --git a/gbe2_ecp3/trb_net16_gbe_packet_constr_nologic.vhd b/gbe2_ecp3/trb_net16_gbe_packet_constr_nologic.vhd new file mode 100644 index 0000000..41ab0b1 --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_packet_constr_nologic.vhd @@ -0,0 +1,1099 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; +use IEEE.std_logic_arith.all; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +entity trb_net16_gbe_packet_constr is +port( + RESET : in std_logic; + CLK : in std_logic; + MULT_EVT_ENABLE_IN : in std_logic; -- gk 06.10.10 + -- ports for user logic + PC_WR_EN_IN : in std_logic; -- write into queueConstr from userLogic + PC_DATA_IN : in std_logic_vector(7 downto 0); + PC_READY_OUT : out std_logic; + PC_START_OF_SUB_IN : in std_logic; + PC_END_OF_SUB_IN : in std_logic; -- gk 07.10.10 + PC_END_OF_DATA_IN : in std_logic; + PC_TRANSMIT_ON_OUT : out std_logic; + -- queue and subevent layer headers + PC_SUB_SIZE_IN : in std_logic_vector(31 downto 0); -- store and swap + PC_PADDING_IN : in std_logic; -- gk 29.03.10 + PC_DECODING_IN : in std_logic_vector(31 downto 0); -- swap + PC_EVENT_ID_IN : in std_logic_vector(31 downto 0); -- swap + PC_TRIG_NR_IN : in std_logic_vector(31 downto 0); -- store and swap! + PC_QUEUE_DEC_IN : in std_logic_vector(31 downto 0); -- swap + PC_MAX_FRAME_SIZE_IN : in std_logic_vector(15 downto 0); -- DO NOT SWAP + PC_DELAY_IN : in std_logic_vector(31 downto 0); -- gk 28.04.10 + -- FrameConstructor ports + TC_WR_EN_OUT : out std_logic; + TC_DATA_OUT : out std_logic_vector(7 downto 0); + TC_H_READY_IN : in std_logic; + TC_READY_IN : in std_logic; + TC_IP_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_UDP_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FLAGS_OFFSET_OUT : out std_logic_vector(15 downto 0); + TC_SOD_OUT : out std_logic; + TC_EOD_OUT : out std_logic; + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end trb_net16_gbe_packet_constr; + +architecture trb_net16_gbe_packet_constr of trb_net16_gbe_packet_constr is + +-- attribute HGROUP : string; +-- attribute HGROUP of trb_net16_gbe_packet_constr : architecture is "GBE_packet_constr"; + +component fifo_64kx9 +port ( + Data : in std_logic_vector(8 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(8 downto 0); + Empty : out std_logic; + Full : out std_logic +); +end component; + +-- FIFO for SubEventHeader information +component fifo_16kx8 is +port ( + Data : in std_logic_vector(7 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(7 downto 0); + Empty : out std_logic; + Full : out std_logic +); +end component; + +signal df_wr_en : std_logic; +signal df_rd_en : std_logic; +signal df_q : std_logic_vector(7 downto 0); +signal df_q_reg : std_logic_vector(7 downto 0); +signal df_empty : std_logic; +signal df_full : std_logic; + +signal fc_data : std_logic_vector(7 downto 0); +signal fc_wr_en : std_logic; +signal fc_sod : std_logic; +signal fc_eod : std_logic; +signal fc_ident : std_logic_vector(15 downto 0); -- change this to own counter! +signal fc_flags_offset : std_logic_vector(15 downto 0); + +signal shf_data : std_logic_vector(7 downto 0); +signal shf_wr_en : std_logic; +signal shf_rd_en : std_logic; +signal shf_q : std_logic_vector(7 downto 0); +signal shf_empty : std_logic; +signal shf_full : std_logic; + +type constructStates is (CIDLE, SAVE_DATA, WAIT_FOR_LOAD); +signal constructCurrentState, constructNextState : constructStates; +signal constr_state : std_logic_vector(3 downto 0); +signal all_int_ctr : integer range 0 to 31; +signal all_ctr : std_logic_vector(4 downto 0); + +type saveSubStates is (SIDLE, SAVE_SIZE, SAVE_DECODING, SAVE_ID, SAVE_TRIG_NR, SAVE_TERM); +signal saveSubCurrentState, saveSubNextState : saveSubStates; +signal save_state : std_logic_vector(3 downto 0); +signal sub_int_ctr : integer range 0 to 31; +signal sub_ctr : std_logic_vector(4 downto 0); +signal my_int_ctr : integer range 0 to 3; +signal my_ctr : std_logic_vector(1 downto 0); + +type loadStates is (LIDLE, WAIT_FOR_FC, PUT_Q_LEN, PUT_Q_DEC, LOAD_SUB, PREP_DATA, LOAD_DATA, DIVIDE, LOAD_TERM, CLEANUP, DELAY); +signal loadCurrentState, loadNextState: loadStates; +signal load_state : std_logic_vector(3 downto 0); + +signal queue_size : std_logic_vector(31 downto 0); -- sum of all subevents sizes plus their headers and queue headers and termination +signal queue_size_temp : std_logic_vector(31 downto 0); +signal actual_queue_size : std_logic_vector(31 downto 0); -- queue size used during loading process when queue_size is no more valid +signal bytes_loaded : std_logic_vector(15 downto 0); -- size of actual constructing frame +signal sub_size_to_save : std_logic_vector(31 downto 0); -- size of subevent to save to shf +signal sub_size_loaded : std_logic_vector(31 downto 0); -- size of subevent actually being transmitted +signal sub_bytes_loaded : std_logic_vector(31 downto 0); -- amount of bytes of actual subevent sent +signal actual_packet_size : std_logic_vector(15 downto 0); -- actual size of whole udp packet +signal size_left : std_logic_vector(31 downto 0); +signal fc_ip_size : std_logic_vector(15 downto 0); +signal fc_udp_size : std_logic_vector(15 downto 0); +signal max_frame_size : std_logic_vector(15 downto 0); +signal divide_position : std_logic_vector(1 downto 0); -- 00->data, 01->sub, 11->term +signal debug : std_logic_vector(63 downto 0); +signal pc_ready : std_logic; + +signal pc_sub_size : std_logic_vector(31 downto 0); +signal pc_trig_nr : std_logic_vector(31 downto 0); +signal rst_after_sub_comb : std_logic; -- gk 08.04.10 +signal rst_after_sub : std_logic; -- gk 08.04.10 +signal load_int_ctr : integer range 0 to 3; -- gk 08.04.10 +signal delay_ctr : std_logic_vector(31 downto 0); -- gk 28.04.10 +signal ticks_ctr : std_logic_vector(7 downto 0); -- gk 28.04.10 + +-- gk 26.07.10 +signal load_eod : std_logic; +signal load_eod_q : std_logic; + +-- gk 07.10.10 +signal df_eod : std_logic; + +-- gk 04.12.10 +signal first_sub_in_multi : std_logic; +signal from_divide_state : std_logic; +signal disable_prep : std_logic; + +begin + + +--PC_TRANSMIT_ON_OUT <= '1' when constructCurrentState = WAIT_FOR_LOAD else '0'; +PC_TRANSMIT_ON_OUT <= '0'; + +-- my_int_ctr <= (3 - to_integer(to_unsigned(sub_int_ctr, 2))); -- reverse byte order +-- load_int_ctr <= (3 - to_integer(to_unsigned(all_int_ctr, 2))); -- gk 08.04.10 +-- +-- all_ctr <= std_logic_vector(to_unsigned(all_int_ctr, all_ctr'length)); -- for debugging +-- sub_ctr <= std_logic_vector(to_unsigned(sub_int_ctr, sub_ctr'length)); -- for debugging +-- my_ctr <= std_logic_vector(to_unsigned(my_int_ctr, my_ctr'length)); -- for debugging +-- +-- max_frame_size <= PC_MAX_FRAME_SIZE_IN; +-- +-- -- Ready signal for PacketConstructor +-- pc_ready <= '1' when (constructCurrentState = CIDLE) and (df_empty = '1') else '0'; +pc_ready <= '0'; + +-- store event information on Start_of_Subevent +-- THE_EVT_INFO_STORE_PROC: process( CLK ) +-- begin +-- if( rising_edge(CLK) ) then +-- if (RESET = '1') then -- gk 31.05.10 +-- pc_sub_size <= (others => '0'); +-- pc_trig_nr <= (others => '0'); +-- elsif( PC_START_OF_SUB_IN = '1' ) then +-- pc_sub_size <= PC_SUB_SIZE_IN; +-- pc_trig_nr <= PC_TRIG_NR_IN; +-- end if; +-- end if; +-- end process; +-- +-- -- gk 07.10.10 +-- df_eod <= '1' when ((MULT_EVT_ENABLE_IN = '0') and (PC_END_OF_DATA_IN = '1')) +-- or ((MULT_EVT_ENABLE_IN = '1') and (PC_END_OF_SUB_IN = '1')) +-- else '0'; + +-- Data FIFO for incoming packet data from IPU buffer +-- gk 26.07.10 +-- DATA_FIFO : fifo_64kx9 +-- port map( +-- Data(7 downto 0) => PC_DATA_IN, +-- Data(8) => df_eod, --PC_END_OF_DATA_IN, -- gk 07.10.10 +-- WrClock => CLK, +-- RdClock => CLK, +-- WrEn => df_wr_en, +-- RdEn => df_rd_en, +-- Reset => RESET, +-- RPReset => RESET, +-- Q(7 downto 0) => df_q, +-- Q(8) => load_eod, +-- Empty => df_empty, +-- Full => df_full +-- ); + +-- LOAD_EOD_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- load_eod_q <= '0'; +-- else +-- load_eod_q <= load_eod; +-- end if; +-- end if; +-- end process LOAD_EOD_PROC; +-- +-- -- Write enable for the data FIFO +-- -- !!!combinatorial signal!!! +-- -- could be avoided as IPU2GBE does only send data in case of PC_READY. +-- df_wr_en <= '1' when ((PC_WR_EN_IN = '1') and (constructCurrentState /= WAIT_FOR_LOAD)) +-- else '0'; +-- +-- -- Output register for data FIFO +-- dfQProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- df_q_reg <= df_q; +-- end if; +-- end process dfQProc; +-- +-- -- Construction state machine +-- constructMachineProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- constructCurrentState <= CIDLE; +-- else +-- constructCurrentState <= constructNextState; +-- end if; +-- end if; +-- end process constructMachineProc; +-- +-- constructMachine : process(constructCurrentState, PC_START_OF_SUB_IN, PC_WR_EN_IN, PC_END_OF_DATA_IN, loadCurrentState, saveSubCurrentState, sub_int_ctr) +-- begin +-- case constructCurrentState is +-- when CIDLE => +-- constr_state <= x"0"; +-- --if( PC_WR_EN_IN = '1' ) then +-- -- gk 04.12.10 +-- if (PC_START_OF_SUB_IN = '1') then +-- +-- constructNextState <= SAVE_DATA; +-- else +-- constructNextState <= CIDLE; +-- end if; +-- when SAVE_DATA => +-- constr_state <= x"1"; +-- if( PC_END_OF_DATA_IN = '1' ) then +-- constructNextState <= WAIT_FOR_LOAD; +-- else +-- constructNextState <= SAVE_DATA; +-- end if; +-- when WAIT_FOR_LOAD => +-- constr_state <= x"2"; +-- if( (df_empty = '1') and (loadCurrentState = LIDLE) ) then -- waits until the whole packet is transmitted +-- constructNextState <= CIDLE; +-- else +-- constructNextState <= WAIT_FOR_LOAD; +-- end if; +-- when others => +-- constr_state <= x"f"; +-- constructNextState <= CIDLE; +-- end case; +-- end process constructMachine; + +--*********************** +-- SIZE COUNTERS FOR SAVING SIDE +--*********************** + +-- gk 29.03.10 the subevent size saved to its headers cannot contain padding bytes but they are included in pc_sub_size +-- that's why they are removed if pc_padding flag is asserted +-- sub_size_to_save <= (x"10" + pc_sub_size) when (PC_PADDING_IN = '0') +-- else (x"c" + pc_sub_size); -- subevent headers + data +-- +-- -- BUG HERE BUG HERE BUG HERE BUG HERE +-- -- gk 29.03.10 no changes here because the queue size should contain the padding bytes of subevents +-- queueSizeProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- --if (RESET = '1') or (loadCurrentState = PUT_Q_DEC) then -- gk 07.10.10 -- (loadCurrentState = CLEANUP) then +-- if (RESET = '1') or (loadCurrentState = CLEANUP) then +-- queue_size <= x"00000028"; -- + 8B for queue headers and 32B for termination +-- elsif (saveSubCurrentState = SAVE_SIZE) and (sub_int_ctr = 3) then +-- queue_size <= queue_size + pc_sub_size + x"10"; -- + 16B for each subevent headers +-- end if; +-- end if; +-- end process queueSizeProc; + + +--*********************** +-- LOAD DATA COMBINED WITH HEADERS INTO FC, QUEUE TRANSMISSION +--*********************** + +-- loadMachineProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- loadCurrentState <= LIDLE; +-- else +-- loadCurrentState <= loadNextState; +-- end if; +-- end if; +-- end process loadMachineProc; +-- +-- loadMachine : process(loadCurrentState, constructCurrentState, all_int_ctr, df_empty, +-- sub_bytes_loaded, sub_size_loaded, size_left, TC_H_READY_IN, +-- max_frame_size, bytes_loaded, divide_position, PC_DELAY_IN, +-- delay_ctr, load_eod_q, MULT_EVT_ENABLE_IN) +-- begin +-- case loadCurrentState is +-- when LIDLE => +-- load_state <= x"0"; +-- if ((constructCurrentState = WAIT_FOR_LOAD) and (df_empty = '0')) then +-- loadNextState <= WAIT_FOR_FC; +-- else +-- loadNextState <= LIDLE; +-- end if; +-- when WAIT_FOR_FC => +-- load_state <= x"1"; +-- if (TC_H_READY_IN = '1') then +-- loadNextState <= PUT_Q_LEN; +-- else +-- loadNextState <= WAIT_FOR_FC; +-- end if; +-- when PUT_Q_LEN => +-- load_state <= x"2"; +-- if (all_int_ctr = 3) then +-- loadNextState <= PUT_Q_DEC; +-- else +-- loadNextState <= PUT_Q_LEN; +-- end if; +-- when PUT_Q_DEC => +-- load_state <= x"3"; +-- if (all_int_ctr = 3) then +-- loadNextState <= LOAD_SUB; +-- else +-- loadNextState <= PUT_Q_DEC; +-- end if; +-- when LOAD_SUB => +-- load_state <= x"4"; +-- if (bytes_loaded = max_frame_size - 1) then +-- loadNextState <= DIVIDE; +-- elsif (all_int_ctr = 15) then +-- loadNextState <= PREP_DATA; +-- else +-- loadNextState <= LOAD_SUB; +-- end if; +-- when PREP_DATA => +-- load_state <= x"5"; +-- loadNextState <= LOAD_DATA; +-- when LOAD_DATA => +-- load_state <= x"6"; +-- -- if (bytes_loaded = max_frame_size - 1) then +-- -- loadNextState <= DIVIDE; +-- -- -- gk 07.10.10 +-- -- elsif (MULT_EVT_ENABLE_IN = '1') then +-- -- if (size_left = x"0000_0023") then +-- -- loadNextState <= LOAD_TERM; +-- -- elsif (load_eod_q = '1') then +-- -- loadNextState <= LOAD_SUB; +-- -- else +-- -- loadNextState <= LOAD_DATA; +-- -- end if; +-- -- else +-- -- if (load_eod_q = '1') then +-- -- loadNextState <= LOAD_TERM; +-- -- else +-- -- loadNextState <= LOAD_DATA; +-- -- end if; +-- -- end if; +-- if (bytes_loaded = max_frame_size - 1) then +-- loadNextState <= DIVIDE; +-- -- gk 07.10.10 +-- elsif (load_eod_q = '1') then +-- if (MULT_EVT_ENABLE_IN = '1') then +-- if (size_left < x"0000_0030") then +-- loadNextState <= LOAD_TERM; +-- else +-- loadNextState <= LOAD_SUB; +-- end if; +-- else +-- loadNextState <= LOAD_TERM; +-- end if; +-- else +-- loadNextState <= LOAD_DATA; +-- end if; +-- when DIVIDE => +-- load_state <= x"7"; +-- if (TC_H_READY_IN = '1') then +-- if (divide_position = "00") then +-- loadNextState <= PREP_DATA; +-- elsif (divide_position = "01") then +-- loadNextState <= LOAD_SUB; +-- else +-- loadNextState <= LOAD_TERM; +-- end if; +-- else +-- loadNextState <= DIVIDE; +-- end if; +-- when LOAD_TERM => +-- load_state <= x"8"; +-- if (bytes_loaded = max_frame_size - 1) and (all_int_ctr /= 31) then +-- loadNextState <= DIVIDE; +-- elsif (all_int_ctr = 31) then +-- loadNextState <= CLEANUP; +-- else +-- loadNextState <= LOAD_TERM; +-- end if; +-- -- gk 28.04.10 +-- when CLEANUP => +-- load_state <= x"9"; +-- if (PC_DELAY_IN = x"0000_0000") then +-- loadNextState <= LIDLE; +-- else +-- loadNextState <= DELAY; +-- end if; +-- -- gk 28.04.10 +-- when DELAY => +-- load_state <= x"a"; +-- if (delay_ctr = x"0000_0000") then +-- loadNextState <= LIDLE; +-- else +-- loadNextState <= DELAY; +-- end if; +-- when others => +-- load_state <= x"f"; +-- loadNextState <= LIDLE; +-- end case; +-- end process loadMachine; +-- +-- -- gk 04.12.10 +-- firstSubInMultiProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = LOAD_TERM) then +-- first_sub_in_multi <= '1'; +-- elsif (loadCurrentState = LOAD_DATA) then +-- first_sub_in_multi <= '0'; +-- end if; +-- end if; +-- end process; +-- +-- -- gk 04.12.10 +-- fromDivideStateProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- from_divide_state <= '0'; +-- elsif (loadCurrentState = DIVIDE) then +-- from_divide_state <= '1'; +-- elsif (loadCurrentState = PREP_DATA) then +-- from_divide_state <= '0'; +-- end if; +-- end if; +-- end process fromDivideStateProc; +-- +-- +-- dividePositionProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- divide_position <= "00"; +-- -- elsif (bytes_loaded = max_frame_size - 1) then +-- -- if (loadCurrentState = LIDLE) then +-- -- divide_position <= "00"; +-- -- elsif (loadCurrentState = LOAD_DATA) then +-- -- -- gk 07.10.10 +-- -- if (MULT_EVT_ENABLE_IN = '1') and (size_left = x"0000_003a") then +-- -- divide_position <= "11"; +-- -- -- gk 07.10.10 +-- -- elsif (MULT_EVT_ENABLE_IN = '1') and (load_eod_q = '1') then +-- -- divide_position <= "01"; +-- -- -- gk 26.07.10 +-- -- elsif (MULT_EVT_ENABLE_IN = '0') and (load_eod_q = '1') then -- if termination is about to be loaded divide on term +-- -- divide_position <= "11"; +-- -- else +-- -- divide_position <= "00"; -- still data loaded divide on data +-- -- end if; +-- -- elsif (loadCurrentState = LOAD_SUB) then +-- -- if (all_int_ctr = 15) then +-- -- divide_position <= "00"; +-- -- else +-- -- divide_position <= "01"; +-- -- end if; +-- -- elsif (loadCurrentState = LOAD_TERM) then +-- -- divide_position <= "11"; +-- -- end if; +-- -- end if; +-- elsif (bytes_loaded = max_frame_size - 1) then +-- if (loadCurrentState = LIDLE) then +-- divide_position <= "00"; +-- disable_prep <= '0'; -- gk 05.12.10 +-- elsif (loadCurrentState = LOAD_DATA) then +-- -- gk 05.12.10 +-- -- gk 26.07.10 +-- if (MULT_EVT_ENABLE_IN = '0') and (load_eod_q = '1') then -- if termination is about to be loaded divide on term +-- divide_position <= "11"; +-- disable_prep <= '0'; -- gk 05.12.10 +-- elsif (MULT_EVT_ENABLE_IN = '1') and (load_eod_q = '1') then +-- if (size_left > x"0000_0028") then +-- divide_position <= "01"; +-- disable_prep <= '0'; -- gk 05.12.10 +-- else +-- divide_position <= "11"; +-- disable_prep <= '0'; -- gk 05.12.10 +-- end if; +-- else +-- divide_position <= "00"; -- still data loaded divide on data +-- disable_prep <= '1'; -- gk 05.12.10 +-- end if; +-- elsif (loadCurrentState = LOAD_SUB) then +-- if (all_int_ctr = 15) then +-- divide_position <= "00"; +-- disable_prep <= '1'; -- gk 05.12.10 +-- else +-- divide_position <= "01"; +-- disable_prep <= '0'; -- gk 05.12.10 +-- end if; +-- elsif (loadCurrentState = LOAD_TERM) then +-- divide_position <= "11"; +-- disable_prep <= '0'; -- gk 05.12.10 +-- end if; +-- elsif (loadCurrentState = PREP_DATA) then -- gk 06.12.10 reset disable_prep +-- disable_prep <= '0'; +-- end if; +-- +-- end if; +-- end process dividePositionProc; +-- +-- allIntCtrProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then -- gk 31.05.10 +-- all_int_ctr <= 0; +-- else +-- case loadCurrentState is +-- +-- when LIDLE => all_int_ctr <= 0; +-- +-- when WAIT_FOR_FC => all_int_ctr <= 0; +-- +-- when PUT_Q_LEN => +-- if (all_int_ctr = 3) then +-- all_int_ctr <= 0; +-- else +-- all_int_ctr <= all_int_ctr + 1; +-- end if; +-- +-- when PUT_Q_DEC => +-- if (all_int_ctr = 3) then +-- all_int_ctr <= 0; +-- else +-- all_int_ctr <= all_int_ctr + 1; +-- end if; +-- +-- when LOAD_SUB => +-- if (all_int_ctr = 15) then +-- all_int_ctr <= 0; +-- else +-- all_int_ctr <= all_int_ctr + 1; +-- end if; +-- +-- when LOAD_DATA => all_int_ctr <= 0; +-- +-- when LOAD_TERM => +-- if (all_int_ctr = 31) then +-- all_int_ctr <= 0; +-- else +-- all_int_ctr <= all_int_ctr + 1; +-- end if; +-- +-- when DIVIDE => null; +-- +-- when CLEANUP => all_int_ctr <= 0; +-- +-- when PREP_DATA => all_int_ctr <= 0; +-- +-- when DELAY => all_int_ctr <= 0; +-- end case; +-- end if; +-- end if; +-- end process allIntCtrProc; +-- +-- dfRdEnProc : process(loadCurrentState, bytes_loaded, max_frame_size, sub_bytes_loaded, +-- sub_size_loaded, all_int_ctr, RESET, size_left, load_eod_q) +-- begin +-- if (RESET = '1') then +-- df_rd_en <= '0'; +-- elsif (loadCurrentState = LOAD_DATA) then +-- -- if (bytes_loaded = max_frame_size - x"1") then +-- -- df_rd_en <= '0'; +-- -- -- gk 07.10.10 +-- -- elsif (MULT_EVT_ENABLE_IN = '0') and (load_eod_q = '1') then +-- -- df_rd_en <= '0'; +-- -- -- gk 07.10.10 +-- -- elsif (MULT_EVT_ENABLE_IN = '1') and (size_left = x"0000_003a") then +-- -- df_rd_en <= '0'; +-- -- else +-- -- df_rd_en <= '1'; +-- -- end if; +-- if (bytes_loaded = max_frame_size - x"1") then +-- df_rd_en <= '0'; +-- -- gk 26.07.10 +-- --elsif (load_eod = '1') or (load_eod_q = '1') then +-- elsif (load_eod_q = '1') then +-- df_rd_en <= '0'; +-- -- elsif (sub_bytes_loaded = sub_size_loaded) then +-- -- df_rd_en <= '0'; +-- else +-- df_rd_en <= '1'; +-- end if; +-- +-- elsif (loadCurrentState = LOAD_SUB) and (all_int_ctr = 15) and (bytes_loaded /= max_frame_size - x"1") then +-- df_rd_en <= '1'; +-- elsif (loadCurrentState = PREP_DATA) then +-- df_rd_en <= '1'; +-- else +-- df_rd_en <= '0'; +-- end if; +-- end process dfRdEnProc; +-- +-- shfRdEnProc : process(loadCurrentState, all_int_ctr, RESET) +-- begin +-- if (RESET = '1') then -- gk 31.05.10 +-- shf_rd_en <= '0'; +-- elsif (loadCurrentState = LOAD_SUB) then +-- shf_rd_en <= '1'; +-- elsif (loadCurrentState = LOAD_TERM) and (all_int_ctr < 31) then +-- shf_rd_en <= '1'; +-- elsif (loadCurrentState = PUT_Q_DEC) and (all_int_ctr = 3) then +-- shf_rd_en <= '1'; +-- else +-- shf_rd_en <= '0'; +-- end if; +-- end process shfRdEnProc; +-- +-- +-- -- fcWrEnProc : process(loadCurrentState, RESET) +-- -- begin +-- -- if (RESET = '1') then -- gk 31.05.10 +-- -- fc_wr_en <= '0'; +-- -- elsif (loadCurrentState = PUT_Q_LEN) or (loadCurrentState = PUT_Q_DEC) then +-- -- fc_wr_en <= '1'; +-- -- elsif (loadCurrentState = LOAD_SUB) or (loadCurrentState = LOAD_DATA) or (loadCurrentState = LOAD_TERM) then +-- -- fc_wr_en <= '1'; +-- -- else +-- -- fc_wr_en <= '0'; +-- -- end if; +-- -- end process fcWrEnProc; +-- fcWrEnProc : process(loadCurrentState, RESET, first_sub_in_multi, from_divide_state, MULT_EVT_ENABLE_IN, divide_position, disable_prep) +-- begin +-- if (RESET = '1') then -- gk 31.05.10 +-- fc_wr_en <= '0'; +-- elsif (loadCurrentState = PUT_Q_LEN) or (loadCurrentState = PUT_Q_DEC) then +-- fc_wr_en <= '1'; +-- elsif (loadCurrentState = LOAD_SUB) or (loadCurrentState = LOAD_DATA) or (loadCurrentState = LOAD_TERM) then +-- fc_wr_en <= '1'; +-- -- gk 04.12.10 +-- elsif (MULT_EVT_ENABLE_IN = '1') and (loadCurrentState = PREP_DATA) and (first_sub_in_multi = '0') and (from_divide_state = '0') and (disable_prep = '0') then +-- fc_wr_en <= '1'; +-- elsif (MULT_EVT_ENABLE_IN = '1') and (loadCurrentState = PREP_DATA) and (from_divide_state = '1') and ((divide_position = "00") or (divide_position = "01")) and (disable_prep = '0') then +-- fc_wr_en <= '1'; +-- else +-- fc_wr_en <= '0'; +-- end if; +-- end process fcWrEnProc; +-- +-- +-- -- was all_int_ctr +-- fcDataProc : process(loadCurrentState, queue_size_temp, PC_QUEUE_DEC_IN, shf_q, df_q_reg, load_int_ctr) +-- begin +-- case loadCurrentState is +-- when LIDLE => fc_data <= x"af"; +-- when WAIT_FOR_FC => fc_data <= x"bf"; +-- -- gk 08.04.10 my_int_ctr changed to load_int_ctr +-- when PUT_Q_LEN => fc_data <= queue_size_temp(load_int_ctr * 8 + 7 downto load_int_ctr * 8); +-- when PUT_Q_DEC => fc_data <= PC_QUEUE_DEC_IN(load_int_ctr * 8 + 7 downto load_int_ctr * 8); +-- when LOAD_SUB => fc_data <= shf_q; +-- when PREP_DATA => fc_data <= df_q_reg; +-- when LOAD_DATA => fc_data <= df_q_reg; +-- when LOAD_TERM => fc_data <= shf_q; +-- when DIVIDE => fc_data <= x"cf"; +-- when CLEANUP => fc_data <= x"df"; +-- when others => fc_data <= x"00"; +-- end case; +-- end process fcDataProc; +-- +-- -- delay counters +-- -- gk 28.04.10 +-- DELAY_CTR_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if ((RESET = '1') or (loadCurrentState = LIDLE)) then +-- delay_ctr <= PC_DELAY_IN; +-- elsif ((loadCurrentState = DELAY) and (ticks_ctr(7) = '1')) then +-- delay_ctr <= delay_ctr - x"1"; +-- end if; +-- end if; +-- end process DELAY_CTR_PROC; +-- +-- -- gk 28.04.10 +-- TICKS_CTR_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if ((RESET = '1') or (loadCurrentState = LIDLE) or (ticks_ctr(7) = '1')) then +-- ticks_ctr <= x"00"; +-- elsif (loadCurrentState = DELAY) then +-- ticks_ctr <= ticks_ctr + x"1"; +-- end if; +-- end if; +-- end process TICKS_CTR_PROC; + + +--*********************** +-- SIZE COUNTERS FOR LOADING SIDE +--*********************** + +-- queue_size_temp <= queue_size - x"20"; -- size of data without termination +-- +-- -- gk 08.04.10 +-- rst_after_sub_comb <= '1' when (loadCurrentState = LIDLE) or +-- ((loadCurrentState = LOAD_DATA) and (size_left /= x"00000021")) -- gk 26.07.10 -- and (sub_bytes_loaded = sub_size_loaded) +-- else '0'; +-- +-- -- gk 08.04.10 +-- RST_AFTER_SUB_PROC : process(CLK) +-- begin +-- if(rising_edge(CLK)) then +-- if(RESET = '1') then +-- rst_after_sub <= '0'; +-- else +-- rst_after_sub <= rst_after_sub_comb; +-- end if; +-- end if; +-- end process RST_AFTER_SUB_PROC; +-- +-- -- counts all bytes loaded to divide data into frames +-- bytesLoadedProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = DIVIDE) or (loadCurrentState = CLEANUP) then +-- bytes_loaded <= x"0000"; +-- elsif (loadCurrentState = PUT_Q_LEN) or (loadCurrentState = PUT_Q_DEC) or (loadCurrentState = LOAD_DATA) or (loadCurrentState = LOAD_SUB) or (loadCurrentState = LOAD_TERM) then +-- bytes_loaded <= bytes_loaded + x"1"; +-- -- gk 05.12.10 +-- -- elsif (MULT_EVT_ENABLE_IN = '1') and (loadCurrentState = PREP_DATA) and (first_sub_in_multi = '0') and (from_divide_state = '0') then +-- -- bytes_loaded <= bytes_loaded + x"1"; +-- elsif (MULT_EVT_ENABLE_IN = '1') and (loadCurrentState = PREP_DATA) and (first_sub_in_multi = '0') and (from_divide_state = '0') and (disable_prep = '0') then +-- bytes_loaded <= bytes_loaded + x"1"; +-- elsif (MULT_EVT_ENABLE_IN = '1') and (loadCurrentState = PREP_DATA) and (from_divide_state = '1') and ((divide_position = "00") or (divide_position = "01")) and (disable_prep = '0') then +-- bytes_loaded <= bytes_loaded + x"1"; +-- end if; +-- end if; +-- end process bytesLoadedProc; +-- +-- -- size of subevent loaded from memory +-- subSizeLoadedProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) or (rst_after_sub = '1') then -- gk 08.04.10 +-- sub_size_loaded <= x"00000000"; +-- elsif (loadCurrentState = LOAD_SUB) and (all_int_ctr < 4) then +-- -- was all_int_ctr +-- -- gk 08.04.10 my_int_ctr changed to load_int_ctr +-- sub_size_loaded(7 + load_int_ctr * 8 downto load_int_ctr * 8) <= shf_q; +-- -- gk 29.03.10 here the padding bytes have to be added to the loadedSize in order to load the correct amount of bytes from fifo +-- elsif (loadCurrentState = LOAD_SUB) and (all_int_ctr = 5) and (sub_size_loaded(2) = '1') then +-- sub_size_loaded <= sub_size_loaded + x"4"; +-- end if; +-- end if; +-- end process subSizeLoadedProc; +-- +-- -- counts only raw data bytes being loaded +-- subBytesLoadedProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) or (rst_after_sub = '1') then -- gk 26.07.10 --or (sub_bytes_loaded = sub_size_loaded) -- gk 08.04.10 +-- sub_bytes_loaded <= x"00000011"; -- subevent headers doesnt count +-- elsif (loadCurrentState = LOAD_DATA) then +-- sub_bytes_loaded <= sub_bytes_loaded + x"1"; +-- end if; +-- end if; +-- end process subBytesLoadedProc; +-- +-- -- counts the size of the large udp packet +-- actualPacketProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) then +-- actual_packet_size <= x"0008"; +-- elsif (fc_wr_en = '1') then +-- actual_packet_size <= actual_packet_size + x"1"; +-- end if; +-- end if; +-- end process actualPacketProc; +-- +-- actualQueueSizeProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = CLEANUP) then +-- actual_queue_size <= (others => '0'); +-- elsif (loadCurrentState = LIDLE) then +-- actual_queue_size <= queue_size; +-- end if; +-- end if; +-- end process actualQueueSizeProc; +-- +-- -- amount of bytes left to send in current packet +-- sizeLeftProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = CLEANUP) then +-- size_left <= (others => '0'); +-- elsif (loadCurrentState = LIDLE) then +-- size_left <= queue_size; +-- elsif (fc_wr_en = '1') then +-- size_left <= size_left - 1; +-- end if; +-- end if; +-- end process sizeLeftProc; +-- +-- -- HOT FIX: don't rely on CTS information, count the packets on your own. +-- -- In this case, we increment the fragmented packet ID with EOD from ipu2gbe. +-- THE_FC_IDENT_COUNTER_PROC: process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- fc_ident <= (others => '0'); +-- elsif (PC_END_OF_DATA_IN = '1') then +-- fc_ident <= fc_ident + 1; +-- end if; +-- end if; +-- end process THE_FC_IDENT_COUNTER_PROC; +-- +-- fc_flags_offset(15 downto 14) <= "00"; +-- +-- moreFragmentsProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) then +-- fc_flags_offset(13) <= '0'; +-- elsif ((loadCurrentState = DIVIDE) and (TC_READY_IN = '1')) or ((loadCurrentState = WAIT_FOR_FC) and (TC_READY_IN = '1')) then +-- if ((actual_queue_size - actual_packet_size) < max_frame_size) then +-- fc_flags_offset(13) <= '0'; -- no more fragments +-- else +-- fc_flags_offset(13) <= '1'; -- more fragments +-- end if; +-- end if; +-- end if; +-- end process moreFragmentsProc; +-- +-- eodProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- fc_eod <= '0'; +-- elsif (loadCurrentState = LOAD_DATA) and (bytes_loaded = max_frame_size - 2) then +-- fc_eod <= '1'; +-- elsif (loadCurrentState = LOAD_SUB) and (bytes_loaded = max_frame_size - 2) then +-- fc_eod <= '1'; +-- elsif (loadCurrentState = LOAD_TERM) and ((bytes_loaded = max_frame_size - 2) or (all_int_ctr = 30)) then +-- fc_eod <= '1'; +-- else +-- fc_eod <= '0'; +-- end if; +-- end if; +-- end process eodProc; +-- +-- sodProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- fc_sod <= '0'; +-- elsif (loadCurrentState = WAIT_FOR_FC) and (TC_READY_IN = '1') then +-- fc_sod <= '1'; +-- elsif (loadCurrentState = DIVIDE) and (TC_READY_IN = '1') then +-- fc_sod <= '1'; +-- else +-- fc_sod <= '0'; +-- end if; +-- end if; +-- end process sodProc; +-- +-- offsetProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) then +-- fc_flags_offset(12 downto 0) <= (others => '0'); +-- elsif ((loadCurrentState = DIVIDE) and (TC_READY_IN = '1')) then +-- fc_flags_offset(12 downto 0) <= actual_packet_size(15 downto 3); +-- end if; +-- end if; +-- end process offsetProc; +-- +-- fcIPSizeProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET= '1') then +-- fc_ip_size <= (others => '0'); +-- elsif ((loadCurrentState = DIVIDE) and (TC_READY_IN = '1')) or ((loadCurrentState = WAIT_FOR_FC) and (TC_READY_IN = '1')) then +-- if (size_left >= max_frame_size) then +-- fc_ip_size <= max_frame_size; +-- else +-- fc_ip_size <= size_left(15 downto 0); +-- end if; +-- end if; +-- end if; +-- end process fcIPSizeProc; +-- +-- fcUDPSizeProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- fc_udp_size <= (others => '0'); +-- elsif (loadCurrentState = WAIT_FOR_FC) and (TC_READY_IN = '1') then +-- fc_udp_size <= queue_size(15 downto 0); +-- end if; +-- end if; +-- end process fcUDPSizeProc; + + +--*********************** +-- SUBEVENT HEADERS WRITE AND READ +--*********************** + +-- SUBEVENT_HEADERS_FIFO : fifo_16kx8 +-- port map( +-- Data => shf_data, +-- WrClock => CLK, +-- RdClock => CLK, +-- WrEn => shf_wr_en, +-- RdEn => shf_rd_en, +-- Reset => RESET, +-- RPReset => RESET, +-- Q => shf_q, +-- Empty => shf_empty, +-- Full => shf_full +-- ); +-- +-- -- write enable for SHF +-- shf_wr_en <= '1' when ((saveSubCurrentState /= SIDLE) and (loadCurrentState /= PREP_DATA)) +-- else '0'; +-- +-- -- data multiplexing for SHF (convert 32bit LWs to 8bit) +-- -- CHANGED. +-- -- The SubEventHeader (4x 32bit is stored in [MSB:LSB] now, same byte order as data from PC. +-- shfDataProc : process(saveSubCurrentState, sub_size_to_save, PC_DECODING_IN, PC_EVENT_ID_IN, +-- pc_trig_nr, my_int_ctr, fc_data) +-- begin +-- case saveSubCurrentState is +-- when SIDLE => shf_data <= x"ac"; +-- when SAVE_SIZE => shf_data <= sub_size_to_save(my_int_ctr * 8 + 7 downto my_int_ctr * 8); +-- when SAVE_DECODING => shf_data <= PC_DECODING_IN(my_int_ctr * 8 + 7 downto my_int_ctr * 8); +-- when SAVE_ID => shf_data <= PC_EVENT_ID_IN(my_int_ctr * 8 + 7 downto my_int_ctr * 8); +-- when SAVE_TRIG_NR => shf_data <= pc_trig_nr(my_int_ctr * 8 + 7 downto my_int_ctr * 8); +-- when SAVE_TERM => shf_data <= fc_data; +-- when others => shf_data <= x"00"; +-- end case; +-- end process shfDataProc; +-- +-- saveSubMachineProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- saveSubCurrentState <= SIDLE; +-- else +-- saveSubCurrentState <= saveSubNextState; +-- end if; +-- end if; +-- end process saveSubMachineProc; +-- +-- saveSubMachine : process(saveSubCurrentState, PC_START_OF_SUB_IN, sub_int_ctr, loadCurrentState, TC_H_READY_IN) +-- begin +-- case saveSubCurrentState is +-- when SIDLE => +-- save_state <= x"0"; +-- if (PC_START_OF_SUB_IN = '1') then +-- saveSubNextState <= SAVE_SIZE; +-- -- this branch is dangerous! +-- elsif (loadCurrentState = WAIT_FOR_FC) and (TC_H_READY_IN = '1') then -- means that loadCurrentState is put_q_len +-- saveSubNextState <= SAVE_TERM; +-- else +-- saveSubNextState <= SIDLE; +-- end if; +-- when SAVE_SIZE => +-- save_state <= x"1"; +-- if (sub_int_ctr = 3) then +-- saveSubNextState <= SAVE_DECODING; +-- else +-- saveSubNextState <= SAVE_SIZE; +-- end if; +-- when SAVE_DECODING => +-- save_state <= x"2"; +-- if (sub_int_ctr = 3) then +-- saveSubNextState <= SAVE_ID; +-- else +-- saveSubNextState <= SAVE_DECODING; +-- end if; +-- when SAVE_ID => +-- save_state <= x"3"; +-- if (sub_int_ctr = 3) then +-- saveSubNextState <= SAVE_TRIG_NR; +-- else +-- saveSubNextState <= SAVE_ID; +-- end if; +-- when SAVE_TRIG_NR => +-- save_state <= x"4"; +-- if (sub_int_ctr = 3) then +-- saveSubNextState <= SIDLE; +-- else +-- saveSubNextState <= SAVE_TRIG_NR; +-- end if; +-- when SAVE_TERM => +-- save_state <= x"5"; +-- if (sub_int_ctr = 31) then +-- saveSubNextState <= SIDLE; +-- else +-- saveSubNextState <= SAVE_TERM; +-- end if; +-- when others => +-- save_state <= x"f"; +-- saveSubNextState <= SIDLE; +-- end case; +-- end process; +-- +-- -- This counter is used for breaking down 32bit information words into 8bit bytes for +-- -- storing them in the SHF. +-- -- It is also used for the termination 32byte sequence. +-- subIntProc: process( CLK ) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (saveSubCurrentState = SIDLE) then +-- sub_int_ctr <= 0; +-- elsif (sub_int_ctr = 3) and (saveSubCurrentState /= SAVE_TERM) then +-- sub_int_ctr <= 0; +-- elsif (sub_int_ctr = 31) and (saveSubCurrentState = SAVE_TERM) then +-- sub_int_ctr <= 0; +-- elsif (saveSubCurrentState /= SIDLE) and (loadCurrentState /= PREP_DATA) then +-- sub_int_ctr <= sub_int_ctr + 1; +-- end if; +-- end if; +-- end process subIntProc; +-- +-- debug(3 downto 0) <= constr_state; +-- debug(7 downto 4) <= save_state; +-- debug(11 downto 8) <= load_state; +-- debug(27 downto 12) <= queue_size(15 downto 0); +-- debug(28) <= df_full; +-- debug(29) <= df_empty; +-- debug(30) <= shf_full; +-- debug(31) <= shf_empty; +-- +-- debug(47 downto 32) <= size_left(15 downto 0); +-- debug(52 downto 48) <= all_ctr; +-- debug(53) <= pc_ready; + +-- outputs +-- PC_READY_OUT <= pc_ready; +-- TC_WR_EN_OUT <= fc_wr_en; +-- TC_DATA_OUT <= fc_data; +-- TC_IP_SIZE_OUT <= fc_ip_size; +-- TC_UDP_SIZE_OUT <= fc_udp_size; +-- -- FC_IDENT_OUT(15 downto 8) <= fc_ident(7 downto 0); +-- -- FC_IDENT_OUT(7 downto 0) <= fc_ident(15 downto 8); +-- TC_FLAGS_OFFSET_OUT <= fc_flags_offset; +-- TC_SOD_OUT <= fc_sod; +-- TC_EOD_OUT <= fc_eod; + +PC_READY_OUT <= '1'; +TC_IP_SIZE_OUT <= (others => '0'); +TC_UDP_SIZE_OUT <= (others => '0'); +-- FC_IDENT_OUT(15 downto 8) <= fc_ident(7 downto 0); +-- FC_IDENT_OUT(7 downto 0) <= fc_ident(15 downto 8); +-- TC_FLAGS_OFFSET_OUT <= fc_flags_offset; +-- TC_SOD_OUT <= fc_sod; +-- TC_EOD_OUT <= fc_eod; + +DEBUG_OUT <= debug; + +end trb_net16_gbe_packet_constr; \ No newline at end of file diff --git a/gbe2_ecp3/trb_net16_gbe_packet_constr_simple_sender.vhd b/gbe2_ecp3/trb_net16_gbe_packet_constr_simple_sender.vhd new file mode 100644 index 0000000..49cf13e --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_packet_constr_simple_sender.vhd @@ -0,0 +1,1170 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; +use IEEE.std_logic_arith.all; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +entity trb_net16_gbe_packet_constr is +port( + RESET : in std_logic; + CLK : in std_logic; + MULT_EVT_ENABLE_IN : in std_logic; -- gk 06.10.10 + -- ports for user logic + PC_WR_EN_IN : in std_logic; -- write into queueConstr from userLogic + PC_DATA_IN : in std_logic_vector(7 downto 0); + PC_READY_OUT : out std_logic; + PC_START_OF_SUB_IN : in std_logic; -- CHANGED TO SLOW CONTROL PULSE + PC_END_OF_SUB_IN : in std_logic; -- gk 07.10.10 + PC_END_OF_DATA_IN : in std_logic; + PC_TRANSMIT_ON_OUT : out std_logic; + -- queue and subevent layer headers + PC_SUB_SIZE_IN : in std_logic_vector(31 downto 0); -- store and swap + PC_PADDING_IN : in std_logic; -- gk 29.03.10 + PC_DECODING_IN : in std_logic_vector(31 downto 0); -- swap + PC_EVENT_ID_IN : in std_logic_vector(31 downto 0); -- swap + PC_TRIG_NR_IN : in std_logic_vector(31 downto 0); -- store and swap! + PC_QUEUE_DEC_IN : in std_logic_vector(31 downto 0); -- swap + PC_MAX_FRAME_SIZE_IN : in std_logic_vector(15 downto 0); -- DO NOT SWAP + PC_DELAY_IN : in std_logic_vector(31 downto 0); -- gk 28.04.10 + -- FrameConstructor ports + TC_WR_EN_OUT : out std_logic; + TC_DATA_OUT : out std_logic_vector(7 downto 0); + TC_H_READY_IN : in std_logic; + TC_READY_IN : in std_logic; + TC_IP_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_UDP_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FLAGS_OFFSET_OUT : out std_logic_vector(15 downto 0); + TC_SOD_OUT : out std_logic; + TC_EOD_OUT : out std_logic; + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end trb_net16_gbe_packet_constr; + +architecture trb_net16_gbe_packet_constr of trb_net16_gbe_packet_constr is + +-- attribute HGROUP : string; +-- attribute HGROUP of trb_net16_gbe_packet_constr : architecture is "GBE_packet_constr"; + +component fifo_64kx9 +port ( + Data : in std_logic_vector(8 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(8 downto 0); + Empty : out std_logic; + Full : out std_logic +); +end component; + +-- FIFO for SubEventHeader information +component fifo_16kx8 is +port ( + Data : in std_logic_vector(7 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(7 downto 0); + Empty : out std_logic; + Full : out std_logic +); +end component; + +signal df_wr_en : std_logic; +signal df_rd_en : std_logic; +signal df_q : std_logic_vector(7 downto 0); +signal df_q_reg : std_logic_vector(7 downto 0); +signal df_empty : std_logic; +signal df_full : std_logic; + +signal fc_data : std_logic_vector(7 downto 0); +signal fc_wr_en : std_logic; +signal fc_sod : std_logic; +signal fc_eod : std_logic; +signal fc_ident : std_logic_vector(15 downto 0); -- change this to own counter! +signal fc_flags_offset : std_logic_vector(15 downto 0); + +signal shf_data : std_logic_vector(7 downto 0); +signal shf_wr_en : std_logic; +signal shf_rd_en : std_logic; +signal shf_q : std_logic_vector(7 downto 0); +signal shf_empty : std_logic; +signal shf_full : std_logic; + +type constructStates is (CIDLE, SAVE_DATA, WAIT_FOR_LOAD); +signal constructCurrentState, constructNextState : constructStates; +signal constr_state : std_logic_vector(3 downto 0); +signal all_int_ctr : integer range 0 to 31; +signal all_ctr : std_logic_vector(4 downto 0); + +type saveSubStates is (SIDLE, SAVE_SIZE, SAVE_DECODING, SAVE_ID, SAVE_TRIG_NR, SAVE_TERM); +signal saveSubCurrentState, saveSubNextState : saveSubStates; +signal save_state : std_logic_vector(3 downto 0); +signal sub_int_ctr : integer range 0 to 31; +signal sub_ctr : std_logic_vector(4 downto 0); +signal my_int_ctr : integer range 0 to 3; +signal my_ctr : std_logic_vector(1 downto 0); + +type loadStates is (LIDLE, WAIT_FOR_FC, PUT_Q_LEN, PUT_Q_DEC, LOAD_SUB, PREP_DATA, LOAD_DATA, DIVIDE, LOAD_TERM, CLEANUP, DELAY); +signal loadCurrentState, loadNextState: loadStates; +signal load_state : std_logic_vector(3 downto 0); + +signal queue_size : std_logic_vector(31 downto 0); -- sum of all subevents sizes plus their headers and queue headers and termination +signal queue_size_temp : std_logic_vector(31 downto 0); +signal actual_queue_size : std_logic_vector(31 downto 0); -- queue size used during loading process when queue_size is no more valid +signal bytes_loaded : std_logic_vector(15 downto 0); -- size of actual constructing frame +signal sub_size_to_save : std_logic_vector(31 downto 0); -- size of subevent to save to shf +signal sub_size_loaded : std_logic_vector(31 downto 0); -- size of subevent actually being transmitted +signal sub_bytes_loaded : std_logic_vector(31 downto 0); -- amount of bytes of actual subevent sent +signal actual_packet_size : std_logic_vector(15 downto 0); -- actual size of whole udp packet +signal size_left : std_logic_vector(31 downto 0); +signal fc_ip_size : std_logic_vector(15 downto 0); +signal fc_udp_size : std_logic_vector(15 downto 0); +signal max_frame_size : std_logic_vector(15 downto 0); +signal divide_position : std_logic_vector(1 downto 0); -- 00->data, 01->sub, 11->term +signal debug : std_logic_vector(63 downto 0); +signal pc_ready : std_logic; + +signal pc_sub_size : std_logic_vector(31 downto 0); +signal pc_trig_nr : std_logic_vector(31 downto 0); +signal rst_after_sub_comb : std_logic; -- gk 08.04.10 +signal rst_after_sub : std_logic; -- gk 08.04.10 +signal load_int_ctr : integer range 0 to 3; -- gk 08.04.10 +signal delay_ctr : std_logic_vector(31 downto 0); -- gk 28.04.10 +signal ticks_ctr : std_logic_vector(7 downto 0); -- gk 28.04.10 + +-- gk 26.07.10 +signal load_eod : std_logic; +signal load_eod_q : std_logic; + +-- gk 07.10.10 +signal df_eod : std_logic; + +-- gk 04.12.10 +signal first_sub_in_multi : std_logic; +signal from_divide_state : std_logic; +signal disable_prep : std_logic; + +-- gk 02.08.11 +type constructSimpleFrameStates is (IDLE, WAIT_FOR_HEADERS, PUT_DATA, FINISH); +signal constrSimpleFrameCurrentState, constrSimpleFrameNextState : constructSimpleFrameStates; + +signal gen_data_ctr : std_logic_vector(15 downto 0); + +begin + +costrSimpleFrameMachineProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + constrSimpleFrameCurrentState <= IDLE; + else + constrSimpleFrameCurrentState <= constrSimpleFrameNextState; + end if; + end if; +end process costrSimpleFrameMachineProc; + +constrSimpleFrameMachine : process(constrSimpleFrameCurrentState, PC_START_OF_SUB_IN, TC_H_READY_IN, gen_data_ctr, TC_READY_IN) +begin + case constrSimpleFrameCurrentState is + + when IDLE => + if (PC_START_OF_SUB_IN = '1') then + constrSimpleFrameNextState <= WAIT_FOR_HEADERS; + else + constrSimpleFrameNextState <= IDLE; + end if; + + when WAIT_FOR_HEADERS => + if (TC_H_READY_IN = '1') then + constrSimpleFrameNextState <= PUT_DATA; + else + constrSimpleFrameNextState <= WAIT_FOR_HEADERS; + end if; + + when PUT_DATA => + if (gen_data_ctr = x"0100") then + constrSimpleFrameNextState <= FINISH; + else + constrSimpleFrameNextState <= PUT_DATA; + end if; + + when FINISH => + if (TC_READY_IN = '1') then + constrSimpleFrameNextState <= IDLE; + else + constrSimpleFrameNextState <= FINISH; + end if; + + end case; +end process constrSimpleFrameMachine; + +GEN_DATA_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (constrSimpleFrameCurrentState = IDLE) then + gen_data_ctr <= (others => '0'); + elsif (constrSimpleFrameCurrentState = PUT_DATA) then + gen_data_ctr <= gen_data_ctr + x"1"; + end if; + end if; +end process; + +TC_DATA_OUT <= gen_data_ctr(7 downto 0); +TC_WR_EN_OUT <= '1' when constrSimpleFrameCurrentState = PUT_DATA else '0'; +TC_SOD_OUT <= '1' when (constrSimpleFrameCurrentState = IDLE and PC_START_OF_SUB_IN = '1') or (constrSimpleFrameCurrentState = WAIT_FOR_HEADERS and TC_H_READY_IN = '0') else '0'; +TC_EOD_OUT <= '1' when constrSimpleFrameCurrentState = PUT_DATA and gen_data_ctr = x"0100" else '0'; +PC_READY_OUT <= '1' when constrSimpleFrameCurrentState = IDLE else '0'; +PC_TRANSMIT_ON_OUT <= '0' when constrSimpleFrameCurrentState = IDLE and PC_START_OF_SUB_IN = '0' else '1'; +TC_IP_SIZE_OUT <= x"0100"; +TC_UDP_SIZE_OUT <= x"0100"; + +--PC_TRANSMIT_ON_OUT <= '1' when constructCurrentState = WAIT_FOR_LOAD else '0'; +--PC_TRANSMIT_ON_OUT <= '0'; + +-- my_int_ctr <= (3 - to_integer(to_unsigned(sub_int_ctr, 2))); -- reverse byte order +-- load_int_ctr <= (3 - to_integer(to_unsigned(all_int_ctr, 2))); -- gk 08.04.10 +-- +-- all_ctr <= std_logic_vector(to_unsigned(all_int_ctr, all_ctr'length)); -- for debugging +-- sub_ctr <= std_logic_vector(to_unsigned(sub_int_ctr, sub_ctr'length)); -- for debugging +-- my_ctr <= std_logic_vector(to_unsigned(my_int_ctr, my_ctr'length)); -- for debugging +-- +-- max_frame_size <= PC_MAX_FRAME_SIZE_IN; +-- +-- -- Ready signal for PacketConstructor +-- pc_ready <= '1' when (constructCurrentState = CIDLE) and (df_empty = '1') else '0'; +pc_ready <= '0'; + +-- store event information on Start_of_Subevent +-- THE_EVT_INFO_STORE_PROC: process( CLK ) +-- begin +-- if( rising_edge(CLK) ) then +-- if (RESET = '1') then -- gk 31.05.10 +-- pc_sub_size <= (others => '0'); +-- pc_trig_nr <= (others => '0'); +-- elsif( PC_START_OF_SUB_IN = '1' ) then +-- pc_sub_size <= PC_SUB_SIZE_IN; +-- pc_trig_nr <= PC_TRIG_NR_IN; +-- end if; +-- end if; +-- end process; +-- +-- -- gk 07.10.10 +-- df_eod <= '1' when ((MULT_EVT_ENABLE_IN = '0') and (PC_END_OF_DATA_IN = '1')) +-- or ((MULT_EVT_ENABLE_IN = '1') and (PC_END_OF_SUB_IN = '1')) +-- else '0'; + +-- Data FIFO for incoming packet data from IPU buffer +-- gk 26.07.10 +-- DATA_FIFO : fifo_64kx9 +-- port map( +-- Data(7 downto 0) => PC_DATA_IN, +-- Data(8) => df_eod, --PC_END_OF_DATA_IN, -- gk 07.10.10 +-- WrClock => CLK, +-- RdClock => CLK, +-- WrEn => df_wr_en, +-- RdEn => df_rd_en, +-- Reset => RESET, +-- RPReset => RESET, +-- Q(7 downto 0) => df_q, +-- Q(8) => load_eod, +-- Empty => df_empty, +-- Full => df_full +-- ); + +-- LOAD_EOD_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- load_eod_q <= '0'; +-- else +-- load_eod_q <= load_eod; +-- end if; +-- end if; +-- end process LOAD_EOD_PROC; +-- +-- -- Write enable for the data FIFO +-- -- !!!combinatorial signal!!! +-- -- could be avoided as IPU2GBE does only send data in case of PC_READY. +-- df_wr_en <= '1' when ((PC_WR_EN_IN = '1') and (constructCurrentState /= WAIT_FOR_LOAD)) +-- else '0'; +-- +-- -- Output register for data FIFO +-- dfQProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- df_q_reg <= df_q; +-- end if; +-- end process dfQProc; +-- +-- -- Construction state machine +-- constructMachineProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- constructCurrentState <= CIDLE; +-- else +-- constructCurrentState <= constructNextState; +-- end if; +-- end if; +-- end process constructMachineProc; +-- +-- constructMachine : process(constructCurrentState, PC_START_OF_SUB_IN, PC_WR_EN_IN, PC_END_OF_DATA_IN, loadCurrentState, saveSubCurrentState, sub_int_ctr) +-- begin +-- case constructCurrentState is +-- when CIDLE => +-- constr_state <= x"0"; +-- --if( PC_WR_EN_IN = '1' ) then +-- -- gk 04.12.10 +-- if (PC_START_OF_SUB_IN = '1') then +-- +-- constructNextState <= SAVE_DATA; +-- else +-- constructNextState <= CIDLE; +-- end if; +-- when SAVE_DATA => +-- constr_state <= x"1"; +-- if( PC_END_OF_DATA_IN = '1' ) then +-- constructNextState <= WAIT_FOR_LOAD; +-- else +-- constructNextState <= SAVE_DATA; +-- end if; +-- when WAIT_FOR_LOAD => +-- constr_state <= x"2"; +-- if( (df_empty = '1') and (loadCurrentState = LIDLE) ) then -- waits until the whole packet is transmitted +-- constructNextState <= CIDLE; +-- else +-- constructNextState <= WAIT_FOR_LOAD; +-- end if; +-- when others => +-- constr_state <= x"f"; +-- constructNextState <= CIDLE; +-- end case; +-- end process constructMachine; + +--*********************** +-- SIZE COUNTERS FOR SAVING SIDE +--*********************** + +-- gk 29.03.10 the subevent size saved to its headers cannot contain padding bytes but they are included in pc_sub_size +-- that's why they are removed if pc_padding flag is asserted +-- sub_size_to_save <= (x"10" + pc_sub_size) when (PC_PADDING_IN = '0') +-- else (x"c" + pc_sub_size); -- subevent headers + data +-- +-- -- BUG HERE BUG HERE BUG HERE BUG HERE +-- -- gk 29.03.10 no changes here because the queue size should contain the padding bytes of subevents +-- queueSizeProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- --if (RESET = '1') or (loadCurrentState = PUT_Q_DEC) then -- gk 07.10.10 -- (loadCurrentState = CLEANUP) then +-- if (RESET = '1') or (loadCurrentState = CLEANUP) then +-- queue_size <= x"00000028"; -- + 8B for queue headers and 32B for termination +-- elsif (saveSubCurrentState = SAVE_SIZE) and (sub_int_ctr = 3) then +-- queue_size <= queue_size + pc_sub_size + x"10"; -- + 16B for each subevent headers +-- end if; +-- end if; +-- end process queueSizeProc; + + +--*********************** +-- LOAD DATA COMBINED WITH HEADERS INTO FC, QUEUE TRANSMISSION +--*********************** + +-- loadMachineProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- loadCurrentState <= LIDLE; +-- else +-- loadCurrentState <= loadNextState; +-- end if; +-- end if; +-- end process loadMachineProc; +-- +-- loadMachine : process(loadCurrentState, constructCurrentState, all_int_ctr, df_empty, +-- sub_bytes_loaded, sub_size_loaded, size_left, TC_H_READY_IN, +-- max_frame_size, bytes_loaded, divide_position, PC_DELAY_IN, +-- delay_ctr, load_eod_q, MULT_EVT_ENABLE_IN) +-- begin +-- case loadCurrentState is +-- when LIDLE => +-- load_state <= x"0"; +-- if ((constructCurrentState = WAIT_FOR_LOAD) and (df_empty = '0')) then +-- loadNextState <= WAIT_FOR_FC; +-- else +-- loadNextState <= LIDLE; +-- end if; +-- when WAIT_FOR_FC => +-- load_state <= x"1"; +-- if (TC_H_READY_IN = '1') then +-- loadNextState <= PUT_Q_LEN; +-- else +-- loadNextState <= WAIT_FOR_FC; +-- end if; +-- when PUT_Q_LEN => +-- load_state <= x"2"; +-- if (all_int_ctr = 3) then +-- loadNextState <= PUT_Q_DEC; +-- else +-- loadNextState <= PUT_Q_LEN; +-- end if; +-- when PUT_Q_DEC => +-- load_state <= x"3"; +-- if (all_int_ctr = 3) then +-- loadNextState <= LOAD_SUB; +-- else +-- loadNextState <= PUT_Q_DEC; +-- end if; +-- when LOAD_SUB => +-- load_state <= x"4"; +-- if (bytes_loaded = max_frame_size - 1) then +-- loadNextState <= DIVIDE; +-- elsif (all_int_ctr = 15) then +-- loadNextState <= PREP_DATA; +-- else +-- loadNextState <= LOAD_SUB; +-- end if; +-- when PREP_DATA => +-- load_state <= x"5"; +-- loadNextState <= LOAD_DATA; +-- when LOAD_DATA => +-- load_state <= x"6"; +-- -- if (bytes_loaded = max_frame_size - 1) then +-- -- loadNextState <= DIVIDE; +-- -- -- gk 07.10.10 +-- -- elsif (MULT_EVT_ENABLE_IN = '1') then +-- -- if (size_left = x"0000_0023") then +-- -- loadNextState <= LOAD_TERM; +-- -- elsif (load_eod_q = '1') then +-- -- loadNextState <= LOAD_SUB; +-- -- else +-- -- loadNextState <= LOAD_DATA; +-- -- end if; +-- -- else +-- -- if (load_eod_q = '1') then +-- -- loadNextState <= LOAD_TERM; +-- -- else +-- -- loadNextState <= LOAD_DATA; +-- -- end if; +-- -- end if; +-- if (bytes_loaded = max_frame_size - 1) then +-- loadNextState <= DIVIDE; +-- -- gk 07.10.10 +-- elsif (load_eod_q = '1') then +-- if (MULT_EVT_ENABLE_IN = '1') then +-- if (size_left < x"0000_0030") then +-- loadNextState <= LOAD_TERM; +-- else +-- loadNextState <= LOAD_SUB; +-- end if; +-- else +-- loadNextState <= LOAD_TERM; +-- end if; +-- else +-- loadNextState <= LOAD_DATA; +-- end if; +-- when DIVIDE => +-- load_state <= x"7"; +-- if (TC_H_READY_IN = '1') then +-- if (divide_position = "00") then +-- loadNextState <= PREP_DATA; +-- elsif (divide_position = "01") then +-- loadNextState <= LOAD_SUB; +-- else +-- loadNextState <= LOAD_TERM; +-- end if; +-- else +-- loadNextState <= DIVIDE; +-- end if; +-- when LOAD_TERM => +-- load_state <= x"8"; +-- if (bytes_loaded = max_frame_size - 1) and (all_int_ctr /= 31) then +-- loadNextState <= DIVIDE; +-- elsif (all_int_ctr = 31) then +-- loadNextState <= CLEANUP; +-- else +-- loadNextState <= LOAD_TERM; +-- end if; +-- -- gk 28.04.10 +-- when CLEANUP => +-- load_state <= x"9"; +-- if (PC_DELAY_IN = x"0000_0000") then +-- loadNextState <= LIDLE; +-- else +-- loadNextState <= DELAY; +-- end if; +-- -- gk 28.04.10 +-- when DELAY => +-- load_state <= x"a"; +-- if (delay_ctr = x"0000_0000") then +-- loadNextState <= LIDLE; +-- else +-- loadNextState <= DELAY; +-- end if; +-- when others => +-- load_state <= x"f"; +-- loadNextState <= LIDLE; +-- end case; +-- end process loadMachine; +-- +-- -- gk 04.12.10 +-- firstSubInMultiProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = LOAD_TERM) then +-- first_sub_in_multi <= '1'; +-- elsif (loadCurrentState = LOAD_DATA) then +-- first_sub_in_multi <= '0'; +-- end if; +-- end if; +-- end process; +-- +-- -- gk 04.12.10 +-- fromDivideStateProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- from_divide_state <= '0'; +-- elsif (loadCurrentState = DIVIDE) then +-- from_divide_state <= '1'; +-- elsif (loadCurrentState = PREP_DATA) then +-- from_divide_state <= '0'; +-- end if; +-- end if; +-- end process fromDivideStateProc; +-- +-- +-- dividePositionProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- divide_position <= "00"; +-- -- elsif (bytes_loaded = max_frame_size - 1) then +-- -- if (loadCurrentState = LIDLE) then +-- -- divide_position <= "00"; +-- -- elsif (loadCurrentState = LOAD_DATA) then +-- -- -- gk 07.10.10 +-- -- if (MULT_EVT_ENABLE_IN = '1') and (size_left = x"0000_003a") then +-- -- divide_position <= "11"; +-- -- -- gk 07.10.10 +-- -- elsif (MULT_EVT_ENABLE_IN = '1') and (load_eod_q = '1') then +-- -- divide_position <= "01"; +-- -- -- gk 26.07.10 +-- -- elsif (MULT_EVT_ENABLE_IN = '0') and (load_eod_q = '1') then -- if termination is about to be loaded divide on term +-- -- divide_position <= "11"; +-- -- else +-- -- divide_position <= "00"; -- still data loaded divide on data +-- -- end if; +-- -- elsif (loadCurrentState = LOAD_SUB) then +-- -- if (all_int_ctr = 15) then +-- -- divide_position <= "00"; +-- -- else +-- -- divide_position <= "01"; +-- -- end if; +-- -- elsif (loadCurrentState = LOAD_TERM) then +-- -- divide_position <= "11"; +-- -- end if; +-- -- end if; +-- elsif (bytes_loaded = max_frame_size - 1) then +-- if (loadCurrentState = LIDLE) then +-- divide_position <= "00"; +-- disable_prep <= '0'; -- gk 05.12.10 +-- elsif (loadCurrentState = LOAD_DATA) then +-- -- gk 05.12.10 +-- -- gk 26.07.10 +-- if (MULT_EVT_ENABLE_IN = '0') and (load_eod_q = '1') then -- if termination is about to be loaded divide on term +-- divide_position <= "11"; +-- disable_prep <= '0'; -- gk 05.12.10 +-- elsif (MULT_EVT_ENABLE_IN = '1') and (load_eod_q = '1') then +-- if (size_left > x"0000_0028") then +-- divide_position <= "01"; +-- disable_prep <= '0'; -- gk 05.12.10 +-- else +-- divide_position <= "11"; +-- disable_prep <= '0'; -- gk 05.12.10 +-- end if; +-- else +-- divide_position <= "00"; -- still data loaded divide on data +-- disable_prep <= '1'; -- gk 05.12.10 +-- end if; +-- elsif (loadCurrentState = LOAD_SUB) then +-- if (all_int_ctr = 15) then +-- divide_position <= "00"; +-- disable_prep <= '1'; -- gk 05.12.10 +-- else +-- divide_position <= "01"; +-- disable_prep <= '0'; -- gk 05.12.10 +-- end if; +-- elsif (loadCurrentState = LOAD_TERM) then +-- divide_position <= "11"; +-- disable_prep <= '0'; -- gk 05.12.10 +-- end if; +-- elsif (loadCurrentState = PREP_DATA) then -- gk 06.12.10 reset disable_prep +-- disable_prep <= '0'; +-- end if; +-- +-- end if; +-- end process dividePositionProc; +-- +-- allIntCtrProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then -- gk 31.05.10 +-- all_int_ctr <= 0; +-- else +-- case loadCurrentState is +-- +-- when LIDLE => all_int_ctr <= 0; +-- +-- when WAIT_FOR_FC => all_int_ctr <= 0; +-- +-- when PUT_Q_LEN => +-- if (all_int_ctr = 3) then +-- all_int_ctr <= 0; +-- else +-- all_int_ctr <= all_int_ctr + 1; +-- end if; +-- +-- when PUT_Q_DEC => +-- if (all_int_ctr = 3) then +-- all_int_ctr <= 0; +-- else +-- all_int_ctr <= all_int_ctr + 1; +-- end if; +-- +-- when LOAD_SUB => +-- if (all_int_ctr = 15) then +-- all_int_ctr <= 0; +-- else +-- all_int_ctr <= all_int_ctr + 1; +-- end if; +-- +-- when LOAD_DATA => all_int_ctr <= 0; +-- +-- when LOAD_TERM => +-- if (all_int_ctr = 31) then +-- all_int_ctr <= 0; +-- else +-- all_int_ctr <= all_int_ctr + 1; +-- end if; +-- +-- when DIVIDE => null; +-- +-- when CLEANUP => all_int_ctr <= 0; +-- +-- when PREP_DATA => all_int_ctr <= 0; +-- +-- when DELAY => all_int_ctr <= 0; +-- end case; +-- end if; +-- end if; +-- end process allIntCtrProc; +-- +-- dfRdEnProc : process(loadCurrentState, bytes_loaded, max_frame_size, sub_bytes_loaded, +-- sub_size_loaded, all_int_ctr, RESET, size_left, load_eod_q) +-- begin +-- if (RESET = '1') then +-- df_rd_en <= '0'; +-- elsif (loadCurrentState = LOAD_DATA) then +-- -- if (bytes_loaded = max_frame_size - x"1") then +-- -- df_rd_en <= '0'; +-- -- -- gk 07.10.10 +-- -- elsif (MULT_EVT_ENABLE_IN = '0') and (load_eod_q = '1') then +-- -- df_rd_en <= '0'; +-- -- -- gk 07.10.10 +-- -- elsif (MULT_EVT_ENABLE_IN = '1') and (size_left = x"0000_003a") then +-- -- df_rd_en <= '0'; +-- -- else +-- -- df_rd_en <= '1'; +-- -- end if; +-- if (bytes_loaded = max_frame_size - x"1") then +-- df_rd_en <= '0'; +-- -- gk 26.07.10 +-- --elsif (load_eod = '1') or (load_eod_q = '1') then +-- elsif (load_eod_q = '1') then +-- df_rd_en <= '0'; +-- -- elsif (sub_bytes_loaded = sub_size_loaded) then +-- -- df_rd_en <= '0'; +-- else +-- df_rd_en <= '1'; +-- end if; +-- +-- elsif (loadCurrentState = LOAD_SUB) and (all_int_ctr = 15) and (bytes_loaded /= max_frame_size - x"1") then +-- df_rd_en <= '1'; +-- elsif (loadCurrentState = PREP_DATA) then +-- df_rd_en <= '1'; +-- else +-- df_rd_en <= '0'; +-- end if; +-- end process dfRdEnProc; +-- +-- shfRdEnProc : process(loadCurrentState, all_int_ctr, RESET) +-- begin +-- if (RESET = '1') then -- gk 31.05.10 +-- shf_rd_en <= '0'; +-- elsif (loadCurrentState = LOAD_SUB) then +-- shf_rd_en <= '1'; +-- elsif (loadCurrentState = LOAD_TERM) and (all_int_ctr < 31) then +-- shf_rd_en <= '1'; +-- elsif (loadCurrentState = PUT_Q_DEC) and (all_int_ctr = 3) then +-- shf_rd_en <= '1'; +-- else +-- shf_rd_en <= '0'; +-- end if; +-- end process shfRdEnProc; +-- +-- +-- -- fcWrEnProc : process(loadCurrentState, RESET) +-- -- begin +-- -- if (RESET = '1') then -- gk 31.05.10 +-- -- fc_wr_en <= '0'; +-- -- elsif (loadCurrentState = PUT_Q_LEN) or (loadCurrentState = PUT_Q_DEC) then +-- -- fc_wr_en <= '1'; +-- -- elsif (loadCurrentState = LOAD_SUB) or (loadCurrentState = LOAD_DATA) or (loadCurrentState = LOAD_TERM) then +-- -- fc_wr_en <= '1'; +-- -- else +-- -- fc_wr_en <= '0'; +-- -- end if; +-- -- end process fcWrEnProc; +-- fcWrEnProc : process(loadCurrentState, RESET, first_sub_in_multi, from_divide_state, MULT_EVT_ENABLE_IN, divide_position, disable_prep) +-- begin +-- if (RESET = '1') then -- gk 31.05.10 +-- fc_wr_en <= '0'; +-- elsif (loadCurrentState = PUT_Q_LEN) or (loadCurrentState = PUT_Q_DEC) then +-- fc_wr_en <= '1'; +-- elsif (loadCurrentState = LOAD_SUB) or (loadCurrentState = LOAD_DATA) or (loadCurrentState = LOAD_TERM) then +-- fc_wr_en <= '1'; +-- -- gk 04.12.10 +-- elsif (MULT_EVT_ENABLE_IN = '1') and (loadCurrentState = PREP_DATA) and (first_sub_in_multi = '0') and (from_divide_state = '0') and (disable_prep = '0') then +-- fc_wr_en <= '1'; +-- elsif (MULT_EVT_ENABLE_IN = '1') and (loadCurrentState = PREP_DATA) and (from_divide_state = '1') and ((divide_position = "00") or (divide_position = "01")) and (disable_prep = '0') then +-- fc_wr_en <= '1'; +-- else +-- fc_wr_en <= '0'; +-- end if; +-- end process fcWrEnProc; +-- +-- +-- -- was all_int_ctr +-- fcDataProc : process(loadCurrentState, queue_size_temp, PC_QUEUE_DEC_IN, shf_q, df_q_reg, load_int_ctr) +-- begin +-- case loadCurrentState is +-- when LIDLE => fc_data <= x"af"; +-- when WAIT_FOR_FC => fc_data <= x"bf"; +-- -- gk 08.04.10 my_int_ctr changed to load_int_ctr +-- when PUT_Q_LEN => fc_data <= queue_size_temp(load_int_ctr * 8 + 7 downto load_int_ctr * 8); +-- when PUT_Q_DEC => fc_data <= PC_QUEUE_DEC_IN(load_int_ctr * 8 + 7 downto load_int_ctr * 8); +-- when LOAD_SUB => fc_data <= shf_q; +-- when PREP_DATA => fc_data <= df_q_reg; +-- when LOAD_DATA => fc_data <= df_q_reg; +-- when LOAD_TERM => fc_data <= shf_q; +-- when DIVIDE => fc_data <= x"cf"; +-- when CLEANUP => fc_data <= x"df"; +-- when others => fc_data <= x"00"; +-- end case; +-- end process fcDataProc; +-- +-- -- delay counters +-- -- gk 28.04.10 +-- DELAY_CTR_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if ((RESET = '1') or (loadCurrentState = LIDLE)) then +-- delay_ctr <= PC_DELAY_IN; +-- elsif ((loadCurrentState = DELAY) and (ticks_ctr(7) = '1')) then +-- delay_ctr <= delay_ctr - x"1"; +-- end if; +-- end if; +-- end process DELAY_CTR_PROC; +-- +-- -- gk 28.04.10 +-- TICKS_CTR_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if ((RESET = '1') or (loadCurrentState = LIDLE) or (ticks_ctr(7) = '1')) then +-- ticks_ctr <= x"00"; +-- elsif (loadCurrentState = DELAY) then +-- ticks_ctr <= ticks_ctr + x"1"; +-- end if; +-- end if; +-- end process TICKS_CTR_PROC; + + +--*********************** +-- SIZE COUNTERS FOR LOADING SIDE +--*********************** + +-- queue_size_temp <= queue_size - x"20"; -- size of data without termination +-- +-- -- gk 08.04.10 +-- rst_after_sub_comb <= '1' when (loadCurrentState = LIDLE) or +-- ((loadCurrentState = LOAD_DATA) and (size_left /= x"00000021")) -- gk 26.07.10 -- and (sub_bytes_loaded = sub_size_loaded) +-- else '0'; +-- +-- -- gk 08.04.10 +-- RST_AFTER_SUB_PROC : process(CLK) +-- begin +-- if(rising_edge(CLK)) then +-- if(RESET = '1') then +-- rst_after_sub <= '0'; +-- else +-- rst_after_sub <= rst_after_sub_comb; +-- end if; +-- end if; +-- end process RST_AFTER_SUB_PROC; +-- +-- -- counts all bytes loaded to divide data into frames +-- bytesLoadedProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = DIVIDE) or (loadCurrentState = CLEANUP) then +-- bytes_loaded <= x"0000"; +-- elsif (loadCurrentState = PUT_Q_LEN) or (loadCurrentState = PUT_Q_DEC) or (loadCurrentState = LOAD_DATA) or (loadCurrentState = LOAD_SUB) or (loadCurrentState = LOAD_TERM) then +-- bytes_loaded <= bytes_loaded + x"1"; +-- -- gk 05.12.10 +-- -- elsif (MULT_EVT_ENABLE_IN = '1') and (loadCurrentState = PREP_DATA) and (first_sub_in_multi = '0') and (from_divide_state = '0') then +-- -- bytes_loaded <= bytes_loaded + x"1"; +-- elsif (MULT_EVT_ENABLE_IN = '1') and (loadCurrentState = PREP_DATA) and (first_sub_in_multi = '0') and (from_divide_state = '0') and (disable_prep = '0') then +-- bytes_loaded <= bytes_loaded + x"1"; +-- elsif (MULT_EVT_ENABLE_IN = '1') and (loadCurrentState = PREP_DATA) and (from_divide_state = '1') and ((divide_position = "00") or (divide_position = "01")) and (disable_prep = '0') then +-- bytes_loaded <= bytes_loaded + x"1"; +-- end if; +-- end if; +-- end process bytesLoadedProc; +-- +-- -- size of subevent loaded from memory +-- subSizeLoadedProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) or (rst_after_sub = '1') then -- gk 08.04.10 +-- sub_size_loaded <= x"00000000"; +-- elsif (loadCurrentState = LOAD_SUB) and (all_int_ctr < 4) then +-- -- was all_int_ctr +-- -- gk 08.04.10 my_int_ctr changed to load_int_ctr +-- sub_size_loaded(7 + load_int_ctr * 8 downto load_int_ctr * 8) <= shf_q; +-- -- gk 29.03.10 here the padding bytes have to be added to the loadedSize in order to load the correct amount of bytes from fifo +-- elsif (loadCurrentState = LOAD_SUB) and (all_int_ctr = 5) and (sub_size_loaded(2) = '1') then +-- sub_size_loaded <= sub_size_loaded + x"4"; +-- end if; +-- end if; +-- end process subSizeLoadedProc; +-- +-- -- counts only raw data bytes being loaded +-- subBytesLoadedProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) or (rst_after_sub = '1') then -- gk 26.07.10 --or (sub_bytes_loaded = sub_size_loaded) -- gk 08.04.10 +-- sub_bytes_loaded <= x"00000011"; -- subevent headers doesnt count +-- elsif (loadCurrentState = LOAD_DATA) then +-- sub_bytes_loaded <= sub_bytes_loaded + x"1"; +-- end if; +-- end if; +-- end process subBytesLoadedProc; +-- +-- -- counts the size of the large udp packet +-- actualPacketProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) then +-- actual_packet_size <= x"0008"; +-- elsif (fc_wr_en = '1') then +-- actual_packet_size <= actual_packet_size + x"1"; +-- end if; +-- end if; +-- end process actualPacketProc; +-- +-- actualQueueSizeProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = CLEANUP) then +-- actual_queue_size <= (others => '0'); +-- elsif (loadCurrentState = LIDLE) then +-- actual_queue_size <= queue_size; +-- end if; +-- end if; +-- end process actualQueueSizeProc; +-- +-- -- amount of bytes left to send in current packet +-- sizeLeftProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = CLEANUP) then +-- size_left <= (others => '0'); +-- elsif (loadCurrentState = LIDLE) then +-- size_left <= queue_size; +-- elsif (fc_wr_en = '1') then +-- size_left <= size_left - 1; +-- end if; +-- end if; +-- end process sizeLeftProc; +-- +-- -- HOT FIX: don't rely on CTS information, count the packets on your own. +-- -- In this case, we increment the fragmented packet ID with EOD from ipu2gbe. +-- THE_FC_IDENT_COUNTER_PROC: process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- fc_ident <= (others => '0'); +-- elsif (PC_END_OF_DATA_IN = '1') then +-- fc_ident <= fc_ident + 1; +-- end if; +-- end if; +-- end process THE_FC_IDENT_COUNTER_PROC; +-- +-- fc_flags_offset(15 downto 14) <= "00"; +-- +-- moreFragmentsProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) then +-- fc_flags_offset(13) <= '0'; +-- elsif ((loadCurrentState = DIVIDE) and (TC_READY_IN = '1')) or ((loadCurrentState = WAIT_FOR_FC) and (TC_READY_IN = '1')) then +-- if ((actual_queue_size - actual_packet_size) < max_frame_size) then +-- fc_flags_offset(13) <= '0'; -- no more fragments +-- else +-- fc_flags_offset(13) <= '1'; -- more fragments +-- end if; +-- end if; +-- end if; +-- end process moreFragmentsProc; +-- +-- eodProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- fc_eod <= '0'; +-- elsif (loadCurrentState = LOAD_DATA) and (bytes_loaded = max_frame_size - 2) then +-- fc_eod <= '1'; +-- elsif (loadCurrentState = LOAD_SUB) and (bytes_loaded = max_frame_size - 2) then +-- fc_eod <= '1'; +-- elsif (loadCurrentState = LOAD_TERM) and ((bytes_loaded = max_frame_size - 2) or (all_int_ctr = 30)) then +-- fc_eod <= '1'; +-- else +-- fc_eod <= '0'; +-- end if; +-- end if; +-- end process eodProc; +-- +-- sodProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- fc_sod <= '0'; +-- elsif (loadCurrentState = WAIT_FOR_FC) and (TC_READY_IN = '1') then +-- fc_sod <= '1'; +-- elsif (loadCurrentState = DIVIDE) and (TC_READY_IN = '1') then +-- fc_sod <= '1'; +-- else +-- fc_sod <= '0'; +-- end if; +-- end if; +-- end process sodProc; +-- +-- offsetProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (loadCurrentState = LIDLE) or (loadCurrentState = CLEANUP) then +-- fc_flags_offset(12 downto 0) <= (others => '0'); +-- elsif ((loadCurrentState = DIVIDE) and (TC_READY_IN = '1')) then +-- fc_flags_offset(12 downto 0) <= actual_packet_size(15 downto 3); +-- end if; +-- end if; +-- end process offsetProc; +-- +-- fcIPSizeProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET= '1') then +-- fc_ip_size <= (others => '0'); +-- elsif ((loadCurrentState = DIVIDE) and (TC_READY_IN = '1')) or ((loadCurrentState = WAIT_FOR_FC) and (TC_READY_IN = '1')) then +-- if (size_left >= max_frame_size) then +-- fc_ip_size <= max_frame_size; +-- else +-- fc_ip_size <= size_left(15 downto 0); +-- end if; +-- end if; +-- end if; +-- end process fcIPSizeProc; +-- +-- fcUDPSizeProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- fc_udp_size <= (others => '0'); +-- elsif (loadCurrentState = WAIT_FOR_FC) and (TC_READY_IN = '1') then +-- fc_udp_size <= queue_size(15 downto 0); +-- end if; +-- end if; +-- end process fcUDPSizeProc; + + +--*********************** +-- SUBEVENT HEADERS WRITE AND READ +--*********************** + +-- SUBEVENT_HEADERS_FIFO : fifo_16kx8 +-- port map( +-- Data => shf_data, +-- WrClock => CLK, +-- RdClock => CLK, +-- WrEn => shf_wr_en, +-- RdEn => shf_rd_en, +-- Reset => RESET, +-- RPReset => RESET, +-- Q => shf_q, +-- Empty => shf_empty, +-- Full => shf_full +-- ); +-- +-- -- write enable for SHF +-- shf_wr_en <= '1' when ((saveSubCurrentState /= SIDLE) and (loadCurrentState /= PREP_DATA)) +-- else '0'; +-- +-- -- data multiplexing for SHF (convert 32bit LWs to 8bit) +-- -- CHANGED. +-- -- The SubEventHeader (4x 32bit is stored in [MSB:LSB] now, same byte order as data from PC. +-- shfDataProc : process(saveSubCurrentState, sub_size_to_save, PC_DECODING_IN, PC_EVENT_ID_IN, +-- pc_trig_nr, my_int_ctr, fc_data) +-- begin +-- case saveSubCurrentState is +-- when SIDLE => shf_data <= x"ac"; +-- when SAVE_SIZE => shf_data <= sub_size_to_save(my_int_ctr * 8 + 7 downto my_int_ctr * 8); +-- when SAVE_DECODING => shf_data <= PC_DECODING_IN(my_int_ctr * 8 + 7 downto my_int_ctr * 8); +-- when SAVE_ID => shf_data <= PC_EVENT_ID_IN(my_int_ctr * 8 + 7 downto my_int_ctr * 8); +-- when SAVE_TRIG_NR => shf_data <= pc_trig_nr(my_int_ctr * 8 + 7 downto my_int_ctr * 8); +-- when SAVE_TERM => shf_data <= fc_data; +-- when others => shf_data <= x"00"; +-- end case; +-- end process shfDataProc; +-- +-- saveSubMachineProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- saveSubCurrentState <= SIDLE; +-- else +-- saveSubCurrentState <= saveSubNextState; +-- end if; +-- end if; +-- end process saveSubMachineProc; +-- +-- saveSubMachine : process(saveSubCurrentState, PC_START_OF_SUB_IN, sub_int_ctr, loadCurrentState, TC_H_READY_IN) +-- begin +-- case saveSubCurrentState is +-- when SIDLE => +-- save_state <= x"0"; +-- if (PC_START_OF_SUB_IN = '1') then +-- saveSubNextState <= SAVE_SIZE; +-- -- this branch is dangerous! +-- elsif (loadCurrentState = WAIT_FOR_FC) and (TC_H_READY_IN = '1') then -- means that loadCurrentState is put_q_len +-- saveSubNextState <= SAVE_TERM; +-- else +-- saveSubNextState <= SIDLE; +-- end if; +-- when SAVE_SIZE => +-- save_state <= x"1"; +-- if (sub_int_ctr = 3) then +-- saveSubNextState <= SAVE_DECODING; +-- else +-- saveSubNextState <= SAVE_SIZE; +-- end if; +-- when SAVE_DECODING => +-- save_state <= x"2"; +-- if (sub_int_ctr = 3) then +-- saveSubNextState <= SAVE_ID; +-- else +-- saveSubNextState <= SAVE_DECODING; +-- end if; +-- when SAVE_ID => +-- save_state <= x"3"; +-- if (sub_int_ctr = 3) then +-- saveSubNextState <= SAVE_TRIG_NR; +-- else +-- saveSubNextState <= SAVE_ID; +-- end if; +-- when SAVE_TRIG_NR => +-- save_state <= x"4"; +-- if (sub_int_ctr = 3) then +-- saveSubNextState <= SIDLE; +-- else +-- saveSubNextState <= SAVE_TRIG_NR; +-- end if; +-- when SAVE_TERM => +-- save_state <= x"5"; +-- if (sub_int_ctr = 31) then +-- saveSubNextState <= SIDLE; +-- else +-- saveSubNextState <= SAVE_TERM; +-- end if; +-- when others => +-- save_state <= x"f"; +-- saveSubNextState <= SIDLE; +-- end case; +-- end process; +-- +-- -- This counter is used for breaking down 32bit information words into 8bit bytes for +-- -- storing them in the SHF. +-- -- It is also used for the termination 32byte sequence. +-- subIntProc: process( CLK ) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (saveSubCurrentState = SIDLE) then +-- sub_int_ctr <= 0; +-- elsif (sub_int_ctr = 3) and (saveSubCurrentState /= SAVE_TERM) then +-- sub_int_ctr <= 0; +-- elsif (sub_int_ctr = 31) and (saveSubCurrentState = SAVE_TERM) then +-- sub_int_ctr <= 0; +-- elsif (saveSubCurrentState /= SIDLE) and (loadCurrentState /= PREP_DATA) then +-- sub_int_ctr <= sub_int_ctr + 1; +-- end if; +-- end if; +-- end process subIntProc; +-- +-- debug(3 downto 0) <= constr_state; +-- debug(7 downto 4) <= save_state; +-- debug(11 downto 8) <= load_state; +-- debug(27 downto 12) <= queue_size(15 downto 0); +-- debug(28) <= df_full; +-- debug(29) <= df_empty; +-- debug(30) <= shf_full; +-- debug(31) <= shf_empty; +-- +-- debug(47 downto 32) <= size_left(15 downto 0); +-- debug(52 downto 48) <= all_ctr; +-- debug(53) <= pc_ready; + +-- outputs +-- PC_READY_OUT <= pc_ready; +-- TC_WR_EN_OUT <= fc_wr_en; +-- TC_DATA_OUT <= fc_data; +-- TC_IP_SIZE_OUT <= fc_ip_size; +-- TC_UDP_SIZE_OUT <= fc_udp_size; +-- -- FC_IDENT_OUT(15 downto 8) <= fc_ident(7 downto 0); +-- -- FC_IDENT_OUT(7 downto 0) <= fc_ident(15 downto 8); +-- TC_FLAGS_OFFSET_OUT <= fc_flags_offset; +-- TC_SOD_OUT <= fc_sod; +-- TC_EOD_OUT <= fc_eod; + +--PC_READY_OUT <= '1'; +--TC_IP_SIZE_OUT <= (others => '0'); +--TC_UDP_SIZE_OUT <= (others => '0'); +-- FC_IDENT_OUT(15 downto 8) <= fc_ident(7 downto 0); +-- FC_IDENT_OUT(7 downto 0) <= fc_ident(15 downto 8); +-- TC_FLAGS_OFFSET_OUT <= fc_flags_offset; +-- TC_SOD_OUT <= fc_sod; +-- TC_EOD_OUT <= fc_eod; + +DEBUG_OUT <= debug; + +end trb_net16_gbe_packet_constr; \ No newline at end of file diff --git a/gbe2_ecp3/trb_net16_gbe_protocol_prioritizer.vhd b/gbe2_ecp3/trb_net16_gbe_protocol_prioritizer.vhd new file mode 100644 index 0000000..fa4a3f8 --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_protocol_prioritizer.vhd @@ -0,0 +1,93 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +use work.trb_net_gbe_components.all; +use work.trb_net_gbe_protocols.all; + +--******** +-- maps the frame type and protocol code into internal value which sets the priority + +entity trb_net16_gbe_protocol_prioritizer is +port ( + CLK : in std_logic; + RESET : in std_logic; + + FRAME_TYPE_IN : in std_logic_vector(15 downto 0); -- recovered frame type + PROTOCOL_CODE_IN : in std_logic_vector(7 downto 0); -- ip protocol + UDP_PROTOCOL_IN : in std_logic_vector(15 downto 0); + + CODE_OUT : out std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0) +); +end trb_net16_gbe_protocol_prioritizer; + + +architecture trb_net16_gbe_protocol_prioritizer of trb_net16_gbe_protocol_prioritizer is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_protocol_prioritizer : architecture is "GBE_MAIN_group"; + +begin + +PRIORITIZE : process(CLK, FRAME_TYPE_IN, PROTOCOL_CODE_IN) +begin + + if rising_edge(CLK) then + + CODE_OUT <= (others => '0'); + + if (RESET = '0') then + + --**** HERE ADD YOU PROTOCOL RECOGNITION AT WANTED PRIORITY LEVEL + -- priority level is the bit position in the CODE_OUT vector + -- less significant bit has the higher priority + case FRAME_TYPE_IN is + + -- IPv4 + when x"0800" => + if (PROTOCOL_CODE_IN = x"11") then -- UDP + -- No. 2 = DHCP + if (UDP_PROTOCOL_IN = x"0044") then -- DHCP Client + CODE_OUT(1) <= '1'; + else + -- branch for pure IPv4 + CODE_OUT <= (others => '0'); + end if; + -- No. 3 = ICMP + elsif (PROTOCOL_CODE_IN = x"01") then -- ICMP + CODE_OUT(2) <= '1'; + -- No. 4 = Test1a + elsif (PROTOCOL_CODE_IN = x"dd") then -- Test1 b + CODE_OUT(3) <= '1'; + -- No. 5 = Test1b + elsif (PROTOCOL_CODE_IN = x"ee") then -- Test1 a + CODE_OUT(4) <= '1'; + else + CODE_OUT <= (others => '0'); -- vector full of 1 means invalid protocol + end if; + + -- No. 1 = ARP + when x"0806" => + CODE_OUT(0) <= '1'; + + -- last slot is reserved for Trash + when others => + CODE_OUT <= (others => '0'); + + end case; + + end if; + + end if; + +end process PRIORITIZE; + +end trb_net16_gbe_protocol_prioritizer; + + diff --git a/gbe2_ecp3/trb_net16_gbe_protocol_selector.vhd b/gbe2_ecp3/trb_net16_gbe_protocol_selector.vhd new file mode 100644 index 0000000..df426db --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_protocol_selector.vhd @@ -0,0 +1,372 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +use work.trb_net_gbe_components.all; +use work.trb_net_gbe_protocols.all; + +--******** +-- multiplexes between different protocols and manages the responses +-- +-- + + +entity trb_net16_gbe_protocol_selector is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- signals to/from main controller + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_PROTO_SELECT_IN : in std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); + PS_BUSY_OUT : out std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); + PS_FRAME_SIZE_IN : in std_logic_vector(15 downto 0); + PS_RESPONSE_READY_OUT : out std_logic; + + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + +-- singals to/from transmit controller with constructed response + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_RD_EN_IN : in std_logic; + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + + TC_BUSY_IN : in std_logic; + + -- counters from response constructors + RECEIVED_FRAMES_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); + SENT_FRAMES_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); + PROTOS_DEBUG_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0); + + -- misc signals for response constructors + DHCP_START_IN : in std_logic; + DHCP_DONE_OUT : out std_logic; + + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end trb_net16_gbe_protocol_selector; + + +architecture trb_net16_gbe_protocol_selector of trb_net16_gbe_protocol_selector is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_protocol_selector : architecture is "GBE_MAIN_group"; + +signal rd_en : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); +signal resp_ready : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); +signal tc_data : std_logic_vector(c_MAX_PROTOCOLS * 9 - 1 downto 0); +signal tc_size : std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); +signal tc_type : std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); +signal busy : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); +signal selected : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); +signal tc_mac : std_logic_vector(c_MAX_PROTOCOLS * 48 - 1 downto 0); +signal tc_ip : std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0); +signal tc_udp : std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); +signal tc_src_mac : std_logic_vector(c_MAX_PROTOCOLS * 48 - 1 downto 0); +signal tc_src_ip : std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0); +signal tc_src_udp : std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); +signal tc_ip_proto : std_logic_vector(c_MAX_PROTOCOLS * 8 - 1 downto 0); + +begin + +-- protocol Nr. 1 ARP +ARP : trb_net16_gbe_response_constructor_ARP +port map ( + CLK => CLK, + RESET => RESET, + +-- INTERFACE + PS_DATA_IN => PS_DATA_IN, + PS_WR_EN_IN => PS_WR_EN_IN, + PS_ACTIVATE_IN => PS_PROTO_SELECT_IN(0), + PS_RESPONSE_READY_OUT => resp_ready(0), + PS_BUSY_OUT => busy(0), + PS_SELECTED_IN => selected(0), + + PS_SRC_MAC_ADDRESS_IN => PS_SRC_MAC_ADDRESS_IN, + PS_DEST_MAC_ADDRESS_IN => PS_DEST_MAC_ADDRESS_IN, + PS_SRC_IP_ADDRESS_IN => PS_SRC_IP_ADDRESS_IN, + PS_DEST_IP_ADDRESS_IN => PS_DEST_IP_ADDRESS_IN, + PS_SRC_UDP_PORT_IN => PS_SRC_UDP_PORT_IN, + PS_DEST_UDP_PORT_IN => PS_DEST_UDP_PORT_IN, + + TC_RD_EN_IN => TC_RD_EN_IN, + TC_DATA_OUT => tc_data(1 * 9 - 1 downto 0 * 9), + TC_FRAME_SIZE_OUT => tc_size(1 * 16 - 1 downto 0 * 16), + TC_FRAME_TYPE_OUT => tc_type(1 * 16 - 1 downto 0 * 16), + TC_IP_PROTOCOL_OUT => tc_ip_proto(1 * 8 - 1 downto 0 * 8), + + TC_DEST_MAC_OUT => tc_mac(1 * 48 - 1 downto 0 * 48), + TC_DEST_IP_OUT => tc_ip(1 * 32 - 1 downto 0 * 32), + TC_DEST_UDP_OUT => tc_udp(1 * 16 - 1 downto 0 * 16), + TC_SRC_MAC_OUT => tc_src_mac(1 * 48 - 1 downto 0 * 48), + TC_SRC_IP_OUT => tc_src_ip(1 * 32 - 1 downto 0 * 32), + TC_SRC_UDP_OUT => tc_src_udp(1 * 16 - 1 downto 0 * 16), + + TC_BUSY_IN => TC_BUSY_IN, + + RECEIVED_FRAMES_OUT => RECEIVED_FRAMES_OUT(1 * 16 - 1 downto 0 * 16), + SENT_FRAMES_OUT => SENT_FRAMES_OUT(1 * 16 - 1 downto 0 * 16), + DEBUG_OUT => PROTOS_DEBUG_OUT(1 * 32 - 1 downto 0 * 32) +-- END OF INTERFACE +); + +-- protocol No. 2 DHCP +DHCP : trb_net16_gbe_response_constructor_DHCP +port map ( + CLK => CLK, + RESET => RESET, + +-- INTERFACE + PS_DATA_IN => PS_DATA_IN, + PS_WR_EN_IN => PS_WR_EN_IN, + PS_ACTIVATE_IN => PS_PROTO_SELECT_IN(1), + PS_RESPONSE_READY_OUT => resp_ready(1), + PS_BUSY_OUT => busy(1), + PS_SELECTED_IN => selected(1), + + PS_SRC_MAC_ADDRESS_IN => PS_SRC_MAC_ADDRESS_IN, + PS_DEST_MAC_ADDRESS_IN => PS_DEST_MAC_ADDRESS_IN, + PS_SRC_IP_ADDRESS_IN => PS_SRC_IP_ADDRESS_IN, + PS_DEST_IP_ADDRESS_IN => PS_DEST_IP_ADDRESS_IN, + PS_SRC_UDP_PORT_IN => PS_SRC_UDP_PORT_IN, + PS_DEST_UDP_PORT_IN => PS_DEST_UDP_PORT_IN, + + TC_RD_EN_IN => TC_RD_EN_IN, + TC_DATA_OUT => tc_data(2 * 9 - 1 downto 1 * 9), + TC_FRAME_SIZE_OUT => tc_size(2 * 16 - 1 downto 1 * 16), + TC_FRAME_TYPE_OUT => tc_type(2 * 16 - 1 downto 1 * 16), + TC_IP_PROTOCOL_OUT => tc_ip_proto(2 * 8 - 1 downto 1 * 8), + + TC_DEST_MAC_OUT => tc_mac(2 * 48 - 1 downto 1 * 48), + TC_DEST_IP_OUT => tc_ip(2 * 32 - 1 downto 1 * 32), + TC_DEST_UDP_OUT => tc_udp(2 * 16 - 1 downto 1 * 16), + TC_SRC_MAC_OUT => tc_src_mac(2 * 48 - 1 downto 1 * 48), + TC_SRC_IP_OUT => tc_src_ip(2 * 32 - 1 downto 1 * 32), + TC_SRC_UDP_OUT => tc_src_udp(2 * 16 - 1 downto 1 * 16), + + TC_BUSY_IN => TC_BUSY_IN, + + RECEIVED_FRAMES_OUT => RECEIVED_FRAMES_OUT(2 * 16 - 1 downto 1 * 16), + SENT_FRAMES_OUT => SENT_FRAMES_OUT(2 * 16 - 1 downto 1 * 16), +-- END OF INTERFACE + + DHCP_START_IN => DHCP_START_IN, + DHCP_DONE_OUT => DHCP_DONE_OUT, + + DEBUG_OUT => PROTOS_DEBUG_OUT(2 * 32 - 1 downto 1 * 32) + ); + +-- protocol No. 3 Ping +Ping : trb_net16_gbe_response_constructor_Ping +port map ( + CLK => CLK, + RESET => RESET, + +-- INTERFACE + PS_DATA_IN => PS_DATA_IN, + PS_WR_EN_IN => PS_WR_EN_IN, + PS_ACTIVATE_IN => PS_PROTO_SELECT_IN(2), + PS_RESPONSE_READY_OUT => resp_ready(2), + PS_BUSY_OUT => busy(2), + PS_SELECTED_IN => selected(2), + + PS_SRC_MAC_ADDRESS_IN => PS_SRC_MAC_ADDRESS_IN, + PS_DEST_MAC_ADDRESS_IN => PS_DEST_MAC_ADDRESS_IN, + PS_SRC_IP_ADDRESS_IN => PS_SRC_IP_ADDRESS_IN, + PS_DEST_IP_ADDRESS_IN => PS_DEST_IP_ADDRESS_IN, + PS_SRC_UDP_PORT_IN => PS_SRC_UDP_PORT_IN, + PS_DEST_UDP_PORT_IN => PS_DEST_UDP_PORT_IN, + + TC_RD_EN_IN => TC_RD_EN_IN, + TC_DATA_OUT => tc_data(3 * 9 - 1 downto 2 * 9), + TC_FRAME_SIZE_OUT => tc_size(3 * 16 - 1 downto 2 * 16), + TC_FRAME_TYPE_OUT => tc_type(3 * 16 - 1 downto 2 * 16), + TC_IP_PROTOCOL_OUT => tc_ip_proto(3 * 8 - 1 downto 2 * 8), + + TC_DEST_MAC_OUT => tc_mac(3 * 48 - 1 downto 2 * 48), + TC_DEST_IP_OUT => tc_ip(3 * 32 - 1 downto 2 * 32), + TC_DEST_UDP_OUT => tc_udp(3 * 16 - 1 downto 2 * 16), + TC_SRC_MAC_OUT => tc_src_mac(3 * 48 - 1 downto 2 * 48), + TC_SRC_IP_OUT => tc_src_ip(3 * 32 - 1 downto 2 * 32), + TC_SRC_UDP_OUT => tc_src_udp(3 * 16 - 1 downto 2 * 16), + + TC_BUSY_IN => TC_BUSY_IN, + + RECEIVED_FRAMES_OUT => RECEIVED_FRAMES_OUT(3 * 16 - 1 downto 2 * 16), + SENT_FRAMES_OUT => SENT_FRAMES_OUT(3 * 16 - 1 downto 2 * 16), + DEBUG_OUT => PROTOS_DEBUG_OUT(3 * 32 - 1 downto 2 * 32) +-- END OF INTERFACE +); + +Test1a : trb_net16_gbe_response_constructor_Test1 +port map ( + CLK => CLK, + RESET => RESET, + +-- INTERFACE + PS_DATA_IN => PS_DATA_IN, + PS_WR_EN_IN => PS_WR_EN_IN, + PS_ACTIVATE_IN => PS_PROTO_SELECT_IN(3), + PS_RESPONSE_READY_OUT => resp_ready(3), + PS_BUSY_OUT => busy(3), + PS_SELECTED_IN => selected(3), + + PS_SRC_MAC_ADDRESS_IN => PS_SRC_MAC_ADDRESS_IN, + PS_DEST_MAC_ADDRESS_IN => PS_DEST_MAC_ADDRESS_IN, + PS_SRC_IP_ADDRESS_IN => PS_SRC_IP_ADDRESS_IN, + PS_DEST_IP_ADDRESS_IN => PS_DEST_IP_ADDRESS_IN, + PS_SRC_UDP_PORT_IN => PS_SRC_UDP_PORT_IN, + PS_DEST_UDP_PORT_IN => PS_DEST_UDP_PORT_IN, + + TC_RD_EN_IN => TC_RD_EN_IN, + TC_DATA_OUT => tc_data(4 * 9 - 1 downto 3 * 9), + TC_FRAME_SIZE_OUT => tc_size(4 * 16 - 1 downto 3 * 16), + TC_FRAME_TYPE_OUT => tc_type(4 * 16 - 1 downto 3 * 16), + TC_IP_PROTOCOL_OUT => tc_ip_proto(4 * 8 - 1 downto 3 * 8), + + TC_DEST_MAC_OUT => tc_mac(4 * 48 - 1 downto 3 * 48), + TC_DEST_IP_OUT => tc_ip(4 * 32 - 1 downto 3 * 32), + TC_DEST_UDP_OUT => tc_udp(4 * 16 - 1 downto 3 * 16), + TC_SRC_MAC_OUT => tc_src_mac(4 * 48 - 1 downto 3 * 48), + TC_SRC_IP_OUT => tc_src_ip(4 * 32 - 1 downto 3 * 32), + TC_SRC_UDP_OUT => tc_src_udp(4 * 16 - 1 downto 3 * 16), + + TC_BUSY_IN => TC_BUSY_IN, + + RECEIVED_FRAMES_OUT => RECEIVED_FRAMES_OUT(4 * 16 - 1 downto 3 * 16), + SENT_FRAMES_OUT => SENT_FRAMES_OUT(4 * 16 - 1 downto 3 * 16), + DEBUG_OUT => PROTOS_DEBUG_OUT(4 * 32 - 1 downto 3 * 32) +-- END OF INTERFACE +); + +Test1b : trb_net16_gbe_response_constructor_Test1 +port map ( + CLK => CLK, + RESET => RESET, + +-- INTERFACE + PS_DATA_IN => PS_DATA_IN, + PS_WR_EN_IN => PS_WR_EN_IN, + PS_ACTIVATE_IN => PS_PROTO_SELECT_IN(4), + PS_RESPONSE_READY_OUT => resp_ready(4), + PS_BUSY_OUT => busy(4), + PS_SELECTED_IN => selected(4), + + PS_SRC_MAC_ADDRESS_IN => PS_SRC_MAC_ADDRESS_IN, + PS_DEST_MAC_ADDRESS_IN => PS_DEST_MAC_ADDRESS_IN, + PS_SRC_IP_ADDRESS_IN => PS_SRC_IP_ADDRESS_IN, + PS_DEST_IP_ADDRESS_IN => PS_DEST_IP_ADDRESS_IN, + PS_SRC_UDP_PORT_IN => PS_SRC_UDP_PORT_IN, + PS_DEST_UDP_PORT_IN => PS_DEST_UDP_PORT_IN, + + TC_RD_EN_IN => TC_RD_EN_IN, + TC_DATA_OUT => tc_data(5 * 9 - 1 downto 4 * 9), + TC_FRAME_SIZE_OUT => tc_size(5 * 16 - 1 downto 4 * 16), + TC_FRAME_TYPE_OUT => tc_type(5 * 16 - 1 downto 4 * 16), + TC_IP_PROTOCOL_OUT => tc_ip_proto(5 * 8 - 1 downto 4 * 8), + + TC_DEST_MAC_OUT => tc_mac(5 * 48 - 1 downto 4 * 48), + TC_DEST_IP_OUT => tc_ip(5 * 32 - 1 downto 4 * 32), + TC_DEST_UDP_OUT => tc_udp(5 * 16 - 1 downto 4 * 16), + TC_SRC_MAC_OUT => tc_src_mac(5 * 48 - 1 downto 4 * 48), + TC_SRC_IP_OUT => tc_src_ip(5 * 32 - 1 downto 4 * 32), + TC_SRC_UDP_OUT => tc_src_udp(5 * 16 - 1 downto 4 * 16), + + TC_BUSY_IN => TC_BUSY_IN, + + RECEIVED_FRAMES_OUT => RECEIVED_FRAMES_OUT(5 * 16 - 1 downto 4 * 16), + SENT_FRAMES_OUT => SENT_FRAMES_OUT(5 * 16 - 1 downto 4 * 16), + DEBUG_OUT => PROTOS_DEBUG_OUT(5 * 32 - 1 downto 4 * 32) +); + +--*************** +-- DO NOT TOUCH, response selection logic +PS_BUSY_OUT <= busy; + +SELECTOR_PROC : process(CLK) + variable found : boolean := false; +begin + if rising_edge(CLK) then + + selected <= (others => '0'); + + if (RESET = '1') then + TC_DATA_OUT <= (others => '0'); + TC_FRAME_SIZE_OUT <= (others => '0'); + TC_FRAME_TYPE_OUT <= (others => '0'); + TC_DEST_MAC_OUT <= (others => '0'); + TC_DEST_IP_OUT <= (others => '0'); + TC_DEST_UDP_OUT <= (others => '0'); + TC_SRC_MAC_OUT <= (others => '0'); + TC_SRC_IP_OUT <= (others => '0'); + TC_SRC_UDP_OUT <= (others => '0'); + TC_IP_PROTOCOL_OUT <= (others => '0'); + PS_RESPONSE_READY_OUT <= '0'; + selected <= (others => '0'); + found := false; + else + if (or_all(resp_ready) = '1') then + for i in 0 to c_MAX_PROTOCOLS - 1 loop + if (resp_ready(i) = '1') then + TC_DATA_OUT <= tc_data((i + 1) * 9 - 1 downto i * 9); + TC_FRAME_SIZE_OUT <= tc_size((i + 1) * 16 - 1 downto i * 16); + TC_FRAME_TYPE_OUT <= tc_type((i + 1) * 16 - 1 downto i * 16); + TC_DEST_MAC_OUT <= tc_mac((i + 1) * 48 - 1 downto i * 48); + TC_DEST_IP_OUT <= tc_ip((i + 1) * 32 - 1 downto i * 32); + TC_DEST_UDP_OUT <= tc_udp((i + 1) * 16 - 1 downto i * 16); + TC_SRC_MAC_OUT <= tc_src_mac((i + 1) * 48 - 1 downto i * 48); + TC_SRC_IP_OUT <= tc_src_ip((i + 1) * 32 - 1 downto i * 32); + TC_SRC_UDP_OUT <= tc_src_udp((i + 1) * 16 - 1 downto i * 16); + TC_IP_PROTOCOL_OUT <= tc_ip_proto((i + 1) * 8 - 1 downto i * 8); + PS_RESPONSE_READY_OUT <= '1'; + selected(i) <= '1'; + found := true; + elsif (i = c_MAX_PROTOCOLS - 1) and (resp_ready(i) = '0') and (found = false) then + found := false; + PS_RESPONSE_READY_OUT <= '0'; + end if; + end loop; + else + TC_DATA_OUT <= (others => '0'); + TC_FRAME_SIZE_OUT <= (others => '0'); + TC_FRAME_TYPE_OUT <= (others => '0'); + TC_DEST_MAC_OUT <= (others => '0'); + TC_DEST_IP_OUT <= (others => '0'); + TC_DEST_UDP_OUT <= (others => '0'); + TC_SRC_MAC_OUT <= (others => '0'); + TC_SRC_IP_OUT <= (others => '0'); + TC_SRC_UDP_OUT <= (others => '0'); + TC_IP_PROTOCOL_OUT <= (others => '0'); + PS_RESPONSE_READY_OUT <= '0'; + found := false; + end if; + end if; + + end if; +end process SELECTOR_PROC; +-- ************ + +end trb_net16_gbe_protocol_selector; + + diff --git a/gbe2_ecp3/trb_net16_gbe_receive_control.vhd b/gbe2_ecp3/trb_net16_gbe_receive_control.vhd new file mode 100644 index 0000000..549ffbf --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_receive_control.vhd @@ -0,0 +1,227 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +use work.trb_net_gbe_components.all; +use work.trb_net_gbe_protocols.all; + +--******** +-- controller has to control the rest of the logic (TX part, TS_MAC, HUB) accordingly to +-- the message received from receiver, frame checking is already done +-- + + +entity trb_net16_gbe_receive_control is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- signals to/from frame_receiver + RC_DATA_IN : in std_logic_vector(8 downto 0); + FR_RD_EN_OUT : out std_logic; + FR_FRAME_VALID_IN : in std_logic; + FR_GET_FRAME_OUT : out std_logic; + FR_FRAME_SIZE_IN : in std_logic_vector(15 downto 0); + FR_FRAME_PROTO_IN : in std_logic_vector(15 downto 0); + FR_IP_PROTOCOL_IN : in std_logic_vector(7 downto 0); + + FR_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + FR_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + FR_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + FR_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + FR_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + FR_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + + +-- signals to/from main controller + RC_RD_EN_IN : in std_logic; + RC_Q_OUT : out std_logic_vector(8 downto 0); + RC_FRAME_WAITING_OUT : out std_logic; + RC_LOADING_DONE_IN : in std_logic; + RC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + RC_FRAME_PROTO_OUT : out std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); + + RC_SRC_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0); + RC_DEST_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0); + RC_SRC_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0); + RC_DEST_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0); + RC_SRC_UDP_PORT_OUT : out std_logic_vector(15 downto 0); + RC_DEST_UDP_PORT_OUT : out std_logic_vector(15 downto 0); + +-- statistics + FRAMES_RECEIVED_OUT : out std_logic_vector(31 downto 0); + BYTES_RECEIVED_OUT : out std_logic_vector(31 downto 0); + + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end trb_net16_gbe_receive_control; + + +architecture trb_net16_gbe_receive_control of trb_net16_gbe_receive_control is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_receive_control : architecture is "GBE_MAIN_group"; + +type load_states is (IDLE, PREPARE, READY); +signal load_current_state, load_next_state : load_states; + +signal frames_received_ctr : std_logic_vector(31 downto 0); +signal frames_readout_ctr : std_logic_vector(31 downto 0); +signal bytes_rec_ctr : std_logic_vector(31 downto 0); + +signal state : std_logic_vector(3 downto 0); +signal proto_code : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); +signal reset_prioritizer : std_logic; + +-- debug only +signal saved_proto : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); + +begin + +FR_RD_EN_OUT <= RC_RD_EN_IN; +RC_Q_OUT <= RC_DATA_IN; +RC_FRAME_SIZE_OUT <= FR_FRAME_SIZE_IN; +RC_SRC_MAC_ADDRESS_OUT <= FR_SRC_MAC_ADDRESS_IN; +RC_DEST_MAC_ADDRESS_OUT <= FR_DEST_MAC_ADDRESS_IN; +RC_SRC_IP_ADDRESS_OUT <= FR_SRC_IP_ADDRESS_IN; +RC_DEST_IP_ADDRESS_OUT <= FR_DEST_IP_ADDRESS_IN; +RC_SRC_UDP_PORT_OUT <= FR_SRC_UDP_PORT_IN; +RC_DEST_UDP_PORT_OUT <= FR_DEST_UDP_PORT_IN; + +protocol_prioritizer : trb_net16_gbe_protocol_prioritizer +port map( + CLK => CLK, + RESET => reset_prioritizer, + + FRAME_TYPE_IN => FR_FRAME_PROTO_IN, + PROTOCOL_CODE_IN => FR_IP_PROTOCOL_IN, + UDP_PROTOCOL_IN => FR_DEST_UDP_PORT_IN, + + CODE_OUT => proto_code +); + +reset_prioritizer <= '1' when load_current_state = IDLE else '0'; + +--RC_FRAME_PROTO_OUT <= proto_code when (and_all(proto_code) = '0') else (others => '0'); +RC_FRAME_PROTO_OUT <= proto_code; -- no more ones as the incorrect value, last slot for Trash + +DEBUG_OUT(3 downto 0) <= state; +DEBUG_OUT(11 downto 4) <= frames_received_ctr(7 downto 0); +DEBUG_OUT(19 downto 12) <= frames_readout_ctr(7 downto 0); +DEBUG_OUT(31 downto 20) <= bytes_rec_ctr(11 downto 0); + +LOAD_MACHINE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + load_current_state <= IDLE; + else + load_current_state <= load_next_state; + end if; + end if; +end process LOAD_MACHINE_PROC; + +LOAD_MACHINE : process(load_current_state, frames_readout_ctr, frames_received_ctr, RC_LOADING_DONE_IN) +begin + case load_current_state is + + when IDLE => + state <= x"1"; + if (frames_readout_ctr /= frames_received_ctr) then -- frame is still waiting in frame_receiver + load_next_state <= PREPARE; + else + load_next_state <= IDLE; + end if; + + when PREPARE => -- prepare frame size + state <= x"2"; + load_next_state <= READY; + + when READY => -- wait for reading out the whole frame + state <= x"3"; + if (RC_LOADING_DONE_IN = '1') then + load_next_state <= IDLE; + else + load_next_state <= READY; + end if; + + end case; +end process LOAD_MACHINE; + +FR_GET_FRAME_OUT <= '1' when (load_current_state = PREPARE) + else '0'; + +RC_FRAME_WAITING_OUT <= '1' when (load_current_state = READY) + else '0'; + +SYNC_PROC : process(CLK) +begin + if rising_edge(CLK) then + FRAMES_RECEIVED_OUT <= frames_received_ctr; + --BYTES_RECEIVED_OUT <= bytes_rec_ctr; + BYTES_RECEIVED_OUT(15 downto 0) <= bytes_rec_ctr(15 downto 0); + BYTES_RECEIVED_OUT(16 + c_MAX_PROTOCOLS - 1 downto 16) <= saved_proto; + BYTES_RECEIVED_OUT(31 downto 16 + c_MAX_PROTOCOLS) <= (others => '0'); + end if; +end process SYNC_PROC; + +FRAMES_REC_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + frames_received_ctr <= (others => '0'); + elsif (FR_FRAME_VALID_IN = '1') then + frames_received_ctr <= frames_received_ctr + x"1"; + end if; + end if; +end process FRAMES_REC_CTR_PROC; + +FRAMES_READOUT_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + frames_readout_ctr <= (others => '0'); + elsif (RC_LOADING_DONE_IN = '1') then + frames_readout_ctr <= frames_readout_ctr + x"1"; + end if; + end if; +end process FRAMES_READOUT_CTR_PROC; + +BYTES_REC_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + bytes_rec_ctr <= (others => '0'); + elsif (FR_FRAME_VALID_IN = '1') then + bytes_rec_ctr <= bytes_rec_ctr + FR_FRAME_SIZE_IN; + end if; + end if; +end process BYTES_REC_CTR_PROC; + +-- debug only +SAVED_PROTO_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + saved_proto <= (others => '0'); + elsif (load_current_state = READY) then + if (and_all(proto_code) = '0') then + saved_proto <= proto_code; + else + saved_proto <= (others => '0'); + end if; + end if; + end if; +end process SAVED_PROTO_PROC; +-- end of debug + + +end trb_net16_gbe_receive_control; + + diff --git a/gbe2_ecp3/trb_net16_gbe_response_constructor_ARP.vhd b/gbe2_ecp3/trb_net16_gbe_response_constructor_ARP.vhd new file mode 100644 index 0000000..444b014 --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_response_constructor_ARP.vhd @@ -0,0 +1,287 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +use work.trb_net_gbe_components.all; +use work.trb_net_gbe_protocols.all; + +--******** +-- creates a reply for an incoming ARP request + +entity trb_net16_gbe_response_constructor_ARP is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- INTERFACE + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_ACTIVATE_IN : in std_logic; + PS_RESPONSE_READY_OUT : out std_logic; + PS_BUSY_OUT : out std_logic; + PS_SELECTED_IN : in std_logic; + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + + TC_RD_EN_IN : in std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + + TC_BUSY_IN : in std_logic; + + RECEIVED_FRAMES_OUT : out std_logic_vector(15 downto 0); + SENT_FRAMES_OUT : out std_logic_vector(15 downto 0); +-- END OF INTERFACE + +-- debug + DEBUG_OUT : out std_logic_vector(31 downto 0) +); +end trb_net16_gbe_response_constructor_ARP; + + +architecture trb_net16_gbe_response_constructor_ARP of trb_net16_gbe_response_constructor_ARP is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_response_constructor_ARP : architecture is "GBE_MAIN_group"; + +attribute syn_encoding : string; + +type dissect_states is (IDLE, READ_FRAME, DECIDE, LOAD_FRAME, WAIT_FOR_LOAD, CLEANUP); +signal dissect_current_state, dissect_next_state : dissect_states; +attribute syn_encoding of dissect_current_state: signal is "safe,gray"; + +signal saved_opcode : std_logic_vector(15 downto 0); +signal saved_sender_ip : std_logic_vector(31 downto 0); +signal saved_target_ip : std_logic_vector(31 downto 0); +signal data_ctr : integer range 0 to 30; +signal values : std_logic_vector(223 downto 0); +signal tc_data : std_logic_vector(8 downto 0); + +signal state : std_logic_vector(3 downto 0); +signal rec_frames : std_logic_vector(15 downto 0); +signal sent_frames : std_logic_vector(15 downto 0); + +begin + +values(15 downto 0) <= x"0100"; -- hardware type +values(31 downto 16) <= x"0008"; -- protocol type +values(39 downto 32) <= x"06"; -- hardware size +values(47 downto 40) <= x"04"; -- protocol size +values(63 downto 48) <= x"0200"; --opcode (reply) +values(111 downto 64) <= g_MY_MAC; -- sender (my) mac +values(143 downto 112) <= g_MY_IP; +values(191 downto 144) <= PS_SRC_MAC_ADDRESS_IN; -- target mac +values(223 downto 192) <= saved_sender_ip; -- target ip + +DISSECT_MACHINE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + dissect_current_state <= IDLE; + else + dissect_current_state <= dissect_next_state; + end if; + end if; +end process DISSECT_MACHINE_PROC; + +DISSECT_MACHINE : process(dissect_current_state, g_MY_IP, PS_WR_EN_IN, PS_ACTIVATE_IN, PS_DATA_IN, TC_BUSY_IN, data_ctr, PS_SELECTED_IN, saved_target_ip) +begin + case dissect_current_state is + + when IDLE => + state <= x"1"; + if (PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then + dissect_next_state <= READ_FRAME; + else + dissect_next_state <= IDLE; + end if; + + when READ_FRAME => + state <= x"2"; + if (PS_DATA_IN(8) = '1') then + dissect_next_state <= DECIDE; + else + dissect_next_state <= READ_FRAME; + end if; + + when DECIDE => + state <= x"3"; + if (saved_target_ip = g_MY_IP) then + dissect_next_state <= WAIT_FOR_LOAD; + -- in case the request is not for me, drop it + else + dissect_next_state <= IDLE; + end if; + + when WAIT_FOR_LOAD => + state <= x"4"; + if (TC_BUSY_IN = '0' and PS_SELECTED_IN = '1') then + dissect_next_state <= LOAD_FRAME; + else + dissect_next_state <= WAIT_FOR_LOAD; + end if; + + when LOAD_FRAME => + state <= x"5"; + if (data_ctr = 28) then + dissect_next_state <= CLEANUP; + else + dissect_next_state <= LOAD_FRAME; + end if; + + when CLEANUP => + state <= x"e"; + dissect_next_state <= IDLE; + + end case; +end process DISSECT_MACHINE; + +DATA_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (dissect_current_state = IDLE) or (dissect_current_state = WAIT_FOR_LOAD) then + data_ctr <= 1; + elsif (dissect_current_state = READ_FRAME and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then -- in case of saving data from incoming frame + data_ctr <= data_ctr + 1; + elsif (dissect_current_state = LOAD_FRAME and TC_RD_EN_IN = '1' and PS_SELECTED_IN = '1') then -- in case of constructing response + data_ctr <= data_ctr + 1; + end if; + end if; +end process DATA_CTR_PROC; + +SAVE_VALUES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + saved_opcode <= (others => '0'); + saved_sender_ip <= (others => '0'); + saved_target_ip <= (others => '0'); + elsif (dissect_current_state = READ_FRAME) then + case (data_ctr) is + + when 7 => + saved_opcode(7 downto 0) <= PS_DATA_IN(7 downto 0); + when 8 => + saved_opcode(15 downto 8) <= PS_DATA_IN(7 downto 0); + + + when 14 => + saved_sender_ip(7 downto 0) <= PS_DATA_IN(7 downto 0); + when 15 => + saved_sender_ip(15 downto 8) <= PS_DATA_IN(7 downto 0); + when 16 => + saved_sender_ip(23 downto 16) <= PS_DATA_IN(7 downto 0); + when 17 => + saved_sender_ip(31 downto 24) <= PS_DATA_IN(7 downto 0); + + when 24 => + saved_target_ip(7 downto 0) <= PS_DATA_IN(7 downto 0); + when 25 => + saved_target_ip(15 downto 8) <= PS_DATA_IN(7 downto 0); + when 26 => + saved_target_ip(23 downto 16) <= PS_DATA_IN(7 downto 0); + when 27 => + saved_target_ip(31 downto 24) <= PS_DATA_IN(7 downto 0); + + when others => null; + end case; + end if; + end if; +end process SAVE_VALUES_PROC; + +TC_DATA_PROC : process(dissect_current_state, data_ctr, values) +begin + tc_data(8) <= '0'; + + if (dissect_current_state = LOAD_FRAME) then + for i in 0 to 7 loop + tc_data(i) <= values((data_ctr - 1) * 8 + i); + end loop; + -- mark the last byte + if (data_ctr = 28) then + tc_data(8) <= '1'; + end if; + else + tc_data(7 downto 0) <= (others => '0'); + end if; + +end process TC_DATA_PROC; + +TC_DATA_SYNC : process(CLK) +begin + if rising_edge(CLK) then + TC_DATA_OUT <= tc_data; + end if; +end process TC_DATA_SYNC; + +PS_BUSY_OUT <= '0' when (dissect_current_state = IDLE) else '1'; + +PS_RESPONSE_READY_OUT <= '1' when (dissect_current_state = WAIT_FOR_LOAD or dissect_current_state = LOAD_FRAME or dissect_current_state = CLEANUP) else '0'; + +TC_FRAME_SIZE_OUT <= x"001c"; -- fixed frame size + +TC_FRAME_TYPE_OUT <= x"0608"; +TC_DEST_MAC_OUT <= PS_SRC_MAC_ADDRESS_IN; +TC_DEST_IP_OUT <= x"00000000"; -- doesnt matter +TC_DEST_UDP_OUT <= x"0000"; -- doesnt matter +TC_SRC_MAC_OUT <= g_MY_MAC; +TC_SRC_IP_OUT <= x"00000000"; -- doesnt matter +TC_SRC_UDP_OUT <= x"0000"; -- doesnt matter +TC_IP_PROTOCOL_OUT <= x"00"; -- doesnt matter + +-- **** statistice +REC_FRAMES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + rec_frames <= (others => '0'); + elsif (dissect_current_state = IDLE and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then + rec_frames <= rec_frames + x"1"; + end if; + end if; +end process REC_FRAMES_PROC; + +SENT_FRAMES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + sent_frames <= (others => '0'); + elsif (dissect_current_state = CLEANUP) then + sent_frames <= sent_frames + x"1"; + end if; + end if; +end process SENT_FRAMES_PROC; + +RECEIVED_FRAMES_OUT <= rec_frames; +SENT_FRAMES_OUT <= sent_frames; + +-- **** debug +DEBUG_OUT(3 downto 0) <= state; +DEBUG_OUT(4) <= '0'; +DEBUG_OUT(7 downto 5) <= "000"; +DEBUG_OUT(8) <= '0'; +DEBUG_OUT(11 downto 9) <= "000"; +DEBUG_OUT(31 downto 12) <= (others => '0'); +-- **** + +end trb_net16_gbe_response_constructor_ARP; + + diff --git a/gbe2_ecp3/trb_net16_gbe_response_constructor_DHCP.vhd b/gbe2_ecp3/trb_net16_gbe_response_constructor_DHCP.vhd new file mode 100644 index 0000000..04fca1c --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_response_constructor_DHCP.vhd @@ -0,0 +1,659 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +use work.trb_net_gbe_components.all; +use work.trb_net_gbe_protocols.all; + +--******** +-- + +entity trb_net16_gbe_response_constructor_DHCP is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- INTERFACE + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_ACTIVATE_IN : in std_logic; + PS_RESPONSE_READY_OUT : out std_logic; + PS_BUSY_OUT : out std_logic; + PS_SELECTED_IN : in std_logic; + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + + TC_RD_EN_IN : in std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + + TC_BUSY_IN : in std_logic; + + RECEIVED_FRAMES_OUT : out std_logic_vector(15 downto 0); + SENT_FRAMES_OUT : out std_logic_vector(15 downto 0); +-- END OF INTERFACE + + DHCP_START_IN : in std_logic; + DHCP_DONE_OUT : out std_logic; + +-- debug + DEBUG_OUT : out std_logic_vector(31 downto 0) +); +end trb_net16_gbe_response_constructor_DHCP; + + +architecture trb_net16_gbe_response_constructor_DHCP of trb_net16_gbe_response_constructor_DHCP is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_response_constructor_DHCP : architecture is "GBE_MAIN_group"; + +attribute syn_encoding : string; + +type main_states is (BOOTING, SENDING_DISCOVER, WAITING_FOR_OFFER, SENDING_REQUEST, WAITING_FOR_ACK, ESTABLISHED); +signal main_current_state, main_next_state : main_states; +attribute syn_encoding of main_current_state: signal is "safe,gray"; + +type receive_states is (IDLE, DISCARD, CLEANUP, SAVE_VALUES); +signal receive_current_state, receive_next_state : receive_states; +attribute syn_encoding of receive_current_state: signal is "safe,gray"; + +type discover_states is (IDLE, BOOTP_HEADERS, CLIENT_IP, YOUR_IP, ZEROS1, MY_MAC, ZEROS2, VENDOR_VALS, VENDOR_VALS2, TERMINATION, CLEANUP); +signal construct_current_state, construct_next_state : discover_states; +attribute syn_encoding of construct_current_state: signal is "safe,gray"; + +signal state : std_logic_vector(3 downto 0); +signal rec_frames : std_logic_vector(15 downto 0); +signal sent_frames : std_logic_vector(15 downto 0); + +signal wait_ctr : std_logic_vector(31 downto 0); -- wait for 5 sec before sending request +signal load_ctr : integer range 0 to 600 := 0; + +signal bootp_hdr : std_logic_vector(95 downto 0); + +signal tc_data : std_logic_vector(8 downto 0); +signal vendor_values : std_logic_vector(175 downto 0); +signal save_ctr : integer range 0 to 600 := 0; +signal saved_transaction_id : std_logic_vector(31 downto 0); +signal saved_proposed_ip : std_logic_vector(31 downto 0); +signal saved_dhcp_type : std_logic_vector(23 downto 0); +signal saved_true_ip : std_logic_vector(31 downto 0); +signal transaction_id : std_logic_vector(31 downto 0); +signal client_ip_reg : std_logic_vector(31 downto 0); +signal your_ip_reg : std_logic_vector(31 downto 0); +signal saved_server_mac : std_logic_vector(47 downto 0); +signal saved_server_ip : std_logic_vector(31 downto 0); +signal state2 : std_logic_vector(3 downto 0); +signal state3 : std_logic_vector(3 downto 0); +signal vendor_values2 : std_logic_vector(47 downto 0); + +signal discarded_ctr : std_logic_vector(15 downto 0); + +begin + + +-- **** +-- fixing the constant values for DHCP request headers +TC_DEST_MAC_OUT <= x"ffffffffffff" when (main_current_state = BOOTING or main_current_state = SENDING_DISCOVER) else saved_server_mac; +TC_DEST_IP_OUT <= x"ffffffff" when (main_current_state = BOOTING or main_current_state = SENDING_DISCOVER) else saved_server_ip; +TC_DEST_UDP_OUT <= x"4300"; +TC_SRC_MAC_OUT <= g_MY_MAC; +TC_SRC_IP_OUT <= x"00000000" when (main_current_state = BOOTING or main_current_state = SENDING_DISCOVER) else saved_proposed_ip; +TC_SRC_UDP_OUT <= x"4400"; +TC_IP_PROTOCOL_OUT <= x"11"; -- udp +bootp_hdr(7 downto 0) <= x"01"; -- message type(request) +bootp_hdr(15 downto 8) <= x"01"; -- hardware type (eth) +bootp_hdr(23 downto 16) <= x"06"; -- hardware address length +bootp_hdr(31 downto 24) <= x"00"; -- hops +bootp_hdr(63 downto 32) <= transaction_id; -- transaction id; +bootp_hdr(95 downto 64) <= x"0000_0000"; -- seconds elapsed/flags +transaction_id <= x"cefa_adde"; +vendor_values(31 downto 0) <= x"63538263"; -- magic cookie (dhcp message) +vendor_values(55 downto 32) <= x"010135" when (main_current_state = BOOTING or main_current_state = SENDING_DISCOVER) else x"030135"; -- dhcp discover, then dhcp request +vendor_values(79 downto 56) <= x"01073d"; -- client identifier +vendor_values(127 downto 80) <= g_MY_MAC; -- client identifier +vendor_values(143 downto 128) <= x"040c"; -- client name +vendor_values(175 downto 144) <= x"33425254"; -- client name (TRB3) +vendor_values2(15 downto 0) <= x"0436"; -- server identifier +vendor_values2(47 downto 16) <= saved_server_ip; + +--***************** +-- setting of global variable for IP address +g_MY_IP <= saved_true_ip when main_current_state = ESTABLISHED else (others => '0'); +-- +--***************** + +SAVE_SERVER_ADDR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + saved_server_mac <= (others => '0'); + saved_server_ip <= (others => '0'); + elsif (main_current_state = WAITING_FOR_OFFER) and (receive_current_state = SAVE_VALUES and save_ctr = 1) then + saved_server_mac <= PS_SRC_MAC_ADDRESS_IN; + saved_server_ip <= PS_SRC_IP_ADDRESS_IN; + end if; + end if; +end process SAVE_SERVER_ADDR_PROC; + + +-- **** MAIN MACHINE PART + +MAIN_MACHINE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + main_current_state <= BOOTING; + else + main_current_state <= main_next_state; + end if; + end if; +end process MAIN_MACHINE_PROC; + +MAIN_MACHINE : process(main_current_state, DHCP_START_IN, construct_current_state, wait_ctr, receive_current_state, PS_DATA_IN) +begin + + case (main_current_state) is + + when BOOTING => + state2 <= x"1"; + if (DHCP_START_IN = '1') then + --if (wait_ctr = x"3baa_ca00") then -- wait for 10 sec + --if (wait_ctr = x"0000_0010") then -- for sim only + main_next_state <= SENDING_DISCOVER; + else + main_next_state <= BOOTING; + end if; + + when SENDING_DISCOVER => + state2 <= x"2"; + if (construct_current_state = CLEANUP) then + main_next_state <= WAITING_FOR_OFFER; + else + main_next_state <= SENDING_DISCOVER; + end if; + + when WAITING_FOR_OFFER => + state2 <= x"3"; + if (receive_current_state = SAVE_VALUES) and (PS_DATA_IN(8) = '1') then + main_next_state <= SENDING_REQUEST; + else + main_next_state <= WAITING_FOR_OFFER; + end if; + + when SENDING_REQUEST => + state2 <= x"4"; + if (construct_current_state = CLEANUP) then + main_next_state <= WAITING_FOR_ACK; + else + main_next_state <= SENDING_REQUEST; + end if; + + when WAITING_FOR_ACK => + state2 <= x"5"; + if (receive_current_state = SAVE_VALUES) and (PS_DATA_IN(8) = '1') then + main_next_state <= ESTABLISHED; + else + main_next_state <= WAITING_FOR_ACK; + end if; + + when ESTABLISHED => + state2 <= x"6"; + if (saved_proposed_ip = saved_true_ip) then + main_next_state <= ESTABLISHED; + else + main_next_state <= BOOTING; + end if; + + end case; + +end process MAIN_MACHINE; + +WAIT_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (main_current_state = ESTABLISHED) then + wait_ctr <= (others => '0'); + elsif (main_current_state = BOOTING) then + wait_ctr <= wait_ctr + x"1"; + end if; + end if; +end process WAIT_CTR_PROC; + +DHCP_DONE_OUT <= '1' when main_current_state = ESTABLISHED else '0'; + + +-- **** MESSAGES RECEIVEING PART + +RECEIVE_MACHINE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + receive_current_state <= IDLE; + else + receive_current_state <= receive_next_state; + end if; + end if; +end process RECEIVE_MACHINE_PROC; + +RECEIVE_MACHINE : process(receive_current_state, main_current_state, PS_DATA_IN, PS_DEST_MAC_ADDRESS_IN, g_MY_MAC, PS_ACTIVATE_IN, PS_WR_EN_IN, save_ctr) +begin + case receive_current_state is + + when IDLE => + state3 <= x"1"; + if (PS_ACTIVATE_IN = '1' and PS_WR_EN_IN = '1') then + if (main_current_state = WAITING_FOR_OFFER or main_current_state = WAITING_FOR_ACK) then -- ready to receive dhcp frame + if (PS_DEST_MAC_ADDRESS_IN = g_MY_MAC) then -- check if i'm the addressee (discards broadcasts also) + receive_next_state <= SAVE_VALUES; + else + receive_next_state <= DISCARD; -- discard if the frame is not for me + end if; + else + receive_next_state <= DISCARD; -- discard if the frame arrived at wrong time + end if; + else + receive_next_state <= IDLE; + end if; + + when SAVE_VALUES => + state3 <= x"2"; + if (PS_DATA_IN(8) = '1') then + receive_next_state <= CLEANUP; + -- check if the same transaction + elsif (save_ctr = 9) and (saved_transaction_id /= bootp_hdr(63 downto 32)) then + receive_next_state <= DISCARD; + -- if the wrong message at the wrong time + elsif (main_current_state = WAITING_FOR_OFFER) and (save_ctr = 242) and (saved_dhcp_type /= x"020135") then + receive_next_state <= DISCARD; + -- if the wrong message at the wrong time + elsif (main_current_state = WAITING_FOR_ACK) and (save_ctr = 242) and (saved_dhcp_type /= x"050135") then + receive_next_state <= DISCARD; + else + receive_next_state <= SAVE_VALUES; + end if; + + when DISCARD => + state3 <= x"3"; + if (PS_DATA_IN(8) = '1') then + receive_next_state <= CLEANUP; + else + receive_next_state <= DISCARD; + end if; + + when CLEANUP => + state3 <= x"4"; + receive_next_state <= IDLE; + + end case; + +end process RECEIVE_MACHINE; + +SAVE_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (receive_current_state = IDLE) then + save_ctr <= 0; + elsif (receive_current_state = SAVE_VALUES and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then + save_ctr <= save_ctr + 1; + end if; + end if; +end process SAVE_CTR_PROC; + +SAVE_VALUES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + saved_transaction_id <= (others => '0'); + saved_proposed_ip <= (others => '0'); + saved_dhcp_type <= (others => '0'); + -- dissection of DHCP Offer message + elsif (main_current_state = WAITING_FOR_OFFER and receive_current_state = SAVE_VALUES) then + + case save_ctr is + + when 3 => + saved_transaction_id(7 downto 0) <= PS_DATA_IN(7 downto 0); + + when 4 => + saved_transaction_id(15 downto 8) <= PS_DATA_IN(7 downto 0); + + when 5 => + saved_transaction_id(23 downto 16) <= PS_DATA_IN(7 downto 0); + + when 6 => + saved_transaction_id(31 downto 24) <= PS_DATA_IN(7 downto 0); + + + when 15 => + saved_proposed_ip(7 downto 0) <= PS_DATA_IN(7 downto 0); + + when 16 => + saved_proposed_ip(15 downto 8) <= PS_DATA_IN(7 downto 0); + + when 17 => + saved_proposed_ip(23 downto 16) <= PS_DATA_IN(7 downto 0); + + when 18 => + saved_proposed_ip(31 downto 24) <= PS_DATA_IN(7 downto 0); + + + when 239 => + saved_dhcp_type(7 downto 0) <= PS_DATA_IN(7 downto 0); + + when 240 => + saved_dhcp_type(15 downto 8) <= PS_DATA_IN(7 downto 0); + + when 241 => + saved_dhcp_type(23 downto 16) <= PS_DATA_IN(7 downto 0); + + when others => null; + + end case; + -- dissection on DHCP Ack message + elsif (main_current_state = WAITING_FOR_ACK and receive_current_state = SAVE_VALUES) then + + case save_ctr is + + when 3 => + saved_transaction_id(7 downto 0) <= PS_DATA_IN(7 downto 0); + + when 4 => + saved_transaction_id(15 downto 8) <= PS_DATA_IN(7 downto 0); + + when 5 => + saved_transaction_id(23 downto 16) <= PS_DATA_IN(7 downto 0); + + when 6 => + saved_transaction_id(31 downto 24) <= PS_DATA_IN(7 downto 0); + + + when 15 => + saved_true_ip(7 downto 0) <= PS_DATA_IN(7 downto 0); + + when 16 => + saved_true_ip(15 downto 8) <= PS_DATA_IN(7 downto 0); + + when 17 => + saved_true_ip(23 downto 16) <= PS_DATA_IN(7 downto 0); + + when 18 => + saved_true_ip(31 downto 24) <= PS_DATA_IN(7 downto 0); + + + when 239 => + saved_dhcp_type(7 downto 0) <= PS_DATA_IN(7 downto 0); + + when 240 => + saved_dhcp_type(15 downto 8) <= PS_DATA_IN(7 downto 0); + + when 241 => + saved_dhcp_type(23 downto 16) <= PS_DATA_IN(7 downto 0); + + when others => null; + + end case; + + end if; + end if; +end process SAVE_VALUES_PROC; + + +-- **** MESSAGES CONSTRUCTING PART + +CONSTRUCT_MACHINE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + construct_current_state <= IDLE; + else + construct_current_state <= construct_next_state; + end if; + end if; +end process CONSTRUCT_MACHINE_PROC; + +CONSTRUCT_MACHINE : process(construct_current_state, main_current_state, load_ctr) +begin + case construct_current_state is + + when IDLE => + state <= x"1"; + if (main_current_state = SENDING_DISCOVER) or (main_current_state = SENDING_REQUEST) then + construct_next_state <= BOOTP_HEADERS; + else + construct_next_state <= IDLE; + end if; + + when BOOTP_HEADERS => + state <= x"3"; + if (load_ctr = 11) then + construct_next_state <= CLIENT_IP; + else + construct_next_state <= BOOTP_HEADERS; + end if; + + when CLIENT_IP => + state <= x"5"; + if (load_ctr = 15) then + construct_next_state <= YOUR_IP; + else + construct_next_state <= CLIENT_IP; + end if; + + when YOUR_IP => + state <= x"b"; + if (load_ctr = 19) then + construct_next_state <= ZEROS1; + else + construct_next_state <= YOUR_IP; + end if; + + when ZEROS1 => + state <= x"c"; + if (load_ctr = 27) then + construct_next_state <= MY_MAC; + else + construct_next_state <= ZEROS1; + end if; + + when MY_MAC => + state <= x"6"; + if (load_ctr = 33) then + construct_next_state <= ZEROS2; + else + construct_next_state <= MY_MAC; + end if; + + when ZEROS2 => + state <= x"7"; + if (load_ctr = 235) then + construct_next_state <= VENDOR_VALS; + else + construct_next_state <= ZEROS2; + end if; + + when VENDOR_VALS => + state <= x"8"; + if (load_ctr = 257) then + -- for discover it's enough of values + if (main_current_state = SENDING_DISCOVER) then + construct_next_state <= TERMINATION; + -- for request there is some more values needed + else + construct_next_state <= VENDOR_VALS2; + end if; + else + construct_next_state <= VENDOR_VALS; + end if; + + when VENDOR_VALS2 => + state <= x"d"; + if (load_ctr = 263) then + construct_next_state <= TERMINATION; + else + construct_next_state <= VENDOR_VALS2; + end if; + + when TERMINATION => + state <= x"e"; + construct_next_state <= CLEANUP; + + when CLEANUP => + state <= x"9"; + construct_next_state <= IDLE; + + end case; +end process CONSTRUCT_MACHINE; + +LOAD_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (construct_current_state = IDLE) then + load_ctr <= 0; + elsif (TC_RD_EN_IN = '1') and (PS_SELECTED_IN = '1') then + load_ctr <= load_ctr + 1; + end if; + end if; +end process LOAD_CTR_PROC; + +TC_DATA_PROC : process(construct_current_state, load_ctr, bootp_hdr, g_MY_MAC, main_current_state) +begin + + tc_data(8) <= '0'; + + case (construct_current_state) is + + when BOOTP_HEADERS => + for i in 0 to 7 loop + tc_data(i) <= bootp_hdr(load_ctr * 8 + i); + end loop; + + when CLIENT_IP => + if (main_current_state = SENDING_DISCOVER) then + tc_data(7 downto 0) <= x"00"; + elsif (main_current_state = SENDING_REQUEST) then + for i in 0 to 7 loop + tc_data(i) <= saved_proposed_ip((load_ctr - 12) * 8 + i); + end loop; + end if; + + when YOUR_IP => + tc_data(7 downto 0) <= x"00"; + + when ZEROS1 => + tc_data(7 downto 0) <= x"00"; + + when MY_MAC => + for i in 0 to 7 loop + tc_data(i) <= g_MY_MAC((load_ctr - 28) * 8 + i); + end loop; + + when ZEROS2 => + tc_data(7 downto 0) <= x"00"; + + when VENDOR_VALS => + for i in 0 to 7 loop + tc_data(i) <= vendor_values((load_ctr - 236) * 8 + i); + end loop; + + -- needed only for DHCP Request message + when VENDOR_VALS2 => + for i in 0 to 7 loop + tc_data(i) <= vendor_values2((load_ctr - 258) * 8 + i); + end loop; + + when TERMINATION => + tc_data(7 downto 0) <= x"ff"; + tc_data(8) <= '1'; + + when others => tc_data(7 downto 0) <= x"00"; + + end case; + +end process; + +TC_DATA_SYNC : process(CLK) +begin + if rising_edge(CLK) then + TC_DATA_OUT <= tc_data; + end if; +end process TC_DATA_SYNC; + + +PS_BUSY_OUT <= '0' when (construct_current_state = IDLE) else '1'; + +PS_RESPONSE_READY_OUT <= '0' when (construct_current_state = IDLE) else '1'; + +-- fixed sizes for discover and request messages +TC_FRAME_SIZE_OUT <= x"0103" when (main_current_state = SENDING_DISCOVER) else x"0109"; + +TC_FRAME_TYPE_OUT <= x"0008"; -- frame type: ip + +-- **** statistics +REC_FRAMES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + rec_frames <= (others => '0'); + --elsif (receive_current_state = IDLE and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then + elsif (receive_current_state = SAVE_VALUES and PS_DATA_IN(8) = '1') then + rec_frames <= rec_frames + x"1"; + end if; + end if; +end process REC_FRAMES_PROC; + +SENT_FRAMES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + sent_frames <= (others => '0'); + elsif (construct_current_state = CLEANUP) then + sent_frames <= sent_frames + x"1"; + end if; + end if; +end process SENT_FRAMES_PROC; + +RECEIVED_FRAMES_OUT <= rec_frames; +SENT_FRAMES_OUT <= sent_frames; +-- **** + + +-- **** debug +DEBUG_OUT(3 downto 0) <= state; +DEBUG_OUT(7 downto 4) <= state2; +DEBUG_OUT(11 downto 8) <= state3; +DEBUG_OUT(15 downto 12) <= (others => '0'); +DEBUG_OUT(31 downto 16) <= discarded_ctr; + +DISCARDED_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + discarded_ctr <= (others => '0'); + elsif (receive_current_state = DISCARD and PS_DATA_IN(8) = '1') then + discarded_ctr <= discarded_ctr + x"1"; + end if; + end if; +end process DISCARDED_CTR_PROC; +-- **** + +end trb_net16_gbe_response_constructor_DHCP; + + diff --git a/gbe2_ecp3/trb_net16_gbe_response_constructor_Forward.vhd b/gbe2_ecp3/trb_net16_gbe_response_constructor_Forward.vhd new file mode 100644 index 0000000..b5ef95b --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_response_constructor_Forward.vhd @@ -0,0 +1,236 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +use work.trb_net_gbe_components.all; + +--******** +-- Response Constructor which forwards received frame back ceating a loopback +-- + +entity trb_net16_gbe_response_constructor_Forward is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- INTERFACE + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_ACTIVATE_IN : in std_logic; + PS_RESPONSE_READY_OUT : out std_logic; + PS_BUSY_OUT : out std_logic; + PS_SELECTED_IN : in std_logic; + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + + TC_RD_EN_IN : in std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + + TC_BUSY_IN : in std_logic; + + RECEIVED_FRAMES_OUT : out std_logic_vector(15 downto 0); + SENT_FRAMES_OUT : out std_logic_vector(15 downto 0); +-- END OF INTERFACE + +-- debug + DEBUG_OUT : out std_logic_vector(31 downto 0) +); +end trb_net16_gbe_response_constructor_Forward; + + +architecture trb_net16_gbe_response_constructor_Forward of trb_net16_gbe_response_constructor_Forward is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_response_constructor_Forward : architecture is "GBE_MAIN_group"; + +attribute syn_encoding : string; + +type dissect_states is (IDLE, SAVE, WAIT_FOR_LOAD, LOAD, CLEANUP); +signal dissect_current_state, dissect_next_state : dissect_states; +attribute syn_encoding of dissect_current_state: signal is "safe,gray"; + +signal ff_wr_en : std_logic; +signal ff_rd_en : std_logic; +signal resp_bytes_ctr : std_logic_vector(15 downto 0); +signal ff_empty : std_logic; +signal ff_full : std_logic; +signal ff_q : std_logic_vector(8 downto 0); +signal ff_rd_lock : std_logic; + +signal state : std_logic_vector(3 downto 0); +signal rec_frames : std_logic_vector(15 downto 0); +signal sent_frames : std_logic_vector(15 downto 0); + +begin + +DISSECT_MACHINE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + dissect_current_state <= IDLE; + else + dissect_current_state <= dissect_next_state; + end if; + end if; +end process DISSECT_MACHINE_PROC; + +DISSECT_MACHINE : process(dissect_current_state, PS_WR_EN_IN, PS_ACTIVATE_IN, PS_DATA_IN, ff_q, ff_rd_lock, TC_BUSY_IN) +begin + case dissect_current_state is + + when IDLE => + state <= x"1"; + if (PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then + dissect_next_state <= SAVE; + else + dissect_next_state <= IDLE; + end if; + + when SAVE => + state <= x"2"; + if (PS_DATA_IN(8) = '1') then + dissect_next_state <= WAIT_FOR_LOAD; + else + dissect_next_state <= SAVE; + end if; + + when WAIT_FOR_LOAD => + state <= x"3"; + if (TC_BUSY_IN = '0') then + dissect_next_state <= LOAD; + else + dissect_next_state <= WAIT_FOR_LOAD; + end if; + + when LOAD => + state <= x"4"; + if (ff_q(8) = '1') and (ff_rd_lock = '0') then + dissect_next_state <= CLEANUP; + else + dissect_next_state <= LOAD; + end if; + + when CLEANUP => + state <= x"5"; + dissect_next_state <= IDLE; + + end case; +end process DISSECT_MACHINE; + +--PS_BUSY_OUT <= '1' when ff_wr_en = '1' else '0'; +PS_BUSY_OUT <= '0' when dissect_current_state = IDLE else '1'; + +ff_wr_en <= '1' when (PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') else '0'; + +FF_RD_LOCK_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + ff_rd_lock <= '1'; + elsif (dissect_current_state = LOAD and ff_rd_en = '1') then + ff_rd_lock <= '0'; + else + ff_rd_lock <= '1'; + end if; + end if; +end process FF_RD_LOCK_PROC; + +-- TODO: put a smaller fifo here +FRAME_FIFO: fifo_4096x9 +port map( + Data => PS_DATA_IN, + WrClock => CLK, + RdClock => CLK, + WrEn => ff_wr_en, + RdEn => ff_rd_en, + Reset => RESET, + RPReset => RESET, + Q => ff_q, + Empty => ff_empty, + Full => ff_full +); + +ff_rd_en <= '1' when (TC_RD_EN_IN = '1' and PS_SELECTED_IN = '1') else '0'; + +TC_DATA_OUT <= ff_q; + +PS_RESPONSE_READY_OUT <= '1' when (dissect_current_state = LOAD) else '0'; + +TC_FRAME_SIZE_OUT <= resp_bytes_ctr + x"1"; + +TC_FRAME_TYPE_OUT <= x"0008"; +TC_DEST_MAC_OUT <= x"9a680f201300"; +TC_DEST_IP_OUT <= x"0100a8c0"; +TC_DEST_UDP_OUT <= x"50c3"; +TC_SRC_MAC_OUT <= x"efbeefbe0000"; +TC_SRC_IP_OUT <= x"0b00a8c0"; +TC_SRC_UDP_OUT <= x"50c3"; +TC_IP_PROTOCOL_OUT <= x"11"; + +RESP_BYTES_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (dissect_current_state = IDLE) then + resp_bytes_ctr <= (others => '0'); + elsif (dissect_current_state = SAVE) then + resp_bytes_ctr <= resp_bytes_ctr + x"1"; + end if; + end if; +end process RESP_BYTES_CTR_PROC; + +REC_FRAMES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + rec_frames <= (others => '0'); + elsif (dissect_current_state = IDLE and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then + rec_frames <= rec_frames + x"1"; + end if; + end if; +end process REC_FRAMES_PROC; + +SENT_FRAMES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + sent_frames <= (others => '0'); + elsif (dissect_current_state = WAIT_FOR_LOAD and TC_BUSY_IN = '0') then + sent_frames <= sent_frames + x"1"; + end if; + end if; +end process SENT_FRAMES_PROC; + +RECEIVED_FRAMES_OUT <= rec_frames; +SENT_FRAMES_OUT <= sent_frames; + +-- **** debug +DEBUG_OUT(3 downto 0) <= state; +DEBUG_OUT(4) <= ff_empty; +DEBUG_OUT(7 downto 5) <= "000"; +DEBUG_OUT(8) <= ff_full; +DEBUG_OUT(11 downto 9) <= "000"; +DEBUG_OUT(31 downto 12) <= (others => '0'); +-- **** + +end trb_net16_gbe_response_constructor_Forward; + + diff --git a/gbe2_ecp3/trb_net16_gbe_response_constructor_Ping.vhd b/gbe2_ecp3/trb_net16_gbe_response_constructor_Ping.vhd new file mode 100644 index 0000000..ddcd6a6 --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_response_constructor_Ping.vhd @@ -0,0 +1,299 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +use work.trb_net_gbe_components.all; +use work.trb_net_gbe_protocols.all; + +--******** +-- Response Constructor which responds to Ping messages +-- + +entity trb_net16_gbe_response_constructor_Ping is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- INTERFACE + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_ACTIVATE_IN : in std_logic; + PS_RESPONSE_READY_OUT : out std_logic; + PS_BUSY_OUT : out std_logic; + PS_SELECTED_IN : in std_logic; + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + + TC_RD_EN_IN : in std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + + TC_BUSY_IN : in std_logic; + + RECEIVED_FRAMES_OUT : out std_logic_vector(15 downto 0); + SENT_FRAMES_OUT : out std_logic_vector(15 downto 0); +-- END OF INTERFACE + +-- debug + DEBUG_OUT : out std_logic_vector(31 downto 0) +); +end trb_net16_gbe_response_constructor_Ping; + + +architecture trb_net16_gbe_response_constructor_Ping of trb_net16_gbe_response_constructor_Ping is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_response_constructor_Ping : architecture is "GBE_MAIN_group"; + +attribute syn_encoding : string; + +type dissect_states is (IDLE, READ_FRAME, WAIT_FOR_LOAD, LOAD_FRAME, CLEANUP); +signal dissect_current_state, dissect_next_state : dissect_states; +attribute syn_encoding of dissect_current_state: signal is "safe,gray"; + + +signal state : std_logic_vector(3 downto 0); +signal rec_frames : std_logic_vector(15 downto 0); +signal sent_frames : std_logic_vector(15 downto 0); + +signal saved_data : std_logic_vector(447 downto 0); +signal saved_headers : std_logic_vector(63 downto 0); + +signal data_ctr : integer range 1 to 66; +signal data_length : integer range 1 to 66; +signal tc_data : std_logic_vector(8 downto 0); + +signal checksum : std_logic_vector(15 downto 0); + +begin + +DISSECT_MACHINE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + dissect_current_state <= IDLE; + else + dissect_current_state <= dissect_next_state; + end if; + end if; +end process DISSECT_MACHINE_PROC; + +DISSECT_MACHINE : process(dissect_current_state, PS_WR_EN_IN, PS_ACTIVATE_IN, PS_DATA_IN, TC_BUSY_IN, data_ctr, data_length) +begin + case dissect_current_state is + + when IDLE => + state <= x"1"; + if (PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then + dissect_next_state <= READ_FRAME; + else + dissect_next_state <= IDLE; + end if; + + when READ_FRAME => + state <= x"2"; + if (PS_DATA_IN(8) = '1') then + dissect_next_state <= WAIT_FOR_LOAD; + else + dissect_next_state <= READ_FRAME; + end if; + + when WAIT_FOR_LOAD => + state <= x"3"; + if (TC_BUSY_IN = '0') then + dissect_next_state <= LOAD_FRAME; + else + dissect_next_state <= WAIT_FOR_LOAD; + end if; + + when LOAD_FRAME => + state <= x"4"; + if (data_ctr = data_length + 1) then + dissect_next_state <= CLEANUP; + else + dissect_next_state <= LOAD_FRAME; + end if; + + when CLEANUP => + state <= x"5"; + dissect_next_state <= IDLE; + + end case; +end process DISSECT_MACHINE; + +DATA_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (dissect_current_state = IDLE) or (dissect_current_state = WAIT_FOR_LOAD) then + data_ctr <= 2; + elsif (dissect_current_state = READ_FRAME and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then -- in case of saving data from incoming frame + data_ctr <= data_ctr + 1; + elsif (dissect_current_state = LOAD_FRAME and TC_RD_EN_IN = '1' and PS_SELECTED_IN = '1') then -- in case of constructing response + data_ctr <= data_ctr + 1; + end if; + end if; +end process DATA_CTR_PROC; + +DATA_LENGTH_PROC: process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + data_length <= 1; + elsif (dissect_current_state = READ_FRAME and PS_DATA_IN(8) = '1') then + data_length <= data_ctr; + end if; + end if; +end process DATA_LENGTH_PROC; + +SAVE_VALUES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + saved_headers <= (others => '0'); + saved_data <= (others => '0'); + elsif (dissect_current_state = IDLE and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then + saved_headers(7 downto 0) <= PS_DATA_IN(7 downto 0); + elsif (dissect_current_state = READ_FRAME) then + if (data_ctr < 9) then -- headers + saved_headers(data_ctr * 8 - 1 downto (data_ctr - 1) * 8) <= PS_DATA_IN(7 downto 0); + else + saved_data((data_ctr - 8) * 8 - 1 downto (data_ctr - 9) * 8) <= PS_DATA_IN(7 downto 0); + end if; + elsif (dissect_current_state = LOAD_FRAME) then + saved_headers(7 downto 0) <= x"00"; + saved_headers(23 downto 16) <= checksum(15 downto 8); + saved_headers(31 downto 24) <= checksum(7 downto 0); + end if; + end if; +end process SAVE_VALUES_PROC; + +CS_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + checksum(15 downto 0) <= (others => '0'); + elsif (dissect_current_state = READ_FRAME and data_ctr > 4) then + if (std_logic_vector(to_unsigned(data_ctr, 1)) = "0") then + checksum(7 downto 0) <= checksum(7 downto 0) + PS_DATA_IN(7 downto 0); + else + checksum(15 downto 8) <= checksum(15 downto 8) + PS_DATA_IN(7 downto 0); + end if; + end if; + end if; +end process CS_PROC; + +TC_DATA_PROC : process(dissect_current_state, data_ctr, saved_headers, saved_data, data_length) +begin + tc_data(8) <= '0'; + + if (dissect_current_state = LOAD_FRAME) then + if (data_ctr < 10) then -- headers + for i in 0 to 7 loop + tc_data(i) <= saved_headers((data_ctr - 2) * 8 + i); + end loop; + else -- data + for i in 0 to 7 loop + tc_data(i) <= saved_data((data_ctr - 10) * 8 + i); + end loop; + + -- mark the last byte + if (data_ctr = data_length + 1) then + tc_data(8) <= '1'; + end if; + end if; + else + tc_data(7 downto 0) <= (others => '0'); + end if; + +end process TC_DATA_PROC; + +TC_DATA_SYNC : process(CLK) +begin + if rising_edge(CLK) then + TC_DATA_OUT <= tc_data; + end if; +end process TC_DATA_SYNC; + + +PS_BUSY_OUT <= '0' when (dissect_current_state = IDLE) else '1'; + +PS_RESPONSE_READY_OUT <= '1' when (dissect_current_state = WAIT_FOR_LOAD or dissect_current_state = LOAD_FRAME or dissect_current_state = CLEANUP) else '0'; + +TC_FRAME_SIZE_OUT <= std_logic_vector(to_unsigned(data_length, 16)); + +TC_FRAME_TYPE_OUT <= x"0008"; +--TC_DEST_MAC_OUT <= x"9a680f201300"; +--TC_DEST_IP_OUT <= x"00000000"; +TC_DEST_UDP_OUT <= x"0000"; -- not used +TC_SRC_MAC_OUT <= g_MY_MAC; +TC_SRC_IP_OUT <= g_MY_IP; +TC_SRC_UDP_OUT <= x"0000"; -- not used +TC_IP_PROTOCOL_OUT <= X"01"; -- ICMP + +ADDR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (dissect_current_state = READ_FRAME) then + TC_DEST_MAC_OUT <= PS_SRC_MAC_ADDRESS_IN; + TC_DEST_IP_OUT <= PS_SRC_IP_ADDRESS_IN; + end if; + end if; +end process ADDR_PROC; + +-- statistics + +REC_FRAMES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + rec_frames <= (others => '0'); + elsif (dissect_current_state = IDLE and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then + rec_frames <= rec_frames + x"1"; + end if; + end if; +end process REC_FRAMES_PROC; + +SENT_FRAMES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + sent_frames <= (others => '0'); + elsif (dissect_current_state = CLEANUP) then + sent_frames <= sent_frames + x"1"; + end if; + end if; +end process SENT_FRAMES_PROC; + +RECEIVED_FRAMES_OUT <= rec_frames; +SENT_FRAMES_OUT <= sent_frames; + +-- **** debug +DEBUG_OUT(3 downto 0) <= state; +DEBUG_OUT(4) <= '0'; +DEBUG_OUT(7 downto 5) <= "000"; +DEBUG_OUT(8) <= '0'; +DEBUG_OUT(11 downto 9) <= "000"; +DEBUG_OUT(31 downto 12) <= (others => '0'); +-- **** + +end trb_net16_gbe_response_constructor_Ping; + + diff --git a/gbe2_ecp3/trb_net16_gbe_response_constructor_Test.vhd b/gbe2_ecp3/trb_net16_gbe_response_constructor_Test.vhd new file mode 100644 index 0000000..cf8005d --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_response_constructor_Test.vhd @@ -0,0 +1,235 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +use work.trb_net_gbe_components.all; + +--******** +-- Response Constructor which forwards received frame back ceating a loopback +-- + +entity trb_net16_gbe_response_constructor_Test is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- INTERFACE + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_ACTIVATE_IN : in std_logic; + PS_RESPONSE_READY_OUT : out std_logic; + PS_BUSY_OUT : out std_logic; + PS_SELECTED_IN : in std_logic; + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + + TC_RD_EN_IN : in std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + + TC_BUSY_IN : in std_logic; + + RECEIVED_FRAMES_OUT : out std_logic_vector(15 downto 0); + SENT_FRAMES_OUT : out std_logic_vector(15 downto 0); +-- END OF INTERFACE + +-- debug + DEBUG_OUT : out std_logic_vector(31 downto 0) +); +end trb_net16_gbe_response_constructor_Test; + + +architecture trb_net16_gbe_response_constructor_Test of trb_net16_gbe_response_constructor_Test is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_response_constructor_Test: architecture is "GBE_MAIN_group"; + +attribute syn_encoding : string; + +type dissect_states is (IDLE, SAVE, WAIT_FOR_LOAD, LOAD, CLEANUP); +signal dissect_current_state, dissect_next_state : dissect_states; +attribute syn_encoding of dissect_current_state: signal is "safe,gray"; + +signal ff_wr_en : std_logic; +signal ff_rd_en : std_logic; +signal resp_bytes_ctr : std_logic_vector(15 downto 0); +signal ff_empty : std_logic; +signal ff_full : std_logic; +signal ff_q : std_logic_vector(8 downto 0); +signal ff_rd_lock : std_logic; + +signal state : std_logic_vector(3 downto 0); +signal rec_frames : std_logic_vector(15 downto 0); +signal sent_frames : std_logic_vector(15 downto 0); + +begin + +DISSECT_MACHINE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + dissect_current_state <= IDLE; + else + dissect_current_state <= dissect_next_state; + end if; + end if; +end process DISSECT_MACHINE_PROC; + +DISSECT_MACHINE : process(dissect_current_state, PS_WR_EN_IN, PS_ACTIVATE_IN, PS_DATA_IN, ff_q, ff_rd_lock, TC_BUSY_IN) +begin + case dissect_current_state is + + when IDLE => + state <= x"1"; + if (PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then + dissect_next_state <= SAVE; + else + dissect_next_state <= IDLE; + end if; + + when SAVE => + state <= x"2"; + if (PS_DATA_IN(8) = '1') then + dissect_next_state <= WAIT_FOR_LOAD; + else + dissect_next_state <= SAVE; + end if; + + when WAIT_FOR_LOAD => + state <= x"3"; + if (TC_BUSY_IN = '0') then + dissect_next_state <= LOAD; + else + dissect_next_state <= WAIT_FOR_LOAD; + end if; + + when LOAD => + state <= x"4"; + if (ff_q(8) = '1') and (ff_rd_lock = '0') then + dissect_next_state <= CLEANUP; + else + dissect_next_state <= LOAD; + end if; + + when CLEANUP => + state <= x"5"; + dissect_next_state <= IDLE; + + end case; +end process DISSECT_MACHINE; + +PS_BUSY_OUT <= '0' when dissect_current_state = IDLE else '1'; + +ff_wr_en <= '1' when (PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') else '0'; + +FF_RD_LOCK_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + ff_rd_lock <= '1'; + elsif (dissect_current_state = LOAD and ff_rd_en = '1') then + ff_rd_lock <= '0'; + else + ff_rd_lock <= '1'; + end if; + end if; +end process FF_RD_LOCK_PROC; + +-- TODO: put a smaller fifo here +FRAME_FIFO: fifo_4096x9 +port map( + Data => PS_DATA_IN, + WrClock => CLK, + RdClock => CLK, + WrEn => ff_wr_en, + RdEn => ff_rd_en, + Reset => RESET, + RPReset => RESET, + Q => ff_q, + Empty => ff_empty, + Full => ff_full +); + +ff_rd_en <= '1' when (TC_RD_EN_IN = '1' and PS_SELECTED_IN = '1') else '0'; + +TC_DATA_OUT <= ff_q; + +PS_RESPONSE_READY_OUT <= '1' when (dissect_current_state = LOAD) else '0'; + +TC_FRAME_SIZE_OUT <= resp_bytes_ctr + x"1"; + +TC_FRAME_TYPE_OUT <= x"aa08"; +TC_DEST_MAC_OUT <= x"9a680f201300"; +TC_DEST_IP_OUT <= x"0100a8c0"; +TC_DEST_UDP_OUT <= x"51c3"; +TC_SRC_MAC_OUT <= x"efbeefbe0000"; +TC_SRC_IP_OUT <= x"0b00a8c0"; +TC_SRC_UDP_OUT <= x"51c3"; +TC_IP_PROTOCOL_OUT <= x"11"; + +RESP_BYTES_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (dissect_current_state = IDLE) then + resp_bytes_ctr <= (others => '0'); + elsif (dissect_current_state = SAVE) then + resp_bytes_ctr <= resp_bytes_ctr + x"1"; + end if; + end if; +end process RESP_BYTES_CTR_PROC; + +REC_FRAMES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + rec_frames <= (others => '0'); + elsif (dissect_current_state = IDLE and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then + rec_frames <= rec_frames + x"1"; + end if; + end if; +end process REC_FRAMES_PROC; + +SENT_FRAMES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + sent_frames <= (others => '0'); + elsif (dissect_current_state = WAIT_FOR_LOAD and TC_BUSY_IN = '0') then + sent_frames <= sent_frames + x"1"; + end if; + end if; +end process SENT_FRAMES_PROC; + +RECEIVED_FRAMES_OUT <= rec_frames; +SENT_FRAMES_OUT <= sent_frames; + +-- **** debug +DEBUG_OUT(3 downto 0) <= state; +DEBUG_OUT(4) <= ff_empty; +DEBUG_OUT(7 downto 5) <= "000"; +DEBUG_OUT(8) <= ff_full; +DEBUG_OUT(11 downto 9) <= "000"; +DEBUG_OUT(31 downto 12) <= (others => '0'); +-- **** + +end trb_net16_gbe_response_constructor_Test; + + diff --git a/gbe2_ecp3/trb_net16_gbe_response_constructor_Test1.vhd b/gbe2_ecp3/trb_net16_gbe_response_constructor_Test1.vhd new file mode 100644 index 0000000..8a1b618 --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_response_constructor_Test1.vhd @@ -0,0 +1,160 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +use work.trb_net_gbe_components.all; + +--******** +-- Response Constructor which recevies data and does nothing except counting incoming packets +-- + +entity trb_net16_gbe_response_constructor_Test1 is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- INTERFACE + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_ACTIVATE_IN : in std_logic; + PS_RESPONSE_READY_OUT : out std_logic; + PS_BUSY_OUT : out std_logic; + PS_SELECTED_IN : in std_logic; + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + + TC_RD_EN_IN : in std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + + TC_BUSY_IN : in std_logic; + + RECEIVED_FRAMES_OUT : out std_logic_vector(15 downto 0); + SENT_FRAMES_OUT : out std_logic_vector(15 downto 0); +-- END OF INTERFACE + +-- debug + DEBUG_OUT : out std_logic_vector(31 downto 0) +); +end trb_net16_gbe_response_constructor_Test1; + + +architecture trb_net16_gbe_response_constructor_Test1 of trb_net16_gbe_response_constructor_Test1 is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_response_constructor_Forward : architecture is "GBE_MAIN_group"; + +attribute syn_encoding : string; + +type dissect_states is (IDLE, SAVE, CLEANUP); +signal dissect_current_state, dissect_next_state : dissect_states; +attribute syn_encoding of dissect_current_state: signal is "safe,gray"; + +signal ff_wr_en : std_logic; +signal ff_rd_en : std_logic; +signal resp_bytes_ctr : std_logic_vector(15 downto 0); +signal ff_empty : std_logic; +signal ff_full : std_logic; +signal ff_q : std_logic_vector(8 downto 0); +signal ff_rd_lock : std_logic; + +signal state : std_logic_vector(3 downto 0); +signal rec_frames : std_logic_vector(15 downto 0); +signal sent_frames : std_logic_vector(15 downto 0); + +begin + +DISSECT_MACHINE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + dissect_current_state <= IDLE; + else + dissect_current_state <= dissect_next_state; + end if; + end if; +end process DISSECT_MACHINE_PROC; + +DISSECT_MACHINE : process(dissect_current_state, PS_WR_EN_IN, PS_ACTIVATE_IN, PS_DATA_IN) +begin + case dissect_current_state is + + when IDLE => + state <= x"1"; + if (PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then + dissect_next_state <= SAVE; + else + dissect_next_state <= IDLE; + end if; + + when SAVE => + state <= x"2"; + if (PS_DATA_IN(8) = '1') then + dissect_next_state <= CLEANUP; + else + dissect_next_state <= SAVE; + end if; + + when CLEANUP => + state <= x"5"; + dissect_next_state <= IDLE; + + end case; +end process DISSECT_MACHINE; + +PS_BUSY_OUT <= '0'; + +TC_DATA_OUT <= (others => '0'); + +PS_RESPONSE_READY_OUT <= '0'; + +TC_FRAME_SIZE_OUT <= (others => '0'); + +TC_FRAME_TYPE_OUT <= x"0008"; +TC_DEST_MAC_OUT <= x"9a680f201300"; +TC_DEST_IP_OUT <= x"0100a8c0"; +TC_DEST_UDP_OUT <= x"50c3"; +TC_SRC_MAC_OUT <= x"efbeefbe0000"; +TC_SRC_IP_OUT <= x"0b00a8c0"; +TC_SRC_UDP_OUT <= x"50c3"; +TC_IP_PROTOCOL_OUT <= x"11"; + +REC_FRAMES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + rec_frames <= (others => '0'); + elsif (dissect_current_state = IDLE and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then + rec_frames <= rec_frames + x"1"; + end if; + end if; +end process REC_FRAMES_PROC; + +RECEIVED_FRAMES_OUT <= rec_frames; +SENT_FRAMES_OUT <= (others => '0'); + +-- **** debug +DEBUG_OUT(31 downto 0) <= (others => '0'); +-- **** + +end trb_net16_gbe_response_constructor_Test1; + + diff --git a/gbe2_ecp3/trb_net16_gbe_response_constructor_Trash.vhd b/gbe2_ecp3/trb_net16_gbe_response_constructor_Trash.vhd new file mode 100644 index 0000000..bf85023 --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_response_constructor_Trash.vhd @@ -0,0 +1,153 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +use work.trb_net_gbe_components.all; + +--******** +-- gets all the data which is not supposed to be received by other protocols +-- simply clears the fifo from garbage + +entity trb_net16_gbe_response_constructor_Trash is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- INTERFACE + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_ACTIVATE_IN : in std_logic; + PS_RESPONSE_READY_OUT : out std_logic; + PS_BUSY_OUT : out std_logic; + PS_SELECTED_IN : in std_logic; + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + + TC_RD_EN_IN : in std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + + TC_BUSY_IN : in std_logic; + + RECEIVED_FRAMES_OUT : out std_logic_vector(15 downto 0); + SENT_FRAMES_OUT : out std_logic_vector(15 downto 0); +-- END OF INTERFACE + +-- debug + DEBUG_OUT : out std_logic_vector(31 downto 0) +); +end trb_net16_gbe_response_constructor_Trash; + + +architecture trb_net16_gbe_response_constructor_Trash of trb_net16_gbe_response_constructor_Trash is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_response_constructor_Trash : architecture is "GBE_MAIN_group"; + +attribute syn_encoding : string; + +type dissect_states is (IDLE, SAVE, CLEANUP); +signal dissect_current_state, dissect_next_state : dissect_states; +attribute syn_encoding of dissect_current_state: signal is "safe,gray"; + +signal state : std_logic_vector(3 downto 0); +signal rec_frames : std_logic_vector(15 downto 0); +signal sent_frames : std_logic_vector(15 downto 0); + +begin + +DISSECT_MACHINE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + dissect_current_state <= IDLE; + else + dissect_current_state <= dissect_next_state; + end if; + end if; +end process DISSECT_MACHINE_PROC; + +DISSECT_MACHINE : process(dissect_current_state, PS_WR_EN_IN, PS_ACTIVATE_IN, PS_DATA_IN) +begin + case dissect_current_state is + + when IDLE => + state <= x"1"; + if (PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then + dissect_next_state <= SAVE; + else + dissect_next_state <= IDLE; + end if; + + when SAVE => + state <= x"2"; + if (PS_DATA_IN(8) = '1') then + dissect_next_state <= CLEANUP; + else + dissect_next_state <= SAVE; + end if; + + when CLEANUP => + state <= x"5"; + dissect_next_state <= IDLE; + + end case; +end process DISSECT_MACHINE; + +PS_BUSY_OUT <= '0' when dissect_current_state = IDLE else '1'; + +TC_DATA_OUT <= '0' & x"ab"; + +PS_RESPONSE_READY_OUT <= '0'; + +TC_FRAME_SIZE_OUT <= (others => '0'); + +TC_FRAME_TYPE_OUT <= (others => '0'); +TC_DEST_MAC_OUT <= (others => '0'); +TC_DEST_IP_OUT <= (others => '0'); +TC_DEST_UDP_OUT <= (others => '0'); +TC_SRC_MAC_OUT <= (others => '0'); +TC_SRC_IP_OUT <= (others => '0'); +TC_SRC_UDP_OUT <= (others => '0'); +TC_IP_PROTOCOL_OUT <= (others => '0'); + +REC_FRAMES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + rec_frames <= (others => '0'); + elsif (dissect_current_state = IDLE and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then + rec_frames <= rec_frames + x"1"; + end if; + end if; +end process REC_FRAMES_PROC; + +RECEIVED_FRAMES_OUT <= rec_frames; +SENT_FRAMES_OUT <= (others => '0'); + +-- **** debug +DEBUG_OUT(3 downto 0) <= state; +DEBUG_OUT(31 downto 4) <= (others => '0'); +-- **** + +end trb_net16_gbe_response_constructor_Trash; + + diff --git a/gbe2_ecp3/trb_net16_gbe_setup.vhd b/gbe2_ecp3/trb_net16_gbe_setup.vhd new file mode 100644 index 0000000..59a1d49 --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_setup.vhd @@ -0,0 +1,605 @@ +LIBRARY ieee; +use ieee.std_logic_1164.all; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; +--use work.version.all; + +use work.trb_net_gbe_components.all; +use work.trb_net_gbe_protocols.all; + +entity gbe_setup is +port( + CLK : in std_logic; + RESET : in std_logic; + + -- interface to regio bus + BUS_ADDR_IN : in std_logic_vector(7 downto 0); + BUS_DATA_IN : in std_logic_vector(31 downto 0); + BUS_DATA_OUT : out std_logic_vector(31 downto 0); -- gk 26.04.10 + BUS_WRITE_EN_IN : in std_logic; -- gk 26.04.10 + BUS_READ_EN_IN : in std_logic; -- gk 26.04.10 + BUS_ACK_OUT : out std_logic; -- gk 26.04.10 + + -- gk 26.04.10 + -- input from gbe_buf (only to return the whole trigger number via regio) + GBE_TRIG_NR_IN : in std_logic_vector(31 downto 0); + + -- output to gbe_buf + GBE_SUBEVENT_ID_OUT : out std_logic_vector(31 downto 0); + GBE_SUBEVENT_DEC_OUT : out std_logic_vector(31 downto 0); + GBE_QUEUE_DEC_OUT : out std_logic_vector(31 downto 0); + GBE_MAX_PACKET_OUT : out std_logic_vector(31 downto 0); + GBE_MIN_PACKET_OUT : out std_logic_vector(31 downto 0); + GBE_MAX_FRAME_OUT : out std_logic_vector(15 downto 0); + GBE_USE_GBE_OUT : out std_logic; + GBE_USE_TRBNET_OUT : out std_logic; + GBE_USE_MULTIEVENTS_OUT : out std_logic; + GBE_READOUT_CTR_OUT : out std_logic_vector(23 downto 0); -- gk 26.04.10 + GBE_READOUT_CTR_VALID_OUT : out std_logic; -- gk 26.04.10 + GBE_DELAY_OUT : out std_logic_vector(31 downto 0); + GBE_ALLOW_LARGE_OUT : out std_logic; + GBE_ALLOW_RX_OUT : out std_logic; + GBE_ALLOW_BRDCST_ETH_OUT : out std_logic; + GBE_ALLOW_BRDCST_IP_OUT : out std_logic; + GBE_FRAME_DELAY_OUT : out std_logic_vector(31 downto 0); -- gk 09.12.10 + GBE_ALLOWED_TYPES_OUT : out std_logic_vector(31 downto 0); + GBE_ALLOWED_IP_OUT : out std_logic_vector(31 downto 0); + GBE_ALLOWED_UDP_OUT : out std_logic_vector(31 downto 0); + GBE_VLAN_ID_OUT : out std_logic_vector(31 downto 0); + -- gk 28.07.10 + MONITOR_BYTES_IN : in std_logic_vector(31 downto 0); + MONITOR_SENT_IN : in std_logic_vector(31 downto 0); + MONITOR_DROPPED_IN : in std_logic_vector(31 downto 0); + MONITOR_SM_IN : in std_logic_vector(31 downto 0); + MONITOR_LR_IN : in std_logic_vector(31 downto 0); + MONITOR_HDR_IN : in std_logic_vector(31 downto 0); + MONITOR_FIFOS_IN : in std_logic_vector(31 downto 0); + MONITOR_DISCFRM_IN : in std_logic_vector(31 downto 0); + MONITOR_LINK_DWN_IN : in std_logic_vector(31 downto 0); -- gk 30.09.10 + MONITOR_EMPTY_IN : in std_logic_vector(31 downto 0); -- gk 01.10.10 + MONITOR_RX_FRAMES_IN : in std_logic_vector(31 downto 0); + MONITOR_RX_BYTES_IN : in std_logic_vector(31 downto 0); + MONITOR_RX_BYTES_R_IN : in std_logic_vector(31 downto 0); + -- gk 01.06.10 + DBG_IPU2GBE1_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE2_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE3_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE4_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE5_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE6_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE7_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE8_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE9_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE10_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE11_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE12_IN : in std_logic_vector(31 downto 0); + DBG_PC1_IN : in std_logic_vector(31 downto 0); + DBG_PC2_IN : in std_logic_vector(31 downto 0); + DBG_FC1_IN : in std_logic_vector(31 downto 0); + DBG_FC2_IN : in std_logic_vector(31 downto 0); + DBG_FT1_IN : in std_logic_vector(31 downto 0); + DBG_FT2_IN : in std_logic_vector(31 downto 0); + DBG_FR_IN : in std_logic_vector(95 downto 0); + DBG_RC_IN : in std_logic_vector(63 downto 0); + DBG_MC_IN : in std_logic_vector(63 downto 0); + DBG_TC_IN : in std_logic_vector(31 downto 0); + DBG_FIFO_RD_EN_OUT : out std_logic; + + DBG_SELECT_REC_IN : in std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); + DBG_SELECT_SENT_IN : in std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); + DBG_SELECT_PROTOS_IN : in std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0); + + DBG_FIFO_Q_IN : in std_logic_vector(15 downto 0) + --DBG_RESET_FIFO_OUT : out std_logic -- gk 28.09.10 +); +end entity; + +architecture gbe_setup of gbe_setup is + +-- attribute HGROUP : string; +-- attribute HGROUP of gbe_setup : architecture is "GBE_conf"; + +signal reset_values : std_logic; + +signal subevent_id : std_logic_vector(31 downto 0); +signal subevent_dec : std_logic_vector(31 downto 0); +signal queue_dec : std_logic_vector(31 downto 0); +signal max_packet : std_logic_vector(31 downto 0); +signal min_packet : std_logic_vector(31 downto 0); -- gk 07.20.10 +signal max_frame : std_logic_vector(15 downto 0); +signal use_gbe : std_logic; +signal use_trbnet : std_logic; +signal use_multievents : std_logic; +signal readout_ctr : std_logic_vector(23 downto 0); -- gk 26.04.10 +signal readout_ctr_valid : std_logic; -- gk 26.04.10 +signal ack : std_logic; -- gk 26.04.10 +signal ack_q : std_logic; -- gk 26.04.10 +signal data_out : std_logic_vector(31 downto 0); -- gk 26.04.10 +signal delay : std_logic_vector(31 downto 0); -- gk 28.04.10 +signal allow_large : std_logic; -- gk 21.07.10 +signal reset_fifo : std_logic; -- gk 28.09.10 +signal allow_rx : std_logic; +signal frame_delay : std_logic_vector(31 downto 0); -- gk 09.12.10 +signal allowed_types : std_logic_vector(31 downto 0); +signal allowed_ip : std_logic_vector(31 downto 0); +signal allowed_udp : std_logic_vector(31 downto 0); +signal vlan_id : std_logic_vector(31 downto 0); +signal allow_brdcst_eth : std_logic; +signal allow_brdcst_ip : std_logic; + +begin + +OUT_PROC : process(CLK) +begin + if rising_edge(CLK) then + GBE_SUBEVENT_ID_OUT <= subevent_id; + GBE_SUBEVENT_DEC_OUT <= subevent_dec; + GBE_QUEUE_DEC_OUT <= queue_dec; + GBE_MAX_PACKET_OUT <= max_packet; + GBE_MIN_PACKET_OUT <= min_packet; + GBE_MAX_FRAME_OUT <= max_frame; + GBE_USE_GBE_OUT <= use_gbe; + GBE_USE_TRBNET_OUT <= use_trbnet; + GBE_USE_MULTIEVENTS_OUT <= use_multievents; + GBE_READOUT_CTR_OUT <= readout_ctr; -- gk 26.04.10 + GBE_READOUT_CTR_VALID_OUT <= readout_ctr_valid; -- gk 26.04.10 + BUS_ACK_OUT <= ack_q; -- gk 26.04.10 + ack_q <= ack; -- gk 26.04.10 + BUS_DATA_OUT <= data_out; -- gk 26.04.10 + GBE_DELAY_OUT <= delay; -- gk 28.04.10 + GBE_ALLOW_LARGE_OUT <= allow_large; -- gk 21.07.10 + GBE_ALLOW_RX_OUT <= allow_rx; + GBE_ALLOW_BRDCST_ETH_OUT <= allow_brdcst_eth; + GBE_ALLOW_BRDCST_IP_OUT <= allow_brdcst_ip; + --DBG_RESET_FIFO_OUT <= reset_fifo; -- gk 28.09.10 + GBE_FRAME_DELAY_OUT <= frame_delay; -- gk 09.12.10 + GBE_ALLOWED_TYPES_OUT <= allowed_types; + GBE_ALLOWED_IP_OUT <= allowed_ip; + GBE_ALLOWED_UDP_OUT <= allowed_udp; + GBE_VLAN_ID_OUT <= vlan_id; + end if; +end process OUT_PROC; + +-- gk 26.04.10 +ACK_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + ack <= '0'; + elsif ((BUS_WRITE_EN_IN = '1') or (BUS_READ_EN_IN = '1')) then + ack <= '1'; + else + ack <= '0'; + end if; + end if; +end process ACK_PROC; + +WRITE_PROC : process(CLK) +begin + DBG_FIFO_RD_EN_OUT <= '0'; + + if rising_edge(CLK) then + if ( (RESET = '1') or (reset_values = '1') ) then + subevent_id <= x"0000_00cf"; + subevent_dec <= x"0002_0001"; + queue_dec <= x"0003_0062"; + max_packet <= x"0000_0fd0"; --x"0000_fde8"; -- 65k --x"0000_fde8"; -- tester + min_packet <= x"0000_0007"; -- gk 20.07.10 + max_frame <= x"0578"; + use_gbe <= '1'; --'1'; -- gk 27.08.10 -- blocks the transmission until gbe gets configured + use_trbnet <= '0'; + use_multievents <= '0'; + reset_values <= '0'; + readout_ctr <= x"00_0000"; -- gk 26.04.10 -- gk 07.06.10 corrected bug found by Sergey + readout_ctr_valid <= '0'; -- gk 26.04.10 + delay <= x"0000_0000"; -- gk 28.04.10 + DBG_FIFO_RD_EN_OUT <= '0'; + allow_large <= '0'; -- gk 21.07.10 + reset_fifo <= '0'; -- gk 28.09.10 + allow_rx <= '1'; + frame_delay <= x"0000_0000"; -- gk 09.12.10 + allowed_types <= x"0000_00ff"; -- only test protocol allowed + allowed_ip <= x"0000_00ff"; + allowed_udp <= x"0000_00ff"; + vlan_id <= x"0000_0000"; -- no vlan id by default + allow_brdcst_eth <= '1'; + allow_brdcst_ip <= '1'; + + elsif (BUS_WRITE_EN_IN = '1') then + case BUS_ADDR_IN is + + when x"00" => + subevent_id <= BUS_DATA_IN; + + when x"01" => + subevent_dec <= BUS_DATA_IN; + + when x"02" => + queue_dec <= BUS_DATA_IN; + + when x"03" => + max_packet <= BUS_DATA_IN; + + when x"04" => + max_frame <= BUS_DATA_IN(15 downto 0); + + when x"05" => + if (BUS_DATA_IN = x"0000_0000") then + use_gbe <= '0'; + else + use_gbe <= '1'; + end if; + + when x"06" => + if (BUS_DATA_IN = x"0000_0000") then + use_trbnet <= '0'; + else + use_trbnet <= '1'; + end if; + + when x"07" => + if (BUS_DATA_IN = x"0000_0000") then + use_multievents <= '0'; + else + use_multievents <= '1'; + end if; + + -- gk 26.04.10 + when x"08" => + readout_ctr <= BUS_DATA_IN(23 downto 0); + readout_ctr_valid <= '1'; + + -- gk 28.04.10 + when x"09" => + delay <= BUS_DATA_IN; + + when x"0a" => + DBG_FIFO_RD_EN_OUT <= '1'; + + -- gk 20.07.10 + when x"0b" => + min_packet <= BUS_DATA_IN; + + -- gk 21.07.10 + when x"0c" => + if (BUS_DATA_IN = x"0000_0000") then + allow_large <= '0'; + else + allow_large <= '1'; + end if; + + -- gk 09.12.10 + when x"0d" => + frame_delay <= BUS_DATA_IN; + + when x"0e" => + allow_rx <= BUS_DATA_IN(0); + allow_brdcst_eth <= BUS_DATA_IN(1); + allow_brdcst_ip <= BUS_DATA_IN(2); + + when x"0f" => + allowed_types <= BUS_DATA_IN; + + when x"10" => + vlan_id <= BUS_DATA_IN; + + when x"11" => + allowed_ip <= BUS_DATA_IN; + + when x"12" => + allowed_udp <= BUS_DATA_IN; + + -- gk 28.09.10 + when x"fe" => + if (BUS_DATA_IN = x"ffff_ffff") then + reset_fifo <= '1'; + else + reset_fifo <= '0'; + end if; + + when x"ff" => + if (BUS_DATA_IN = x"ffff_ffff") then + reset_values <= '1'; + else + reset_values <= '0'; + end if; + + when others => + subevent_id <= subevent_id; + subevent_dec <= subevent_dec; + queue_dec <= queue_dec; + max_packet <= max_packet; + min_packet <= min_packet; + max_frame <= max_frame; + use_gbe <= use_gbe; + use_trbnet <= use_trbnet; + use_multievents <= use_multievents; + reset_values <= reset_values; + readout_ctr <= readout_ctr; -- gk 26.04.10 + readout_ctr_valid <= readout_ctr_valid; -- gk 26.04.10 + delay <= delay; -- gk 28.04.10 + DBG_FIFO_RD_EN_OUT <= '0'; + allow_large <= allow_large; + reset_fifo <= reset_fifo; -- gk 28.09.10 + allow_rx <= allow_rx; + frame_delay <= frame_delay; + allowed_types <= allowed_types; + vlan_id <= vlan_id; + allowed_ip <= allowed_ip; + allowed_udp <= allowed_udp; + allow_brdcst_eth <= allow_brdcst_eth; + allow_brdcst_ip <= allow_brdcst_ip; + + end case; + else + reset_values <= '0'; + readout_ctr_valid <= '0'; -- gk 26.04.10 + --reset_fifo <= '0'; -- gk 28.09.10 + end if; + end if; +end process WRITE_PROC; + +-- gk 26.04.10 +READ_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + data_out <= (others => '0'); + elsif (BUS_READ_EN_IN = '1') then + case BUS_ADDR_IN is + + when x"00" => + data_out <= subevent_id; + + when x"01" => + data_out <= subevent_dec; + + when x"02" => + data_out <= queue_dec; + + when x"03" => + data_out <= max_packet; + + when x"04" => + data_out(15 downto 0) <= max_frame; + data_out(31 downto 16) <= (others => '0'); + + when x"05" => + if (use_gbe = '0') then + data_out <= x"0000_0000"; + else + data_out <= x"0000_0001"; + end if; + + when x"06" => + if (use_trbnet = '0') then + data_out <= x"0000_0000"; + else + data_out <= x"0000_0001"; + end if; + + when x"07" => + if (use_multievents = '0') then + data_out <= x"0000_0000"; + else + data_out <= x"0000_0001"; + end if; + + when x"08" => + data_out <= GBE_TRIG_NR_IN; + + when x"09" => + data_out <= delay; + + when x"0b" => + data_out <= min_packet; + + -- gk 21.07.10 + when x"0c" => + if (allow_large = '0') then + data_out <= x"0000_0000"; + else + data_out <= x"0000_0001"; + end if; + + -- gk 09.12.10 + when x"0d" => + data_out <= frame_delay; + + + when x"0e" => + data_out(0) <= allow_rx; + data_out(1) <= allow_brdcst_eth; + data_out(2) <= allow_brdcst_ip; + data_out(31 downto 3) <= (others => '0'); + + when x"0f" => + data_out <= allowed_types; + + when x"10" => + data_out <= vlan_id; + + when x"11" => + data_out <= allowed_ip; + + when x"12" => + data_out <= allowed_udp; + + -- gk 01.06.10 + when x"e0" => + data_out <= DBG_IPU2GBE1_IN; + + when x"e1" => + data_out <= DBG_IPU2GBE2_IN; + + when x"e2" => + data_out <= DBG_PC1_IN; + + when x"e3" => + data_out <= DBG_PC2_IN; + + when x"e4" => + data_out <= DBG_FC1_IN; + + when x"e5" => + data_out <= DBG_FC2_IN; + + when x"e6" => + data_out <= DBG_FT1_IN; + + when x"e7" => + data_out <= DBG_FT2_IN; + + when x"e8" => + data_out(15 downto 0) <= DBG_FIFO_Q_IN; + data_out(31 downto 16) <= (others => '0'); + + when x"e9" => + data_out <= DBG_IPU2GBE3_IN; + + when x"ea" => + data_out <= DBG_IPU2GBE4_IN; + + when x"eb" => + data_out <= DBG_IPU2GBE5_IN; + + when x"ec" => + data_out <= DBG_IPU2GBE6_IN; + + when x"ed" => + data_out <= DBG_IPU2GBE7_IN; + + when x"ee" => + data_out <= DBG_IPU2GBE8_IN; + + when x"ef" => + data_out <= DBG_IPU2GBE9_IN; + + when x"f0" => + data_out <= DBG_IPU2GBE10_IN; + + when x"f1" => + data_out <= DBG_IPU2GBE11_IN; + + when x"f2" => + data_out <= DBG_IPU2GBE12_IN; + + when x"f3" => + data_out <= MONITOR_BYTES_IN; + + when x"f4" => + data_out <= MONITOR_SENT_IN; + + when x"f5" => + data_out <= MONITOR_DROPPED_IN; + + when x"f6" => + data_out <= MONITOR_SM_IN; + + when x"f7" => + data_out <= MONITOR_LR_IN; + + when x"f8" => + data_out <= MONITOR_HDR_IN; + + when x"f9" => + data_out <= MONITOR_FIFOS_IN; + + when x"fa" => + data_out <= MONITOR_DISCFRM_IN; + + when x"fb" => + data_out <= MONITOR_LINK_DWN_IN; + + when x"fc" => + data_out <= MONITOR_EMPTY_IN; + + --when x"d1" => + -- data_out <= DBG_FR_IN; + + --when x"d2" => + -- data_out <= DBG_RC_IN; + + --when x"d4" => + -- data_out <= DBG_TC_IN; + + -- **** receive debug section + + when x"a0" => + data_out <= DBG_FR_IN(31 downto 0); -- received frames from tsmac | state machine | fifos status + + when x"a1" => + data_out <= DBG_FR_IN(63 downto 32); -- dropped | accepted frames + + when x"a2" => + data_out <= MONITOR_RX_FRAMES_IN; + + when x"a3" => + data_out <= MONITOR_RX_BYTES_IN; + + when x"a4" => + data_out <= MONITOR_RX_BYTES_R_IN; + + when x"a5" => + data_out <= DBG_MC_IN(31 downto 0); + + + -- *** debug of response constructors + + -- Forward + when x"b0" => + data_out(15 downto 0) <= DBG_SELECT_REC_IN(1 * 16 - 1 downto 0 * 16); + data_out(31 downto 16) <= DBG_SELECT_SENT_IN(1 * 16 - 1 downto 0 * 16); + when x"b1" => + data_out <= DBG_SELECT_PROTOS_IN(1 * 32 - 1 downto 0 * 32); + + -- ARP + when x"b2" => + data_out(15 downto 0) <= DBG_SELECT_REC_IN(2 * 16 - 1 downto 1 * 16); + data_out(31 downto 16) <= DBG_SELECT_SENT_IN(2 * 16 - 1 downto 1 * 16); + when x"b3" => + data_out <= DBG_SELECT_PROTOS_IN(2 * 32 - 1 downto 1 * 32); + + -- Test + when x"b4" => + data_out(15 downto 0) <= DBG_SELECT_REC_IN(3 * 16 - 1 downto 2 * 16); + data_out(31 downto 16) <= DBG_SELECT_SENT_IN(3 * 16 - 1 downto 2 * 16); + when x"b5" => + data_out <= DBG_SELECT_PROTOS_IN(3 * 32 - 1 downto 2 * 32); + + -- DHCP + when x"b6" => + data_out(15 downto 0) <= DBG_SELECT_REC_IN(4 * 16 - 1 downto 3 * 16); + data_out(31 downto 16) <= DBG_SELECT_SENT_IN(4 * 16 - 1 downto 3 * 16); + when x"b7" => + data_out <= DBG_SELECT_PROTOS_IN(4 * 32 - 1 downto 3 * 32); + + -- PING + when x"b8" => + data_out(15 downto 0) <= DBG_SELECT_REC_IN(5 * 16 - 1 downto 4 * 16); + data_out(31 downto 16) <= DBG_SELECT_SENT_IN(5 * 16 - 1 downto 4 * 16); + when x"b9" => + data_out <= DBG_SELECT_PROTOS_IN(5 * 32 - 1 downto 4 * 32); + + -- Trash + --when x"b8" => + -- data_out(15 downto 0) <= DBG_SELECT_REC_IN(5 * 16 - 1 downto 4 * 16); + -- data_out(31 downto 16) <= DBG_SELECT_SENT_IN(5 * 16 - 1 downto 4 * 16); + --when x"b9" => + -- data_out <= DBG_SELECT_PROTOS_IN(4 * 32 - 1 downto 3 * 32); + + -- **** end of received debug section + + when others => + data_out <= (others => '0'); + end case; + end if; + end if; +end process READ_PROC; + +end architecture; \ No newline at end of file diff --git a/gbe2_ecp3/trb_net16_gbe_setup_simplified.vhd b/gbe2_ecp3/trb_net16_gbe_setup_simplified.vhd new file mode 100644 index 0000000..4d3881d --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_setup_simplified.vhd @@ -0,0 +1,595 @@ +LIBRARY ieee; +use ieee.std_logic_1164.all; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; +--use work.version.all; + +use work.trb_net_gbe_components.all; +use work.trb_net_gbe_protocols.all; + +entity gbe_setup is +port( + CLK : in std_logic; + RESET : in std_logic; + + -- interface to regio bus + BUS_ADDR_IN : in std_logic_vector(7 downto 0); + BUS_DATA_IN : in std_logic_vector(31 downto 0); + BUS_DATA_OUT : out std_logic_vector(31 downto 0); -- gk 26.04.10 + BUS_WRITE_EN_IN : in std_logic; -- gk 26.04.10 + BUS_READ_EN_IN : in std_logic; -- gk 26.04.10 + BUS_ACK_OUT : out std_logic; -- gk 26.04.10 + + -- gk 26.04.10 + -- input from gbe_buf (only to return the whole trigger number via regio) + GBE_TRIG_NR_IN : in std_logic_vector(31 downto 0); + + -- output to gbe_buf + GBE_SUBEVENT_ID_OUT : out std_logic_vector(31 downto 0); + GBE_SUBEVENT_DEC_OUT : out std_logic_vector(31 downto 0); + GBE_QUEUE_DEC_OUT : out std_logic_vector(31 downto 0); + GBE_MAX_PACKET_OUT : out std_logic_vector(31 downto 0); + GBE_MIN_PACKET_OUT : out std_logic_vector(31 downto 0); + GBE_MAX_FRAME_OUT : out std_logic_vector(15 downto 0); + GBE_USE_GBE_OUT : out std_logic; + GBE_USE_TRBNET_OUT : out std_logic; + GBE_USE_MULTIEVENTS_OUT : out std_logic; + GBE_READOUT_CTR_OUT : out std_logic_vector(23 downto 0); -- gk 26.04.10 + GBE_READOUT_CTR_VALID_OUT : out std_logic; -- gk 26.04.10 + GBE_DELAY_OUT : out std_logic_vector(31 downto 0); + GBE_ALLOW_LARGE_OUT : out std_logic; + GBE_ALLOW_RX_OUT : out std_logic; + GBE_FRAME_DELAY_OUT : out std_logic_vector(31 downto 0); -- gk 09.12.10 + GBE_ALLOWED_TYPES_OUT : out std_logic_vector(31 downto 0); + GBE_ALLOWED_IP_OUT : out std_logic_vector(31 downto 0); + GBE_ALLOWED_UDP_OUT : out std_logic_vector(31 downto 0); + GBE_VLAN_ID_OUT : out std_logic_vector(31 downto 0); + -- gk 28.07.10 + MONITOR_BYTES_IN : in std_logic_vector(31 downto 0); + MONITOR_SENT_IN : in std_logic_vector(31 downto 0); + MONITOR_DROPPED_IN : in std_logic_vector(31 downto 0); + MONITOR_SM_IN : in std_logic_vector(31 downto 0); + MONITOR_LR_IN : in std_logic_vector(31 downto 0); + MONITOR_HDR_IN : in std_logic_vector(31 downto 0); + MONITOR_FIFOS_IN : in std_logic_vector(31 downto 0); + MONITOR_DISCFRM_IN : in std_logic_vector(31 downto 0); + MONITOR_LINK_DWN_IN : in std_logic_vector(31 downto 0); -- gk 30.09.10 + MONITOR_EMPTY_IN : in std_logic_vector(31 downto 0); -- gk 01.10.10 + MONITOR_RX_FRAMES_IN : in std_logic_vector(31 downto 0); + MONITOR_RX_BYTES_IN : in std_logic_vector(31 downto 0); + MONITOR_RX_BYTES_R_IN : in std_logic_vector(31 downto 0); + -- gk 01.06.10 + DBG_IPU2GBE1_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE2_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE3_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE4_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE5_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE6_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE7_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE8_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE9_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE10_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE11_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE12_IN : in std_logic_vector(31 downto 0); + DBG_PC1_IN : in std_logic_vector(31 downto 0); + DBG_PC2_IN : in std_logic_vector(31 downto 0); + DBG_FC1_IN : in std_logic_vector(31 downto 0); + DBG_FC2_IN : in std_logic_vector(31 downto 0); + DBG_FT1_IN : in std_logic_vector(31 downto 0); + DBG_FT2_IN : in std_logic_vector(31 downto 0); + DBG_FR_IN : in std_logic_vector(95 downto 0); + DBG_RC_IN : in std_logic_vector(63 downto 0); + DBG_MC_IN : in std_logic_vector(63 downto 0); + DBG_TC_IN : in std_logic_vector(31 downto 0); + DBG_FIFO_RD_EN_OUT : out std_logic; + + DBG_SELECT_REC_IN : in std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); + DBG_SELECT_SENT_IN : in std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); + DBG_SELECT_PROTOS_IN : in std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0); + + DBG_FIFO_Q_IN : in std_logic_vector(15 downto 0) + --DBG_RESET_FIFO_OUT : out std_logic -- gk 28.09.10 +); +end entity; + +architecture gbe_setup of gbe_setup is + +-- attribute HGROUP : string; +-- attribute HGROUP of gbe_setup : architecture is "GBE_conf"; + +signal reset_values : std_logic; + +signal subevent_id : std_logic_vector(31 downto 0); +signal subevent_dec : std_logic_vector(31 downto 0); +signal queue_dec : std_logic_vector(31 downto 0); +signal max_packet : std_logic_vector(31 downto 0); +signal min_packet : std_logic_vector(31 downto 0); -- gk 07.20.10 +signal max_frame : std_logic_vector(15 downto 0); +signal use_gbe : std_logic; +signal use_trbnet : std_logic; +signal use_multievents : std_logic; +signal readout_ctr : std_logic_vector(23 downto 0); -- gk 26.04.10 +signal readout_ctr_valid : std_logic; -- gk 26.04.10 +signal ack : std_logic; -- gk 26.04.10 +signal ack_q : std_logic; -- gk 26.04.10 +signal data_out : std_logic_vector(31 downto 0); -- gk 26.04.10 +signal delay : std_logic_vector(31 downto 0); -- gk 28.04.10 +signal allow_large : std_logic; -- gk 21.07.10 +signal reset_fifo : std_logic; -- gk 28.09.10 +signal allow_rx : std_logic; +signal frame_delay : std_logic_vector(31 downto 0); -- gk 09.12.10 +signal allowed_types : std_logic_vector(31 downto 0); +signal allowed_ip : std_logic_vector(31 downto 0); +signal allowed_udp : std_logic_vector(31 downto 0); +signal vlan_id : std_logic_vector(31 downto 0); + +begin + +OUT_PROC : process(CLK) +begin + if rising_edge(CLK) then + GBE_SUBEVENT_ID_OUT <= subevent_id; + GBE_SUBEVENT_DEC_OUT <= subevent_dec; + GBE_QUEUE_DEC_OUT <= queue_dec; + GBE_MAX_PACKET_OUT <= max_packet; + GBE_MIN_PACKET_OUT <= min_packet; + GBE_MAX_FRAME_OUT <= max_frame; + GBE_USE_GBE_OUT <= use_gbe; + GBE_USE_TRBNET_OUT <= use_trbnet; + GBE_USE_MULTIEVENTS_OUT <= use_multievents; + GBE_READOUT_CTR_OUT <= readout_ctr; -- gk 26.04.10 + GBE_READOUT_CTR_VALID_OUT <= readout_ctr_valid; -- gk 26.04.10 + BUS_ACK_OUT <= ack_q; -- gk 26.04.10 + ack_q <= ack; -- gk 26.04.10 + BUS_DATA_OUT <= data_out; -- gk 26.04.10 + GBE_DELAY_OUT <= delay; -- gk 28.04.10 + GBE_ALLOW_LARGE_OUT <= allow_large; -- gk 21.07.10 + GBE_ALLOW_RX_OUT <= allow_rx; + --DBG_RESET_FIFO_OUT <= reset_fifo; -- gk 28.09.10 + GBE_FRAME_DELAY_OUT <= frame_delay; -- gk 09.12.10 + GBE_ALLOWED_TYPES_OUT <= allowed_types; + GBE_ALLOWED_IP_OUT <= allowed_ip; + GBE_ALLOWED_UDP_OUT <= allowed_udp; + GBE_VLAN_ID_OUT <= vlan_id; + end if; +end process OUT_PROC; + +-- gk 26.04.10 +ACK_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + ack <= '0'; + elsif ((BUS_WRITE_EN_IN = '1') or (BUS_READ_EN_IN = '1')) then + ack <= '1'; + else + ack <= '0'; + end if; + end if; +end process ACK_PROC; + +WRITE_PROC : process(CLK) +begin + DBG_FIFO_RD_EN_OUT <= '0'; + + if rising_edge(CLK) then + if ( (RESET = '1') or (reset_values = '1') ) then + subevent_id <= x"0000_00cf"; + subevent_dec <= x"0002_0001"; + queue_dec <= x"0003_0062"; + max_packet <= x"0000_0fd0"; --x"0000_fde8"; -- 65k --x"0000_fde8"; -- tester + min_packet <= x"0000_0007"; -- gk 20.07.10 + max_frame <= x"0578"; + use_gbe <= '0'; --'1'; -- gk 27.08.10 -- blocks the transmission until gbe gets configured + use_trbnet <= '0'; + use_multievents <= '0'; + reset_values <= '0'; + readout_ctr <= x"00_0000"; -- gk 26.04.10 -- gk 07.06.10 corrected bug found by Sergey + readout_ctr_valid <= '0'; -- gk 26.04.10 + delay <= x"0000_0000"; -- gk 28.04.10 + DBG_FIFO_RD_EN_OUT <= '0'; + allow_large <= '0'; -- gk 21.07.10 + reset_fifo <= '0'; -- gk 28.09.10 + allow_rx <= '1'; + frame_delay <= x"0000_0000"; -- gk 09.12.10 + allowed_types <= x"0000_00ff"; -- only test protocol allowed + allowed_ip <= x"0000_00ff"; + allowed_udp <= x"0000_00ff"; + vlan_id <= x"0000_0000"; -- no vlan id by default + + elsif (BUS_WRITE_EN_IN = '1') then + case BUS_ADDR_IN is + + when x"00" => + subevent_id <= BUS_DATA_IN; + + when x"01" => + subevent_dec <= BUS_DATA_IN; + + when x"02" => + queue_dec <= BUS_DATA_IN; + + when x"03" => + max_packet <= BUS_DATA_IN; + + when x"04" => + max_frame <= BUS_DATA_IN(15 downto 0); + + when x"05" => + if (BUS_DATA_IN = x"0000_0000") then + use_gbe <= '0'; + else + use_gbe <= '1'; + end if; + + when x"06" => + if (BUS_DATA_IN = x"0000_0000") then + use_trbnet <= '0'; + else + use_trbnet <= '1'; + end if; + + when x"07" => + if (BUS_DATA_IN = x"0000_0000") then + use_multievents <= '0'; + else + use_multievents <= '1'; + end if; + + -- gk 26.04.10 + when x"08" => + readout_ctr <= BUS_DATA_IN(23 downto 0); + readout_ctr_valid <= '1'; + + -- gk 28.04.10 + when x"09" => + delay <= BUS_DATA_IN; + + when x"0a" => + DBG_FIFO_RD_EN_OUT <= '1'; + + -- gk 20.07.10 + when x"0b" => + min_packet <= BUS_DATA_IN; + + -- gk 21.07.10 + when x"0c" => + if (BUS_DATA_IN = x"0000_0000") then + allow_large <= '0'; + else + allow_large <= '1'; + end if; + + -- gk 09.12.10 + when x"0d" => + frame_delay <= BUS_DATA_IN; + + when x"0e" => + allow_rx <= BUS_DATA_IN(0); + + when x"0f" => + allowed_types <= BUS_DATA_IN; + + when x"10" => + vlan_id <= BUS_DATA_IN; + + when x"11" => + allowed_ip <= BUS_DATA_IN; + + when x"12" => + allowed_udp <= BUS_DATA_IN; + + -- gk 28.09.10 + when x"fe" => + if (BUS_DATA_IN = x"ffff_ffff") then + reset_fifo <= '1'; + else + reset_fifo <= '0'; + end if; + + when x"ff" => + if (BUS_DATA_IN = x"ffff_ffff") then + reset_values <= '1'; + else + reset_values <= '0'; + end if; + + when others => + subevent_id <= subevent_id; + subevent_dec <= subevent_dec; + queue_dec <= queue_dec; + max_packet <= max_packet; + min_packet <= min_packet; + max_frame <= max_frame; + use_gbe <= use_gbe; + use_trbnet <= use_trbnet; + use_multievents <= use_multievents; + reset_values <= reset_values; + readout_ctr <= readout_ctr; -- gk 26.04.10 + readout_ctr_valid <= readout_ctr_valid; -- gk 26.04.10 + delay <= delay; -- gk 28.04.10 + DBG_FIFO_RD_EN_OUT <= '0'; + allow_large <= allow_large; + reset_fifo <= reset_fifo; -- gk 28.09.10 + allow_rx <= allow_rx; + frame_delay <= frame_delay; + allowed_types <= allowed_types; + vlan_id <= vlan_id; + allowed_ip <= allowed_ip; + allowed_udp <= allowed_udp; + + end case; + else + reset_values <= '0'; + readout_ctr_valid <= '0'; -- gk 26.04.10 + --reset_fifo <= '0'; -- gk 28.09.10 + end if; + end if; +end process WRITE_PROC; + +-- gk 26.04.10 +READ_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + data_out <= (others => '0'); + elsif (BUS_READ_EN_IN = '1') then + case BUS_ADDR_IN is + + when x"00" => + data_out <= subevent_id; + + when x"01" => + data_out <= subevent_dec; + + when x"02" => + data_out <= queue_dec; + + when x"03" => + data_out <= max_packet; + + when x"04" => + data_out(15 downto 0) <= max_frame; + data_out(31 downto 16) <= (others => '0'); + + when x"05" => + if (use_gbe = '0') then + data_out <= x"0000_0000"; + else + data_out <= x"0000_0001"; + end if; + + when x"06" => + if (use_trbnet = '0') then + data_out <= x"0000_0000"; + else + data_out <= x"0000_0001"; + end if; + + when x"07" => + if (use_multievents = '0') then + data_out <= x"0000_0000"; + else + data_out <= x"0000_0001"; + end if; + + when x"08" => + data_out <= GBE_TRIG_NR_IN; + + when x"09" => + data_out <= delay; + + when x"0b" => + data_out <= min_packet; + + -- gk 21.07.10 + when x"0c" => + if (allow_large = '0') then + data_out <= x"0000_0000"; + else + data_out <= x"0000_0001"; + end if; + + -- gk 09.12.10 + when x"0d" => + data_out <= frame_delay; + + + when x"0e" => + data_out(0) <= allow_rx; + data_out(31 downto 1) <= (others => '0'); + + when x"0f" => + data_out <= allowed_types; + + when x"10" => + data_out <= vlan_id; + + when x"11" => + data_out <= allowed_ip; + + when x"12" => + data_out <= allowed_udp; + + -- gk 01.06.10 + --when x"e0" => + -- data_out <= DBG_IPU2GBE1_IN; + + --when x"e1" => + -- data_out <= DBG_IPU2GBE2_IN; + + --when x"e2" => + -- data_out <= DBG_PC1_IN; + + --when x"e3" => + -- data_out <= DBG_PC2_IN; + + --when x"e4" => + -- data_out <= DBG_FC1_IN; + + --when x"e5" => + -- data_out <= DBG_FC2_IN; + + --when x"e6" => + -- data_out <= DBG_FT1_IN; + + --when x"e7" => + -- data_out <= DBG_FT2_IN; + + --when x"e8" => + -- data_out(15 downto 0) <= DBG_FIFO_Q_IN; + -- data_out(31 downto 16) <= (others => '0'); + + --when x"e9" => + -- data_out <= DBG_IPU2GBE3_IN; + + --when x"ea" => + -- data_out <= DBG_IPU2GBE4_IN; + + --when x"eb" => + -- data_out <= DBG_IPU2GBE5_IN; + + --when x"ec" => + -- data_out <= DBG_IPU2GBE6_IN; + + --when x"ed" => + -- data_out <= DBG_IPU2GBE7_IN; + + --when x"ee" => + -- data_out <= DBG_IPU2GBE8_IN; + + --when x"ef" => + -- data_out <= DBG_IPU2GBE9_IN; + + --when x"f0" => + -- data_out <= DBG_IPU2GBE10_IN; + + --when x"f1" => + -- data_out <= DBG_IPU2GBE11_IN; + + --when x"f2" => + -- data_out <= DBG_IPU2GBE12_IN; + + --when x"f3" => + -- data_out <= MONITOR_BYTES_IN; + + --when x"f4" => + -- data_out <= MONITOR_SENT_IN; + + --when x"f5" => + -- data_out <= MONITOR_DROPPED_IN; + + --when x"f6" => + -- data_out <= MONITOR_SM_IN; + + --when x"f7" => + -- data_out <= MONITOR_LR_IN; + + --when x"f8" => + -- data_out <= MONITOR_HDR_IN; + + --when x"f9" => + -- data_out <= MONITOR_FIFOS_IN; + + --when x"fa" => + -- data_out <= MONITOR_DISCFRM_IN; + + --when x"fb" => + -- data_out <= MONITOR_LINK_DWN_IN; + + --when x"fc" => + -- data_out <= MONITOR_EMPTY_IN; + + --when x"d1" => + -- data_out <= DBG_FR_IN; + + --when x"d2" => + -- data_out <= DBG_RC_IN; + + --when x"d4" => + -- data_out <= DBG_TC_IN; + + -- **** transmit section + + when x"90" => + data_out <= DBG_FT2_IN; + + -- **** receive debug section + + when x"a0" => + data_out <= DBG_FR_IN(31 downto 0); -- received frames from tsmac | state machine | fifos status + + when x"a1" => + data_out <= DBG_FR_IN(63 downto 32); -- dropped | accepted frames + + when x"a2" => + data_out <= MONITOR_RX_FRAMES_IN; + + when x"a3" => + data_out <= MONITOR_RX_BYTES_IN; + + when x"a4" => + data_out <= MONITOR_RX_BYTES_R_IN; + + when x"a5" => + data_out <= DBG_MC_IN(31 downto 0); + + when x"a6" => + data_out <= g_MY_IP; + + when x"a7" => + data_out <= DBG_FR_IN(95 downto 64); -- ok | error frames + + + -- *** debug of response constructors + + -- ARP + when x"b0" => + data_out(15 downto 0) <= DBG_SELECT_REC_IN(1 * 16 - 1 downto 0 * 16); + data_out(31 downto 16) <= DBG_SELECT_SENT_IN(1 * 16 - 1 downto 0 * 16); + when x"b1" => + data_out <= DBG_SELECT_PROTOS_IN(1 * 32 - 1 downto 0 * 32); + + -- DHCP + when x"b2" => + data_out(15 downto 0) <= DBG_SELECT_REC_IN(2 * 16 - 1 downto 1 * 16); + data_out(31 downto 16) <= DBG_SELECT_SENT_IN(2 * 16 - 1 downto 1 * 16); + when x"b3" => + data_out <= DBG_SELECT_PROTOS_IN(1 * 32 - 1 downto 0 * 32); + + -- PING + when x"b4" => + data_out(15 downto 0) <= DBG_SELECT_REC_IN(3 * 16 - 1 downto 2 * 16); + data_out(31 downto 16) <= DBG_SELECT_SENT_IN(3 * 16 - 1 downto 2 * 16); + when x"b5" => + data_out <= DBG_SELECT_PROTOS_IN(3 * 32 - 1 downto 2 * 32); + + -- Test1a + when x"b6" => + data_out(15 downto 0) <= DBG_SELECT_REC_IN(4 * 16 - 1 downto 3 * 16); + data_out(31 downto 16) <= DBG_SELECT_SENT_IN(4 * 16 - 1 downto 3 * 16); + when x"b7" => + data_out <= DBG_SELECT_PROTOS_IN(4 * 32 - 1 downto 3 * 32); + + -- Test1b + when x"b8" => + data_out(15 downto 0) <= DBG_SELECT_REC_IN(5 * 16 - 1 downto 4 * 16); + data_out(31 downto 16) <= DBG_SELECT_SENT_IN(5 * 16 - 1 downto 4 * 16); + when x"b9" => + data_out <= DBG_SELECT_PROTOS_IN(5 * 32 - 1 downto 4 * 32); + + -- **** end of received debug section + + when others => + data_out <= (others => '0'); + end case; + end if; + end if; +end process READ_PROC; + +end architecture; diff --git a/gbe2_ecp3/trb_net16_gbe_transmit_control.vhd b/gbe2_ecp3/trb_net16_gbe_transmit_control.vhd new file mode 100644 index 0000000..a24592d --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_transmit_control.vhd @@ -0,0 +1,364 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +--******** +-- multiplexes the output stream between data and slow control frames +-- creates slow control frames + +entity trb_net16_gbe_transmit_control is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- signals to/from packet constructor + PC_READY_IN : in std_logic; + PC_DATA_IN : in std_logic_vector(7 downto 0); + PC_WR_EN_IN : in std_logic; + PC_IP_SIZE_IN : in std_logic_vector(15 downto 0); + PC_UDP_SIZE_IN : in std_logic_vector(15 downto 0); + PC_FLAGS_OFFSET_IN : in std_logic_vector(15 downto 0); + PC_SOD_IN : in std_logic; + PC_EOD_IN : in std_logic; + PC_FC_READY_OUT : out std_logic; + PC_FC_H_READY_OUT : out std_logic; + PC_TRANSMIT_ON_IN : in std_logic; + + -- signals from ip_configurator used by packet constructor + IC_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + IC_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + IC_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + IC_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + IC_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + IC_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + +-- signal to/from main controller + MC_TRANSMIT_CTRL_IN : in std_logic; -- slow control frame is waiting to be built and sent + MC_TRANSMIT_DATA_IN : in std_logic; + MC_DATA_IN : in std_logic_vector(8 downto 0); + MC_RD_EN_OUT : out std_logic; + MC_FRAME_SIZE_IN : in std_logic_vector(15 downto 0); + MC_FRAME_TYPE_IN : in std_logic_vector(15 downto 0); + + MC_DEST_MAC_IN : in std_logic_vector(47 downto 0); + MC_DEST_IP_IN : in std_logic_vector(31 downto 0); + MC_DEST_UDP_IN : in std_logic_vector(15 downto 0); + MC_SRC_MAC_IN : in std_logic_vector(47 downto 0); + MC_SRC_IP_IN : in std_logic_vector(31 downto 0); + MC_SRC_UDP_IN : in std_logic_vector(15 downto 0); + + MC_IP_PROTOCOL_IN : in std_logic_vector(7 downto 0); + + MC_BUSY_OUT : out std_logic; + MC_TRANSMIT_DONE_OUT : out std_logic; + +-- signal to/from frame constructor + FC_DATA_OUT : out std_logic_vector(7 downto 0); + FC_WR_EN_OUT : out std_logic; + FC_READY_IN : in std_logic; + FC_H_READY_IN : in std_logic; + FC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + FC_IP_SIZE_OUT : out std_logic_vector(15 downto 0); + FC_UDP_SIZE_OUT : out std_logic_vector(15 downto 0); + FC_IDENT_OUT : out std_logic_vector(15 downto 0); -- internal packet counter + FC_FLAGS_OFFSET_OUT : out std_logic_vector(15 downto 0); + FC_SOD_OUT : out std_logic; + FC_EOD_OUT : out std_logic; + FC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + + DEST_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0); + DEST_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0); + DEST_UDP_PORT_OUT : out std_logic_vector(15 downto 0); + SRC_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0); + SRC_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0); + SRC_UDP_PORT_OUT : out std_logic_vector(15 downto 0); + + +-- debug + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end trb_net16_gbe_transmit_control; + + +architecture trb_net16_gbe_transmit_control of trb_net16_gbe_transmit_control is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_transmit_control : architecture is "GBE_BUF_group"; + +attribute syn_encoding : string; + +type tx_states is (IDLE, TRANSMIT_DATA, TRANSMIT_CTRL, CLEANUP); +signal tx_current_state, tx_next_state : tx_states; +attribute syn_encoding of tx_current_state: signal is "safe,gray"; + +type ctrl_construct_states is (IDLE, WAIT_FOR_FC, LOAD_DATA, CLOSE, CLEANUP); +signal ctrl_construct_current_state, ctrl_construct_next_state : ctrl_construct_states; +attribute syn_encoding of ctrl_construct_current_state: signal is "safe,gray"; + +signal ctrl_sod : std_logic; +signal delayed_wr_en : std_logic; +signal delayed_wr_en_q : std_logic; +signal sent_bytes_ctr : std_logic_vector(15 downto 0); +signal sent_packets_ctr : std_logic_vector(15 downto 0); + +signal state : std_logic_vector(3 downto 0); +signal state2 : std_logic_vector(3 downto 0); + +begin + +DEBUG_OUT(3 downto 0) <= state; +DEBUG_OUT(7 downto 4) <= state2; +DEBUG_OUT(31 downto 8) <= (others => '0'); + +MC_BUSY_OUT <= '0' when (tx_current_state = IDLE) + else '1'; + +MC_TRANSMIT_DONE_OUT <= '1' when (tx_current_state = CLEANUP) else '0'; + +TX_MACHINE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + tx_current_state <= IDLE; + else + tx_current_state <= tx_next_state; + end if; + end if; +end process TX_MACHINE_PROC; + +TX_MACHINE : process(tx_current_state, MC_TRANSMIT_CTRL_IN, MC_TRANSMIT_DATA_IN, FC_READY_IN, PC_EOD_IN, ctrl_construct_current_state) +begin + case tx_current_state is + + when IDLE => + state <= x"1"; + if (FC_READY_IN = '1') then + if (MC_TRANSMIT_DATA_IN = '1') then + tx_next_state <= TRANSMIT_DATA; + elsif (MC_TRANSMIT_CTRL_IN = '1') then + tx_next_state <= TRANSMIT_CTRL; + else + tx_next_state <= IDLE; + end if; + else + tx_next_state <= IDLE; + end if; + + when TRANSMIT_DATA => + state <= x"2"; + if (PC_EOD_IN = '1') then + tx_next_state <= CLEANUP; + else + tx_next_state <= TRANSMIT_DATA; + end if; + + when TRANSMIT_CTRL => + state <= x"3"; + if (ctrl_construct_current_state = CLOSE) then + tx_next_state <= CLEANUP; + else + tx_next_state <= TRANSMIT_CTRL; + end if; + + when CLEANUP => + state <= x"4"; + tx_next_state <= IDLE; + + end case; +end process TX_MACHINE; + +-- in case of data from packet constructor use always IP +FC_FRAME_TYPE_OUT <= MC_FRAME_TYPE_IN when tx_current_state = TRANSMIT_CTRL else x"0008"; + +SELECTOR : process(CLK) +begin + if rising_edge(CLK) then + + case tx_current_state is + + when TRANSMIT_DATA => + -- CHANGED FOR SIMPLE FRAME SENDER + FC_DATA_OUT <= PC_DATA_IN; + FC_SOD_OUT <= PC_SOD_IN; + FC_EOD_OUT <= PC_EOD_IN; + FC_IP_SIZE_OUT <= PC_IP_SIZE_IN; + FC_UDP_SIZE_OUT <= PC_UDP_SIZE_IN; + FC_FLAGS_OFFSET_OUT <= PC_FLAGS_OFFSET_IN; + FC_IDENT_OUT <= sent_packets_ctr; + + DEST_MAC_ADDRESS_OUT <= x"9a680f201300"; --IC_DEST_MAC_ADDRESS_IN; + DEST_IP_ADDRESS_OUT <= x"0100a8c0"; --IC_DEST_IP_ADDRESS_IN; + DEST_UDP_PORT_OUT <= (others => '0'); --IC_DEST_UDP_PORT_IN; + SRC_MAC_ADDRESS_OUT <= x"beefbeef0000"; --IC_SRC_MAC_ADDRESS_IN; + SRC_IP_ADDRESS_OUT <= x"0b00a8c0"; --IC_SRC_IP_ADDRESS_IN; + SRC_UDP_PORT_OUT <= (others => '0'); --IC_SRC_UDP_PORT_IN; + + if (sent_packets_ctr(0) = '0') then + FC_IP_PROTOCOL_OUT <= x"dd"; + else + FC_IP_PROTOCOL_OUT <= x"ee"; + end if; + + + when TRANSMIT_CTRL => + FC_DATA_OUT <= MC_DATA_IN(7 downto 0); + FC_IP_PROTOCOL_OUT <= MC_IP_PROTOCOL_IN; + + if (ctrl_construct_current_state = WAIT_FOR_FC) and (FC_READY_IN = '1') then + FC_SOD_OUT <= '1'; + else + FC_SOD_OUT <= '0'; + end if; + + --if (ctrl_construct_current_state = CLOSE) then + if (ctrl_construct_current_state = LOAD_DATA and sent_bytes_ctr = MC_FRAME_SIZE_IN - x"1") then + FC_EOD_OUT <= '1'; + else + FC_EOD_OUT <= '0'; + end if; + + + FC_IP_SIZE_OUT <= MC_FRAME_SIZE_IN; + FC_UDP_SIZE_OUT <= MC_FRAME_SIZE_IN; + FC_FLAGS_OFFSET_OUT <= (others => '0'); -- fixed to one-frame packets + + if (ctrl_construct_current_state = WAIT_FOR_FC) and (FC_H_READY_IN = '1') then + MC_RD_EN_OUT <= '1'; + delayed_wr_en <= '0'; --'1'; + elsif (ctrl_construct_current_state = LOAD_DATA) and (sent_bytes_ctr < MC_FRAME_SIZE_IN - x"2") then -- (sent_bytes_ctr /= MC_FRAME_SIZE_IN) then + MC_RD_EN_OUT <= '1'; + delayed_wr_en <= '1'; + else + MC_RD_EN_OUT <= '0'; + delayed_wr_en <= '0'; + end if; + + DEST_MAC_ADDRESS_OUT <= MC_DEST_MAC_IN; + DEST_IP_ADDRESS_OUT <= MC_DEST_IP_IN; + DEST_UDP_PORT_OUT <= MC_DEST_UDP_IN; + SRC_MAC_ADDRESS_OUT <= MC_SRC_MAC_IN; + SRC_IP_ADDRESS_OUT <= MC_SRC_IP_IN; + SRC_UDP_PORT_OUT <= MC_SRC_UDP_IN; + + FC_IDENT_OUT <= sent_packets_ctr; + + when others => + MC_RD_EN_OUT <= '0'; + FC_DATA_OUT <= (others => '0'); + delayed_wr_en <= '0'; + FC_SOD_OUT <= '0'; + FC_EOD_OUT <= '0'; + + end case; + + end if; +end process SELECTOR; + +FC_WR_EN_PROC : process(CLK) +begin + if rising_edge(CLK) then + delayed_wr_en_q <= delayed_wr_en; + + case tx_current_state is + when TRANSMIT_DATA => + FC_WR_EN_OUT <= PC_WR_EN_IN; + when TRANSMIT_CTRL => + FC_WR_EN_OUT <= delayed_wr_en_q; + when others => + FC_WR_EN_OUT <= '0'; + end case; + end if; +end process FC_WR_EN_PROC; + + +CTRL_CONSTRUCT_MACHINE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + ctrl_construct_current_state <= IDLE; + else + ctrl_construct_current_state <= ctrl_construct_next_state; + end if; + end if; +end process CTRL_CONSTRUCT_MACHINE_PROC; + +CTRL_CONSTRUCT_MACHINE : process(ctrl_construct_current_state, tx_current_state, FC_H_READY_IN, sent_bytes_ctr, MC_FRAME_SIZE_IN) +begin + + case ctrl_construct_current_state is + + when IDLE => + state2 <= x"1"; + if (tx_current_state = TRANSMIT_CTRL) then + ctrl_construct_next_state <= WAIT_FOR_FC; + else + ctrl_construct_next_state <= IDLE; + end if; + + when WAIT_FOR_FC => + state2 <= x"2"; + if (FC_H_READY_IN = '1') then + ctrl_construct_next_state <= LOAD_DATA; + else + ctrl_construct_next_state <= WAIT_FOR_FC; + end if; + + when LOAD_DATA => + state2 <= x"3"; + if (sent_bytes_ctr = MC_FRAME_SIZE_IN - x"1") then + ctrl_construct_next_state <= CLOSE; + else + ctrl_construct_next_state <= LOAD_DATA; + end if; + + when CLOSE => + state2 <= x"4"; + ctrl_construct_next_state <= CLEANUP; + + when CLEANUP => + state2 <= x"5"; + ctrl_construct_next_state <= IDLE; + + end case; + +end process CTRL_CONSTRUCT_MACHINE; + +SENT_BYTES_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (ctrl_construct_current_state = IDLE) then + sent_bytes_ctr <= (others => '0'); + elsif (delayed_wr_en_q = '1') then + sent_bytes_ctr <= sent_bytes_ctr + x"1"; + end if; + end if; +end process SENT_BYTES_CTR_PROC; + +PC_FC_H_READY_OUT <= FC_H_READY_IN when ((tx_current_state = IDLE) or (tx_current_state = TRANSMIT_DATA)) + else '0'; + +PC_FC_READY_OUT <= FC_READY_IN when ((tx_current_state = IDLE) or (tx_current_state = TRANSMIT_DATA)) + else '0'; + +SENT_PACKETS_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + sent_packets_ctr <= (others => '0'); + elsif (tx_current_state = CLEANUP) then + sent_packets_ctr <= sent_packets_ctr + x"1"; + end if; + end if; +end process SENT_PACKETS_CTR_PROC; + + + +end trb_net16_gbe_transmit_control; + + diff --git a/gbe2_ecp3/trb_net16_gbe_type_validator.vhd b/gbe2_ecp3/trb_net16_gbe_type_validator.vhd new file mode 100644 index 0000000..93147c7 --- /dev/null +++ b/gbe2_ecp3/trb_net16_gbe_type_validator.vhd @@ -0,0 +1,175 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +use work.trb_net_gbe_components.all; +use work.trb_net_gbe_protocols.all; + + +--******** +-- contains valid frame types codes and performs checking of type and vlan id +-- by default there is place for 32 frame type which is hardcoded value +-- due to allow register which is set by slow control + +entity trb_net16_gbe_type_validator is +port ( + CLK : in std_logic; -- 125MHz clock input + RESET : in std_logic; + -- ethernet level + FRAME_TYPE_IN : in std_logic_vector(15 downto 0); -- recovered frame type + SAVED_VLAN_ID_IN : in std_logic_vector(15 downto 0); -- recovered vlan id + ALLOWED_TYPES_IN : in std_logic_vector(31 downto 0); -- signal from gbe_setup + VLAN_ID_IN : in std_logic_vector(31 downto 0); -- two values from gbe setup + + -- IP level + IP_PROTOCOLS_IN : in std_logic_vector(7 downto 0); + ALLOWED_IP_PROTOCOLS_IN : in std_logic_vector(31 downto 0); + + -- UDP level + UDP_PROTOCOL_IN : in std_logic_vector(15 downto 0); + ALLOWED_UDP_PROTOCOLS_IN : in std_logic_vector(31 downto 0); + + VALID_OUT : out std_logic +); +end trb_net16_gbe_type_validator; + + +architecture trb_net16_gbe_type_validator of trb_net16_gbe_type_validator is + +--attribute HGROUP : string; +--attribute HGROUP of trb_net16_gbe_type_validator : architecture is "GBE_MAIN_group"; + +signal result : std_logic_vector(c_MAX_FRAME_TYPES - 1 downto 0); +signal ip_result : std_logic_vector(c_MAX_IP_PROTOCOLS - 1 downto 0); +signal udp_result : std_logic_vector(c_MAX_UDP_PROTOCOLS - 1 downto 0); +signal partially_valid : std_logic; -- only protocols, vlan to be checked + +begin + +-- DO NOT TOUCH +IP_RESULTS_GEN : for i in 0 to c_MAX_IP_PROTOCOLS - 1 generate + + ip_result(i) <= '1' when ( + IP_PROTOCOLS(i) = IP_PROTOCOLS_IN and + ALLOWED_IP_PROTOCOLS_IN(i) = '1' + ) else '0'; + + + +end generate IP_RESULTS_GEN; + +UDP_RESULTS_GEN : for i in 0 to c_MAX_UDP_PROTOCOLS - 1 generate + + udp_result(i) <= '1' when ( + UDP_PROTOCOLS(i) = UDP_PROTOCOL_IN and + ALLOWED_UDP_PROTOCOLS_IN(i) = '1' + ) else '0'; + +end generate UDP_RESULTS_GEN; + + +RESULT_GEN : for i in 0 to c_MAX_FRAME_TYPES - 1 generate + + result(i) <= '1' when ( + FRAME_TYPES(i) = FRAME_TYPE_IN and + ALLOWED_TYPES_IN(i) = '1' + ) else '0'; + +end generate RESULT_GEN; + +PARTIALLY_VALID_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + partially_valid <= '0'; + elsif (FRAME_TYPE_IN = x"0800") then -- ip frame + if (IP_PROTOCOLS_IN = x"11") then -- in case of udp inside ip + partially_valid <= or_all(udp_result); + elsif (IP_PROTOCOLS_IN = x"01" or IP_PROTOCOLS_IN = x"dd" or IP_PROTOCOLS_IN = x"ee") then -- in case of ICMP + partially_valid <= '1'; + else -- do not accept other protocols than udp and icmp inside ip + partially_valid <= '0'; + end if; + else -- other frame + partially_valid <= or_all(result); + end if; + end if; +end process PARTIALLY_VALID_PROC; + +VALID_OUT_PROC : process(partially_valid, SAVED_VLAN_ID_IN, VLAN_ID_IN) +begin + --if rising_edge(CLK) then + -- if (RESET = '1') then + -- VALID_OUT <= '0'; + if (partially_valid = '1') then + if (SAVED_VLAN_ID_IN = x"0000") then + VALID_OUT <= '1'; + elsif (VLAN_ID_IN = x"0000_0000") then + VALID_OUT <= '0'; + elsif (SAVED_VLAN_ID_IN = VLAN_ID_IN(15 downto 0) or SAVED_VLAN_ID_IN = VLAN_ID_IN(31 downto 16)) then + VALID_OUT <= '1'; + else + VALID_OUT <= '0'; + end if; + else + VALID_OUT <= '0'; + end if; + --end if; +end process VALID_OUT_PROC; + + --if rising_edge(CLK) then + -- if (SAVED_VLAN_ID_IN = x"0000") then -- frame without vlan tag + -- if (FRAME_TYPE_IN = x"0800") then -- in case of ip frame + -- if (IP_PROTOCOLS_IN = x"11") then -- in case of udp inside ip + -- VALID_OUT <= or_all(udp_result); + -- elsif (IP_PROTOCOLS_IN = x"01") then -- in case of ICMP + -- VALID_OUT <= '1'; + -- else -- do not accept other protocols than udp inside ip + -- VALID_OUT <= '0'; + -- end if; + -- else -- in case of other frame_type + -- VALID_OUT <= or_all(result); + -- end if; + -- + -- -- cases for tagged frames + -- elsif (VLAN_ID_IN = x"0000_0000") then -- no vlan id configured + -- VALID_OUT <= '0'; + -- elsif (SAVED_VLAN_ID_IN = VLAN_ID_IN(15 downto 0)) then -- match to first vlan id + -- if (FRAME_TYPE_IN = x"0800") then -- in case of ip frame + -- if (IP_PROTOCOLS_IN = x"11") then -- in case of udp inside ip + -- VALID_OUT <= or_all(udp_result); + -- elsif (IP_PROTOCOLS_IN = x"01") then -- in case of ICMP + -- VALID_OUT <= '1'; + -- else -- do not accept other protocols than udp inside ip + -- VALID_OUT <= '0'; + -- end if; + -- else -- in case of other frame_type + -- VALID_OUT <= or_all(result); + -- end if; + -- elsif (SAVED_VLAN_ID_IN = VLAN_ID_IN(31 downto 16)) then -- match to second vlan id + -- if (FRAME_TYPE_IN = x"0800") then -- in case of ip frame + -- if (IP_PROTOCOLS_IN = x"11") then -- in case of udp inside ip + -- VALID_OUT <= or_all(udp_result); + -- elsif (IP_PROTOCOLS_IN = x"01") then -- in case of ICMP + -- VALID_OUT <= '1'; + -- else -- do not accept other protocols than udp inside ip + -- VALID_OUT <= '0'; + -- end if; + -- else -- in case of other frame_type + -- VALID_OUT <= or_all(result); + -- end if; + -- else + -- VALID_OUT <= '0'; + -- end if; + --end if; +--end process VALID_OUT_PROC; + +end trb_net16_gbe_type_validator; + + diff --git a/gbe2_ecp3/trb_net16_ipu2gbe.vhd b/gbe2_ecp3/trb_net16_ipu2gbe.vhd new file mode 100755 index 0000000..d3ae346 --- /dev/null +++ b/gbe2_ecp3/trb_net16_ipu2gbe.vhd @@ -0,0 +1,1403 @@ +LIBRARY ieee; +use ieee.std_logic_1164.all; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; +use IEEE.std_logic_arith.all; + +library work; + +entity trb_net16_ipu2gbe is +port( + CLK : in std_logic; + RESET : in std_logic; + -- IPU interface directed toward the CTS + CTS_NUMBER_IN : in std_logic_vector (15 downto 0); + CTS_CODE_IN : in std_logic_vector (7 downto 0); + CTS_INFORMATION_IN : in std_logic_vector (7 downto 0); + CTS_READOUT_TYPE_IN : in std_logic_vector (3 downto 0); + CTS_START_READOUT_IN : in std_logic; + CTS_READ_IN : in std_logic; + CTS_DATA_OUT : out std_logic_vector (31 downto 0); + CTS_DATAREADY_OUT : out std_logic; + CTS_READOUT_FINISHED_OUT : out std_logic; --no more data, end transfer, send TRM + CTS_LENGTH_OUT : out std_logic_vector (15 downto 0); + CTS_ERROR_PATTERN_OUT : out std_logic_vector (31 downto 0); + -- Data from Frontends + FEE_DATA_IN : in std_logic_vector (15 downto 0); + FEE_DATAREADY_IN : in std_logic; + FEE_READ_OUT : out std_logic; + FEE_BUSY_IN : in std_logic; + FEE_STATUS_BITS_IN : in std_logic_vector (31 downto 0); + -- slow control interface + START_CONFIG_OUT : out std_logic; -- reconfigure MACs/IPs/ports/packet size + BANK_SELECT_OUT : out std_logic_vector(3 downto 0); -- configuration page address + CONFIG_DONE_IN : in std_logic; -- configuration finished + DATA_GBE_ENABLE_IN : in std_logic; -- IPU data is forwarded to GbE + DATA_IPU_ENABLE_IN : in std_logic; -- IPU data is forwarded to CTS / TRBnet + MULT_EVT_ENABLE_IN : in std_logic; + MAX_MESSAGE_SIZE_IN : in std_logic_vector(31 downto 0); -- the maximum size of one HadesQueue -- gk 08.04.10 + MIN_MESSAGE_SIZE_IN : in std_logic_vector(31 downto 0); -- gk 20.07.10 + READOUT_CTR_IN : in std_logic_vector(23 downto 0); -- gk 26.04.10 + READOUT_CTR_VALID_IN : in std_logic; -- gk 26.04.10 + -- PacketConstructor interface + ALLOW_LARGE_IN : in std_logic; -- gk 21.07.10 + PC_WR_EN_OUT : out std_logic; + PC_DATA_OUT : out std_logic_vector (7 downto 0); + PC_READY_IN : in std_logic; + PC_SOS_OUT : out std_logic; + PC_EOS_OUT : out std_logic; -- gk 07.10.10 + PC_EOD_OUT : out std_logic; + PC_SUB_SIZE_OUT : out std_logic_vector(31 downto 0); + PC_TRIG_NR_OUT : out std_logic_vector(31 downto 0); + PC_PADDING_OUT : out std_logic; + MONITOR_OUT : out std_logic_vector(223 downto 0); + DEBUG_OUT : out std_logic_vector(383 downto 0) +); +end entity; + +architecture trb_net16_ipu2gbe of trb_net16_ipu2gbe is + +-- attribute HGROUP : string; +-- attribute HGROUP of trb_net16_ipu2gbe : architecture is "GBE_ipu2gbe"; + +component fifo_32kx16x8_mb2 +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; + AmEmptyThresh : in std_logic_vector(15 downto 0); + AmFullThresh : in std_logic_vector(14 downto 0); + Q : out std_logic_vector(8 downto 0); + WCNT : out std_logic_vector(15 downto 0); + RCNT : out std_logic_vector(16 downto 0); + Empty : out std_logic; + AlmostEmpty : out std_logic; + Full : out std_logic; + AlmostFull : out std_logic +); +end component; + +type saveStates is (SIDLE, SAVE_EVT_ADDR, WAIT_FOR_DATA, SAVE_DATA, ADD_SUBSUB1, ADD_SUBSUB2, ADD_SUBSUB3, ADD_SUBSUB4, TERMINATE, SCLOSE); +signal saveCurrentState, saveNextState : saveStates; +signal state : std_logic_vector(3 downto 0); +signal data_req_comb : std_logic; +signal data_req : std_logic; -- request data signal, will be used for fee_read generation +signal rst_saved_ctr_comb : std_logic; +signal rst_saved_ctr : std_logic; + +signal fee_read_comb : std_logic; +signal fee_read : std_logic; -- fee_read signal +signal saved_ctr : std_logic_vector(16 downto 0); +signal ce_saved_ctr : std_logic; + +-- header data +signal cts_rnd : std_logic_vector(15 downto 0); +signal cts_rnd_saved : std_logic; +signal cts_trg : std_logic_vector(15 downto 0); +signal cts_trg_saved : std_logic; +signal cts_len : std_logic_vector(16 downto 0); +signal cts_len_saved : std_logic; + +-- CTS interface +signal cts_error_pattern : std_logic_vector(31 downto 0); +signal cts_length : std_logic_vector(15 downto 0); +signal cts_readout_finished : std_logic; +signal cts_dataready : std_logic; +signal cts_data : std_logic_vector(31 downto 0); + +-- Split FIFO signals +signal sf_data : std_logic_vector(15 downto 0); +signal sf_wr_en_comb : std_logic; +signal sf_wr_en : std_logic; -- write signal for FIFO +signal sf_rd_en_comb : std_logic; +signal sf_rd_en : std_logic; -- read signal for FIFO +signal sf_wcnt : std_logic_vector(15 downto 0); +signal sf_rcnt : std_logic_vector(16 downto 0); +signal sf_empty : std_logic; +signal sf_aempty : std_logic; +signal sf_full : std_logic; +signal sf_afull : std_logic; + +------------------------------------------------------------------- +type loadStates is (LIDLE, INIT, REMOVE, DECIDE, CALCA, CALCB, LOAD, PAD0, PAD1, PAD2, PAD3, LOAD_SUBSUB, CALCC, CLOSE, WAIT_PC, DROP, WAIT_TO_REMOVE, DROP_SUBSUB, PAUSE_BEFORE_DROP1, PAUSE_BEFORE_DROP2); +signal loadCurrentState, loadNextState : loadStates; +signal state2 : std_logic_vector(3 downto 0); + +signal rem_ctr : std_logic_vector(3 downto 0); -- counter for stripping / storing header data +signal rst_rem_ctr_comb : std_logic; +signal rst_rem_ctr : std_logic; -- reset the remove counter +signal rst_regs_comb : std_logic; +signal rst_regs : std_logic; -- reset storage registers +signal rem_phase_comb : std_logic; +signal rem_phase : std_logic; -- header remove phase +signal data_phase_comb : std_logic; +signal data_phase : std_logic; -- data transport phase from split fifo to PC +signal pad_phase_comb : std_logic; +signal pad_phase : std_logic; -- padding phase +signal calc_pad_comb : std_logic; +signal calc_pad : std_logic; -- check if padding bytes need to be added to PC_SUB_SIZE +signal pad_data_comb : std_logic; +signal pad_data : std_logic; -- reset PC_DATA register to known padding byte value + +signal pc_sos_comb : std_logic; +signal pc_sos : std_logic; -- start of data signal +signal pc_eod_comb : std_logic; +signal pc_eod : std_logic; -- end of data signal + +signal ce_rem_ctr_comb : std_logic; +signal ce_rem_ctr : std_logic; -- count enable for remove counter +signal remove_done_comb : std_logic; +signal remove_done : std_logic; -- end of header stripping process +signal read_done_comb : std_logic; +signal read_done : std_logic; -- end of data phase (read phase from SF) + +signal pc_data : std_logic_vector(7 downto 0); +signal pc_data_q : std_logic_vector(7 downto 0); +signal pc_trig_nr : std_logic_vector(15 downto 0); +signal pc_sub_size : std_logic_vector(17 downto 0); +signal read_size : std_logic_vector(17 downto 0); -- number of byte to be read from split fifo +signal padding_needed : std_logic; +signal pc_wr_en_comb : std_logic; +signal pc_wr_en_q : std_logic; +signal pc_wr_en_qq : std_logic; +signal pc_wr_en_qqq : std_logic; +signal pc_eod_q : std_logic; + +signal debug : std_logic_vector(383 downto 0); + +-- gk +signal bank_select : std_logic_vector(3 downto 0); +signal save_addr_comb : std_logic; +signal save_addr : std_logic; +signal addr_saved_comb : std_logic; +signal addr_saved : std_logic; +signal start_config : std_logic; +signal config_done : std_logic; +signal add_sub_state : std_logic; +signal add_sub_state_comb : std_logic; +signal add_sub_ctr : std_logic_vector(3 downto 0); +signal load_sub : std_logic; +signal load_sub_comb : std_logic; +signal load_sub_done : std_logic; +signal load_sub_done_comb : std_logic; +signal load_sub_ctr : std_logic_vector(3 downto 0); +signal load_sub_ctr_comb : std_logic; +signal actual_message_size : std_logic_vector(31 downto 0); +signal more_subevents : std_logic; +signal trig_random : std_logic_vector(7 downto 0); +signal readout_ctr : std_logic_vector(23 downto 0); +signal readout_ctr_lock : std_logic; +signal pc_trig_nr_q : std_logic_vector(31 downto 0); + +-- gk 20.07.10 +signal inc_data_ctr : std_logic_vector(31 downto 0); +signal dropped_sm_events_ctr : std_logic_vector(31 downto 0); +signal dropped_lr_events_ctr : std_logic_vector(31 downto 0); +signal dropped_ctr : std_logic_vector(31 downto 0); +-- gk 22.07.10 +signal headers_invalid : std_logic; +signal headers_invalid_ctr : std_logic_vector(31 downto 0); +signal cts_len_q : std_logic_vector(15 downto 0); +signal cts_trg_q : std_logic_vector(15 downto 0); +signal cts_rnd_q : std_logic_vector(15 downto 0); +signal first_run_trg : std_logic_vector(15 downto 0); +signal first_run_addr : std_logic_vector(15 downto 0); +signal first_run_lock : std_logic; +signal cts_addr : std_logic_vector(15 downto 0); +signal cts_addr_q : std_logic_vector(15 downto 0); +signal cts_addr_saved : std_logic; + +-- gk 24.07.10 +signal save_eod : std_logic; +signal save_eod_comb : std_logic; + +signal load_eod : std_logic; +signal endpoint_addr : std_logic_vector(15 downto 0); +signal endp_addr_lock : std_logic; + +signal saved_events_ctr : std_logic_vector(15 downto 0); +signal loaded_events_ctr : std_logic_vector(15 downto 0); +signal constr_events_ctr : std_logic_vector(31 downto 0); +signal event_waiting : std_logic; + +signal drop_sub : std_logic; +signal drop_sub_comb : std_logic; +signal drop_event : std_logic; +signal drop_event_comb : std_logic; +signal drop_small : std_logic; +signal drop_large : std_logic; +signal drop_headers : std_logic; +signal drop_small_comb : std_logic; +signal drop_large_comb : std_logic; +signal drop_headers_comb : std_logic; +signal inc_trg_ctr : std_logic; +signal inc_trg_ctr_comb : std_logic; + +signal invalid_hsize_ctr : std_logic_vector(15 downto 0); +signal invalid_hsize_lock : std_logic; + +signal load_eod_q : std_logic; +signal read_size_q : std_logic_vector(17 downto 0); + +-- gk 06.08.10 write to fifo only if gbe is enabled but keep the saving logic unblocked +signal sf_real_wr_en : std_logic; + +-- gk 01.10.10 +signal found_empty_evt : std_logic; +signal found_empty_evt_comb : std_logic; +signal found_empty_evt_ctr : std_logic_vector(31 downto 0); + +-- gk 06.10.10 +signal message_size : std_logic_vector(31 downto 0); + +-- gk 07.12.10 +signal prev_bank_select : std_logic_vector(3 downto 0); +signal first_event : std_logic; + +begin + +BANK_SELECT_OUT <= bank_select; -- gk 27.03.10 +START_CONFIG_OUT <= start_config; -- gk 27.03.10 +config_done <= CONFIG_DONE_IN; -- gk 29.03.10 + +-- CTS interface signals +cts_error_pattern <= (others => '0'); -- FAKE + +cts_length <= x"0000"; -- length of data payload is always 0 +cts_data <= b"0001" & cts_rnd(11 downto 0) & cts_trg; -- reserved bits = '0', pack bit = '1' + +cts_readout_finished <= '1' when (saveCurrentState = SCLOSE) else '0'; + +cts_dataready <= '1' when ((saveCurrentState = SAVE_DATA) and (FEE_BUSY_IN = '0')) or (saveCurrentState = TERMINATE) + else '0'; + +-- Byte swapping... done here. TAKE CARE! +-- The split FIFO is in natural bus order (i.e. Motorola style, [15:0]). This means that the two bytes +-- on the write side need to be swapped to appear in GbE style (i.e. Intel style) on the 8bit port. +-- Please mind that PC_SUB_SIZE and PC_TRIG_NR stay in a human readable format, and need to be byteswapped +-- for GbE inside the packet constructor. +-- +-- Long live the Endianess! + +-- Sync all critical pathes +THE_SYNC_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + --sf_data <= FEE_DATA_IN; -- gk 27.03.10 moved out to the process below + sf_wr_en <= sf_wr_en_comb; + ce_rem_ctr <= ce_rem_ctr_comb; + sf_rd_en <= sf_rd_en_comb; + fee_read <= fee_read_comb; + read_done <= read_done_comb; + pc_eod_q <= pc_eod; + pc_wr_en_qqq <= pc_wr_en_qq; + pc_wr_en_qq <= pc_wr_en_q; + pc_wr_en_q <= pc_wr_en_comb; + end if; +end process THE_SYNC_PROC; + +-- gk 27.03.10 data selector for sf to write the evt builder address on top of data +SF_DATA_PROC : process( CLK ) +begin + if( rising_edge(CLK) ) then + if (RESET = '1') then -- gk 31.05.10 + sf_data <= (others => '0'); + elsif( save_addr = '1' ) then + sf_data(3 downto 0) <= CTS_INFORMATION_IN(3 downto 0); -- only last 4 bits are the evt builder address + sf_data(15 downto 4) <= x"abc"; + -- gk 29.03.10 four entries to save the fee_status into sf for the subsubevent + elsif( (add_sub_state = '1') and (add_sub_ctr = x"0") ) then + sf_data <= x"0001"; -- gk 11.06.10 + elsif( (add_sub_state = '1') and (add_sub_ctr = x"1") ) then + sf_data <= x"5555"; -- gk 11.06.10 + elsif( (add_sub_state = '1') and (add_sub_ctr = x"2") ) then + sf_data <= FEE_STATUS_BITS_IN(31 downto 16); + elsif( (add_sub_state = '1') and (add_sub_ctr = x"3") ) then + sf_data <= FEE_STATUS_BITS_IN(15 downto 0); + else + sf_data <= FEE_DATA_IN; + end if; + end if; +end process SF_DATA_PROC; + +-- combinatorial read signal for the FEE data interface, DO NOT USE DIRECTLY +fee_read_comb <= '1' when ( (sf_afull = '0') and (data_req = '1') ) --and (DATA_GBE_ENABLE_IN = '1') ) -- GbE enabled + else '0'; + +-- combinatorial write signal for the split FIFO, DO NOT USE DIRECTLY +sf_wr_en_comb <= '1' when ( (fee_read = '1') and (FEE_DATAREADY_IN = '1') ) or -- and (DATA_GBE_ENABLE_IN = '1') ) or -- GbE enabled + (save_addr = '1') or + (add_sub_state = '1') -- gk 29.03.10 save the subsubevent + else '0'; + +-- gk 06.08.10 +sf_real_wr_en <= '1' when ((sf_wr_en = '1') and (DATA_GBE_ENABLE_IN = '1')) else '0'; + +-- gk 27.03.10 do not count evt builder address as saved ipu bytes +--ce_saved_ctr <= sf_wr_en; +ce_saved_ctr <= '0' when addr_saved = '1' else sf_wr_en; + +-- Statemachine for reading data payload, handling IPU channel and storing data in the SPLIT_FIFO +saveMachineProc: process( CLK ) +begin + if rising_edge(CLK) then + if (RESET = '1') then + saveCurrentState <= SIDLE; + data_req <= '0'; + rst_saved_ctr <= '0'; + save_addr <= '0'; -- gk 27.03.10 + addr_saved <= '0'; -- gk 27.03.10 + add_sub_state <= '0'; -- gk 29.03.10 + save_eod <= '0'; -- gk 25.07.10 + else + saveCurrentState <= saveNextState; + data_req <= data_req_comb; + rst_saved_ctr <= rst_saved_ctr_comb; + save_addr <= save_addr_comb; -- gk 27.03.10 + addr_saved <= addr_saved_comb; -- gk 27.03.10 + add_sub_state <= add_sub_state_comb; -- gk 29.03.10 + save_eod <= save_eod_comb; -- gk 25.07.10 + end if; + end if; +end process saveMachineProc; + +saveMachine: process( saveCurrentState, CTS_START_READOUT_IN, FEE_BUSY_IN, CTS_READ_IN) +begin + saveNextState <= SIDLE; + data_req_comb <= '0'; + rst_saved_ctr_comb <= '0'; + save_addr_comb <= '0'; -- gk 27.03.10 + addr_saved_comb <= '0'; -- gk 27.03.10 + add_sub_state_comb <= '0'; -- gk 29.03.10 + save_eod_comb <= '0'; -- gk 25.07.10 + case saveCurrentState is + when SIDLE => + state <= x"0"; + if (CTS_START_READOUT_IN = '1') then + saveNextState <= SAVE_EVT_ADDR; --WAIT_FOR_DATA; -- gk 27.03.10 + data_req_comb <= '1'; + rst_saved_ctr_comb <= '1'; + else + saveNextState <= SIDLE; + end if; + -- gk 27.03.10 + when SAVE_EVT_ADDR => + state <= x"5"; + saveNextState <= WAIT_FOR_DATA; + data_req_comb <= '1'; + save_addr_comb <= '1'; + when WAIT_FOR_DATA => + state <= x"1"; + if (FEE_BUSY_IN = '1') then + saveNextState <= SAVE_DATA; + data_req_comb <= '1'; + else + saveNextState <= WAIT_FOR_DATA; + data_req_comb <= '1'; + end if; + addr_saved_comb <= '1'; -- gk 27.03.10 + when SAVE_DATA => + state <= x"2"; + if (FEE_BUSY_IN = '0') then + saveNextState <= TERMINATE; + else + saveNextState <= SAVE_DATA; + data_req_comb <= '1'; + end if; + when TERMINATE => + state <= x"3"; + if (CTS_READ_IN = '1') then + saveNextState <= SCLOSE; + else + saveNextState <= TERMINATE; + end if; + when SCLOSE => + state <= x"4"; + if (CTS_START_READOUT_IN = '0') then + saveNextState <= ADD_SUBSUB1; --SIDLE; -- gk 29.03.10 + else + saveNextState <= SCLOSE; + end if; + -- gk 29.03.10 new states during which the subsub bytes are saved + when ADD_SUBSUB1 => + state <= x"6"; + saveNextState <= ADD_SUBSUB2; + add_sub_state_comb <= '1'; + when ADD_SUBSUB2 => + state<= x"7"; + saveNextState <= ADD_SUBSUB3; + add_sub_state_comb <= '1'; + save_eod_comb <= '1'; + when ADD_SUBSUB3 => + state<= x"8"; + saveNextState <= ADD_SUBSUB4; + add_sub_state_comb <= '1'; + when ADD_SUBSUB4 => + state<= x"9"; + saveNextState <= SIDLE; + add_sub_state_comb <= '1'; + when others => + state <= x"f"; + saveNextState <= SIDLE; + end case; +end process saveMachine; + +-- gk 29.03.10 +ADD_SUB_CTR_PROC : process( CLK ) +begin + if( rising_edge( CLK ) ) then + if( (RESET = '1') or (rst_saved_ctr = '1') ) then + add_sub_ctr <= (others => '0'); + elsif( add_sub_state = '1' ) then + add_sub_ctr <= add_sub_ctr + 1; + end if; + end if; +end process ADD_SUB_CTR_PROC; + +--******** +-- SAVE INCOMING EVENT HEADERS +--******** + +-- Counter for header word storage +THE_CTS_SAVED_CTR: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_saved_ctr = '1') ) then + saved_ctr <= (others => '0'); + elsif( ce_saved_ctr = '1' ) then + saved_ctr <= saved_ctr + 1; + end if; + end if; +end process THE_CTS_SAVED_CTR; + +-- save triggerRnd from incoming data for cts response +CTS_RND_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_saved_ctr = '1') ) then + cts_rnd <= (others => '0'); + cts_rnd_saved <= '0'; + elsif( (saved_ctr(2 downto 0) = b"000") and (sf_wr_en = '1') and (cts_rnd_saved = '0') ) then + cts_rnd <= sf_data; + cts_rnd_saved <= '1'; + end if; + end if; +end process CTS_RND_PROC; + +-- save triggerNr from incoming data for cts response +CTS_TRG_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_saved_ctr = '1') ) then + cts_trg <= (others => '0'); + cts_trg_saved <= '0'; + elsif( (saved_ctr(2 downto 0) = b"001") and (sf_wr_en = '1') and (cts_trg_saved = '0') ) then + cts_trg <= sf_data; + cts_trg_saved <= '1'; + end if; + end if; +end process CTS_TRG_PROC; + +-- save size from incoming data for cts response (future) and to get rid of padding +CTS_SIZE_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_saved_ctr = '1') ) then + cts_len <= (others => '0'); + cts_len_saved <= '0'; + elsif( (saved_ctr(2 downto 0) = b"010") and (sf_wr_en = '1') and (cts_len_saved = '0') ) then + cts_len(16 downto 1) <= sf_data; -- change from 32b words to 16b words + cts_len(0) <= '0'; + elsif( (saved_ctr(2 downto 0) = b"011") and (cts_len_saved = '0') ) then + cts_len <= cts_len + x"4"; + cts_len_saved <= '1'; + end if; + end if; +end process CTS_SIZE_PROC; + +-- gk 22.07.10 +CTS_ADDR_PROC : process(CLK) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_saved_ctr = '1') ) then + cts_addr <= (others => '0'); + cts_addr_saved <= '0'; + elsif( (saved_ctr(2 downto 0) = b"011") and (sf_wr_en = '1') and (cts_addr_saved = '0') ) then + cts_addr <= sf_data; + cts_addr_saved <= '1'; + end if; + end if; +end process CTS_ADDR_PROC; + +--****** +-- SAVE FIRST EVENT HEADER VALUES +--****** + +-- gk 22.07.10 +FIRST_RUN_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + first_run_trg <= (others => '0'); + first_run_addr <= (others => '0'); + first_run_lock <= '0'; + elsif (first_run_lock = '0') and (cts_addr_saved = '1') then + first_run_trg <= cts_trg; + first_run_addr <= cts_addr; + first_run_lock <= '1'; + -- important: value saved by saveMachine but incremented by loadMachine + elsif (first_run_lock = '1') and (inc_trg_ctr = '1') then + first_run_trg <= first_run_trg + x"1"; + end if; + end if; +end process FIRST_RUN_PROC; + +-- gk 25.07.10 +SAVED_EVT_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + saved_events_ctr <= (others => '0'); + elsif (save_eod = '1') then + saved_events_ctr <= saved_events_ctr + x"1"; + end if; + end if; +end process SAVED_EVT_CTR_PROC; + + +-- gk 20.07.10 +INC_DATA_CTR_proc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (rst_saved_ctr = '1') then + inc_data_ctr <= (others => '0'); + elsif (sf_wr_en = '1') and (data_req = '1') then + inc_data_ctr(31 downto 1) <= inc_data_ctr(31 downto 1) + x"1"; + end if; + end if; +end process INC_DATA_CTR_proc; + +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ + +-- Split FIFO +THE_SPLIT_FIFO: fifo_32kx16x8_mb2 +port map( + -- Byte swapping for correct byte order on readout side of FIFO + Data(7 downto 0) => sf_data(15 downto 8), + Data(8) => '0', + Data(16 downto 9) => sf_data(7 downto 0), + Data(17) => save_eod, + WrClock => CLK, + RdClock => CLK, + WrEn => sf_real_wr_en, -- gk 06.08.10 --sf_wr_en, + RdEn => sf_rd_en, + Reset => RESET, + RPReset => RESET, + AmEmptyThresh => b"0000_0000_0000_0010", -- one byte ahead + AmFullThresh => b"111_1111_1110_1111", -- 0x7fef = 32751 + Q(7 downto 0) => pc_data, + Q(8) => load_eod, + WCNT => sf_wcnt, + RCNT => sf_rcnt, + Empty => sf_empty, + AlmostEmpty => sf_aempty, + Full => sf_full, + AlmostFull => sf_afull +); + +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ + +-- gk 25.07.10 +EVENT_WAITING_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + event_waiting <= '0'; + elsif (loaded_events_ctr /= saved_events_ctr) then + event_waiting <= '1'; + else + event_waiting <= '0'; + end if; + end if; +end process EVENT_WAITING_PROC; + +-- write signal for PC data +pc_wr_en_comb <= '1' when ((data_phase = '1') and (sf_rd_en = '1')) or + (pad_phase = '1') or + ((load_sub = '1') and (sf_rd_en = '1')) or + ((drop_sub = '1') and (sf_rd_en = '1')) or + ((drop_event = '1') and (sf_rd_en = '1')) + else '0'; + +sf_rd_en_comb <= '1' when ( (sf_aempty = '0') and (rem_phase = '1') and (remove_done = '0') ) or + --( (sf_aempty = '0') and (data_phase = '1') and (read_done = '0') ) or + ( (sf_aempty = '0') and (data_phase = '1') and (load_eod = '0') ) or -- gk 26.07.10 + ( (sf_aempty = '0') and (load_sub = '1') and (load_sub_done = '0') ) or -- gk 30.03.10 + ( (sf_aempty = '0') and (drop_event = '1') and (load_eod = '0') ) or + ( (sf_aempty = '0') and (drop_sub = '1') and (load_sub_done = '0') ) + else '0'; + +ce_rem_ctr_comb <= '1' when ( (sf_aempty = '0') and (rem_phase = '1') and ( remove_done = '0') ) + else '0'; + +-- FIFO data delay process (also forces padding bytes to known value) +THE_DATA_DELAY_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if( pad_data = '1' ) then + pc_data_q <= x"aa"; -- padding for 64bit + -- gk 21.07.10 + -- set the error flag if a broken packet is sent + elsif (drop_sub = '1') and (load_sub_ctr = x"3") then + pc_data_q <= pc_data(7 downto 3) & '1' & pc_data(1 downto 0); + else + pc_data_q <= pc_data; + end if; + end if; +end process THE_DATA_DELAY_PROC; + +-- Statemachine for reading the data payload from the SPLIT_FIFO and feeding +-- it into the packet constructor +loadMachineProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + loadCurrentState <= LIDLE; + rst_rem_ctr <= '0'; + rem_phase <= '0'; + calc_pad <= '0'; + data_phase <= '0'; + pad_phase <= '0'; + pc_sos <= '0'; + pc_eod <= '0'; + rst_regs <= '0'; + pad_data <= '0'; + load_sub <= '0'; -- gk 30.03.10 + drop_sub <= '0'; -- gk 25.07.10 + drop_event <= '0'; -- gk 25.07.10 + drop_small <= '0'; -- gk 25.07.10 + drop_large <= '0'; -- gk 25.07.10 + drop_headers <= '0'; -- gk 25.07.10 + inc_trg_ctr <= '0'; -- gk 26.07.10 + found_empty_evt <= '0'; -- gk 01.10.10 + else + loadCurrentState <= loadNextState; + rst_rem_ctr <= rst_rem_ctr_comb; + rem_phase <= rem_phase_comb; + calc_pad <= calc_pad_comb; + data_phase <= data_phase_comb; + pad_phase <= pad_phase_comb; + pc_sos <= pc_sos_comb; + pc_eod <= pc_eod_comb; + rst_regs <= rst_regs_comb; + pad_data <= pad_data_comb; + load_sub <= load_sub_comb; -- gk 30.03.1 + drop_sub <= drop_sub_comb; -- gk 25.07.10 + drop_event <= drop_event_comb; -- gk 25.07.10 + drop_small <= drop_small_comb; -- gk 25.07.10 + drop_large <= drop_large_comb; -- gk 25.07.10 + drop_headers <= drop_headers_comb; -- gk 25.07.10 + inc_trg_ctr <= inc_trg_ctr_comb; -- gk 26.07.10 + found_empty_evt <= found_empty_evt_comb; -- gk 01.10.10 + end if; + end if; +end process loadMachineProc; + +loadMachine : process( loadCurrentState, sf_aempty, remove_done, read_done, padding_needed, + PC_READY_IN, load_sub_done, pc_sub_size, MIN_MESSAGE_SIZE_IN, + MAX_MESSAGE_SIZE_IN, pc_trig_nr, first_run_trg, endpoint_addr, + first_run_addr, load_eod, event_waiting, MULT_EVT_ENABLE_IN, message_size) +begin + loadNextState <= LIDLE; + rst_rem_ctr_comb <= '0'; + rem_phase_comb <= '0'; + calc_pad_comb <= '0'; + data_phase_comb <= '0'; + pad_phase_comb <= '0'; + pc_sos_comb <= '0'; + pc_eod_comb <= '0'; + rst_regs_comb <= '0'; + pad_data_comb <= '0'; + load_sub_comb <= '0'; -- gk 30.03.10 + drop_sub_comb <= '0'; -- gk 25.07.10 + drop_event_comb <= '0'; -- gk 25.07.10 + drop_small_comb <= '0'; -- gk 25.07.10 + drop_large_comb <= '0'; -- gk 25.07.10 + drop_headers_comb <= '0'; -- gk 25.07.10 + inc_trg_ctr_comb <= '0'; -- gk 26.07.10 + found_empty_evt_comb <= '0'; -- gk 01.10.10 + case loadCurrentState is + when LIDLE => + state2 <= x"0"; + -- gk 23.07.10 + if( (sf_aempty = '0') and (event_waiting = '1') and (DATA_GBE_ENABLE_IN = '1') ) then -- gk 06.08.10 -- and (PC_READY_IN = '1') + loadNextState <= INIT; + rst_rem_ctr_comb <= '1'; + rst_regs_comb <= '1'; + else + loadNextState <= LIDLE; + end if; + when INIT => + state2 <= x"1"; + loadNextState <= REMOVE; + rem_phase_comb <= '1'; + when REMOVE => + state2 <= x"2"; + if( remove_done = '1' ) then + -- gk 06.10.10 + if (MULT_EVT_ENABLE_IN = '1') then + if (message_size + pc_sub_size < MAX_MESSAGE_SIZE_IN) then + --loadNextState <= WAIT_TO_REMOVE; + -- gk 07.12.10 + if (first_event = '0') and (prev_bank_select /= bank_select) then -- check if event builder address changed, if so close the current packet + loadNextState <= WAIT_PC; + else + loadNextState <= WAIT_TO_REMOVE; + end if; + + else + loadNextState <= WAIT_PC; + end if; + else + loadNextState <= WAIT_TO_REMOVE; + end if; + inc_trg_ctr_comb <= '1'; + else + loadNextState <= REMOVE; + rem_phase_comb <= '1'; + end if; + when WAIT_TO_REMOVE => + if (rem_ctr = x"a") then + loadNextState <= DECIDE; + else + loadNextState <= WAIT_TO_REMOVE; + end if; + when DECIDE => + if (pc_sub_size >= MAX_MESSAGE_SIZE_IN) then + loadNextState <= PAUSE_BEFORE_DROP1; + drop_large_comb <= '1'; + elsif (pc_sub_size = b"0000_0000_0000_00") then -- gk 01.10.10 + loadNextState <= CALCA; + found_empty_evt_comb <= '1'; + elsif (pc_sub_size < MIN_MESSAGE_SIZE_IN) then + loadNextState <= PAUSE_BEFORE_DROP1; + drop_small_comb <= '1'; + elsif (pc_trig_nr + x"1" /= first_run_trg) then + loadNextState <= PAUSE_BEFORE_DROP1; + drop_headers_comb <= '1'; + elsif (endpoint_addr /= first_run_addr) then + loadNextState <= PAUSE_BEFORE_DROP1; + drop_headers_comb <= '1'; + else + loadNextState <= CALCA; + end if; + calc_pad_comb <= '1'; + when CALCA => + state2 <= x"3"; + loadNextState <= CALCB; + pc_sos_comb <= '1'; + when CALCB => + -- we need a branch in case of length "0"!!!! + state2 <= x"4"; + loadNextState <= LOAD; + data_phase_comb <= '1'; + when LOAD => + state2 <= x"5"; + if (load_eod = '1') then + loadNextState <= LOAD_SUBSUB; + else + loadNextState <= LOAD; + data_phase_comb <= '1'; + end if; + -- gk 31.03.10 + when LOAD_SUBSUB => + state2 <= x"d"; + if( load_sub_done = '1' ) then + if( padding_needed = '0' ) then + loadNextState <= CALCC; + else + loadNextState <= PAD0; + pad_phase_comb <= '1'; + end if; + else + loadNextState <= LOAD_SUBSUB; + load_sub_comb <= '1'; + end if; + when PAD0 => + state2 <= x"6"; + loadNextState <= PAD1; + pad_phase_comb <= '1'; + pad_data_comb <= '1'; + when PAD1 => + state2 <= x"7"; + loadNextState <= PAD2; + pad_phase_comb <= '1'; + pad_data_comb <= '1'; + when PAD2 => + state2 <= x"8"; + loadNextState <= PAD3; + pad_phase_comb <= '1'; + pad_data_comb <= '1'; + when PAD3 => + state2 <= x"9"; + loadNextState <= CALCC; + pad_data_comb <= '1'; + when CALCC => + state2 <= x"a"; + if (MULT_EVT_ENABLE_IN = '1') then + loadNextState <= LIDLE; + else + loadNextState <= CLOSE; + end if; + pc_eod_comb <= '1'; + when CLOSE => + state2 <= x"b"; + loadNextState <= WAIT_PC; + --rst_regs_comb <= '1'; -- gk 07.10.10 + when WAIT_PC => + state2 <= x"c"; + if( PC_READY_IN = '1' ) then + -- gk 06.10.10 + if (MULT_EVT_ENABLE_IN = '1') then + loadNextState <= WAIT_TO_REMOVE; + else + loadNextState <= LIDLE; + end if; + else + loadNextState <= WAIT_PC; + end if; + when PAUSE_BEFORE_DROP1 => + loadNextState <= PAUSE_BEFORE_DROP2; + pc_sos_comb <= '1'; + when PAUSE_BEFORE_DROP2 => + loadNextState <= DROP; + drop_event_comb <= '1'; + -- gk 23.07.10 + when DROP => + state2 <= x"e"; + -- when data is dropped the eod marker stands as its end + if (load_eod = '1') then + loadNextState <= DROP_SUBSUB; + else + loadNextState <= DROP; + drop_event_comb <= '1'; + end if; + -- gk 25.07.10 + when DROP_SUBSUB => + if (load_sub_done = '1') then + if( padding_needed = '0' ) then + loadNextState <= CALCC; + else + loadNextState <= PAD0; + pad_phase_comb <= '1'; + end if; + else + loadNextState <= DROP_SUBSUB; + drop_sub_comb <= '1'; + end if; + when others => + state2 <= x"f"; + loadNextState <= LIDLE; + end case; +end process loadMachine; + +-- gk 07.10.10 +PC_EOS_OUT <= '1' when (MULT_EVT_ENABLE_IN = '1') and (pc_eod = '1') else '0'; + +-- gk 25.07.10 +INVALID_STATS_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + dropped_lr_events_ctr <= (others => '0'); + dropped_sm_events_ctr <= (others => '0'); + headers_invalid_ctr <= (others => '0'); + dropped_ctr <= (others => '0'); + invalid_hsize_ctr <= (others => '0'); + found_empty_evt_ctr <= (others => '0'); -- gk 01.10.10 + elsif (rst_regs = '1') then + invalid_hsize_lock <= '0'; + elsif (drop_small = '1') then + dropped_sm_events_ctr <= dropped_sm_events_ctr + x"1"; + dropped_ctr <= dropped_ctr + x"1"; + elsif (drop_large = '1') then + dropped_lr_events_ctr <= dropped_lr_events_ctr + x"1"; + dropped_ctr <= dropped_ctr + x"1"; + elsif (drop_headers = '1') then + headers_invalid_ctr <= headers_invalid_ctr + x"1"; + dropped_ctr <= dropped_ctr + x"1"; + elsif (load_eod_q = '1') and (read_size_q /= x"3fffe") and (invalid_hsize_lock = '0') then -- ?? + invalid_hsize_ctr <= invalid_hsize_ctr + x"1"; + invalid_hsize_lock <= '1'; + -- gk 01.10.10 + elsif (found_empty_evt = '1') then + found_empty_evt_ctr <= found_empty_evt_ctr + x"1"; + end if; + end if; +end process INVALID_STATS_PROC; + +-- gk 05.08.10 +INVALID_H_PROC : process(CLK) +begin + if rising_edge(CLK) then + load_eod_q <= load_eod; + read_size_q <= read_size; + end if; +end process INVALID_H_PROC; + +-- gk 26.04.10 +READOUT_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if ((RESET = '1') or (READOUT_CTR_VALID_IN = '1')) then + readout_ctr <= READOUT_CTR_IN; + readout_ctr_lock <= '0'; + elsif (pc_sos = '1') then + readout_ctr <= readout_ctr + x"1"; + end if; + end if; +end process READOUT_CTR_PROC; + +--****** +-- SELECTION OF EVENT BUILDER +--****** + +-- gk 27.03.10 +bank_select_proc : process( CLK ) +begin + if rising_edge( CLK ) then + -- gk 29.03.10 + if( (RESET = '1') or (rst_regs = '1') ) then + bank_select <= "0000"; + -- gk 01.06.10 THERE WAS A BUG, IT SHOUDL BE TAKEN FROM SF_Q + elsif( (sf_rd_en = '1') and (rem_ctr = x"2") ) then + bank_select <= pc_data(3 downto 0); --CTS_INFORMATION_IN(3 downto 0); + end if; + end if; +end process bank_select_proc; + +-- gk 07.12.10 +first_event_proc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = WAIT_PC) then + first_event <= '1'; + elsif (remove_done = '1') then + first_event <= '0'; + end if; + end if; +end process first_event_proc; + +-- gk 07.12.10 +prev_bank_proc : process(CLK) +begin + if (RESET = '1') or (loadCurrentState = WAIT_PC) then + prev_bank_select <= "0000"; + elsif ((sf_rd_en = '1') and (rem_ctr = x"3") and (first_event = '1')) then + prev_bank_select <= bank_select; + end if; +end process prev_bank_proc; + + +-- gk 29.03.10 +start_config_proc : process( CLK ) +begin + if rising_edge( CLK ) then + if( (RESET = '1') or (config_done = '1') or (rst_regs = '1') ) then + start_config <= '0'; + elsif( (sf_rd_en = '1') and (rem_ctr = x"2") and (first_event = '1') ) then -- gk 01.06.10 + start_config <= '1'; + end if; + end if; +end process start_config_proc; + + +--****** +-- LOAD SUBSUBEVENT +--****** + +-- gk 30.03.10 +load_sub_ctr_comb <= '1' when ( ((load_sub = '1') or (drop_sub = '1')) and (load_sub_done = '0') and (sf_aempty = '0') ) + else '0'; + +-- gk 30.03.10 +LOAD_SUB_CTR_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_regs = '1') ) then -- gk 08.04.10 + load_sub_ctr <= (others => '0'); + elsif( (load_sub_ctr_comb = '1') ) then + load_sub_ctr <= load_sub_ctr + 1; + end if; + end if; +end process LOAD_SUB_CTR_PROC; + +-- gk 30.03.10 +-- load_sub_done_comb <= '1' when ((load_sub_ctr = x"7") and (drop_sub = '0')) or +-- ((load_sub_ctr = x"4") and (drop_sub = '1')) +-- else '0'; +load_sub_done_comb <= '1' when (load_sub_ctr = x"4") else '0'; + +-- gk 30.03.10 +LOAD_SUB_DONE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if ( (RESET = '1') or (rst_regs = '1') ) then -- gk 08.04.10 + load_sub_done <= '0'; + else + load_sub_done <= load_sub_done_comb; + end if; + end if; +end process LOAD_SUB_DONE_PROC; + +--****** +-- EXTRACT EVENT HEADERS FROM SPLITFIFO +--****** + +-- Counter for stripping the unneeded parts of the data stream, and saving the important parts +THE_REMOVE_CTR: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_rem_ctr = '1') ) then + rem_ctr <= (others => '0'); + elsif( (ce_rem_ctr = '1') ) then + rem_ctr <= rem_ctr + 1; + end if; + end if; +end process THE_REMOVE_CTR; + +remove_done_comb <= '1' when ( rem_ctr = x"8" ) else '0'; --( rem_ctr = x"6" ) else '0'; -- gk 29.03.10 two more for evt builder address + +THE_REM_DONE_SYNC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_rem_ctr = '1') ) then + remove_done <= '0'; + else + remove_done <= remove_done_comb; + end if; + end if; +end process THE_REM_DONE_SYNC; + +-- gk 26.04.10 +TRIG_RANDOM_PROC : process(CLK) +begin + if rising_edge(CLK) then + if ((RESET = '1') or (rst_regs = '1')) then + trig_random <= (others => '0'); + elsif ((sf_rd_en = '1') and (rem_ctr = x"4")) then + trig_random <= pc_data; + end if; + end if; +end process TRIG_RANDOM_PROC; + +-- extract the trigger number from splitfifo data +THE_TRG_NR_PROC: process( CLK ) +begin + if rising_edge(CLK) then + if ( (RESET = '1') or (rst_regs = '1') ) then + pc_trig_nr <= (others => '0'); + elsif( (sf_rd_en = '1') and (rem_ctr = x"6") ) then -- x"4" gk 29.03.10 + pc_trig_nr(7 downto 0) <= pc_data; + elsif( (sf_rd_en = '1') and (rem_ctr = x"5") ) then -- x"3" gk 29.03.10 + pc_trig_nr(15 downto 8) <= pc_data; + end if; + end if; +end process THE_TRG_NR_PROC; + +-- extract the subevent size from the splitfifo data, convert it from 32b to 8b units, +-- and in case of padding needed increase it accordingly +THE_SUB_SIZE_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_regs = '1') ) then + pc_sub_size <= (others => '0'); + elsif( (sf_rd_en = '1') and (rem_ctr = x"8") ) then -- x"6" gk 29.03.10 + pc_sub_size(9 downto 2) <= pc_data; + elsif( (sf_rd_en = '1') and (rem_ctr = x"7") ) then -- x"5" gk 29.03.10 + pc_sub_size(17 downto 10) <= pc_data; + -- gk 20.07.10 + -- gk 30.03.10 bug fixed in the way that is written below + -- gk 27.03.10 should be corrected by sending padding_needed signal to pc and take care of it when setting sub_size_to_save + elsif( (calc_pad = '1') and (padding_needed = '1') ) then + pc_sub_size <= pc_sub_size + x"4" + x"8"; -- BUG: SubEvtSize does NOT include 64bit padding!!! + elsif( (calc_pad = '1') and (padding_needed = '0') ) then + pc_sub_size <= pc_sub_size + x"8"; + end if; + end if; +end process THE_SUB_SIZE_PROC; + +-- gk 06.10.10 +MESSAGE_SIZE_PROC : process(CLK) +begin + if rising_edge(CLK) then +-- if (RESET = '1') then +-- message_size <= (others => '0'); +-- elsif ((MULT_EVT_ENABLE_IN = '1') and (message_size + pc_sub_size >= MAX_MESSAGE_SIZE_IN) and (remove_done = '1')) then +-- message_size <= (others => '0'); +-- elsif (pc_sos = '1') then +-- message_size <= message_size + pc_sub_size; +-- end if; + if (RESET = '1') then + message_size <= x"0000_0028"; + elsif ((MULT_EVT_ENABLE_IN = '1') and (message_size + pc_sub_size >= MAX_MESSAGE_SIZE_IN) and (remove_done = '1')) then + message_size <= x"0000_0028"; + elsif ((MULT_EVT_ENABLE_IN = '1') and (prev_bank_select /= bank_select) and (remove_done = '1')) then + message_size <= x"0000_0028"; + elsif (pc_sos = '1') then + message_size <= message_size + pc_sub_size + x"10"; -- gk 06.12.10 add 16B for subevent headers + end if; + end if; +end process MESSAGE_SIZE_PROC; + + +-- gk 25.07.10 +ENDP_ADDRESS_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (rst_regs = '1') then + endpoint_addr <= (others => '0'); + endp_addr_lock <= '0'; + elsif( (rem_ctr = x"a") and (endp_addr_lock = '0') ) then + endpoint_addr(7 downto 0) <= pc_data; + endp_addr_lock <= '1'; + elsif( (sf_rd_en = '1') and (rem_ctr = x"9") ) then + endpoint_addr(15 downto 8) <= pc_data; + endp_addr_lock <= '0'; + end if; + end if; +end process ENDP_ADDRESS_PROC; + + + +-- check for padding +THE_PADDING_NEEDED_PROC: process( CLK ) +begin + if rising_edge(CLK) then + if ( (RESET = '1') or (rst_regs = '1') ) then + padding_needed <= '0'; + elsif( (remove_done = '1') and (pc_sub_size(2) = '1') ) then + padding_needed <= '1'; + elsif( (remove_done = '1') and (pc_sub_size(2) = '0') ) then + padding_needed <= '0'; + end if; + end if; +end process THE_PADDING_NEEDED_PROC; + +-- number of bytes to read from split fifo +THE_READ_SIZE_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_regs = '1') ) then --(rst_rem_ctr = '1') ) then + read_size <= (others => '0'); + elsif( (sf_rd_en = '1') and (rem_ctr = x"8") ) then -- x"6" gk 29.03.10 + read_size(9 downto 2) <= pc_data; + elsif( (sf_rd_en = '1') and (rem_ctr = x"7") ) then -- x"5" gk 29.03.10 + read_size(17 downto 10) <= pc_data; + elsif( ((sf_rd_en = '1') and (data_phase = '1')) ) then + read_size <= read_size - 1; + -- gk 25.07.10 + elsif( ((sf_rd_en = '1') and (drop_event = '1')) ) then + read_size <= read_size - 1; + end if; + end if; +end process THE_READ_SIZE_PROC; + +read_done_comb <= '1' when (read_size < 3 ) else '0'; -- "2" + +--****** +-- EVENTS COUNTERS +--****** + +-- gk 25.07.10 +LOADED_EVT_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + loaded_events_ctr <= (others => '0'); + elsif (remove_done = '1') then + loaded_events_ctr <= loaded_events_ctr + x"1"; + end if; + end if; +end process LOADED_EVT_CTR_PROC; + +-- gk 25.07.10 +CONSTR_EVENTS_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + constr_events_ctr <= (others => '0'); + elsif (pc_eod = '1') then + constr_events_ctr <= constr_events_ctr + x"1"; + end if; + end if; +end process CONSTR_EVENTS_CTR_PROC; + +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ + +-- Debug signals +debug(0) <= sf_full; +debug(1) <= sf_empty; +debug(2) <= sf_afull; +debug(3) <= sf_aempty; + +debug(7 downto 4) <= state2; + +debug(11 downto 8) <= state; + +dbg_bs_proc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + debug(15 downto 12) <= (others => '0'); + elsif ( (sf_rd_en = '1') and (rem_ctr = x"3") ) then + debug(15 downto 12) <= bank_select; + end if; + end if; +end process dbg_bs_proc; + +debug(16) <= config_done; +debug(17) <= '0'; --remove_done; +debug(18) <= read_done; +debug(19) <= padding_needed; + +debug(20) <= load_sub_done; + +dbg_cts_inf_proc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + debug(39 downto 32) <= (others => '0'); + elsif ( save_addr = '1' ) then + debug(39 downto 32) <= CTS_INFORMATION_IN; + end if; + end if; +end process dbg_cts_inf_proc; + +debug(47 downto 40) <= (others => '0'); + + +debug(63 downto 48) <= actual_message_size(15 downto 0); + +dbg_pc_sub_size_proc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + debug(81 downto 64) <= (others => '0'); + elsif (loadCurrentState = DECIDE) then + debug(81 downto 64) <= pc_sub_size; + end if; + end if; +end process dbg_pc_sub_size_proc; + +dbg_empty_proc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (rst_regs = '1') then + debug(84 downto 82) <= (others => '0'); + elsif (read_size = 2) then + debug(82) <= sf_empty; + elsif (read_size = 1) then + debug(83) <= sf_empty; + elsif (read_size = 0) then + debug(84) <= sf_empty; + end if; + end if; +end process dbg_empty_proc; + +debug(95 downto 85) <= (others => '0'); + +dbg_inc_ctr_proc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + debug(127 downto 96) <= (others => '1'); + elsif (saveCurrentState = SCLOSE) then + debug(127 downto 96) <= inc_data_ctr; + end if; + end if; +end process dbg_inc_ctr_proc; + +debug(143 downto 128) <= dropped_sm_events_ctr(15 downto 0); +debug(159 downto 144) <= dropped_lr_events_ctr(15 downto 0); + +debug(175 downto 160) <= headers_invalid_ctr(15 downto 0); +debug(191 downto 176) <= (others => '0'); + +dbg_cts_q_proc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + cts_len_q <= (others => '0'); + cts_rnd_q <= (others => '0'); + cts_trg_q <= (others => '0'); + cts_addr_q <= (others => '0'); + elsif (cts_len_saved = '1') then + cts_len_q <= cts_len(16 downto 1); + cts_addr_q <= cts_addr; + cts_rnd_q <= cts_rnd; + cts_trg_q <= cts_trg; + end if; + end if; +end process dbg_cts_q_proc; + +debug(207 downto 192) <= cts_trg_q; +debug(223 downto 208) <= cts_rnd_q; +debug(239 downto 224) <= cts_addr_q; +debug(255 downto 240) <= cts_len_q; +debug(271 downto 256) <= first_run_trg; +debug(287 downto 272) <= first_run_addr; + +debug(303 downto 288) <= saved_events_ctr; +debug(319 downto 304) <= loaded_events_ctr; + +debug(335 downto 320) <= constr_events_ctr(15 downto 0); +debug(351 downto 336) <= dropped_ctr(15 downto 0); + +debug(367 downto 352) <= invalid_hsize_ctr; +debug(383 downto 368) <= (others => '0'); + +MONITOR_OUT(31 downto 0) <= constr_events_ctr; +MONITOR_OUT(63 downto 32) <= dropped_ctr; +MONITOR_OUT(95 downto 64) <= headers_invalid_ctr; +MONITOR_OUT(127 downto 96) <= dropped_sm_events_ctr; +MONITOR_OUT(159 downto 128) <= dropped_lr_events_ctr; +MONITOR_OUT(163 downto 160) <= b"1111" when (sf_afull = '1') else b"0000"; +MONITOR_OUT(191 downto 164) <= (others => '0'); +MONITOR_OUT(223 downto 192) <= found_empty_evt_ctr; -- gk 01.10.10 + +-- Outputs +FEE_READ_OUT <= fee_read; +CTS_ERROR_PATTERN_OUT <= cts_error_pattern; +CTS_DATA_OUT <= cts_data; +CTS_DATAREADY_OUT <= cts_dataready; +CTS_READOUT_FINISHED_OUT <= cts_readout_finished; +CTS_LENGTH_OUT <= cts_length; + +PC_SOS_OUT <= pc_sos; +PC_EOD_OUT <= '1' when ((MULT_EVT_ENABLE_IN = '0') and (pc_eod = '1')) + or ((MULT_EVT_ENABLE_IN = '1') and (message_size + pc_sub_size >= MAX_MESSAGE_SIZE_IN) and (remove_done = '1')) + -- gk 07.12.10 + or ((MULT_EVT_ENABLE_IN = '1') and (prev_bank_select /= bank_select) and (remove_done = '1')) + else '0'; -- gk 07.10.10 +PC_DATA_OUT <= pc_data_q; +PC_WR_EN_OUT <= pc_wr_en_qq; + +PC_TRIG_NR_OUT <= readout_ctr(23 downto 16) & pc_trig_nr & trig_random; + +PC_SUB_SIZE_OUT <= b"0000_0000_0000_00" & pc_sub_size; +PC_PADDING_OUT <= padding_needed; + +DEBUG_OUT <= debug; + +end architecture; \ No newline at end of file diff --git a/gbe2_ecp3/trb_net16_ipu2gbe_20101006.vhd b/gbe2_ecp3/trb_net16_ipu2gbe_20101006.vhd new file mode 100644 index 0000000..73c8d7a --- /dev/null +++ b/gbe2_ecp3/trb_net16_ipu2gbe_20101006.vhd @@ -0,0 +1,1316 @@ +LIBRARY ieee; +use ieee.std_logic_1164.all; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; +use IEEE.std_logic_arith.all; + +library work; + +entity trb_net16_ipu2gbe is +port( + CLK : in std_logic; + RESET : in std_logic; + -- IPU interface directed toward the CTS + CTS_NUMBER_IN : in std_logic_vector (15 downto 0); + CTS_CODE_IN : in std_logic_vector (7 downto 0); + CTS_INFORMATION_IN : in std_logic_vector (7 downto 0); + CTS_READOUT_TYPE_IN : in std_logic_vector (3 downto 0); + CTS_START_READOUT_IN : in std_logic; + CTS_READ_IN : in std_logic; + CTS_DATA_OUT : out std_logic_vector (31 downto 0); + CTS_DATAREADY_OUT : out std_logic; + CTS_READOUT_FINISHED_OUT : out std_logic; --no more data, end transfer, send TRM + CTS_LENGTH_OUT : out std_logic_vector (15 downto 0); + CTS_ERROR_PATTERN_OUT : out std_logic_vector (31 downto 0); + -- Data from Frontends + FEE_DATA_IN : in std_logic_vector (15 downto 0); + FEE_DATAREADY_IN : in std_logic; + FEE_READ_OUT : out std_logic; + FEE_BUSY_IN : in std_logic; + FEE_STATUS_BITS_IN : in std_logic_vector (31 downto 0); + -- slow control interface + START_CONFIG_OUT : out std_logic; -- reconfigure MACs/IPs/ports/packet size + BANK_SELECT_OUT : out std_logic_vector(3 downto 0); -- configuration page address + CONFIG_DONE_IN : in std_logic; -- configuration finished + DATA_GBE_ENABLE_IN : in std_logic; -- IPU data is forwarded to GbE + DATA_IPU_ENABLE_IN : in std_logic; -- IPU data is forwarded to CTS / TRBnet + MULT_EVT_ENABLE_IN : in std_logic; + MAX_MESSAGE_SIZE_IN : in std_logic_vector(31 downto 0); -- the maximum size of one HadesQueue -- gk 08.04.10 + MIN_MESSAGE_SIZE_IN : in std_logic_vector(31 downto 0); -- gk 20.07.10 + READOUT_CTR_IN : in std_logic_vector(23 downto 0); -- gk 26.04.10 + READOUT_CTR_VALID_IN : in std_logic; -- gk 26.04.10 + -- PacketConstructor interface + ALLOW_LARGE_IN : in std_logic; -- gk 21.07.10 + PC_WR_EN_OUT : out std_logic; + PC_DATA_OUT : out std_logic_vector (7 downto 0); + PC_READY_IN : in std_logic; + PC_SOS_OUT : out std_logic; + PC_EOD_OUT : out std_logic; + PC_SUB_SIZE_OUT : out std_logic_vector(31 downto 0); + PC_TRIG_NR_OUT : out std_logic_vector(31 downto 0); + PC_PADDING_OUT : out std_logic; + MONITOR_OUT : out std_logic_vector(223 downto 0); + DEBUG_OUT : out std_logic_vector(383 downto 0) +); +end entity; + +architecture trb_net16_ipu2gbe of trb_net16_ipu2gbe is + +-- -- Placer Directives +-- attribute HGROUP : string; +-- -- for whole architecture +-- attribute HGROUP of trb_net16_ipu2gbe : architecture is "GBE_ipu2gbe_group"; + +component fifo_32kx16x8_mb2 +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; + AmEmptyThresh : in std_logic_vector(15 downto 0); + AmFullThresh : in std_logic_vector(14 downto 0); + Q : out std_logic_vector(8 downto 0); + WCNT : out std_logic_vector(15 downto 0); + RCNT : out std_logic_vector(16 downto 0); + Empty : out std_logic; + AlmostEmpty : out std_logic; + Full : out std_logic; + AlmostFull : out std_logic +); +end component; + +type saveStates is (SIDLE, SAVE_EVT_ADDR, WAIT_FOR_DATA, SAVE_DATA, ADD_SUBSUB1, ADD_SUBSUB2, ADD_SUBSUB3, ADD_SUBSUB4, TERMINATE, SCLOSE); +signal saveCurrentState, saveNextState : saveStates; +signal state : std_logic_vector(3 downto 0); +signal data_req_comb : std_logic; +signal data_req : std_logic; -- request data signal, will be used for fee_read generation +signal rst_saved_ctr_comb : std_logic; +signal rst_saved_ctr : std_logic; + +signal fee_read_comb : std_logic; +signal fee_read : std_logic; -- fee_read signal +signal saved_ctr : std_logic_vector(16 downto 0); +signal ce_saved_ctr : std_logic; + +-- header data +signal cts_rnd : std_logic_vector(15 downto 0); +signal cts_rnd_saved : std_logic; +signal cts_trg : std_logic_vector(15 downto 0); +signal cts_trg_saved : std_logic; +signal cts_len : std_logic_vector(16 downto 0); +signal cts_len_saved : std_logic; + +-- CTS interface +signal cts_error_pattern : std_logic_vector(31 downto 0); +signal cts_length : std_logic_vector(15 downto 0); +signal cts_readout_finished : std_logic; +signal cts_dataready : std_logic; +signal cts_data : std_logic_vector(31 downto 0); + +-- Split FIFO signals +signal sf_data : std_logic_vector(15 downto 0); +signal sf_wr_en_comb : std_logic; +signal sf_wr_en : std_logic; -- write signal for FIFO +signal sf_rd_en_comb : std_logic; +signal sf_rd_en : std_logic; -- read signal for FIFO +signal sf_wcnt : std_logic_vector(15 downto 0); +signal sf_rcnt : std_logic_vector(16 downto 0); +signal sf_empty : std_logic; +signal sf_aempty : std_logic; +signal sf_full : std_logic; +signal sf_afull : std_logic; + +------------------------------------------------------------------- +type loadStates is (LIDLE, INIT, REMOVE, DECIDE, CALCA, CALCB, LOAD, PAD0, PAD1, PAD2, PAD3, LOAD_SUBSUB, CALCC, CLOSE, WAIT_PC, DROP, WAIT_TO_REMOVE, DROP_SUBSUB, PAUSE_BEFORE_DROP1, PAUSE_BEFORE_DROP2); +signal loadCurrentState, loadNextState : loadStates; +signal state2 : std_logic_vector(3 downto 0); + +signal rem_ctr : std_logic_vector(3 downto 0); -- counter for stripping / storing header data +signal rst_rem_ctr_comb : std_logic; +signal rst_rem_ctr : std_logic; -- reset the remove counter +signal rst_regs_comb : std_logic; +signal rst_regs : std_logic; -- reset storage registers +signal rem_phase_comb : std_logic; +signal rem_phase : std_logic; -- header remove phase +signal data_phase_comb : std_logic; +signal data_phase : std_logic; -- data transport phase from split fifo to PC +signal pad_phase_comb : std_logic; +signal pad_phase : std_logic; -- padding phase +signal calc_pad_comb : std_logic; +signal calc_pad : std_logic; -- check if padding bytes need to be added to PC_SUB_SIZE +signal pad_data_comb : std_logic; +signal pad_data : std_logic; -- reset PC_DATA register to known padding byte value + +signal pc_sos_comb : std_logic; +signal pc_sos : std_logic; -- start of data signal +signal pc_eod_comb : std_logic; +signal pc_eod : std_logic; -- end of data signal + +signal ce_rem_ctr_comb : std_logic; +signal ce_rem_ctr : std_logic; -- count enable for remove counter +signal remove_done_comb : std_logic; +signal remove_done : std_logic; -- end of header stripping process +signal read_done_comb : std_logic; +signal read_done : std_logic; -- end of data phase (read phase from SF) + +signal pc_data : std_logic_vector(7 downto 0); +signal pc_data_q : std_logic_vector(7 downto 0); +signal pc_trig_nr : std_logic_vector(15 downto 0); +signal pc_sub_size : std_logic_vector(17 downto 0); +signal read_size : std_logic_vector(17 downto 0); -- number of byte to be read from split fifo +signal padding_needed : std_logic; +signal pc_wr_en_comb : std_logic; +signal pc_wr_en_q : std_logic; +signal pc_wr_en_qq : std_logic; +signal pc_wr_en_qqq : std_logic; +signal pc_eod_q : std_logic; + +signal debug : std_logic_vector(383 downto 0); + +-- gk +signal bank_select : std_logic_vector(3 downto 0); +signal save_addr_comb : std_logic; +signal save_addr : std_logic; +signal addr_saved_comb : std_logic; +signal addr_saved : std_logic; +signal start_config : std_logic; +signal config_done : std_logic; +signal add_sub_state : std_logic; +signal add_sub_state_comb : std_logic; +signal add_sub_ctr : std_logic_vector(3 downto 0); +signal load_sub : std_logic; +signal load_sub_comb : std_logic; +signal load_sub_done : std_logic; +signal load_sub_done_comb : std_logic; +signal load_sub_ctr : std_logic_vector(3 downto 0); +signal load_sub_ctr_comb : std_logic; +signal actual_message_size : std_logic_vector(31 downto 0); +signal more_subevents : std_logic; +signal trig_random : std_logic_vector(7 downto 0); +signal readout_ctr : std_logic_vector(23 downto 0); +signal readout_ctr_lock : std_logic; +signal pc_trig_nr_q : std_logic_vector(31 downto 0); + +-- gk 20.07.10 +signal inc_data_ctr : std_logic_vector(31 downto 0); +signal dropped_sm_events_ctr : std_logic_vector(31 downto 0); +signal dropped_lr_events_ctr : std_logic_vector(31 downto 0); +signal dropped_ctr : std_logic_vector(31 downto 0); +-- gk 22.07.10 +signal headers_invalid : std_logic; +signal headers_invalid_ctr : std_logic_vector(31 downto 0); +signal cts_len_q : std_logic_vector(15 downto 0); +signal cts_trg_q : std_logic_vector(15 downto 0); +signal cts_rnd_q : std_logic_vector(15 downto 0); +signal first_run_trg : std_logic_vector(15 downto 0); +signal first_run_addr : std_logic_vector(15 downto 0); +signal first_run_lock : std_logic; +signal cts_addr : std_logic_vector(15 downto 0); +signal cts_addr_q : std_logic_vector(15 downto 0); +signal cts_addr_saved : std_logic; + +-- gk 24.07.10 +signal save_eod : std_logic; +signal save_eod_comb : std_logic; + +signal load_eod : std_logic; +signal endpoint_addr : std_logic_vector(15 downto 0); +signal endp_addr_lock : std_logic; + +signal saved_events_ctr : std_logic_vector(15 downto 0); +signal loaded_events_ctr : std_logic_vector(15 downto 0); +signal constr_events_ctr : std_logic_vector(31 downto 0); +signal event_waiting : std_logic; + +signal drop_sub : std_logic; +signal drop_sub_comb : std_logic; +signal drop_event : std_logic; +signal drop_event_comb : std_logic; +signal drop_small : std_logic; +signal drop_large : std_logic; +signal drop_headers : std_logic; +signal drop_small_comb : std_logic; +signal drop_large_comb : std_logic; +signal drop_headers_comb : std_logic; +signal inc_trg_ctr : std_logic; +signal inc_trg_ctr_comb : std_logic; + +signal invalid_hsize_ctr : std_logic_vector(15 downto 0); +signal invalid_hsize_lock : std_logic; + +signal load_eod_q : std_logic; +signal read_size_q : std_logic_vector(17 downto 0); + +-- gk 06.08.10 write to fifo only if gbe is enabled but keep the saving logic unblocked +signal sf_real_wr_en : std_logic; + +-- gk 01.10.10 +signal found_empty_evt : std_logic; +signal found_empty_evt_comb : std_logic; +signal found_empty_evt_ctr : std_logic_vector(31 downto 0); + +begin + +BANK_SELECT_OUT <= bank_select; -- gk 27.03.10 +START_CONFIG_OUT <= start_config; -- gk 27.03.10 +config_done <= CONFIG_DONE_IN; -- gk 29.03.10 + +-- CTS interface signals +cts_error_pattern <= (others => '0'); -- FAKE + +cts_length <= x"0000"; -- length of data payload is always 0 +cts_data <= b"0001" & cts_rnd(11 downto 0) & cts_trg; -- reserved bits = '0', pack bit = '1' + +cts_readout_finished <= '1' when (saveCurrentState = SCLOSE) else '0'; + +cts_dataready <= '1' when ((saveCurrentState = SAVE_DATA) and (FEE_BUSY_IN = '0')) or (saveCurrentState = TERMINATE) + else '0'; + +-- Byte swapping... done here. TAKE CARE! +-- The split FIFO is in natural bus order (i.e. Motorola style, [15:0]). This means that the two bytes +-- on the write side need to be swapped to appear in GbE style (i.e. Intel style) on the 8bit port. +-- Please mind that PC_SUB_SIZE and PC_TRIG_NR stay in a human readable format, and need to be byteswapped +-- for GbE inside the packet constructor. +-- +-- Long live the Endianess! + +-- Sync all critical pathes +THE_SYNC_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + --sf_data <= FEE_DATA_IN; -- gk 27.03.10 moved out to the process below + sf_wr_en <= sf_wr_en_comb; + ce_rem_ctr <= ce_rem_ctr_comb; + sf_rd_en <= sf_rd_en_comb; + fee_read <= fee_read_comb; + read_done <= read_done_comb; + pc_eod_q <= pc_eod; + pc_wr_en_qqq <= pc_wr_en_qq; + pc_wr_en_qq <= pc_wr_en_q; + pc_wr_en_q <= pc_wr_en_comb; + end if; +end process THE_SYNC_PROC; + +-- gk 27.03.10 data selector for sf to write the evt builder address on top of data +SF_DATA_PROC : process( CLK ) +begin + if( rising_edge(CLK) ) then + if (RESET = '1') then -- gk 31.05.10 + sf_data <= (others => '0'); + elsif( save_addr = '1' ) then + sf_data(3 downto 0) <= CTS_INFORMATION_IN(3 downto 0); -- only last 4 bits are the evt builder address + sf_data(15 downto 4) <= x"abc"; + -- gk 29.03.10 four entries to save the fee_status into sf for the subsubevent + elsif( (add_sub_state = '1') and (add_sub_ctr = x"0") ) then + sf_data <= x"0001"; -- gk 11.06.10 + elsif( (add_sub_state = '1') and (add_sub_ctr = x"1") ) then + sf_data <= x"5555"; -- gk 11.06.10 + elsif( (add_sub_state = '1') and (add_sub_ctr = x"2") ) then + sf_data <= FEE_STATUS_BITS_IN(31 downto 16); + elsif( (add_sub_state = '1') and (add_sub_ctr = x"3") ) then + sf_data <= FEE_STATUS_BITS_IN(15 downto 0); + else + sf_data <= FEE_DATA_IN; + end if; + end if; +end process SF_DATA_PROC; + +-- combinatorial read signal for the FEE data interface, DO NOT USE DIRECTLY +fee_read_comb <= '1' when ( (sf_afull = '0') and (data_req = '1') ) --and (DATA_GBE_ENABLE_IN = '1') ) -- GbE enabled + else '0'; + +-- combinatorial write signal for the split FIFO, DO NOT USE DIRECTLY +sf_wr_en_comb <= '1' when ( (fee_read = '1') and (FEE_DATAREADY_IN = '1') ) or -- and (DATA_GBE_ENABLE_IN = '1') ) or -- GbE enabled + (save_addr = '1') or + (add_sub_state = '1') -- gk 29.03.10 save the subsubevent + else '0'; + +-- gk 06.08.10 +sf_real_wr_en <= '1' when ((sf_wr_en = '1') and (DATA_GBE_ENABLE_IN = '1')) else '0'; + +-- gk 27.03.10 do not count evt builder address as saved ipu bytes +--ce_saved_ctr <= sf_wr_en; +ce_saved_ctr <= '0' when addr_saved = '1' else sf_wr_en; + +-- Statemachine for reading data payload, handling IPU channel and storing data in the SPLIT_FIFO +saveMachineProc: process( CLK ) +begin + if rising_edge(CLK) then + if (RESET = '1') then + saveCurrentState <= SIDLE; + data_req <= '0'; + rst_saved_ctr <= '0'; + save_addr <= '0'; -- gk 27.03.10 + addr_saved <= '0'; -- gk 27.03.10 + add_sub_state <= '0'; -- gk 29.03.10 + save_eod <= '0'; -- gk 25.07.10 + else + saveCurrentState <= saveNextState; + data_req <= data_req_comb; + rst_saved_ctr <= rst_saved_ctr_comb; + save_addr <= save_addr_comb; -- gk 27.03.10 + addr_saved <= addr_saved_comb; -- gk 27.03.10 + add_sub_state <= add_sub_state_comb; -- gk 29.03.10 + save_eod <= save_eod_comb; -- gk 25.07.10 + end if; + end if; +end process saveMachineProc; + +saveMachine: process( saveCurrentState, CTS_START_READOUT_IN, FEE_BUSY_IN, CTS_READ_IN) +begin + saveNextState <= SIDLE; + data_req_comb <= '0'; + rst_saved_ctr_comb <= '0'; + save_addr_comb <= '0'; -- gk 27.03.10 + addr_saved_comb <= '0'; -- gk 27.03.10 + add_sub_state_comb <= '0'; -- gk 29.03.10 + save_eod_comb <= '0'; -- gk 25.07.10 + case saveCurrentState is + when SIDLE => + state <= x"0"; + if (CTS_START_READOUT_IN = '1') then + saveNextState <= SAVE_EVT_ADDR; --WAIT_FOR_DATA; -- gk 27.03.10 + data_req_comb <= '1'; + rst_saved_ctr_comb <= '1'; + else + saveNextState <= SIDLE; + end if; + -- gk 27.03.10 + when SAVE_EVT_ADDR => + state <= x"5"; + saveNextState <= WAIT_FOR_DATA; + data_req_comb <= '1'; + save_addr_comb <= '1'; + when WAIT_FOR_DATA => + state <= x"1"; + if (FEE_BUSY_IN = '1') then + saveNextState <= SAVE_DATA; + data_req_comb <= '1'; + else + saveNextState <= WAIT_FOR_DATA; + data_req_comb <= '1'; + end if; + addr_saved_comb <= '1'; -- gk 27.03.10 + when SAVE_DATA => + state <= x"2"; + if (FEE_BUSY_IN = '0') then + saveNextState <= TERMINATE; + else + saveNextState <= SAVE_DATA; + data_req_comb <= '1'; + end if; + when TERMINATE => + state <= x"3"; + if (CTS_READ_IN = '1') then + saveNextState <= SCLOSE; + else + saveNextState <= TERMINATE; + end if; + when SCLOSE => + state <= x"4"; + if (CTS_START_READOUT_IN = '0') then + saveNextState <= ADD_SUBSUB1; --SIDLE; -- gk 29.03.10 + else + saveNextState <= SCLOSE; + end if; + -- gk 29.03.10 new states during which the subsub bytes are saved + when ADD_SUBSUB1 => + state <= x"6"; + saveNextState <= ADD_SUBSUB2; + add_sub_state_comb <= '1'; + when ADD_SUBSUB2 => + state<= x"7"; + saveNextState <= ADD_SUBSUB3; + add_sub_state_comb <= '1'; + save_eod_comb <= '1'; + when ADD_SUBSUB3 => + state<= x"8"; + saveNextState <= ADD_SUBSUB4; + add_sub_state_comb <= '1'; + when ADD_SUBSUB4 => + state<= x"9"; + saveNextState <= SIDLE; + add_sub_state_comb <= '1'; + when others => + state <= x"f"; + saveNextState <= SIDLE; + end case; +end process saveMachine; + +-- gk 29.03.10 +ADD_SUB_CTR_PROC : process( CLK ) +begin + if( rising_edge( CLK ) ) then + if( (RESET = '1') or (rst_saved_ctr = '1') ) then + add_sub_ctr <= (others => '0'); + elsif( add_sub_state = '1' ) then + add_sub_ctr <= add_sub_ctr + 1; + end if; + end if; +end process ADD_SUB_CTR_PROC; + +--******** +-- SAVE INCOMING EVENT HEADERS +--******** + +-- Counter for header word storage +THE_CTS_SAVED_CTR: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_saved_ctr = '1') ) then + saved_ctr <= (others => '0'); + elsif( ce_saved_ctr = '1' ) then + saved_ctr <= saved_ctr + 1; + end if; + end if; +end process THE_CTS_SAVED_CTR; + +-- save triggerRnd from incoming data for cts response +CTS_RND_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_saved_ctr = '1') ) then + cts_rnd <= (others => '0'); + cts_rnd_saved <= '0'; + elsif( (saved_ctr(2 downto 0) = b"000") and (sf_wr_en = '1') and (cts_rnd_saved = '0') ) then + cts_rnd <= sf_data; + cts_rnd_saved <= '1'; + end if; + end if; +end process CTS_RND_PROC; + +-- save triggerNr from incoming data for cts response +CTS_TRG_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_saved_ctr = '1') ) then + cts_trg <= (others => '0'); + cts_trg_saved <= '0'; + elsif( (saved_ctr(2 downto 0) = b"001") and (sf_wr_en = '1') and (cts_trg_saved = '0') ) then + cts_trg <= sf_data; + cts_trg_saved <= '1'; + end if; + end if; +end process CTS_TRG_PROC; + +-- save size from incoming data for cts response (future) and to get rid of padding +CTS_SIZE_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_saved_ctr = '1') ) then + cts_len <= (others => '0'); + cts_len_saved <= '0'; + elsif( (saved_ctr(2 downto 0) = b"010") and (sf_wr_en = '1') and (cts_len_saved = '0') ) then + cts_len(16 downto 1) <= sf_data; -- change from 32b words to 16b words + cts_len(0) <= '0'; + elsif( (saved_ctr(2 downto 0) = b"011") and (cts_len_saved = '0') ) then + cts_len <= cts_len + x"4"; + cts_len_saved <= '1'; + end if; + end if; +end process CTS_SIZE_PROC; + +-- gk 22.07.10 +CTS_ADDR_PROC : process(CLK) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_saved_ctr = '1') ) then + cts_addr <= (others => '0'); + cts_addr_saved <= '0'; + elsif( (saved_ctr(2 downto 0) = b"011") and (sf_wr_en = '1') and (cts_addr_saved = '0') ) then + cts_addr <= sf_data; + cts_addr_saved <= '1'; + end if; + end if; +end process CTS_ADDR_PROC; + +--****** +-- SAVE FIRST EVENT HEADER VALUES +--****** + +-- gk 22.07.10 +FIRST_RUN_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + first_run_trg <= (others => '0'); + first_run_addr <= (others => '0'); + first_run_lock <= '0'; + elsif (first_run_lock = '0') and (cts_addr_saved = '1') then + first_run_trg <= cts_trg; + first_run_addr <= cts_addr; + first_run_lock <= '1'; + -- important: value saved by saveMachine but incremented by loadMachine + elsif (first_run_lock = '1') and (inc_trg_ctr = '1') then + first_run_trg <= first_run_trg + x"1"; + end if; + end if; +end process FIRST_RUN_PROC; + +-- gk 25.07.10 +SAVED_EVT_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + saved_events_ctr <= (others => '0'); + elsif (save_eod = '1') then + saved_events_ctr <= saved_events_ctr + x"1"; + end if; + end if; +end process SAVED_EVT_CTR_PROC; + + +-- gk 20.07.10 +INC_DATA_CTR_proc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (rst_saved_ctr = '1') then + inc_data_ctr <= (others => '0'); + elsif (sf_wr_en = '1') and (data_req = '1') then + inc_data_ctr(31 downto 1) <= inc_data_ctr(31 downto 1) + x"1"; + end if; + end if; +end process INC_DATA_CTR_proc; + +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ + +-- Split FIFO +THE_SPLIT_FIFO: fifo_32kx16x8_mb2 +port map( + -- Byte swapping for correct byte order on readout side of FIFO + Data(7 downto 0) => sf_data(15 downto 8), + Data(8) => '0', + Data(16 downto 9) => sf_data(7 downto 0), + Data(17) => save_eod, + WrClock => CLK, + RdClock => CLK, + WrEn => sf_real_wr_en, -- gk 06.08.10 --sf_wr_en, + RdEn => sf_rd_en, + Reset => RESET, + RPReset => RESET, + AmEmptyThresh => b"0000_0000_0000_0010", -- one byte ahead + AmFullThresh => b"111_1111_1110_1111", -- 0x7fef = 32751 + Q(7 downto 0) => pc_data, + Q(8) => load_eod, + WCNT => sf_wcnt, + RCNT => sf_rcnt, + Empty => sf_empty, + AlmostEmpty => sf_aempty, + Full => sf_full, + AlmostFull => sf_afull +); + +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ + +-- gk 25.07.10 +EVENT_WAITING_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + event_waiting <= '0'; + elsif (loaded_events_ctr /= saved_events_ctr) then + event_waiting <= '1'; + else + event_waiting <= '0'; + end if; + end if; +end process EVENT_WAITING_PROC; + +-- write signal for PC data +pc_wr_en_comb <= '1' when ((data_phase = '1') and (sf_rd_en = '1')) or + (pad_phase = '1') or + ((load_sub = '1') and (sf_rd_en = '1')) or + ((drop_sub = '1') and (sf_rd_en = '1')) or + ((drop_event = '1') and (sf_rd_en = '1')) + else '0'; + +sf_rd_en_comb <= '1' when ( (sf_aempty = '0') and (rem_phase = '1') and (remove_done = '0') ) or + --( (sf_aempty = '0') and (data_phase = '1') and (read_done = '0') ) or + ( (sf_aempty = '0') and (data_phase = '1') and (load_eod = '0') ) or -- gk 26.07.10 + ( (sf_aempty = '0') and (load_sub = '1') and (load_sub_done = '0') ) or -- gk 30.03.10 + ( (sf_aempty = '0') and (drop_event = '1') and (load_eod = '0') ) or + ( (sf_aempty = '0') and (drop_sub = '1') and (load_sub_done = '0') ) + else '0'; + +ce_rem_ctr_comb <= '1' when ( (sf_aempty = '0') and (rem_phase = '1') and ( remove_done = '0') ) + else '0'; + +-- FIFO data delay process (also forces padding bytes to known value) +THE_DATA_DELAY_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if( pad_data = '1' ) then + pc_data_q <= x"aa"; -- padding for 64bit + -- gk 21.07.10 + -- set the error flag if a broken packet is sent + elsif (drop_sub = '1') and (load_sub_ctr = x"3") then + pc_data_q <= pc_data(7 downto 3) & '1' & pc_data(1 downto 0); + else + pc_data_q <= pc_data; + end if; + end if; +end process THE_DATA_DELAY_PROC; + +-- Statemachine for reading the data payload from the SPLIT_FIFO and feeding +-- it into the packet constructor +loadMachineProc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + loadCurrentState <= LIDLE; + rst_rem_ctr <= '0'; + rem_phase <= '0'; + calc_pad <= '0'; + data_phase <= '0'; + pad_phase <= '0'; + pc_sos <= '0'; + pc_eod <= '0'; + rst_regs <= '0'; + pad_data <= '0'; + load_sub <= '0'; -- gk 30.03.10 + drop_sub <= '0'; -- gk 25.07.10 + drop_event <= '0'; -- gk 25.07.10 + drop_small <= '0'; -- gk 25.07.10 + drop_large <= '0'; -- gk 25.07.10 + drop_headers <= '0'; -- gk 25.07.10 + inc_trg_ctr <= '0'; -- gk 26.07.10 + found_empty_evt <= '0'; -- gk 01.10.10 + else + loadCurrentState <= loadNextState; + rst_rem_ctr <= rst_rem_ctr_comb; + rem_phase <= rem_phase_comb; + calc_pad <= calc_pad_comb; + data_phase <= data_phase_comb; + pad_phase <= pad_phase_comb; + pc_sos <= pc_sos_comb; + pc_eod <= pc_eod_comb; + rst_regs <= rst_regs_comb; + pad_data <= pad_data_comb; + load_sub <= load_sub_comb; -- gk 30.03.1 + drop_sub <= drop_sub_comb; -- gk 25.07.10 + drop_event <= drop_event_comb; -- gk 25.07.10 + drop_small <= drop_small_comb; -- gk 25.07.10 + drop_large <= drop_large_comb; -- gk 25.07.10 + drop_headers <= drop_headers_comb; -- gk 25.07.10 + inc_trg_ctr <= inc_trg_ctr_comb; -- gk 26.07.10 + found_empty_evt <= found_empty_evt_comb; -- gk 01.10.10 + end if; + end if; +end process loadMachineProc; + +loadMachine : process( loadCurrentState, sf_aempty, remove_done, read_done, padding_needed, PC_READY_IN, load_sub_done, pc_sub_size, MIN_MESSAGE_SIZE_IN, MAX_MESSAGE_SIZE_IN, pc_trig_nr, first_run_trg, endpoint_addr, first_run_addr, load_eod, event_waiting) +begin + loadNextState <= LIDLE; + rst_rem_ctr_comb <= '0'; + rem_phase_comb <= '0'; + calc_pad_comb <= '0'; + data_phase_comb <= '0'; + pad_phase_comb <= '0'; + pc_sos_comb <= '0'; + pc_eod_comb <= '0'; + rst_regs_comb <= '0'; + pad_data_comb <= '0'; + load_sub_comb <= '0'; -- gk 30.03.10 + drop_sub_comb <= '0'; -- gk 25.07.10 + drop_event_comb <= '0'; -- gk 25.07.10 + drop_small_comb <= '0'; -- gk 25.07.10 + drop_large_comb <= '0'; -- gk 25.07.10 + drop_headers_comb <= '0'; -- gk 25.07.10 + inc_trg_ctr_comb <= '0'; -- gk 26.07.10 + found_empty_evt_comb <= '0'; -- gk 01.10.10 + case loadCurrentState is + when LIDLE => + state2 <= x"0"; + -- gk 23.07.10 + if( (sf_aempty = '0') and (PC_READY_IN = '1') and (event_waiting = '1') and (DATA_GBE_ENABLE_IN = '1') ) then -- gk 06.08.10 + loadNextState <= INIT; + rst_rem_ctr_comb <= '1'; + rst_regs_comb <= '1'; + else + loadNextState <= LIDLE; + end if; + when INIT => + state2 <= x"1"; + loadNextState <= REMOVE; + rem_phase_comb <= '1'; + when REMOVE => + state2 <= x"2"; + if( remove_done = '1' ) then + loadNextState <= WAIT_TO_REMOVE; + inc_trg_ctr_comb <= '1'; + else + loadNextState <= REMOVE; + rem_phase_comb <= '1'; + end if; + when WAIT_TO_REMOVE => + if (rem_ctr = x"a") then + loadNextState <= DECIDE; + else + loadNextState <= WAIT_TO_REMOVE; + end if; + when DECIDE => + if (pc_sub_size >= MAX_MESSAGE_SIZE_IN) then + loadNextState <= PAUSE_BEFORE_DROP1; + drop_large_comb <= '1'; + elsif (pc_sub_size = b"0000_0000_0000_00") then -- gk 01.10.10 + loadNextState <= CALCA; + found_empty_evt_comb <= '1'; + elsif (pc_sub_size < MIN_MESSAGE_SIZE_IN) then + loadNextState <= PAUSE_BEFORE_DROP1; + drop_small_comb <= '1'; + elsif (pc_trig_nr + x"1" /= first_run_trg) then + loadNextState <= PAUSE_BEFORE_DROP1; + drop_headers_comb <= '1'; + elsif (endpoint_addr /= first_run_addr) then + loadNextState <= PAUSE_BEFORE_DROP1; + drop_headers_comb <= '1'; + else + loadNextState <= CALCA; + end if; + calc_pad_comb <= '1'; + when CALCA => + state2 <= x"3"; + loadNextState <= CALCB; + pc_sos_comb <= '1'; + when CALCB => + -- we need a branch in case of length "0"!!!! + state2 <= x"4"; + loadNextState <= LOAD; + data_phase_comb <= '1'; + when LOAD => + state2 <= x"5"; + -- gk 31.03.10 after loading subevent data read the subsubevent from sf + if (load_eod = '1') then + loadNextState <= LOAD_SUBSUB; + else + loadNextState <= LOAD; + data_phase_comb <= '1'; + end if; + -- gk 31.03.10 + when LOAD_SUBSUB => + state2 <= x"d"; + if( load_sub_done = '1' ) then + if( padding_needed = '0' ) then + loadNextState <= CALCC; + else + loadNextState <= PAD0; + pad_phase_comb <= '1'; + end if; + else + loadNextState <= LOAD_SUBSUB; + load_sub_comb <= '1'; + end if; + when PAD0 => + state2 <= x"6"; + loadNextState <= PAD1; + pad_phase_comb <= '1'; + pad_data_comb <= '1'; + when PAD1 => + state2 <= x"7"; + loadNextState <= PAD2; + pad_phase_comb <= '1'; + pad_data_comb <= '1'; + when PAD2 => + state2 <= x"8"; + loadNextState <= PAD3; + pad_phase_comb <= '1'; + pad_data_comb <= '1'; + when PAD3 => + state2 <= x"9"; + loadNextState <= CALCC; + pad_data_comb <= '1'; + when CALCC => + state2 <= x"a"; + loadNextState <= CLOSE; + pc_eod_comb <= '1'; + when CLOSE => + state2 <= x"b"; + loadNextState <= WAIT_PC; + rst_regs_comb <= '1'; + when WAIT_PC => + state2 <= x"c"; + if( PC_READY_IN = '1' ) then + loadNextState <= LIDLE; + else + loadNextState <= WAIT_PC; + end if; + when PAUSE_BEFORE_DROP1 => + loadNextState <= PAUSE_BEFORE_DROP2; + pc_sos_comb <= '1'; + when PAUSE_BEFORE_DROP2 => + loadNextState <= DROP; + drop_event_comb <= '1'; + -- gk 23.07.10 + when DROP => + state2 <= x"e"; + -- when data is dropped the eod marker stands as its end + if (load_eod = '1') then + loadNextState <= DROP_SUBSUB; + else + loadNextState <= DROP; + drop_event_comb <= '1'; + end if; + -- gk 25.07.10 + when DROP_SUBSUB => + if (load_sub_done = '1') then + if( padding_needed = '0' ) then + loadNextState <= CALCC; + else + loadNextState <= PAD0; + pad_phase_comb <= '1'; + end if; + else + loadNextState <= DROP_SUBSUB; + drop_sub_comb <= '1'; + end if; + when others => + state2 <= x"f"; + loadNextState <= LIDLE; + end case; +end process loadMachine; + +-- gk 25.07.10 +INVALID_STATS_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + dropped_lr_events_ctr <= (others => '0'); + dropped_sm_events_ctr <= (others => '0'); + headers_invalid_ctr <= (others => '0'); + dropped_ctr <= (others => '0'); + invalid_hsize_ctr <= (others => '0'); + found_empty_evt_ctr <= (others => '0'); -- gk 01.10.10 + elsif (rst_regs = '1') then + invalid_hsize_lock <= '0'; + elsif (drop_small = '1') then + dropped_sm_events_ctr <= dropped_sm_events_ctr + x"1"; + dropped_ctr <= dropped_ctr + x"1"; + elsif (drop_large = '1') then + dropped_lr_events_ctr <= dropped_lr_events_ctr + x"1"; + dropped_ctr <= dropped_ctr + x"1"; + elsif (drop_headers = '1') then + headers_invalid_ctr <= headers_invalid_ctr + x"1"; + dropped_ctr <= dropped_ctr + x"1"; + elsif (load_eod_q = '1') and (read_size_q /= x"3fffe") and (invalid_hsize_lock = '0') then -- ?? + invalid_hsize_ctr <= invalid_hsize_ctr + x"1"; + invalid_hsize_lock <= '1'; + -- gk 01.10.10 + elsif (found_empty_evt = '1') then + found_empty_evt_ctr <= found_empty_evt_ctr + x"1"; + end if; + end if; +end process INVALID_STATS_PROC; + +-- gk 05.08.10 +INVALID_H_PROC : process(CLK) +begin + if rising_edge(CLK) then + load_eod_q <= load_eod; + read_size_q <= read_size; + end if; +end process INVALID_H_PROC; + +-- gk 26.04.10 +READOUT_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if ((RESET = '1') or (READOUT_CTR_VALID_IN = '1')) then + readout_ctr <= READOUT_CTR_IN; + readout_ctr_lock <= '0'; + elsif (pc_sos = '1') then + readout_ctr <= readout_ctr + x"1"; + end if; + end if; +end process READOUT_CTR_PROC; + +--****** +-- SELECTION OF EVENT BUILDER +--****** + +-- gk 27.03.10 +bank_select_proc : process( CLK ) +begin + if rising_edge( CLK ) then + -- gk 29.03.10 + if( (RESET = '1') or (rst_regs = '1') ) then + bank_select <= "0000"; + -- gk 01.06.10 THERE WAS A BUG, IT SHOUDL BE TAKEN FROM SF_Q + elsif( (sf_rd_en = '1') and (rem_ctr = x"2") ) then + bank_select <= pc_data(3 downto 0); --CTS_INFORMATION_IN(3 downto 0); + end if; + end if; +end process bank_select_proc; + +-- gk 29.03.10 +start_config_proc : process( CLK ) +begin + if rising_edge( CLK ) then + if( (RESET = '1') or (config_done = '1') or (rst_regs = '1') ) then + start_config <= '0'; + elsif( (sf_rd_en = '1') and (rem_ctr = x"2") ) then -- gk 01.06.10 + start_config <= '1'; + end if; + end if; +end process start_config_proc; + + +--****** +-- LOAD SUBSUBEVENT +--****** + +-- gk 30.03.10 +load_sub_ctr_comb <= '1' when ( ((load_sub = '1') or (drop_sub = '1')) and (load_sub_done = '0') and (sf_aempty = '0') ) + else '0'; + +-- gk 30.03.10 +LOAD_SUB_CTR_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_regs = '1') ) then -- gk 08.04.10 + load_sub_ctr <= (others => '0'); + elsif( (load_sub_ctr_comb = '1') ) then + load_sub_ctr <= load_sub_ctr + 1; + end if; + end if; +end process LOAD_SUB_CTR_PROC; + +-- gk 30.03.10 +-- load_sub_done_comb <= '1' when ((load_sub_ctr = x"7") and (drop_sub = '0')) or +-- ((load_sub_ctr = x"4") and (drop_sub = '1')) +-- else '0'; +load_sub_done_comb <= '1' when (load_sub_ctr = x"4") else '0'; + +-- gk 30.03.10 +LOAD_SUB_DONE_PROC : process(CLK) +begin + if rising_edge(CLK) then + if ( (RESET = '1') or (rst_regs = '1') ) then -- gk 08.04.10 + load_sub_done <= '0'; + else + load_sub_done <= load_sub_done_comb; + end if; + end if; +end process LOAD_SUB_DONE_PROC; + +--****** +-- EXTRACT EVENT HEADERS FROM SPLITFIFO +--****** + +-- Counter for stripping the unneeded parts of the data stream, and saving the important parts +THE_REMOVE_CTR: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_rem_ctr = '1') ) then + rem_ctr <= (others => '0'); + elsif( (ce_rem_ctr = '1') ) then + rem_ctr <= rem_ctr + 1; + end if; + end if; +end process THE_REMOVE_CTR; + +remove_done_comb <= '1' when ( rem_ctr = x"8" ) else '0'; --( rem_ctr = x"6" ) else '0'; -- gk 29.03.10 two more for evt builder address + +THE_REM_DONE_SYNC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_rem_ctr = '1') ) then + remove_done <= '0'; + else + remove_done <= remove_done_comb; + end if; + end if; +end process THE_REM_DONE_SYNC; + +-- gk 26.04.10 +TRIG_RANDOM_PROC : process(CLK) +begin + if rising_edge(CLK) then + if ((RESET = '1') or (rst_regs = '1')) then + trig_random <= (others => '0'); + elsif ((sf_rd_en = '1') and (rem_ctr = x"4")) then + trig_random <= pc_data; + end if; + end if; +end process TRIG_RANDOM_PROC; + +-- extract the trigger number from splitfifo data +THE_TRG_NR_PROC: process( CLK ) +begin + if rising_edge(CLK) then + if ( (RESET = '1') or (rst_regs = '1') ) then + pc_trig_nr <= (others => '0'); + elsif( (sf_rd_en = '1') and (rem_ctr = x"6") ) then -- x"4" gk 29.03.10 + pc_trig_nr(7 downto 0) <= pc_data; + elsif( (sf_rd_en = '1') and (rem_ctr = x"5") ) then -- x"3" gk 29.03.10 + pc_trig_nr(15 downto 8) <= pc_data; + end if; + end if; +end process THE_TRG_NR_PROC; + +-- extract the subevent size from the splitfifo data, convert it from 32b to 8b units, +-- and in case of padding needed increase it accordingly +THE_SUB_SIZE_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_regs = '1') ) then + pc_sub_size <= (others => '0'); + elsif( (sf_rd_en = '1') and (rem_ctr = x"8") ) then -- x"6" gk 29.03.10 + pc_sub_size(9 downto 2) <= pc_data; + elsif( (sf_rd_en = '1') and (rem_ctr = x"7") ) then -- x"5" gk 29.03.10 + pc_sub_size(17 downto 10) <= pc_data; + -- gk 20.07.10 + -- gk 30.03.10 bug fixed in the way that is written below + -- gk 27.03.10 should be corrected by sending padding_needed signal to pc and take care of it when setting sub_size_to_save + elsif( (calc_pad = '1') and (padding_needed = '1') ) then + pc_sub_size <= pc_sub_size + x"4" + x"8"; -- BUG: SubEvtSize does NOT include 64bit padding!!! + elsif( (calc_pad = '1') and (padding_needed = '0') ) then + pc_sub_size <= pc_sub_size + x"8"; + end if; + end if; +end process THE_SUB_SIZE_PROC; + +-- gk 25.07.10 +ENDP_ADDRESS_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (rst_regs = '1') then + endpoint_addr <= (others => '0'); + endp_addr_lock <= '0'; + elsif( (rem_ctr = x"a") and (endp_addr_lock = '0') ) then + endpoint_addr(7 downto 0) <= pc_data; + endp_addr_lock <= '1'; + elsif( (sf_rd_en = '1') and (rem_ctr = x"9") ) then + endpoint_addr(15 downto 8) <= pc_data; + endp_addr_lock <= '0'; + end if; + end if; +end process ENDP_ADDRESS_PROC; + + + +-- check for padding +THE_PADDING_NEEDED_PROC: process( CLK ) +begin + if rising_edge(CLK) then + if ( (RESET = '1') or (rst_regs = '1') ) then + padding_needed <= '0'; + elsif( (remove_done = '1') and (pc_sub_size(2) = '1') ) then + padding_needed <= '1'; + elsif( (remove_done = '1') and (pc_sub_size(2) = '0') ) then + padding_needed <= '0'; + end if; + end if; +end process THE_PADDING_NEEDED_PROC; + +-- number of bytes to read from split fifo +THE_READ_SIZE_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + if ( (RESET = '1') or (rst_regs = '1') ) then --(rst_rem_ctr = '1') ) then + read_size <= (others => '0'); + elsif( (sf_rd_en = '1') and (rem_ctr = x"8") ) then -- x"6" gk 29.03.10 + read_size(9 downto 2) <= pc_data; + elsif( (sf_rd_en = '1') and (rem_ctr = x"7") ) then -- x"5" gk 29.03.10 + read_size(17 downto 10) <= pc_data; + elsif( ((sf_rd_en = '1') and (data_phase = '1')) ) then + read_size <= read_size - 1; + -- gk 25.07.10 + elsif( ((sf_rd_en = '1') and (drop_event = '1')) ) then + read_size <= read_size - 1; + end if; + end if; +end process THE_READ_SIZE_PROC; + +read_done_comb <= '1' when (read_size < 3 ) else '0'; -- "2" + +--****** +-- EVENTS COUNTERS +--****** + +-- gk 25.07.10 +LOADED_EVT_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + loaded_events_ctr <= (others => '0'); + elsif (remove_done = '1') then + loaded_events_ctr <= loaded_events_ctr + x"1"; + end if; + end if; +end process LOADED_EVT_CTR_PROC; + +-- gk 25.07.10 +CONSTR_EVENTS_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + constr_events_ctr <= (others => '0'); + elsif (pc_eod = '1') then + constr_events_ctr <= constr_events_ctr + x"1"; + end if; + end if; +end process CONSTR_EVENTS_CTR_PROC; + +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ + +-- Debug signals +debug(0) <= sf_full; +debug(1) <= sf_empty; +debug(2) <= sf_afull; +debug(3) <= sf_aempty; + +debug(7 downto 4) <= state2; + +debug(11 downto 8) <= state; + +dbg_bs_proc : process(CLK) +begin + if rising_edge(CLK) then + if RESET = '1' then + debug(15 downto 12) <= (others => '0'); + elsif ( (sf_rd_en = '1') and (rem_ctr = x"3") ) then + debug(15 downto 12) <= bank_select; + end if; + end if; +end process dbg_bs_proc; + +debug(16) <= config_done; +debug(17) <= remove_done; +debug(18) <= read_done; +debug(19) <= padding_needed; + +debug(20) <= load_sub_done; + +dbg_cts_inf_proc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + debug(39 downto 32) <= (others => '0'); + elsif ( save_addr = '1' ) then + debug(39 downto 32) <= CTS_INFORMATION_IN; + end if; + end if; +end process dbg_cts_inf_proc; + +debug(47 downto 40) <= (others => '0'); + + +debug(63 downto 48) <= actual_message_size(15 downto 0); + +dbg_pc_sub_size_proc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + debug(81 downto 64) <= (others => '0'); + elsif (loadCurrentState = DECIDE) then + debug(81 downto 64) <= pc_sub_size; + end if; + end if; +end process dbg_pc_sub_size_proc; + +dbg_empty_proc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (rst_regs = '1') then + debug(84 downto 82) <= (others => '0'); + elsif (read_size = 2) then + debug(82) <= sf_empty; + elsif (read_size = 1) then + debug(83) <= sf_empty; + elsif (read_size = 0) then + debug(84) <= sf_empty; + end if; + end if; +end process dbg_empty_proc; + +debug(95 downto 85) <= (others => '0'); + +dbg_inc_ctr_proc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + debug(127 downto 96) <= (others => '1'); + elsif (saveCurrentState = SCLOSE) then + debug(127 downto 96) <= inc_data_ctr; + end if; + end if; +end process dbg_inc_ctr_proc; + +debug(143 downto 128) <= dropped_sm_events_ctr(15 downto 0); +debug(159 downto 144) <= dropped_lr_events_ctr(15 downto 0); + +debug(175 downto 160) <= headers_invalid_ctr(15 downto 0); +debug(191 downto 176) <= (others => '0'); + +dbg_cts_q_proc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + cts_len_q <= (others => '0'); + cts_rnd_q <= (others => '0'); + cts_trg_q <= (others => '0'); + cts_addr_q <= (others => '0'); + elsif (cts_len_saved = '1') then + cts_len_q <= cts_len(16 downto 1); + cts_addr_q <= cts_addr; + cts_rnd_q <= cts_rnd; + cts_trg_q <= cts_trg; + end if; + end if; +end process dbg_cts_q_proc; + +debug(207 downto 192) <= cts_trg_q; +debug(223 downto 208) <= cts_rnd_q; +debug(239 downto 224) <= cts_addr_q; +debug(255 downto 240) <= cts_len_q; +debug(271 downto 256) <= first_run_trg; +debug(287 downto 272) <= first_run_addr; + +debug(303 downto 288) <= saved_events_ctr; +debug(319 downto 304) <= loaded_events_ctr; + +debug(335 downto 320) <= constr_events_ctr(15 downto 0); +debug(351 downto 336) <= dropped_ctr(15 downto 0); + +debug(367 downto 352) <= invalid_hsize_ctr; +debug(383 downto 368) <= (others => '0'); + +MONITOR_OUT(31 downto 0) <= constr_events_ctr; +MONITOR_OUT(63 downto 32) <= dropped_ctr; +MONITOR_OUT(95 downto 64) <= headers_invalid_ctr; +MONITOR_OUT(127 downto 96) <= dropped_sm_events_ctr; +MONITOR_OUT(159 downto 128) <= dropped_lr_events_ctr; +MONITOR_OUT(163 downto 160) <= b"1111" when (sf_afull = '1') else b"0000"; +MONITOR_OUT(191 downto 164) <= (others => '0'); +MONITOR_OUT(223 downto 192) <= found_empty_evt_ctr; -- gk 01.10.10 + +-- Outputs +FEE_READ_OUT <= fee_read; +CTS_ERROR_PATTERN_OUT <= cts_error_pattern; +CTS_DATA_OUT <= cts_data; +CTS_DATAREADY_OUT <= cts_dataready; +CTS_READOUT_FINISHED_OUT <= cts_readout_finished; +CTS_LENGTH_OUT <= cts_length; + +PC_SOS_OUT <= pc_sos; +PC_EOD_OUT <= pc_eod; -- gk 26.07.10 --pc_eod_q; +PC_DATA_OUT <= pc_data_q; +PC_WR_EN_OUT <= pc_wr_en_qq; + +PC_TRIG_NR_OUT <= readout_ctr(23 downto 16) & pc_trig_nr & trig_random; + +PC_SUB_SIZE_OUT <= b"0000_0000_0000_00" & pc_sub_size; +PC_PADDING_OUT <= padding_needed; + +DEBUG_OUT <= debug; + +end architecture; \ No newline at end of file diff --git a/gbe2_ecp3/trb_net16_ipu2gbe_nologic.vhd b/gbe2_ecp3/trb_net16_ipu2gbe_nologic.vhd new file mode 100644 index 0000000..29b1529 --- /dev/null +++ b/gbe2_ecp3/trb_net16_ipu2gbe_nologic.vhd @@ -0,0 +1,1403 @@ +LIBRARY ieee; +use ieee.std_logic_1164.all; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; +use IEEE.std_logic_arith.all; + +library work; + +entity trb_net16_ipu2gbe is +port( + CLK : in std_logic; + RESET : in std_logic; + -- IPU interface directed toward the CTS + CTS_NUMBER_IN : in std_logic_vector (15 downto 0); + CTS_CODE_IN : in std_logic_vector (7 downto 0); + CTS_INFORMATION_IN : in std_logic_vector (7 downto 0); + CTS_READOUT_TYPE_IN : in std_logic_vector (3 downto 0); + CTS_START_READOUT_IN : in std_logic; + CTS_READ_IN : in std_logic; + CTS_DATA_OUT : out std_logic_vector (31 downto 0); + CTS_DATAREADY_OUT : out std_logic; + CTS_READOUT_FINISHED_OUT : out std_logic; --no more data, end transfer, send TRM + CTS_LENGTH_OUT : out std_logic_vector (15 downto 0); + CTS_ERROR_PATTERN_OUT : out std_logic_vector (31 downto 0); + -- Data from Frontends + FEE_DATA_IN : in std_logic_vector (15 downto 0); + FEE_DATAREADY_IN : in std_logic; + FEE_READ_OUT : out std_logic; + FEE_BUSY_IN : in std_logic; + FEE_STATUS_BITS_IN : in std_logic_vector (31 downto 0); + -- slow control interface + START_CONFIG_OUT : out std_logic; -- reconfigure MACs/IPs/ports/packet size + BANK_SELECT_OUT : out std_logic_vector(3 downto 0); -- configuration page address + CONFIG_DONE_IN : in std_logic; -- configuration finished + DATA_GBE_ENABLE_IN : in std_logic; -- IPU data is forwarded to GbE + DATA_IPU_ENABLE_IN : in std_logic; -- IPU data is forwarded to CTS / TRBnet + MULT_EVT_ENABLE_IN : in std_logic; + MAX_MESSAGE_SIZE_IN : in std_logic_vector(31 downto 0); -- the maximum size of one HadesQueue -- gk 08.04.10 + MIN_MESSAGE_SIZE_IN : in std_logic_vector(31 downto 0); -- gk 20.07.10 + READOUT_CTR_IN : in std_logic_vector(23 downto 0); -- gk 26.04.10 + READOUT_CTR_VALID_IN : in std_logic; -- gk 26.04.10 + -- PacketConstructor interface + ALLOW_LARGE_IN : in std_logic; -- gk 21.07.10 + PC_WR_EN_OUT : out std_logic; + PC_DATA_OUT : out std_logic_vector (7 downto 0); + PC_READY_IN : in std_logic; + PC_SOS_OUT : out std_logic; + PC_EOS_OUT : out std_logic; -- gk 07.10.10 + PC_EOD_OUT : out std_logic; + PC_SUB_SIZE_OUT : out std_logic_vector(31 downto 0); + PC_TRIG_NR_OUT : out std_logic_vector(31 downto 0); + PC_PADDING_OUT : out std_logic; + MONITOR_OUT : out std_logic_vector(223 downto 0); + DEBUG_OUT : out std_logic_vector(383 downto 0) +); +end entity; + +architecture trb_net16_ipu2gbe of trb_net16_ipu2gbe is + +-- attribute HGROUP : string; +-- attribute HGROUP of trb_net16_ipu2gbe : architecture is "GBE_ipu2gbe"; + +component fifo_32kx16x8_mb2 +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; + AmEmptyThresh : in std_logic_vector(15 downto 0); + AmFullThresh : in std_logic_vector(14 downto 0); + Q : out std_logic_vector(8 downto 0); + WCNT : out std_logic_vector(15 downto 0); + RCNT : out std_logic_vector(16 downto 0); + Empty : out std_logic; + AlmostEmpty : out std_logic; + Full : out std_logic; + AlmostFull : out std_logic +); +end component; + +type saveStates is (SIDLE, SAVE_EVT_ADDR, WAIT_FOR_DATA, SAVE_DATA, ADD_SUBSUB1, ADD_SUBSUB2, ADD_SUBSUB3, ADD_SUBSUB4, TERMINATE, SCLOSE); +signal saveCurrentState, saveNextState : saveStates; +signal state : std_logic_vector(3 downto 0); +signal data_req_comb : std_logic; +signal data_req : std_logic; -- request data signal, will be used for fee_read generation +signal rst_saved_ctr_comb : std_logic; +signal rst_saved_ctr : std_logic; + +signal fee_read_comb : std_logic; +signal fee_read : std_logic; -- fee_read signal +signal saved_ctr : std_logic_vector(16 downto 0); +signal ce_saved_ctr : std_logic; + +-- header data +signal cts_rnd : std_logic_vector(15 downto 0); +signal cts_rnd_saved : std_logic; +signal cts_trg : std_logic_vector(15 downto 0); +signal cts_trg_saved : std_logic; +signal cts_len : std_logic_vector(16 downto 0); +signal cts_len_saved : std_logic; + +-- CTS interface +signal cts_error_pattern : std_logic_vector(31 downto 0); +signal cts_length : std_logic_vector(15 downto 0); +signal cts_readout_finished : std_logic; +signal cts_dataready : std_logic; +signal cts_data : std_logic_vector(31 downto 0); + +-- Split FIFO signals +signal sf_data : std_logic_vector(15 downto 0); +signal sf_wr_en_comb : std_logic; +signal sf_wr_en : std_logic; -- write signal for FIFO +signal sf_rd_en_comb : std_logic; +signal sf_rd_en : std_logic; -- read signal for FIFO +signal sf_wcnt : std_logic_vector(15 downto 0); +signal sf_rcnt : std_logic_vector(16 downto 0); +signal sf_empty : std_logic; +signal sf_aempty : std_logic; +signal sf_full : std_logic; +signal sf_afull : std_logic; + +------------------------------------------------------------------- +type loadStates is (LIDLE, INIT, REMOVE, DECIDE, CALCA, CALCB, LOAD, PAD0, PAD1, PAD2, PAD3, LOAD_SUBSUB, CALCC, CLOSE, WAIT_PC, DROP, WAIT_TO_REMOVE, DROP_SUBSUB, PAUSE_BEFORE_DROP1, PAUSE_BEFORE_DROP2); +signal loadCurrentState, loadNextState : loadStates; +signal state2 : std_logic_vector(3 downto 0); + +signal rem_ctr : std_logic_vector(3 downto 0); -- counter for stripping / storing header data +signal rst_rem_ctr_comb : std_logic; +signal rst_rem_ctr : std_logic; -- reset the remove counter +signal rst_regs_comb : std_logic; +signal rst_regs : std_logic; -- reset storage registers +signal rem_phase_comb : std_logic; +signal rem_phase : std_logic; -- header remove phase +signal data_phase_comb : std_logic; +signal data_phase : std_logic; -- data transport phase from split fifo to PC +signal pad_phase_comb : std_logic; +signal pad_phase : std_logic; -- padding phase +signal calc_pad_comb : std_logic; +signal calc_pad : std_logic; -- check if padding bytes need to be added to PC_SUB_SIZE +signal pad_data_comb : std_logic; +signal pad_data : std_logic; -- reset PC_DATA register to known padding byte value + +signal pc_sos_comb : std_logic; +signal pc_sos : std_logic; -- start of data signal +signal pc_eod_comb : std_logic; +signal pc_eod : std_logic; -- end of data signal + +signal ce_rem_ctr_comb : std_logic; +signal ce_rem_ctr : std_logic; -- count enable for remove counter +signal remove_done_comb : std_logic; +signal remove_done : std_logic; -- end of header stripping process +signal read_done_comb : std_logic; +signal read_done : std_logic; -- end of data phase (read phase from SF) + +signal pc_data : std_logic_vector(7 downto 0); +signal pc_data_q : std_logic_vector(7 downto 0); +signal pc_trig_nr : std_logic_vector(15 downto 0); +signal pc_sub_size : std_logic_vector(17 downto 0); +signal read_size : std_logic_vector(17 downto 0); -- number of byte to be read from split fifo +signal padding_needed : std_logic; +signal pc_wr_en_comb : std_logic; +signal pc_wr_en_q : std_logic; +signal pc_wr_en_qq : std_logic; +signal pc_wr_en_qqq : std_logic; +signal pc_eod_q : std_logic; + +signal debug : std_logic_vector(383 downto 0); + +-- gk +signal bank_select : std_logic_vector(3 downto 0); +signal save_addr_comb : std_logic; +signal save_addr : std_logic; +signal addr_saved_comb : std_logic; +signal addr_saved : std_logic; +signal start_config : std_logic; +signal config_done : std_logic; +signal add_sub_state : std_logic; +signal add_sub_state_comb : std_logic; +signal add_sub_ctr : std_logic_vector(3 downto 0); +signal load_sub : std_logic; +signal load_sub_comb : std_logic; +signal load_sub_done : std_logic; +signal load_sub_done_comb : std_logic; +signal load_sub_ctr : std_logic_vector(3 downto 0); +signal load_sub_ctr_comb : std_logic; +signal actual_message_size : std_logic_vector(31 downto 0); +signal more_subevents : std_logic; +signal trig_random : std_logic_vector(7 downto 0); +signal readout_ctr : std_logic_vector(23 downto 0); +signal readout_ctr_lock : std_logic; +signal pc_trig_nr_q : std_logic_vector(31 downto 0); + +-- gk 20.07.10 +signal inc_data_ctr : std_logic_vector(31 downto 0); +signal dropped_sm_events_ctr : std_logic_vector(31 downto 0); +signal dropped_lr_events_ctr : std_logic_vector(31 downto 0); +signal dropped_ctr : std_logic_vector(31 downto 0); +-- gk 22.07.10 +signal headers_invalid : std_logic; +signal headers_invalid_ctr : std_logic_vector(31 downto 0); +signal cts_len_q : std_logic_vector(15 downto 0); +signal cts_trg_q : std_logic_vector(15 downto 0); +signal cts_rnd_q : std_logic_vector(15 downto 0); +signal first_run_trg : std_logic_vector(15 downto 0); +signal first_run_addr : std_logic_vector(15 downto 0); +signal first_run_lock : std_logic; +signal cts_addr : std_logic_vector(15 downto 0); +signal cts_addr_q : std_logic_vector(15 downto 0); +signal cts_addr_saved : std_logic; + +-- gk 24.07.10 +signal save_eod : std_logic; +signal save_eod_comb : std_logic; + +signal load_eod : std_logic; +signal endpoint_addr : std_logic_vector(15 downto 0); +signal endp_addr_lock : std_logic; + +signal saved_events_ctr : std_logic_vector(15 downto 0); +signal loaded_events_ctr : std_logic_vector(15 downto 0); +signal constr_events_ctr : std_logic_vector(31 downto 0); +signal event_waiting : std_logic; + +signal drop_sub : std_logic; +signal drop_sub_comb : std_logic; +signal drop_event : std_logic; +signal drop_event_comb : std_logic; +signal drop_small : std_logic; +signal drop_large : std_logic; +signal drop_headers : std_logic; +signal drop_small_comb : std_logic; +signal drop_large_comb : std_logic; +signal drop_headers_comb : std_logic; +signal inc_trg_ctr : std_logic; +signal inc_trg_ctr_comb : std_logic; + +signal invalid_hsize_ctr : std_logic_vector(15 downto 0); +signal invalid_hsize_lock : std_logic; + +signal load_eod_q : std_logic; +signal read_size_q : std_logic_vector(17 downto 0); + +-- gk 06.08.10 write to fifo only if gbe is enabled but keep the saving logic unblocked +signal sf_real_wr_en : std_logic; + +-- gk 01.10.10 +signal found_empty_evt : std_logic; +signal found_empty_evt_comb : std_logic; +signal found_empty_evt_ctr : std_logic_vector(31 downto 0); + +-- gk 06.10.10 +signal message_size : std_logic_vector(31 downto 0); + +-- gk 07.12.10 +signal prev_bank_select : std_logic_vector(3 downto 0); +signal first_event : std_logic; + +begin + +BANK_SELECT_OUT <= bank_select; -- gk 27.03.10 +START_CONFIG_OUT <= start_config; -- gk 27.03.10 +config_done <= CONFIG_DONE_IN; -- gk 29.03.10 + +-- CTS interface signals +cts_error_pattern <= (others => '0'); -- FAKE + +cts_length <= x"0000"; -- length of data payload is always 0 +cts_data <= b"0001" & cts_rnd(11 downto 0) & cts_trg; -- reserved bits = '0', pack bit = '1' + +cts_readout_finished <= '1' when (saveCurrentState = SCLOSE) else '0'; + +cts_dataready <= '1' when ((saveCurrentState = SAVE_DATA) and (FEE_BUSY_IN = '0')) or (saveCurrentState = TERMINATE) + else '0'; + +-- Byte swapping... done here. TAKE CARE! +-- The split FIFO is in natural bus order (i.e. Motorola style, [15:0]). This means that the two bytes +-- on the write side need to be swapped to appear in GbE style (i.e. Intel style) on the 8bit port. +-- Please mind that PC_SUB_SIZE and PC_TRIG_NR stay in a human readable format, and need to be byteswapped +-- for GbE inside the packet constructor. +-- +-- Long live the Endianess! + +-- Sync all critical pathes +THE_SYNC_PROC: process( CLK ) +begin + if( rising_edge(CLK) ) then + --sf_data <= FEE_DATA_IN; -- gk 27.03.10 moved out to the process below + sf_wr_en <= sf_wr_en_comb; + ce_rem_ctr <= ce_rem_ctr_comb; + sf_rd_en <= sf_rd_en_comb; + fee_read <= fee_read_comb; + read_done <= read_done_comb; + pc_eod_q <= pc_eod; + pc_wr_en_qqq <= pc_wr_en_qq; + pc_wr_en_qq <= pc_wr_en_q; + pc_wr_en_q <= pc_wr_en_comb; + end if; +end process THE_SYNC_PROC; + +-- -- gk 27.03.10 data selector for sf to write the evt builder address on top of data +-- SF_DATA_PROC : process( CLK ) +-- begin +-- if( rising_edge(CLK) ) then +-- if (RESET = '1') then -- gk 31.05.10 +-- sf_data <= (others => '0'); +-- elsif( save_addr = '1' ) then +-- sf_data(3 downto 0) <= CTS_INFORMATION_IN(3 downto 0); -- only last 4 bits are the evt builder address +-- sf_data(15 downto 4) <= x"abc"; +-- -- gk 29.03.10 four entries to save the fee_status into sf for the subsubevent +-- elsif( (add_sub_state = '1') and (add_sub_ctr = x"0") ) then +-- sf_data <= x"0001"; -- gk 11.06.10 +-- elsif( (add_sub_state = '1') and (add_sub_ctr = x"1") ) then +-- sf_data <= x"5555"; -- gk 11.06.10 +-- elsif( (add_sub_state = '1') and (add_sub_ctr = x"2") ) then +-- sf_data <= FEE_STATUS_BITS_IN(31 downto 16); +-- elsif( (add_sub_state = '1') and (add_sub_ctr = x"3") ) then +-- sf_data <= FEE_STATUS_BITS_IN(15 downto 0); +-- else +-- sf_data <= FEE_DATA_IN; +-- end if; +-- end if; +-- end process SF_DATA_PROC; + +-- combinatorial read signal for the FEE data interface, DO NOT USE DIRECTLY +fee_read_comb <= '1' when ( (sf_afull = '0') and (data_req = '1') ) --and (DATA_GBE_ENABLE_IN = '1') ) -- GbE enabled + else '0'; + +-- combinatorial write signal for the split FIFO, DO NOT USE DIRECTLY +sf_wr_en_comb <= '1' when ( (fee_read = '1') and (FEE_DATAREADY_IN = '1') ) or -- and (DATA_GBE_ENABLE_IN = '1') ) or -- GbE enabled + (save_addr = '1') or + (add_sub_state = '1') -- gk 29.03.10 save the subsubevent + else '0'; + +-- gk 06.08.10 +sf_real_wr_en <= '1' when ((sf_wr_en = '1') and (DATA_GBE_ENABLE_IN = '1')) else '0'; + +-- gk 27.03.10 do not count evt builder address as saved ipu bytes +--ce_saved_ctr <= sf_wr_en; +ce_saved_ctr <= '0' when addr_saved = '1' else sf_wr_en; + +-- Statemachine for reading data payload, handling IPU channel and storing data in the SPLIT_FIFO +-- saveMachineProc: process( CLK ) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- saveCurrentState <= SIDLE; +-- data_req <= '0'; +-- rst_saved_ctr <= '0'; +-- save_addr <= '0'; -- gk 27.03.10 +-- addr_saved <= '0'; -- gk 27.03.10 +-- add_sub_state <= '0'; -- gk 29.03.10 +-- save_eod <= '0'; -- gk 25.07.10 +-- else +-- saveCurrentState <= saveNextState; +-- data_req <= data_req_comb; +-- rst_saved_ctr <= rst_saved_ctr_comb; +-- save_addr <= save_addr_comb; -- gk 27.03.10 +-- addr_saved <= addr_saved_comb; -- gk 27.03.10 +-- add_sub_state <= add_sub_state_comb; -- gk 29.03.10 +-- save_eod <= save_eod_comb; -- gk 25.07.10 +-- end if; +-- end if; +-- end process saveMachineProc; +-- +-- saveMachine: process( saveCurrentState, CTS_START_READOUT_IN, FEE_BUSY_IN, CTS_READ_IN) +-- begin +-- saveNextState <= SIDLE; +-- data_req_comb <= '0'; +-- rst_saved_ctr_comb <= '0'; +-- save_addr_comb <= '0'; -- gk 27.03.10 +-- addr_saved_comb <= '0'; -- gk 27.03.10 +-- add_sub_state_comb <= '0'; -- gk 29.03.10 +-- save_eod_comb <= '0'; -- gk 25.07.10 +-- case saveCurrentState is +-- when SIDLE => +-- state <= x"0"; +-- if (CTS_START_READOUT_IN = '1') then +-- saveNextState <= SAVE_EVT_ADDR; --WAIT_FOR_DATA; -- gk 27.03.10 +-- data_req_comb <= '1'; +-- rst_saved_ctr_comb <= '1'; +-- else +-- saveNextState <= SIDLE; +-- end if; +-- -- gk 27.03.10 +-- when SAVE_EVT_ADDR => +-- state <= x"5"; +-- saveNextState <= WAIT_FOR_DATA; +-- data_req_comb <= '1'; +-- save_addr_comb <= '1'; +-- when WAIT_FOR_DATA => +-- state <= x"1"; +-- if (FEE_BUSY_IN = '1') then +-- saveNextState <= SAVE_DATA; +-- data_req_comb <= '1'; +-- else +-- saveNextState <= WAIT_FOR_DATA; +-- data_req_comb <= '1'; +-- end if; +-- addr_saved_comb <= '1'; -- gk 27.03.10 +-- when SAVE_DATA => +-- state <= x"2"; +-- if (FEE_BUSY_IN = '0') then +-- saveNextState <= TERMINATE; +-- else +-- saveNextState <= SAVE_DATA; +-- data_req_comb <= '1'; +-- end if; +-- when TERMINATE => +-- state <= x"3"; +-- if (CTS_READ_IN = '1') then +-- saveNextState <= SCLOSE; +-- else +-- saveNextState <= TERMINATE; +-- end if; +-- when SCLOSE => +-- state <= x"4"; +-- if (CTS_START_READOUT_IN = '0') then +-- saveNextState <= ADD_SUBSUB1; --SIDLE; -- gk 29.03.10 +-- else +-- saveNextState <= SCLOSE; +-- end if; +-- -- gk 29.03.10 new states during which the subsub bytes are saved +-- when ADD_SUBSUB1 => +-- state <= x"6"; +-- saveNextState <= ADD_SUBSUB2; +-- add_sub_state_comb <= '1'; +-- when ADD_SUBSUB2 => +-- state<= x"7"; +-- saveNextState <= ADD_SUBSUB3; +-- add_sub_state_comb <= '1'; +-- save_eod_comb <= '1'; +-- when ADD_SUBSUB3 => +-- state<= x"8"; +-- saveNextState <= ADD_SUBSUB4; +-- add_sub_state_comb <= '1'; +-- when ADD_SUBSUB4 => +-- state<= x"9"; +-- saveNextState <= SIDLE; +-- add_sub_state_comb <= '1'; +-- when others => +-- state <= x"f"; +-- saveNextState <= SIDLE; +-- end case; +-- end process saveMachine; +-- +-- -- gk 29.03.10 +-- ADD_SUB_CTR_PROC : process( CLK ) +-- begin +-- if( rising_edge( CLK ) ) then +-- if( (RESET = '1') or (rst_saved_ctr = '1') ) then +-- add_sub_ctr <= (others => '0'); +-- elsif( add_sub_state = '1' ) then +-- add_sub_ctr <= add_sub_ctr + 1; +-- end if; +-- end if; +-- end process ADD_SUB_CTR_PROC; +-- +-- --******** +-- -- SAVE INCOMING EVENT HEADERS +-- --******** +-- +-- -- Counter for header word storage +-- THE_CTS_SAVED_CTR: process( CLK ) +-- begin +-- if( rising_edge(CLK) ) then +-- if ( (RESET = '1') or (rst_saved_ctr = '1') ) then +-- saved_ctr <= (others => '0'); +-- elsif( ce_saved_ctr = '1' ) then +-- saved_ctr <= saved_ctr + 1; +-- end if; +-- end if; +-- end process THE_CTS_SAVED_CTR; +-- +-- -- save triggerRnd from incoming data for cts response +-- CTS_RND_PROC: process( CLK ) +-- begin +-- if( rising_edge(CLK) ) then +-- if ( (RESET = '1') or (rst_saved_ctr = '1') ) then +-- cts_rnd <= (others => '0'); +-- cts_rnd_saved <= '0'; +-- elsif( (saved_ctr(2 downto 0) = b"000") and (sf_wr_en = '1') and (cts_rnd_saved = '0') ) then +-- cts_rnd <= sf_data; +-- cts_rnd_saved <= '1'; +-- end if; +-- end if; +-- end process CTS_RND_PROC; +-- +-- -- save triggerNr from incoming data for cts response +-- CTS_TRG_PROC: process( CLK ) +-- begin +-- if( rising_edge(CLK) ) then +-- if ( (RESET = '1') or (rst_saved_ctr = '1') ) then +-- cts_trg <= (others => '0'); +-- cts_trg_saved <= '0'; +-- elsif( (saved_ctr(2 downto 0) = b"001") and (sf_wr_en = '1') and (cts_trg_saved = '0') ) then +-- cts_trg <= sf_data; +-- cts_trg_saved <= '1'; +-- end if; +-- end if; +-- end process CTS_TRG_PROC; +-- +-- -- save size from incoming data for cts response (future) and to get rid of padding +-- CTS_SIZE_PROC: process( CLK ) +-- begin +-- if( rising_edge(CLK) ) then +-- if ( (RESET = '1') or (rst_saved_ctr = '1') ) then +-- cts_len <= (others => '0'); +-- cts_len_saved <= '0'; +-- elsif( (saved_ctr(2 downto 0) = b"010") and (sf_wr_en = '1') and (cts_len_saved = '0') ) then +-- cts_len(16 downto 1) <= sf_data; -- change from 32b words to 16b words +-- cts_len(0) <= '0'; +-- elsif( (saved_ctr(2 downto 0) = b"011") and (cts_len_saved = '0') ) then +-- cts_len <= cts_len + x"4"; +-- cts_len_saved <= '1'; +-- end if; +-- end if; +-- end process CTS_SIZE_PROC; +-- +-- -- gk 22.07.10 +-- CTS_ADDR_PROC : process(CLK) +-- begin +-- if( rising_edge(CLK) ) then +-- if ( (RESET = '1') or (rst_saved_ctr = '1') ) then +-- cts_addr <= (others => '0'); +-- cts_addr_saved <= '0'; +-- elsif( (saved_ctr(2 downto 0) = b"011") and (sf_wr_en = '1') and (cts_addr_saved = '0') ) then +-- cts_addr <= sf_data; +-- cts_addr_saved <= '1'; +-- end if; +-- end if; +-- end process CTS_ADDR_PROC; +-- +-- --****** +-- -- SAVE FIRST EVENT HEADER VALUES +-- --****** +-- +-- -- gk 22.07.10 +-- FIRST_RUN_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- first_run_trg <= (others => '0'); +-- first_run_addr <= (others => '0'); +-- first_run_lock <= '0'; +-- elsif (first_run_lock = '0') and (cts_addr_saved = '1') then +-- first_run_trg <= cts_trg; +-- first_run_addr <= cts_addr; +-- first_run_lock <= '1'; +-- -- important: value saved by saveMachine but incremented by loadMachine +-- elsif (first_run_lock = '1') and (inc_trg_ctr = '1') then +-- first_run_trg <= first_run_trg + x"1"; +-- end if; +-- end if; +-- end process FIRST_RUN_PROC; +-- +-- -- gk 25.07.10 +-- SAVED_EVT_CTR_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- saved_events_ctr <= (others => '0'); +-- elsif (save_eod = '1') then +-- saved_events_ctr <= saved_events_ctr + x"1"; +-- end if; +-- end if; +-- end process SAVED_EVT_CTR_PROC; +-- +-- +-- -- gk 20.07.10 +-- INC_DATA_CTR_proc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (rst_saved_ctr = '1') then +-- inc_data_ctr <= (others => '0'); +-- elsif (sf_wr_en = '1') and (data_req = '1') then +-- inc_data_ctr(31 downto 1) <= inc_data_ctr(31 downto 1) + x"1"; +-- end if; +-- end if; +-- end process INC_DATA_CTR_proc; + +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ + +-- Split FIFO +-- THE_SPLIT_FIFO: fifo_32kx16x8_mb2 +-- port map( +-- -- Byte swapping for correct byte order on readout side of FIFO +-- Data(7 downto 0) => sf_data(15 downto 8), +-- Data(8) => '0', +-- Data(16 downto 9) => sf_data(7 downto 0), +-- Data(17) => save_eod, +-- WrClock => CLK, +-- RdClock => CLK, +-- WrEn => sf_real_wr_en, -- gk 06.08.10 --sf_wr_en, +-- RdEn => sf_rd_en, +-- Reset => RESET, +-- RPReset => RESET, +-- AmEmptyThresh => b"0000_0000_0000_0010", -- one byte ahead +-- AmFullThresh => b"111_1111_1110_1111", -- 0x7fef = 32751 +-- Q(7 downto 0) => pc_data, +-- Q(8) => load_eod, +-- WCNT => sf_wcnt, +-- RCNT => sf_rcnt, +-- Empty => sf_empty, +-- AlmostEmpty => sf_aempty, +-- Full => sf_full, +-- AlmostFull => sf_afull +-- ); + +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ + +-- gk 25.07.10 +-- EVENT_WAITING_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- event_waiting <= '0'; +-- elsif (loaded_events_ctr /= saved_events_ctr) then +-- event_waiting <= '1'; +-- else +-- event_waiting <= '0'; +-- end if; +-- end if; +-- end process EVENT_WAITING_PROC; +-- +-- -- write signal for PC data +-- pc_wr_en_comb <= '1' when ((data_phase = '1') and (sf_rd_en = '1')) or +-- (pad_phase = '1') or +-- ((load_sub = '1') and (sf_rd_en = '1')) or +-- ((drop_sub = '1') and (sf_rd_en = '1')) or +-- ((drop_event = '1') and (sf_rd_en = '1')) +-- else '0'; +-- +-- sf_rd_en_comb <= '1' when ( (sf_aempty = '0') and (rem_phase = '1') and (remove_done = '0') ) or +-- --( (sf_aempty = '0') and (data_phase = '1') and (read_done = '0') ) or +-- ( (sf_aempty = '0') and (data_phase = '1') and (load_eod = '0') ) or -- gk 26.07.10 +-- ( (sf_aempty = '0') and (load_sub = '1') and (load_sub_done = '0') ) or -- gk 30.03.10 +-- ( (sf_aempty = '0') and (drop_event = '1') and (load_eod = '0') ) or +-- ( (sf_aempty = '0') and (drop_sub = '1') and (load_sub_done = '0') ) +-- else '0'; +-- +-- ce_rem_ctr_comb <= '1' when ( (sf_aempty = '0') and (rem_phase = '1') and ( remove_done = '0') ) +-- else '0'; +-- +-- -- FIFO data delay process (also forces padding bytes to known value) +-- THE_DATA_DELAY_PROC: process( CLK ) +-- begin +-- if( rising_edge(CLK) ) then +-- if( pad_data = '1' ) then +-- pc_data_q <= x"aa"; -- padding for 64bit +-- -- gk 21.07.10 +-- -- set the error flag if a broken packet is sent +-- elsif (drop_sub = '1') and (load_sub_ctr = x"3") then +-- pc_data_q <= pc_data(7 downto 3) & '1' & pc_data(1 downto 0); +-- else +-- pc_data_q <= pc_data; +-- end if; +-- end if; +-- end process THE_DATA_DELAY_PROC; +-- +-- -- Statemachine for reading the data payload from the SPLIT_FIFO and feeding +-- -- it into the packet constructor +-- loadMachineProc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- loadCurrentState <= LIDLE; +-- rst_rem_ctr <= '0'; +-- rem_phase <= '0'; +-- calc_pad <= '0'; +-- data_phase <= '0'; +-- pad_phase <= '0'; +-- pc_sos <= '0'; +-- pc_eod <= '0'; +-- rst_regs <= '0'; +-- pad_data <= '0'; +-- load_sub <= '0'; -- gk 30.03.10 +-- drop_sub <= '0'; -- gk 25.07.10 +-- drop_event <= '0'; -- gk 25.07.10 +-- drop_small <= '0'; -- gk 25.07.10 +-- drop_large <= '0'; -- gk 25.07.10 +-- drop_headers <= '0'; -- gk 25.07.10 +-- inc_trg_ctr <= '0'; -- gk 26.07.10 +-- found_empty_evt <= '0'; -- gk 01.10.10 +-- else +-- loadCurrentState <= loadNextState; +-- rst_rem_ctr <= rst_rem_ctr_comb; +-- rem_phase <= rem_phase_comb; +-- calc_pad <= calc_pad_comb; +-- data_phase <= data_phase_comb; +-- pad_phase <= pad_phase_comb; +-- pc_sos <= pc_sos_comb; +-- pc_eod <= pc_eod_comb; +-- rst_regs <= rst_regs_comb; +-- pad_data <= pad_data_comb; +-- load_sub <= load_sub_comb; -- gk 30.03.1 +-- drop_sub <= drop_sub_comb; -- gk 25.07.10 +-- drop_event <= drop_event_comb; -- gk 25.07.10 +-- drop_small <= drop_small_comb; -- gk 25.07.10 +-- drop_large <= drop_large_comb; -- gk 25.07.10 +-- drop_headers <= drop_headers_comb; -- gk 25.07.10 +-- inc_trg_ctr <= inc_trg_ctr_comb; -- gk 26.07.10 +-- found_empty_evt <= found_empty_evt_comb; -- gk 01.10.10 +-- end if; +-- end if; +-- end process loadMachineProc; +-- +-- loadMachine : process( loadCurrentState, sf_aempty, remove_done, read_done, padding_needed, +-- PC_READY_IN, load_sub_done, pc_sub_size, MIN_MESSAGE_SIZE_IN, +-- MAX_MESSAGE_SIZE_IN, pc_trig_nr, first_run_trg, endpoint_addr, +-- first_run_addr, load_eod, event_waiting, MULT_EVT_ENABLE_IN, message_size) +-- begin +-- loadNextState <= LIDLE; +-- rst_rem_ctr_comb <= '0'; +-- rem_phase_comb <= '0'; +-- calc_pad_comb <= '0'; +-- data_phase_comb <= '0'; +-- pad_phase_comb <= '0'; +-- pc_sos_comb <= '0'; +-- pc_eod_comb <= '0'; +-- rst_regs_comb <= '0'; +-- pad_data_comb <= '0'; +-- load_sub_comb <= '0'; -- gk 30.03.10 +-- drop_sub_comb <= '0'; -- gk 25.07.10 +-- drop_event_comb <= '0'; -- gk 25.07.10 +-- drop_small_comb <= '0'; -- gk 25.07.10 +-- drop_large_comb <= '0'; -- gk 25.07.10 +-- drop_headers_comb <= '0'; -- gk 25.07.10 +-- inc_trg_ctr_comb <= '0'; -- gk 26.07.10 +-- found_empty_evt_comb <= '0'; -- gk 01.10.10 +-- case loadCurrentState is +-- when LIDLE => +-- state2 <= x"0"; +-- -- gk 23.07.10 +-- if( (sf_aempty = '0') and (event_waiting = '1') and (DATA_GBE_ENABLE_IN = '1') ) then -- gk 06.08.10 -- and (PC_READY_IN = '1') +-- loadNextState <= INIT; +-- rst_rem_ctr_comb <= '1'; +-- rst_regs_comb <= '1'; +-- else +-- loadNextState <= LIDLE; +-- end if; +-- when INIT => +-- state2 <= x"1"; +-- loadNextState <= REMOVE; +-- rem_phase_comb <= '1'; +-- when REMOVE => +-- state2 <= x"2"; +-- if( remove_done = '1' ) then +-- -- gk 06.10.10 +-- if (MULT_EVT_ENABLE_IN = '1') then +-- if (message_size + pc_sub_size < MAX_MESSAGE_SIZE_IN) then +-- --loadNextState <= WAIT_TO_REMOVE; +-- -- gk 07.12.10 +-- if (first_event = '0') and (prev_bank_select /= bank_select) then -- check if event builder address changed, if so close the current packet +-- loadNextState <= WAIT_PC; +-- else +-- loadNextState <= WAIT_TO_REMOVE; +-- end if; +-- +-- else +-- loadNextState <= WAIT_PC; +-- end if; +-- else +-- loadNextState <= WAIT_TO_REMOVE; +-- end if; +-- inc_trg_ctr_comb <= '1'; +-- else +-- loadNextState <= REMOVE; +-- rem_phase_comb <= '1'; +-- end if; +-- when WAIT_TO_REMOVE => +-- if (rem_ctr = x"a") then +-- loadNextState <= DECIDE; +-- else +-- loadNextState <= WAIT_TO_REMOVE; +-- end if; +-- when DECIDE => +-- if (pc_sub_size >= MAX_MESSAGE_SIZE_IN) then +-- loadNextState <= PAUSE_BEFORE_DROP1; +-- drop_large_comb <= '1'; +-- elsif (pc_sub_size = b"0000_0000_0000_00") then -- gk 01.10.10 +-- loadNextState <= CALCA; +-- found_empty_evt_comb <= '1'; +-- elsif (pc_sub_size < MIN_MESSAGE_SIZE_IN) then +-- loadNextState <= PAUSE_BEFORE_DROP1; +-- drop_small_comb <= '1'; +-- elsif (pc_trig_nr + x"1" /= first_run_trg) then +-- loadNextState <= PAUSE_BEFORE_DROP1; +-- drop_headers_comb <= '1'; +-- elsif (endpoint_addr /= first_run_addr) then +-- loadNextState <= PAUSE_BEFORE_DROP1; +-- drop_headers_comb <= '1'; +-- else +-- loadNextState <= CALCA; +-- end if; +-- calc_pad_comb <= '1'; +-- when CALCA => +-- state2 <= x"3"; +-- loadNextState <= CALCB; +-- pc_sos_comb <= '1'; +-- when CALCB => +-- -- we need a branch in case of length "0"!!!! +-- state2 <= x"4"; +-- loadNextState <= LOAD; +-- data_phase_comb <= '1'; +-- when LOAD => +-- state2 <= x"5"; +-- if (load_eod = '1') then +-- loadNextState <= LOAD_SUBSUB; +-- else +-- loadNextState <= LOAD; +-- data_phase_comb <= '1'; +-- end if; +-- -- gk 31.03.10 +-- when LOAD_SUBSUB => +-- state2 <= x"d"; +-- if( load_sub_done = '1' ) then +-- if( padding_needed = '0' ) then +-- loadNextState <= CALCC; +-- else +-- loadNextState <= PAD0; +-- pad_phase_comb <= '1'; +-- end if; +-- else +-- loadNextState <= LOAD_SUBSUB; +-- load_sub_comb <= '1'; +-- end if; +-- when PAD0 => +-- state2 <= x"6"; +-- loadNextState <= PAD1; +-- pad_phase_comb <= '1'; +-- pad_data_comb <= '1'; +-- when PAD1 => +-- state2 <= x"7"; +-- loadNextState <= PAD2; +-- pad_phase_comb <= '1'; +-- pad_data_comb <= '1'; +-- when PAD2 => +-- state2 <= x"8"; +-- loadNextState <= PAD3; +-- pad_phase_comb <= '1'; +-- pad_data_comb <= '1'; +-- when PAD3 => +-- state2 <= x"9"; +-- loadNextState <= CALCC; +-- pad_data_comb <= '1'; +-- when CALCC => +-- state2 <= x"a"; +-- if (MULT_EVT_ENABLE_IN = '1') then +-- loadNextState <= LIDLE; +-- else +-- loadNextState <= CLOSE; +-- end if; +-- pc_eod_comb <= '1'; +-- when CLOSE => +-- state2 <= x"b"; +-- loadNextState <= WAIT_PC; +-- --rst_regs_comb <= '1'; -- gk 07.10.10 +-- when WAIT_PC => +-- state2 <= x"c"; +-- if( PC_READY_IN = '1' ) then +-- -- gk 06.10.10 +-- if (MULT_EVT_ENABLE_IN = '1') then +-- loadNextState <= WAIT_TO_REMOVE; +-- else +-- loadNextState <= LIDLE; +-- end if; +-- else +-- loadNextState <= WAIT_PC; +-- end if; +-- when PAUSE_BEFORE_DROP1 => +-- loadNextState <= PAUSE_BEFORE_DROP2; +-- pc_sos_comb <= '1'; +-- when PAUSE_BEFORE_DROP2 => +-- loadNextState <= DROP; +-- drop_event_comb <= '1'; +-- -- gk 23.07.10 +-- when DROP => +-- state2 <= x"e"; +-- -- when data is dropped the eod marker stands as its end +-- if (load_eod = '1') then +-- loadNextState <= DROP_SUBSUB; +-- else +-- loadNextState <= DROP; +-- drop_event_comb <= '1'; +-- end if; +-- -- gk 25.07.10 +-- when DROP_SUBSUB => +-- if (load_sub_done = '1') then +-- if( padding_needed = '0' ) then +-- loadNextState <= CALCC; +-- else +-- loadNextState <= PAD0; +-- pad_phase_comb <= '1'; +-- end if; +-- else +-- loadNextState <= DROP_SUBSUB; +-- drop_sub_comb <= '1'; +-- end if; +-- when others => +-- state2 <= x"f"; +-- loadNextState <= LIDLE; +-- end case; +-- end process loadMachine; +-- +-- -- gk 07.10.10 +-- PC_EOS_OUT <= '1' when (MULT_EVT_ENABLE_IN = '1') and (pc_eod = '1') else '0'; +-- +-- -- gk 25.07.10 +-- INVALID_STATS_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- dropped_lr_events_ctr <= (others => '0'); +-- dropped_sm_events_ctr <= (others => '0'); +-- headers_invalid_ctr <= (others => '0'); +-- dropped_ctr <= (others => '0'); +-- invalid_hsize_ctr <= (others => '0'); +-- found_empty_evt_ctr <= (others => '0'); -- gk 01.10.10 +-- elsif (rst_regs = '1') then +-- invalid_hsize_lock <= '0'; +-- elsif (drop_small = '1') then +-- dropped_sm_events_ctr <= dropped_sm_events_ctr + x"1"; +-- dropped_ctr <= dropped_ctr + x"1"; +-- elsif (drop_large = '1') then +-- dropped_lr_events_ctr <= dropped_lr_events_ctr + x"1"; +-- dropped_ctr <= dropped_ctr + x"1"; +-- elsif (drop_headers = '1') then +-- headers_invalid_ctr <= headers_invalid_ctr + x"1"; +-- dropped_ctr <= dropped_ctr + x"1"; +-- elsif (load_eod_q = '1') and (read_size_q /= x"3fffe") and (invalid_hsize_lock = '0') then -- ?? +-- invalid_hsize_ctr <= invalid_hsize_ctr + x"1"; +-- invalid_hsize_lock <= '1'; +-- -- gk 01.10.10 +-- elsif (found_empty_evt = '1') then +-- found_empty_evt_ctr <= found_empty_evt_ctr + x"1"; +-- end if; +-- end if; +-- end process INVALID_STATS_PROC; +-- +-- -- gk 05.08.10 +-- INVALID_H_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- load_eod_q <= load_eod; +-- read_size_q <= read_size; +-- end if; +-- end process INVALID_H_PROC; +-- +-- -- gk 26.04.10 +-- READOUT_CTR_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if ((RESET = '1') or (READOUT_CTR_VALID_IN = '1')) then +-- readout_ctr <= READOUT_CTR_IN; +-- readout_ctr_lock <= '0'; +-- elsif (pc_sos = '1') then +-- readout_ctr <= readout_ctr + x"1"; +-- end if; +-- end if; +-- end process READOUT_CTR_PROC; + +--****** +-- SELECTION OF EVENT BUILDER +--****** + +-- gk 27.03.10 +bank_select_proc : process( CLK ) +begin + if rising_edge( CLK ) then + -- gk 29.03.10 + if( (RESET = '1') or (rst_regs = '1') ) then + bank_select <= "0000"; + -- gk 01.06.10 THERE WAS A BUG, IT SHOUDL BE TAKEN FROM SF_Q + elsif( (sf_rd_en = '1') and (rem_ctr = x"2") ) then + bank_select <= pc_data(3 downto 0); --CTS_INFORMATION_IN(3 downto 0); + end if; + end if; +end process bank_select_proc; + +-- gk 07.12.10 +first_event_proc : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (loadCurrentState = WAIT_PC) then + first_event <= '1'; + elsif (remove_done = '1') then + first_event <= '0'; + end if; + end if; +end process first_event_proc; + +-- gk 07.12.10 +prev_bank_proc : process(CLK) +begin + if (RESET = '1') or (loadCurrentState = WAIT_PC) then + prev_bank_select <= "0000"; + elsif ((sf_rd_en = '1') and (rem_ctr = x"3") and (first_event = '1')) then + prev_bank_select <= bank_select; + end if; +end process prev_bank_proc; + + +-- gk 29.03.10 +start_config_proc : process( CLK ) +begin + if rising_edge( CLK ) then + if( (RESET = '1') or (config_done = '1') or (rst_regs = '1') ) then + start_config <= '0'; + elsif( (sf_rd_en = '1') and (rem_ctr = x"2") and (first_event = '1') ) then -- gk 01.06.10 + start_config <= '1'; + end if; + end if; +end process start_config_proc; + + +--****** +-- LOAD SUBSUBEVENT +--****** + +-- gk 30.03.10 +-- load_sub_ctr_comb <= '1' when ( ((load_sub = '1') or (drop_sub = '1')) and (load_sub_done = '0') and (sf_aempty = '0') ) +-- else '0'; +-- +-- -- gk 30.03.10 +-- LOAD_SUB_CTR_PROC: process( CLK ) +-- begin +-- if( rising_edge(CLK) ) then +-- if ( (RESET = '1') or (rst_regs = '1') ) then -- gk 08.04.10 +-- load_sub_ctr <= (others => '0'); +-- elsif( (load_sub_ctr_comb = '1') ) then +-- load_sub_ctr <= load_sub_ctr + 1; +-- end if; +-- end if; +-- end process LOAD_SUB_CTR_PROC; +-- +-- -- gk 30.03.10 +-- -- load_sub_done_comb <= '1' when ((load_sub_ctr = x"7") and (drop_sub = '0')) or +-- -- ((load_sub_ctr = x"4") and (drop_sub = '1')) +-- -- else '0'; +-- load_sub_done_comb <= '1' when (load_sub_ctr = x"4") else '0'; +-- +-- -- gk 30.03.10 +-- LOAD_SUB_DONE_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if ( (RESET = '1') or (rst_regs = '1') ) then -- gk 08.04.10 +-- load_sub_done <= '0'; +-- else +-- load_sub_done <= load_sub_done_comb; +-- end if; +-- end if; +-- end process LOAD_SUB_DONE_PROC; +-- +-- --****** +-- -- EXTRACT EVENT HEADERS FROM SPLITFIFO +-- --****** +-- +-- -- Counter for stripping the unneeded parts of the data stream, and saving the important parts +-- THE_REMOVE_CTR: process( CLK ) +-- begin +-- if( rising_edge(CLK) ) then +-- if ( (RESET = '1') or (rst_rem_ctr = '1') ) then +-- rem_ctr <= (others => '0'); +-- elsif( (ce_rem_ctr = '1') ) then +-- rem_ctr <= rem_ctr + 1; +-- end if; +-- end if; +-- end process THE_REMOVE_CTR; +-- +-- remove_done_comb <= '1' when ( rem_ctr = x"8" ) else '0'; --( rem_ctr = x"6" ) else '0'; -- gk 29.03.10 two more for evt builder address +-- +-- THE_REM_DONE_SYNC: process( CLK ) +-- begin +-- if( rising_edge(CLK) ) then +-- if ( (RESET = '1') or (rst_rem_ctr = '1') ) then +-- remove_done <= '0'; +-- else +-- remove_done <= remove_done_comb; +-- end if; +-- end if; +-- end process THE_REM_DONE_SYNC; +-- +-- -- gk 26.04.10 +-- TRIG_RANDOM_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if ((RESET = '1') or (rst_regs = '1')) then +-- trig_random <= (others => '0'); +-- elsif ((sf_rd_en = '1') and (rem_ctr = x"4")) then +-- trig_random <= pc_data; +-- end if; +-- end if; +-- end process TRIG_RANDOM_PROC; +-- +-- -- extract the trigger number from splitfifo data +-- THE_TRG_NR_PROC: process( CLK ) +-- begin +-- if rising_edge(CLK) then +-- if ( (RESET = '1') or (rst_regs = '1') ) then +-- pc_trig_nr <= (others => '0'); +-- elsif( (sf_rd_en = '1') and (rem_ctr = x"6") ) then -- x"4" gk 29.03.10 +-- pc_trig_nr(7 downto 0) <= pc_data; +-- elsif( (sf_rd_en = '1') and (rem_ctr = x"5") ) then -- x"3" gk 29.03.10 +-- pc_trig_nr(15 downto 8) <= pc_data; +-- end if; +-- end if; +-- end process THE_TRG_NR_PROC; +-- +-- -- extract the subevent size from the splitfifo data, convert it from 32b to 8b units, +-- -- and in case of padding needed increase it accordingly +-- THE_SUB_SIZE_PROC: process( CLK ) +-- begin +-- if( rising_edge(CLK) ) then +-- if ( (RESET = '1') or (rst_regs = '1') ) then +-- pc_sub_size <= (others => '0'); +-- elsif( (sf_rd_en = '1') and (rem_ctr = x"8") ) then -- x"6" gk 29.03.10 +-- pc_sub_size(9 downto 2) <= pc_data; +-- elsif( (sf_rd_en = '1') and (rem_ctr = x"7") ) then -- x"5" gk 29.03.10 +-- pc_sub_size(17 downto 10) <= pc_data; +-- -- gk 20.07.10 +-- -- gk 30.03.10 bug fixed in the way that is written below +-- -- gk 27.03.10 should be corrected by sending padding_needed signal to pc and take care of it when setting sub_size_to_save +-- elsif( (calc_pad = '1') and (padding_needed = '1') ) then +-- pc_sub_size <= pc_sub_size + x"4" + x"8"; -- BUG: SubEvtSize does NOT include 64bit padding!!! +-- elsif( (calc_pad = '1') and (padding_needed = '0') ) then +-- pc_sub_size <= pc_sub_size + x"8"; +-- end if; +-- end if; +-- end process THE_SUB_SIZE_PROC; +-- +-- -- gk 06.10.10 +-- MESSAGE_SIZE_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- -- if (RESET = '1') then +-- -- message_size <= (others => '0'); +-- -- elsif ((MULT_EVT_ENABLE_IN = '1') and (message_size + pc_sub_size >= MAX_MESSAGE_SIZE_IN) and (remove_done = '1')) then +-- -- message_size <= (others => '0'); +-- -- elsif (pc_sos = '1') then +-- -- message_size <= message_size + pc_sub_size; +-- -- end if; +-- if (RESET = '1') then +-- message_size <= x"0000_0028"; +-- elsif ((MULT_EVT_ENABLE_IN = '1') and (message_size + pc_sub_size >= MAX_MESSAGE_SIZE_IN) and (remove_done = '1')) then +-- message_size <= x"0000_0028"; +-- elsif ((MULT_EVT_ENABLE_IN = '1') and (prev_bank_select /= bank_select) and (remove_done = '1')) then +-- message_size <= x"0000_0028"; +-- elsif (pc_sos = '1') then +-- message_size <= message_size + pc_sub_size + x"10"; -- gk 06.12.10 add 16B for subevent headers +-- end if; +-- end if; +-- end process MESSAGE_SIZE_PROC; +-- +-- +-- -- gk 25.07.10 +-- ENDP_ADDRESS_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (rst_regs = '1') then +-- endpoint_addr <= (others => '0'); +-- endp_addr_lock <= '0'; +-- elsif( (rem_ctr = x"a") and (endp_addr_lock = '0') ) then +-- endpoint_addr(7 downto 0) <= pc_data; +-- endp_addr_lock <= '1'; +-- elsif( (sf_rd_en = '1') and (rem_ctr = x"9") ) then +-- endpoint_addr(15 downto 8) <= pc_data; +-- endp_addr_lock <= '0'; +-- end if; +-- end if; +-- end process ENDP_ADDRESS_PROC; +-- +-- +-- +-- -- check for padding +-- THE_PADDING_NEEDED_PROC: process( CLK ) +-- begin +-- if rising_edge(CLK) then +-- if ( (RESET = '1') or (rst_regs = '1') ) then +-- padding_needed <= '0'; +-- elsif( (remove_done = '1') and (pc_sub_size(2) = '1') ) then +-- padding_needed <= '1'; +-- elsif( (remove_done = '1') and (pc_sub_size(2) = '0') ) then +-- padding_needed <= '0'; +-- end if; +-- end if; +-- end process THE_PADDING_NEEDED_PROC; +-- +-- -- number of bytes to read from split fifo +-- THE_READ_SIZE_PROC: process( CLK ) +-- begin +-- if( rising_edge(CLK) ) then +-- if ( (RESET = '1') or (rst_regs = '1') ) then --(rst_rem_ctr = '1') ) then +-- read_size <= (others => '0'); +-- elsif( (sf_rd_en = '1') and (rem_ctr = x"8") ) then -- x"6" gk 29.03.10 +-- read_size(9 downto 2) <= pc_data; +-- elsif( (sf_rd_en = '1') and (rem_ctr = x"7") ) then -- x"5" gk 29.03.10 +-- read_size(17 downto 10) <= pc_data; +-- elsif( ((sf_rd_en = '1') and (data_phase = '1')) ) then +-- read_size <= read_size - 1; +-- -- gk 25.07.10 +-- elsif( ((sf_rd_en = '1') and (drop_event = '1')) ) then +-- read_size <= read_size - 1; +-- end if; +-- end if; +-- end process THE_READ_SIZE_PROC; +-- +-- read_done_comb <= '1' when (read_size < 3 ) else '0'; -- "2" +-- +-- --****** +-- -- EVENTS COUNTERS +-- --****** +-- +-- -- gk 25.07.10 +-- LOADED_EVT_CTR_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- loaded_events_ctr <= (others => '0'); +-- elsif (remove_done = '1') then +-- loaded_events_ctr <= loaded_events_ctr + x"1"; +-- end if; +-- end if; +-- end process LOADED_EVT_CTR_PROC; +-- +-- -- gk 25.07.10 +-- CONSTR_EVENTS_CTR_PROC : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- constr_events_ctr <= (others => '0'); +-- elsif (pc_eod = '1') then +-- constr_events_ctr <= constr_events_ctr + x"1"; +-- end if; +-- end if; +-- end process CONSTR_EVENTS_CTR_PROC; + +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------ + +-- Debug signals +-- debug(0) <= sf_full; +-- debug(1) <= sf_empty; +-- debug(2) <= sf_afull; +-- debug(3) <= sf_aempty; +-- +-- debug(7 downto 4) <= state2; +-- +-- debug(11 downto 8) <= state; +-- +-- dbg_bs_proc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- debug(15 downto 12) <= (others => '0'); +-- elsif ( (sf_rd_en = '1') and (rem_ctr = x"3") ) then +-- debug(15 downto 12) <= bank_select; +-- end if; +-- end if; +-- end process dbg_bs_proc; +-- +-- debug(16) <= config_done; +-- debug(17) <= '0'; --remove_done; +-- debug(18) <= read_done; +-- debug(19) <= padding_needed; +-- +-- debug(20) <= load_sub_done; +-- +-- dbg_cts_inf_proc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- debug(39 downto 32) <= (others => '0'); +-- elsif ( save_addr = '1' ) then +-- debug(39 downto 32) <= CTS_INFORMATION_IN; +-- end if; +-- end if; +-- end process dbg_cts_inf_proc; +-- +-- debug(47 downto 40) <= (others => '0'); +-- +-- +-- debug(63 downto 48) <= actual_message_size(15 downto 0); +-- +-- dbg_pc_sub_size_proc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- debug(81 downto 64) <= (others => '0'); +-- elsif (loadCurrentState = DECIDE) then +-- debug(81 downto 64) <= pc_sub_size; +-- end if; +-- end if; +-- end process dbg_pc_sub_size_proc; +-- +-- dbg_empty_proc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') or (rst_regs = '1') then +-- debug(84 downto 82) <= (others => '0'); +-- elsif (read_size = 2) then +-- debug(82) <= sf_empty; +-- elsif (read_size = 1) then +-- debug(83) <= sf_empty; +-- elsif (read_size = 0) then +-- debug(84) <= sf_empty; +-- end if; +-- end if; +-- end process dbg_empty_proc; +-- +-- debug(95 downto 85) <= (others => '0'); +-- +-- dbg_inc_ctr_proc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- debug(127 downto 96) <= (others => '1'); +-- elsif (saveCurrentState = SCLOSE) then +-- debug(127 downto 96) <= inc_data_ctr; +-- end if; +-- end if; +-- end process dbg_inc_ctr_proc; +-- +-- debug(143 downto 128) <= dropped_sm_events_ctr(15 downto 0); +-- debug(159 downto 144) <= dropped_lr_events_ctr(15 downto 0); +-- +-- debug(175 downto 160) <= headers_invalid_ctr(15 downto 0); +-- debug(191 downto 176) <= (others => '0'); +-- +-- dbg_cts_q_proc : process(CLK) +-- begin +-- if rising_edge(CLK) then +-- if (RESET = '1') then +-- cts_len_q <= (others => '0'); +-- cts_rnd_q <= (others => '0'); +-- cts_trg_q <= (others => '0'); +-- cts_addr_q <= (others => '0'); +-- elsif (cts_len_saved = '1') then +-- cts_len_q <= cts_len(16 downto 1); +-- cts_addr_q <= cts_addr; +-- cts_rnd_q <= cts_rnd; +-- cts_trg_q <= cts_trg; +-- end if; +-- end if; +-- end process dbg_cts_q_proc; +-- +-- debug(207 downto 192) <= cts_trg_q; +-- debug(223 downto 208) <= cts_rnd_q; +-- debug(239 downto 224) <= cts_addr_q; +-- debug(255 downto 240) <= cts_len_q; +-- debug(271 downto 256) <= first_run_trg; +-- debug(287 downto 272) <= first_run_addr; +-- +-- debug(303 downto 288) <= saved_events_ctr; +-- debug(319 downto 304) <= loaded_events_ctr; +-- +-- debug(335 downto 320) <= constr_events_ctr(15 downto 0); +-- debug(351 downto 336) <= dropped_ctr(15 downto 0); +-- +-- debug(367 downto 352) <= invalid_hsize_ctr; +-- debug(383 downto 368) <= (others => '0'); +-- +-- MONITOR_OUT(31 downto 0) <= constr_events_ctr; +-- MONITOR_OUT(63 downto 32) <= dropped_ctr; +-- MONITOR_OUT(95 downto 64) <= headers_invalid_ctr; +-- MONITOR_OUT(127 downto 96) <= dropped_sm_events_ctr; +-- MONITOR_OUT(159 downto 128) <= dropped_lr_events_ctr; +-- MONITOR_OUT(163 downto 160) <= b"1111" when (sf_afull = '1') else b"0000"; +-- MONITOR_OUT(191 downto 164) <= (others => '0'); +-- MONITOR_OUT(223 downto 192) <= found_empty_evt_ctr; -- gk 01.10.10 + +-- Outputs +FEE_READ_OUT <= fee_read; +CTS_ERROR_PATTERN_OUT <= cts_error_pattern; +CTS_DATA_OUT <= cts_data; +CTS_DATAREADY_OUT <= cts_dataready; +CTS_READOUT_FINISHED_OUT <= cts_readout_finished; +CTS_LENGTH_OUT <= cts_length; + +PC_SOS_OUT <= pc_sos; +PC_EOD_OUT <= '1' when ((MULT_EVT_ENABLE_IN = '0') and (pc_eod = '1')) + or ((MULT_EVT_ENABLE_IN = '1') and (message_size + pc_sub_size >= MAX_MESSAGE_SIZE_IN) and (remove_done = '1')) + -- gk 07.12.10 + or ((MULT_EVT_ENABLE_IN = '1') and (prev_bank_select /= bank_select) and (remove_done = '1')) + else '0'; -- gk 07.10.10 +PC_DATA_OUT <= pc_data_q; +PC_WR_EN_OUT <= pc_wr_en_qq; + +PC_TRIG_NR_OUT <= readout_ctr(23 downto 16) & pc_trig_nr & trig_random; + +PC_SUB_SIZE_OUT <= b"0000_0000_0000_00" & pc_sub_size; +PC_PADDING_OUT <= padding_needed; + +DEBUG_OUT <= debug; + +end architecture; \ No newline at end of file diff --git a/gbe2_ecp3/trb_net16_lsm_sfp_gbe.vhd b/gbe2_ecp3/trb_net16_lsm_sfp_gbe.vhd new file mode 100755 index 0000000..7624a16 --- /dev/null +++ b/gbe2_ecp3/trb_net16_lsm_sfp_gbe.vhd @@ -0,0 +1,236 @@ +-- LinkStateMachine for SFPs (GigE) + +-- Still missing: link reset features, fifo full error handling, signals on stat_op +-- Take care: all input signals must be synchronous to SYSCLK, +-- all output signals are synchronous to SYSCLK. +-- Clock Domain Crossing is in your responsibility! + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.std_logic_ARITH.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +--use work.trb_net_std.all; + +entity trb_net16_lsm_sfp_gbe is +port( SYSCLK : in std_logic; -- fabric clock (100MHz) + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset, connect to '0' if not needed / available + -- status signals + SFP_MISSING_IN : in std_logic; -- SFP Missing ('1' = no SFP mounted, '0' = SFP in place) + SFP_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) + SD_LINK_OK_IN : in std_logic; -- SerDes Link OK ('0' = not linked, '1' link established) + SD_LOS_IN : in std_logic; -- SerDes Loss Of Signal ('0' = OK, '1' = signal lost) + SD_TXCLK_BAD_IN : in std_logic; -- SerDes Tx Clock locked ('0' = locked, '1' = not locked) + SD_RXCLK_BAD_IN : in std_logic; -- SerDes Rx Clock locked ('0' = locked, '1' = not locked) + -- control signals + FULL_RESET_OUT : out std_logic; -- full reset AKA quad_reset + LANE_RESET_OUT : out std_logic; -- partial reset AKA lane_reset + USER_RESET_OUT : out std_logic; -- FPGA reset for user logic + -- debug signals + TIMING_CTR_OUT : out std_logic_vector(18 downto 0); + BSM_OUT : out std_logic_vector(3 downto 0); + DEBUG_OUT : out std_logic_vector(31 downto 0) + ); +end entity; + +architecture lsm_sfp_gbe of trb_net16_lsm_sfp_gbe is + +-- state machine signals +type STATES is ( QRST, SLEEP, DELAY, USERRST, LINK ); +signal CURRENT_STATE, NEXT_STATE: STATES; + +signal state_bits : std_logic_vector(3 downto 0); +signal next_ce_tctr : std_logic; +signal ce_tctr : std_logic; +signal next_rst_tctr : std_logic; +signal rst_tctr : std_logic; +signal next_quad_rst : std_logic; +signal quad_rst : std_logic; +signal next_lane_rst : std_logic; +signal lane_rst : std_logic; +signal next_user_rst : std_logic; +signal user_rst : std_logic; +signal sfp_missing_q : std_logic; +signal sfp_missing_qq : std_logic; +signal sfp_los_q : std_logic; +signal sfp_los_qq : std_logic; +signal sd_rxclk_bad_q : std_logic; +signal sd_rxclk_bad_qq : std_logic; +signal sd_rxclk_bad_qqq : std_logic; +signal sd_txclk_bad_q : std_logic; +signal sd_txclk_bad_qq : std_logic; +signal sd_txclk_bad_qqq : std_logic; +signal sd_rxclk_warn_comb : std_logic; +signal sd_rxclk_warn : std_logic; -- rising edge on rlol detected +signal sd_txclk_warn_comb : std_logic; +signal sd_txclk_warn : std_logic; -- rising edge on plol detected +signal timing_ctr : std_logic_vector(18 downto 0); +signal debug : std_logic_vector(31 downto 0); + +begin + +-- Debug signals +debug(31 downto 4) <= (others => '0'); +debug(3) <= sd_txclk_warn; +debug(2) <= sd_rxclk_warn; +debug(1) <= rst_tctr; +debug(0) <= ce_tctr; + +-- synchronize external signals from SFP +THE_SYNC_PROC: process( sysclk ) +begin + if( rising_edge(sysclk) ) then + -- SFP input signals + sfp_missing_qq <= sfp_missing_q; + sfp_missing_q <= sfp_missing_in; + sfp_los_qq <= sfp_los_q; + sfp_los_q <= sfp_los_in; + -- SerDes input signals + sd_rxclk_bad_qqq <= sd_rxclk_bad_qq; + sd_rxclk_bad_qq <= sd_rxclk_bad_q; + sd_rxclk_bad_q <= sd_rxclk_bad_in; + sd_txclk_bad_qqq <= sd_txclk_bad_q; + sd_txclk_bad_qq <= sd_txclk_bad_q; + sd_txclk_bad_q <= sd_txclk_bad_in; + -- edge detectors + sd_rxclk_warn <= sd_rxclk_warn_comb; + sd_txclk_warn <= sd_txclk_warn_comb; + end if; +end process THE_SYNC_PROC; + +-- combinatorial part of edge detectors (rlol, see remark on page 8-63 in HB1003.pdf) +sd_rxclk_warn_comb <= '1' when ( (sd_rxclk_bad_qqq = '0') and (sd_rxclk_bad_qq = '1') ) else '0'; +sd_txclk_warn_comb <= '1' when ( (sd_txclk_bad_qqq = '0') and (sd_txclk_bad_qq = '1') ) else '0'; + +-------------------------------------------------------------------------- +-- Main control state machine, startup control for SFP +-------------------------------------------------------------------------- + +-- Timing counter for reset sequencing +THE_TIMING_COUNTER_PROC: process( sysclk, clear ) +begin + if( clear = '1' ) then + timing_ctr <= (others => '0'); + elsif( rising_edge(sysclk) ) then + if ( (rst_tctr = '1') or (sd_rxclk_warn = '1') or (sd_txclk_warn = '1') ) then + timing_ctr <= (others => '0'); + elsif( ce_tctr = '1' ) then + timing_ctr <= timing_ctr + 1; + end if; + end if; +end process THE_TIMING_COUNTER_PROC; + +-- State machine +-- state registers +STATE_MEM: process( sysclk, clear ) +begin + if( clear = '1' ) then + CURRENT_STATE <= QRST; + ce_tctr <= '0'; + rst_tctr <= '0'; + quad_rst <= '1'; + lane_rst <= '1'; + user_rst <= '1'; + elsif( rising_edge(sysclk) ) then + CURRENT_STATE <= NEXT_STATE; + ce_tctr <= next_ce_tctr; + rst_tctr <= next_rst_tctr; + quad_rst <= next_quad_rst; + lane_rst <= next_lane_rst; + user_rst <= next_user_rst; + end if; +end process STATE_MEM; + +-- state transitions +PROC_STATE_TRANSFORM: process( CURRENT_STATE, sfp_missing_qq, sfp_los_qq, sd_txclk_bad_qqq, sd_rxclk_bad_qqq, + timing_ctr(8), timing_ctr(18), timing_ctr(17), + reset ) +begin + NEXT_STATE <= QRST; -- avoid latches + next_ce_tctr <= '0'; + next_rst_tctr <= '0'; + next_quad_rst <= '0'; + next_lane_rst <= '0'; + next_user_rst <= '0'; + case CURRENT_STATE is + when QRST => -- initial state, we stay there unless CLEAR is deasserted. + state_bits <= x"0"; + if( (timing_ctr(8) = '1') ) then + NEXT_STATE <= SLEEP; -- release QUAD_RST, wait for lock of RxClock and TxClock + next_lane_rst <= '1'; + next_user_rst <= '1'; + next_rst_tctr <= '1'; + else + NEXT_STATE <= QRST; -- count delay + next_ce_tctr <= '1'; + next_quad_rst <= '1'; + next_lane_rst <= '1'; + next_user_rst <= '1'; + end if; + when SLEEP => -- we check for SFP presence and signal + state_bits <= x"1"; + if( (sfp_missing_qq = '0') and (sfp_los_qq = '0') ) then + NEXT_STATE <= DELAY; -- do a correctly timed QUAD reset (about 150ns) + next_ce_tctr <= '1'; + next_lane_rst <= '1'; + next_user_rst <= '1'; + else + NEXT_STATE <= SLEEP; -- wait for SFP present signal + next_lane_rst <= '1'; + next_user_rst <= '1'; + end if; + when DELAY => -- we wait approx. 4ms and check for PLL lock in the SerDes + state_bits <= x"2"; + if( (timing_ctr(18) = '1') and (timing_ctr(17) = '1') and (sd_rxclk_bad_qqq = '0') and (sd_txclk_bad_qqq = '0') ) then + NEXT_STATE <= USERRST; -- we release lane reset + next_ce_tctr <= '1'; + next_user_rst <= '1'; + else + NEXT_STATE <= DELAY; + next_ce_tctr <= '1'; + next_lane_rst <= '1'; + next_user_rst <= '1'; + end if; + when USERRST => -- short delay for user reset + state_bits <= x"3"; + if( (timing_ctr(18) = '0') and (timing_ctr(17) = '0') ) then + NEXT_STATE <= LINK; + next_rst_tctr <= '1'; + else + NEXT_STATE <= USERRST; + next_ce_tctr <= '1'; + next_user_rst <= '1'; + end if; + when LINK => -- operational + state_bits <= x"4"; + NEXT_STATE <= LINK; + when others => + NEXT_STATE <= QRST; + end case; + + -- emergency jumps in case of SFP problems + if( ((sfp_missing_qq = '1') or (sfp_los_qq = '1') or (RESET = '1')) and CURRENT_STATE /= QRST ) then + NEXT_STATE <= SLEEP; -- wait for SFP present signal + next_rst_tctr <= '1'; + next_lane_rst <= '1'; + next_user_rst <= '1'; + end if; +end process; + +-------------------------------------------------------------------------- +-- Output signals +-------------------------------------------------------------------------- +full_reset_out <= quad_rst; +lane_reset_out <= lane_rst; +user_reset_out <= user_rst; + +-------------------------------------------------------------------------- +-- Debug output +-------------------------------------------------------------------------- +timing_ctr_out <= timing_ctr; +bsm_out <= state_bits; +debug_out <= debug; + +end architecture; \ No newline at end of file diff --git a/gbe2_ecp3/trb_net16_med_ecp_sfp_gbe_8b.vhd b/gbe2_ecp3/trb_net16_med_ecp_sfp_gbe_8b.vhd new file mode 100755 index 0000000..e8b886a --- /dev/null +++ b/gbe2_ecp3/trb_net16_med_ecp_sfp_gbe_8b.vhd @@ -0,0 +1,532 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.std_logic_ARITH.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; + +use work.trb_net_gbe_components.all; + +entity trb_net16_med_ecp_sfp_gbe_8b is +-- gk 28.04.10 +generic ( + USE_125MHZ_EXTCLK : integer range 0 to 1 := 1 +); +port( + RESET : in std_logic; + GSR_N : in std_logic; + CLK_125_OUT : out std_logic; + CLK_125_IN : in std_logic; -- gk 28.04.10 used when intclk + CLK_125_RX_OUT : out std_logic; + --SGMII connection to frame transmitter (tsmac) + FT_TX_CLK_EN_OUT : out std_logic; + FT_RX_CLK_EN_OUT : out std_logic; + FT_COL_OUT : out std_logic; + FT_CRS_OUT : out std_logic; + FT_TXD_IN : in std_logic_vector(7 downto 0); + FT_TX_EN_IN : in std_logic; + FT_TX_ER_IN : in std_logic; + + FT_RXD_OUT : out std_logic_vector(7 downto 0); + FT_RX_EN_OUT : out std_logic; + FT_RX_ER_OUT : out std_logic; + --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; -- SFP disable + -- Autonegotiation stuff + MR_RESET_IN : in std_logic; + MR_MODE_IN : in std_logic; + MR_ADV_ABILITY_IN : in std_logic_vector(15 downto 0); -- should be x"0020 + MR_AN_LP_ABILITY_OUT : out std_logic_vector(15 downto 0); -- advert page from link partner + MR_AN_PAGE_RX_OUT : out std_logic; + MR_AN_COMPLETE_OUT : out std_logic; + MR_AN_ENABLE_IN : in std_logic; + MR_RESTART_AN_IN : in std_logic; + -- 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 entity; + +architecture trb_net16_med_ecp_sfp_gbe_8b of trb_net16_med_ecp_sfp_gbe_8b is + +-- Placer Directives +--attribute HGROUP : string; +-- for whole architecture +--attribute HGROUP of trb_net16_med_ecp_sfp_gbe_8b : architecture is "media_interface_group"; +attribute syn_sharing : string; +attribute syn_sharing of trb_net16_med_ecp_sfp_gbe_8b : architecture is "off"; + +component serdes_gbe_0_extclock_8b is +GENERIC (USER_CONFIG_FILE : String := "serdes_gbe_0_extclock_8b.txt"); +port( refclkp : in std_logic; + refclkn : in std_logic; + hdinp0 : in std_logic; + hdinn0 : in std_logic; + hdoutp0 : out std_logic; + hdoutn0 : out std_logic; + ff_rxiclk_ch0 : in std_logic; + ff_txiclk_ch0 : in std_logic; + ff_ebrd_clk_0 : in std_logic; + ff_txdata_ch0 : in std_logic_vector (7 downto 0); + ff_rxdata_ch0 : out std_logic_vector (7 downto 0); + ff_tx_k_cntrl_ch0 : in std_logic; + ff_rx_k_cntrl_ch0 : out std_logic; + ff_rxfullclk_ch0 : out std_logic; + ff_xmit_ch0 : in std_logic; + ff_correct_disp_ch0 : in std_logic; + ff_disp_err_ch0 : out std_logic; + ff_cv_ch0 : out std_logic; + ff_rx_even_ch0 : out std_logic; + ffc_rrst_ch0 : in std_logic; + ffc_lane_tx_rst_ch0 : in std_logic; + ffc_lane_rx_rst_ch0 : in std_logic; + ffc_txpwdnb_ch0 : in std_logic; + ffc_rxpwdnb_ch0 : in std_logic; + ffs_rlos_lo_ch0 : out std_logic; + ffs_ls_sync_status_ch0 : out std_logic; + ffs_rlol_ch0 : out std_logic; + oob_out_ch0 : out std_logic; + ffc_macro_rst : in std_logic; + ffc_quad_rst : in std_logic; + ffc_trst : in std_logic; + ff_txfullclk : out std_logic; + ff_txhalfclk : out std_logic; + refck2core : out std_logic; + ffs_plol : out std_logic + ); +end component; + +component serdes_gbe_0_intclock_8b is + GENERIC (USER_CONFIG_FILE : String := "serdes_gbe_0_intclock_8b.txt"); + port ( + core_txrefclk : in std_logic; + core_rxrefclk : in std_logic; + hdinp0, hdinn0 : in std_logic; + hdoutp0, hdoutn0 : out std_logic; + ff_rxiclk_ch0, ff_txiclk_ch0, ff_ebrd_clk_0 : in std_logic; + ff_txdata_ch0 : in std_logic_vector (7 downto 0); + ff_rxdata_ch0 : out std_logic_vector (7 downto 0); + ff_tx_k_cntrl_ch0 : in std_logic; + ff_rx_k_cntrl_ch0 : out std_logic; + ff_rxfullclk_ch0 : out std_logic; + ff_xmit_ch0 : in std_logic; + ff_correct_disp_ch0 : in std_logic; + ff_disp_err_ch0, ff_cv_ch0 : out std_logic; + ff_rx_even_ch0 : out std_logic; + ffc_rrst_ch0 : in std_logic; + ffc_lane_tx_rst_ch0 : in std_logic; + ffc_lane_rx_rst_ch0 : in std_logic; + ffc_txpwdnb_ch0 : in std_logic; + ffc_rxpwdnb_ch0 : in std_logic; + ffs_rlos_lo_ch0 : out std_logic; + ffs_ls_sync_status_ch0 : out std_logic; + ffs_rlol_ch0 : out std_logic; + oob_out_ch0 : out std_logic; + ffc_macro_rst : in std_logic; + ffc_quad_rst : in std_logic; + ffc_trst : in std_logic; + ff_txfullclk : out std_logic; + ff_txhalfclk : out std_logic; + ffs_plol : out std_logic); + +end component; + +component sgmii_gbe_pcs34 +port( rst_n : in std_logic; + signal_detect : in std_logic; + gbe_mode : in std_logic; + sgmii_mode : in std_logic; + operational_rate : in std_logic_vector(1 downto 0); + debug_link_timer_short : in std_logic; + rx_compensation_err : out std_logic; + tx_clk_125 : in std_logic; + tx_clock_enable_source : out std_logic; + tx_clock_enable_sink : in std_logic; + tx_d : in std_logic_vector(7 downto 0); + tx_en : in std_logic; + tx_er : in std_logic; + rx_clk_125 : in std_logic; + rx_clock_enable_source : out std_logic; + rx_clock_enable_sink : in std_logic; + rx_d : out std_logic_vector(7 downto 0); + rx_dv : out std_logic; + rx_er : out std_logic; + col : out std_logic; + crs : out std_logic; + tx_data : out std_logic_vector(7 downto 0); + tx_kcntl : out std_logic; + tx_disparity_cntl : out std_logic; + serdes_recovered_clk : in std_logic; + rx_data : in std_logic_vector(7 downto 0); + rx_even : in std_logic; + rx_kcntl : in std_logic; + rx_disp_err : in std_logic; + rx_cv_err : in std_logic; + rx_err_decode_mode : in std_logic; + mr_an_complete : out std_logic; + mr_page_rx : out std_logic; + mr_lp_adv_ability : out std_logic_vector(15 downto 0); + mr_main_reset : in std_logic; + mr_an_enable : in std_logic; + mr_restart_an : in std_logic; + mr_adv_ability : in std_logic_vector(15 downto 0) + ); +end component; + +component trb_net16_lsm_sfp_gbe is +port( SYSCLK : in std_logic; -- fabric clock (100MHz) + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset, connect to '0' if not needed / available + -- status signals + SFP_MISSING_IN : in std_logic; -- SFP Missing ('1' = no SFP mounted, '0' = SFP in place) + SFP_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) + SD_LINK_OK_IN : in std_logic; -- SerDes Link OK ('0' = not linked, '1' link established) + SD_LOS_IN : in std_logic; -- SerDes Loss Of Signal ('0' = OK, '1' = signal lost) + SD_TXCLK_BAD_IN : in std_logic; -- SerDes Tx Clock locked ('0' = locked, '1' = not locked) + SD_RXCLK_BAD_IN : in std_logic; -- SerDes Rx Clock locked ('0' = locked, '1' = not locked) + -- control signals + FULL_RESET_OUT : out std_logic; -- full reset AKA quad_reset + LANE_RESET_OUT : out std_logic; -- partial reset AKA lane_reset + USER_RESET_OUT : out std_logic; -- FPGA reset for user logic + -- debug signals + TIMING_CTR_OUT : out std_logic_vector(18 downto 0); + BSM_OUT : out std_logic_vector(3 downto 0); + DEBUG_OUT : out std_logic_vector(31 downto 0) + ); +end component; + +signal refclkcore : std_logic; + +signal sd_link_ok : std_logic; +signal sd_link_error : std_logic_vector(2 downto 0); + +signal sd_tx_data : std_logic_vector(7 downto 0); +signal sd_tx_kcntl : std_logic; +signal sd_tx_correct_disp : std_logic; +signal sd_tx_clk : std_logic; + +signal sd_rx_data : std_logic_vector(7 downto 0); +signal sd_rx_even : std_logic; +signal sd_rx_kcntl : std_logic; +signal sd_rx_disp_error : std_logic; +signal sd_rx_cv_error : std_logic; +signal sd_rx_clk : std_logic; + +signal pcs_mr_an_complete : std_logic; +signal pcs_mr_ability : std_logic_vector(15 downto 0); +signal pcs_mr_page_rx : std_logic; +signal pcs_mr_reset : std_logic; + +signal pcs_tx_clk_en : std_logic; +signal pcs_rx_clk_en : std_logic; +signal pcs_rx_comp_err : std_logic; + +signal pcs_rx_d : std_logic_vector(7 downto 0); +signal pcs_rx_dv : std_logic; +signal pcs_rx_er : std_logic; + +signal sd_rx_debug : std_logic_vector(15 downto 0); +signal sd_tx_debug : std_logic_vector(15 downto 0); + +signal buf_stat_debug : std_logic_vector(63 downto 0); + +signal quad_rst : std_logic; +signal lane_rst : std_logic; +signal user_rst : std_logic; + +signal reset_bsm : std_logic_vector(3 downto 0); +signal reset_debug : std_logic_vector(31 downto 0); +signal test_clk : std_logic; + + + + attribute syn_keep : boolean; + attribute syn_preserve : boolean; + + attribute syn_keep of sd_tx_clk : signal is true; + attribute syn_preserve of sd_tx_clk : signal is true; + attribute syn_keep of sd_rx_clk : signal is true; + attribute syn_preserve of sd_rx_clk : signal is true; + +begin + +-- Reset state machine for SerDes +THE_RESET_STATEMACHINE: trb_net16_lsm_sfp_gbe +port map( + SYSCLK => CLK_125_IN, + RESET => '0', -- really? + CLEAR => RESET, -- from 100MHz PLL, includes async part + -- status signals + SFP_MISSING_IN => SD_PRSNT_N_IN, + SFP_LOS_IN => SD_LOS_IN, + SD_LINK_OK_IN => '1', -- not used + SD_LOS_IN => '0', -- not used + SD_TXCLK_BAD_IN => sd_link_error(2), -- plol + SD_RXCLK_BAD_IN => sd_link_error(1), -- rlol + -- control signals + FULL_RESET_OUT => quad_rst, + LANE_RESET_OUT => lane_rst, + USER_RESET_OUT => user_rst, + -- debug signals + TIMING_CTR_OUT => open, + BSM_OUT => reset_bsm, + DEBUG_OUT => reset_debug +); + +-- gk 28.04.10 +-- SerDes for GbE +clk_int : if (USE_125MHZ_EXTCLK = 0) generate + + refclkcore <= sd_tx_clk; --CLK_125_IN; + +-- SERDES_GBE : serdes_gbe_0_intclock_8b +-- port map( +-- core_txrefclk => CLK_125_IN, +-- core_rxrefclk => CLK_125_IN, +-- hdinp0 => SD_RXD_P_IN, +-- hdinn0 => SD_RXD_N_IN, +-- hdoutp0 => SD_TXD_P_OUT, +-- hdoutn0 => SD_TXD_N_OUT, +-- ff_rxiclk_ch0 => sd_rx_clk, +-- ff_txiclk_ch0 => sd_tx_clk, +-- ff_ebrd_clk_0 => sd_rx_clk, +-- ff_txdata_ch0 => sd_tx_data, +-- ff_rxdata_ch0 => sd_rx_data, +-- ff_tx_k_cntrl_ch0 => sd_tx_kcntl, +-- ff_rx_k_cntrl_ch0 => sd_rx_kcntl, +-- ff_rxfullclk_ch0 => sd_rx_clk, +-- ff_xmit_ch0 => '0', +-- ff_correct_disp_ch0 => sd_tx_correct_disp, +-- ff_disp_err_ch0 => sd_rx_disp_error, +-- ff_cv_ch0 => sd_rx_cv_error, +-- ff_rx_even_ch0 => sd_rx_even, +-- ffc_rrst_ch0 => '0', +-- ffc_lane_tx_rst_ch0 => lane_rst, +-- ffc_lane_rx_rst_ch0 => lane_rst, +-- ffc_txpwdnb_ch0 => '1', +-- ffc_rxpwdnb_ch0 => '1', +-- ffs_rlos_lo_ch0 => sd_link_error(0), +-- ffs_ls_sync_status_ch0 => sd_link_ok, +-- ffs_rlol_ch0 => sd_link_error(1), +-- oob_out_ch0 => open, +-- ffc_macro_rst => '0', +-- ffc_quad_rst => quad_rst, +-- ffc_trst => '0', +-- ff_txfullclk => sd_tx_clk, +-- ff_txhalfclk => open, +-- ffs_plol => sd_link_error(2) +-- ); + + SERDES_GBE : serdes_gbe_0_intclock_8b_ecp3 + port map( + ------------------ + -- CH0 -- + hdinp_ch0 => SD_RXD_P_IN, + hdinn_ch0 => SD_RXD_N_IN, + hdoutp_ch0 => SD_TXD_P_OUT, + hdoutn_ch0 => SD_TXD_N_OUT, + rxiclk_ch0 => sd_rx_clk, + txiclk_ch0 => sd_tx_clk, + rx_full_clk_ch0 => sd_rx_clk, + rx_half_clk_ch0 => open, + tx_full_clk_ch0 => sd_tx_clk, + tx_half_clk_ch0 => open, + fpga_rxrefclk_ch0 => CLK_125_IN, + txdata_ch0 => sd_tx_data, + tx_k_ch0 => sd_tx_kcntl, + xmit_ch0 => '0', + tx_disp_correct_ch0 => sd_tx_correct_disp, + rxdata_ch0 => sd_rx_data, + rx_k_ch0 => sd_rx_kcntl, + rx_disp_err_ch0 => sd_rx_disp_error, + rx_cv_err_ch0 => sd_rx_cv_error, + --rx_serdes_rst_ch0_c => lane_rst, + sb_felb_ch0_c => '0', + sb_felb_rst_ch0_c => '0', +-- tx_pcs_rst_ch0_c => lane_rst, + tx_pwrup_ch0_c => '1', + --rx_pcs_rst_ch0_c => lane_rst, + rx_pwrup_ch0_c => '1', + rx_los_low_ch0_s => sd_link_error(0), + lsm_status_ch0_s => sd_link_ok, + rx_cdr_lol_ch0_s => sd_link_error(1), + -- CH1 -- + -- CH2 -- + -- CH3 -- + ---- Miscillaneous ports + fpga_txrefclk => CLK_125_IN, + tx_serdes_rst_c => RESET, + tx_pll_lol_qd_s => sd_link_error(2), + refclk2fpga => open, + rst_n => '1', + serdes_rst_qd_c => quad_rst + ); + + +end generate clk_int; + +clk_ext : if (USE_125MHZ_EXTCLK = 1) generate + SERDES_GBE : serdes_gbe_0_extclock_8b + port map( -- SerDes connection to outside world + refclkp => SD_REFCLK_P_IN, -- SerDes REFCLK diff. input + refclkn => SD_REFCLK_N_IN, + hdinp0 => SD_RXD_P_IN, -- SerDes RX diff. input + hdinn0 => SD_RXD_N_IN, + hdoutp0 => SD_TXD_P_OUT, -- SerDes TX diff. output + hdoutn0 => SD_TXD_N_OUT, + refck2core => refclkcore, -- reference clock from input + -- RX part + ff_rxfullclk_ch0 => sd_rx_clk, -- RX full clock output + ff_rxiclk_ch0 => sd_rx_clk, + ff_ebrd_clk_0 => sd_rx_clk, -- EB ist not used as recommended by Lattice + ff_rxdata_ch0 => sd_rx_data, -- RX data output + ff_rx_k_cntrl_ch0 => sd_rx_kcntl, -- RX komma output + ff_rx_even_ch0 => sd_rx_even, -- for autonegotiation (output) + ff_disp_err_ch0 => sd_rx_disp_error, -- RX disparity error + ff_cv_ch0 => sd_rx_cv_error, -- RX code violation error + -- TX part + ff_txfullclk => sd_tx_clk, -- TX full clock output + ff_txiclk_ch0 => sd_tx_clk, + ff_txhalfclk => open, + ff_txdata_ch0 => sd_tx_data, -- TX data input + ff_tx_k_cntrl_ch0 => sd_tx_kcntl, -- TX komma input + ff_xmit_ch0 => '0', -- for autonegotiation (input) + ff_correct_disp_ch0 => sd_tx_correct_disp, -- controls disparity at IPG start (input) + -- Resets and power down + ffc_quad_rst => quad_rst, -- async reset for whole QUAD (active high) + ffc_lane_tx_rst_ch0 => lane_rst, -- async reset for TX channel + ffc_lane_rx_rst_ch0 => lane_rst, -- async reset for RX channel + ffc_rrst_ch0 => '0', -- '0' for normal operation + ffc_macro_rst => '0', -- '0' for normal operation + ffc_trst => '0', -- '0' for normal operation + ffc_txpwdnb_ch0 => '1', -- must be '1' + ffc_rxpwdnb_ch0 => '1', -- must be '1' + -- Status outputs + ffs_ls_sync_status_ch0 => sd_link_ok, -- synced to kommas? + ffs_rlos_lo_ch0 => sd_link_error(0), -- loss of signal in RX channel + ffs_rlol_ch0 => sd_link_error(1), -- loss of lock in RX PLL + ffs_plol => sd_link_error(2), -- loss of lock in TX PLL + oob_out_ch0 => open -- not needed + ); +end generate clk_ext; + +SD_RX_DATA_PROC: process( sd_rx_clk ) +begin + if( rising_edge(sd_rx_clk) ) then + sd_rx_debug(15 downto 12) <= (others => '0'); + sd_rx_debug(11) <= sd_rx_disp_error; + sd_rx_debug(10) <= sd_rx_even; + sd_rx_debug(9) <= sd_rx_cv_error; + sd_rx_debug(8) <= sd_rx_kcntl; + sd_rx_debug(7 downto 0) <= sd_rx_data; + end if; +end process SD_RX_DATA_PROC; + +SD_TX_DATA_PROC: process( sd_tx_clk ) +begin + if( rising_edge(sd_tx_clk) ) then + sd_tx_debug(15 downto 10) <= (others => '0'); + sd_tx_debug(9) <= sd_tx_correct_disp; + sd_tx_debug(8) <= sd_tx_kcntl; + sd_tx_debug(7 downto 0) <= sd_tx_data; + end if; +end process SD_TX_DATA_PROC; + +buf_stat_debug(63 downto 40) <= (others => '0'); +buf_stat_debug(39 downto 36) <= reset_debug(3 downto 0); +buf_stat_debug(35 downto 32) <= reset_bsm; +-- logic analyzer signals +buf_stat_debug(31) <= pcs_mr_page_rx; +buf_stat_debug(30) <= pcs_mr_reset; --pcs_mr_an_complete; +buf_stat_debug(28 downto 26) <= reset_bsm(2 downto 0); +buf_stat_debug(25 downto 23) <= sd_link_error(2 downto 0); +buf_stat_debug(22) <= sd_link_ok; +buf_stat_debug(21 downto 12) <= sd_tx_debug(9 downto 0); +buf_stat_debug(11 downto 0) <= sd_rx_debug(11 downto 0); + + +SGMII_GBE_PCS : sgmii_gbe_pcs34 +port map( + rst_n => GSR_N, + signal_detect => sd_link_ok, + gbe_mode => '1', + sgmii_mode => MR_MODE_IN, + operational_rate => "10", + debug_link_timer_short => '0', + rx_compensation_err => pcs_rx_comp_err, + -- MAC interface + tx_clk_125 => refclkcore, -- original clock from SerDes + tx_clock_enable_source => pcs_tx_clk_en, + tx_clock_enable_sink => pcs_tx_clk_en, + tx_d => FT_TXD_IN, -- TX data from MAC + tx_en => FT_TX_EN_IN, -- TX data enable from MAC + tx_er => FT_TX_ER_IN, -- TX error from MAC + rx_clk_125 => refclkcore, -- original clock from SerDes + rx_clock_enable_source => pcs_rx_clk_en, + rx_clock_enable_sink => pcs_rx_clk_en, + rx_d => pcs_rx_d, -- RX data to MAC + rx_dv => pcs_rx_dv, -- RX data enable to MAC + rx_er => pcs_rx_er, -- RX error to MAC + col => FT_COL_OUT, + crs => FT_CRS_OUT, + -- SerDes interface + tx_data => sd_tx_data, -- TX data to SerDes + tx_kcntl => sd_tx_kcntl, -- TX komma control to SerDes + tx_disparity_cntl => sd_tx_correct_disp, -- idle parity state control in IPG (to SerDes) + serdes_recovered_clk => sd_rx_clk, -- 125MHz recovered from receive bit stream + rx_data => sd_rx_data, -- RX data from SerDes + rx_kcntl => sd_rx_kcntl, -- RX komma control from SerDes + rx_err_decode_mode => '0', -- receive error control mode fixed to normal + rx_even => '0', -- unused (receive error control mode = normal, tie to GND) + rx_disp_err => sd_rx_disp_error, -- RX disparity error from SerDes + rx_cv_err => sd_rx_cv_error, -- RX code violation error from SerDes + -- Autonegotiation stuff + mr_an_complete => pcs_mr_an_complete, + mr_page_rx => pcs_mr_page_rx, + mr_lp_adv_ability => pcs_mr_ability, + mr_main_reset => pcs_mr_reset, + mr_an_enable => MR_AN_ENABLE_IN, + mr_restart_an => MR_RESTART_AN_IN, + mr_adv_ability => MR_ADV_ABILITY_IN +); + +SYNC_RX_PROC : process(sd_rx_clk) +begin + if rising_edge(sd_rx_clk) then + FT_RXD_OUT <= pcs_rx_d; + FT_RX_EN_OUT <= pcs_rx_dv; + FT_RX_ER_OUT <= pcs_rx_er; + end if; +end process SYNC_RX_PROC; + +pcs_mr_reset <= MR_RESET_IN or RESET or user_rst; + +FT_TX_CLK_EN_OUT <= pcs_tx_clk_en; -- to MAC +FT_RX_CLK_EN_OUT <= pcs_rx_clk_en; -- to MAC + +MR_AN_LP_ABILITY_OUT <= pcs_mr_ability; +MR_AN_COMPLETE_OUT <= pcs_mr_an_complete; +MR_AN_PAGE_RX_OUT <= pcs_mr_page_rx; + +-- Clock games +CLK_125_OUT <= sd_tx_clk; +CLK_125_RX_OUT <= sd_rx_clk; + +-- Fakes +STAT_OP <= (others => '0'); +SD_TXDIS_OUT <= '0'; -- enable +STAT_DEBUG <= buf_stat_debug; + +end architecture; \ No newline at end of file diff --git a/gbe2_ecp3/trb_net_gbe_components.vhd b/gbe2_ecp3/trb_net_gbe_components.vhd new file mode 100644 index 0000000..5757f82 --- /dev/null +++ b/gbe2_ecp3/trb_net_gbe_components.vhd @@ -0,0 +1,861 @@ +library ieee; +use ieee.std_logic_1164.all; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; +library work; +use work.trb_net_std.all; + +use work.trb_net_gbe_protocols.all; + +package trb_net_gbe_components is + + +component trb_net16_gbe_buf is +generic( + DO_SIMULATION : integer range 0 to 1 := 1; + USE_125MHZ_EXTCLK : integer range 0 to 1 := 1 +); +port( + CLK : in std_logic; + TEST_CLK : in std_logic; -- only for simulation! + CLK_125_IN : in std_logic; -- gk 28.04.01 used only in internal 125MHz clock mode + RESET : in std_logic; + GSR_N : in std_logic; + -- Debug + STAGE_STAT_REGS_OUT : out std_logic_vector(31 downto 0); + STAGE_CTRL_REGS_IN : in std_logic_vector(31 downto 0); + -- configuration interface + IP_CFG_START_IN : in std_logic; + IP_CFG_BANK_SEL_IN : in std_logic_vector(3 downto 0); + IP_CFG_DONE_OUT : out std_logic; + IP_CFG_MEM_ADDR_OUT : out std_logic_vector(7 downto 0); + IP_CFG_MEM_DATA_IN : in std_logic_vector(31 downto 0); + IP_CFG_MEM_CLK_OUT : out std_logic; + MR_RESET_IN : in std_logic; + MR_MODE_IN : in std_logic; + MR_RESTART_IN : in std_logic; + -- gk 29.03.10 + SLV_ADDR_IN : in std_logic_vector(7 downto 0); + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_BUSY_OUT : out std_logic; + SLV_ACK_OUT : out std_logic; + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + -- gk 22.04.10 + -- registers setup interface + BUS_ADDR_IN : in std_logic_vector(7 downto 0); + BUS_DATA_IN : in std_logic_vector(31 downto 0); + BUS_DATA_OUT : out std_logic_vector(31 downto 0); -- gk 26.04.10 + BUS_WRITE_EN_IN : in std_logic; -- gk 26.04.10 + BUS_READ_EN_IN : in std_logic; -- gk 26.04.10 + BUS_ACK_OUT : out std_logic; -- gk 26.04.10 + -- gk 23.04.10 + LED_PACKET_SENT_OUT : out std_logic; + LED_AN_DONE_N_OUT : out std_logic; + -- CTS interface + CTS_NUMBER_IN : in std_logic_vector (15 downto 0); + CTS_CODE_IN : in std_logic_vector (7 downto 0); + CTS_INFORMATION_IN : in std_logic_vector (7 downto 0); + CTS_READOUT_TYPE_IN : in std_logic_vector (3 downto 0); + CTS_START_READOUT_IN : in std_logic; + CTS_DATA_OUT : out std_logic_vector (31 downto 0); + CTS_DATAREADY_OUT : out std_logic; + CTS_READOUT_FINISHED_OUT : out std_logic; + CTS_READ_IN : in std_logic; + CTS_LENGTH_OUT : out std_logic_vector (15 downto 0); + CTS_ERROR_PATTERN_OUT : out std_logic_vector (31 downto 0); + -- Data payload interface + FEE_DATA_IN : in std_logic_vector (15 downto 0); + FEE_DATAREADY_IN : in std_logic; + FEE_READ_OUT : out std_logic; + FEE_STATUS_BITS_IN : in std_logic_vector (31 downto 0); + FEE_BUSY_IN : in std_logic; + --SFP Connection + SFP_RXD_P_IN : in std_logic; + SFP_RXD_N_IN : in std_logic; + SFP_TXD_P_OUT : out std_logic; + SFP_TXD_N_OUT : out std_logic; + SFP_REFCLK_P_IN : in std_logic; + SFP_REFCLK_N_IN : in std_logic; + SFP_PRSNT_N_IN : in std_logic; -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) + SFP_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) + SFP_TXDIS_OUT : out std_logic; -- SFP disable + + -- for simulation of receiving part only + MAC_RX_EOF_IN : in std_logic; + MAC_RXD_IN : in std_logic_vector(7 downto 0); + MAC_RX_EN_IN : in std_logic; + + -- debug ports + ANALYZER_DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end component; + +component trb_net16_gbe_protocol_prioritizer is +port ( + CLK : in std_logic; + RESET : in std_logic; + + FRAME_TYPE_IN : in std_logic_vector(15 downto 0); -- recovered frame type + PROTOCOL_CODE_IN : in std_logic_vector(7 downto 0); -- ip protocol + UDP_PROTOCOL_IN : in std_logic_vector(15 downto 0); + + CODE_OUT : out std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0) +); +end component; + +component trb_net16_gbe_type_validator is +port ( + CLK : in std_logic; + RESET : in std_logic; + FRAME_TYPE_IN : in std_logic_vector(15 downto 0); -- recovered frame type + SAVED_VLAN_ID_IN : in std_logic_vector(15 downto 0); -- recovered vlan id + ALLOWED_TYPES_IN : in std_logic_vector(31 downto 0); -- signal from gbe_setup + VLAN_ID_IN : in std_logic_vector(31 downto 0); -- two values from gbe setup + + -- IP level + IP_PROTOCOLS_IN : in std_logic_vector(7 downto 0); + ALLOWED_IP_PROTOCOLS_IN : in std_logic_vector(31 downto 0); + + -- UDP level + UDP_PROTOCOL_IN : in std_logic_vector(15 downto 0); + ALLOWED_UDP_PROTOCOLS_IN : in std_logic_vector(31 downto 0); + + VALID_OUT : out std_logic +); +end component; + +component trb_net16_gbe_protocol_selector is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- signals to/from main controller + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_PROTO_SELECT_IN : in std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); + PS_BUSY_OUT : out std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); + PS_FRAME_SIZE_IN : in std_logic_vector(15 downto 0); + PS_RESPONSE_READY_OUT : out std_logic; + + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + +-- singals to/from transmi controller with constructed response + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_RD_EN_IN : in std_logic; + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + + TC_BUSY_IN : in std_logic; + + -- counters from response constructors + RECEIVED_FRAMES_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); + SENT_FRAMES_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); + PROTOS_DEBUG_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0); + + -- misc signals for response constructors + DHCP_START_IN : in std_logic; + DHCP_DONE_OUT : out std_logic; + + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end component; + +component trb_net16_gbe_mac_control is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- signals to/from main controller + MC_TSMAC_READY_OUT : out std_logic; + MC_RECONF_IN : in std_logic; + MC_GBE_EN_IN : in std_logic; + MC_RX_DISCARD_FCS : in std_logic; + MC_PROMISC_IN : in std_logic; + MC_MAC_ADDR_IN : in std_logic_vector(47 downto 0); + +-- signal to/from Host interface of TriSpeed MAC + TSM_HADDR_OUT : out std_logic_vector(7 downto 0); + TSM_HDATA_OUT : out std_logic_vector(7 downto 0); + TSM_HCS_N_OUT : out std_logic; + TSM_HWRITE_N_OUT : out std_logic; + TSM_HREAD_N_OUT : out std_logic; + TSM_HREADY_N_IN : in std_logic; + TSM_HDATA_EN_N_IN : in std_logic; + + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end component; + +component trb_net16_gbe_main_control is +port ( + CLK : in std_logic; -- system clock + CLK_125 : in std_logic; + RESET : in std_logic; + + MC_LINK_OK_OUT : out std_logic; + MC_RESET_LINK_IN : in std_logic; + +-- signals to/from receive controller + RC_FRAME_WAITING_IN : in std_logic; + RC_LOADING_DONE_OUT : out std_logic; + RC_DATA_IN : in std_logic_vector(8 downto 0); + RC_RD_EN_OUT : out std_logic; + RC_FRAME_SIZE_IN : in std_logic_vector(15 downto 0); + RC_FRAME_PROTO_IN : in std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); + + RC_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + RC_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + RC_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + RC_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + RC_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + RC_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + +-- signals to/from transmit controller + TC_TRANSMIT_CTRL_OUT : out std_logic; -- slow control frame is waiting to be built and sent + TC_TRANSMIT_DATA_OUT : out std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_RD_EN_IN : in std_logic; + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + + TC_BUSY_IN : in std_logic; + TC_TRANSMIT_DONE_IN : in std_logic; + +-- signals to/from packet constructor + PC_READY_IN : in std_logic; + PC_TRANSMIT_ON_IN : in std_logic; + PC_SOD_IN : in std_logic; + +-- signals to/from sgmii/gbe pcs_an_complete + PCS_AN_COMPLETE_IN : in std_logic; + +-- signals to/from hub + +-- signal to/from Host interface of TriSpeed MAC + TSM_HADDR_OUT : out std_logic_vector(7 downto 0); + TSM_HDATA_OUT : out std_logic_vector(7 downto 0); + TSM_HCS_N_OUT : out std_logic; + TSM_HWRITE_N_OUT : out std_logic; + TSM_HREAD_N_OUT : out std_logic; + TSM_HREADY_N_IN : in std_logic; + TSM_HDATA_EN_N_IN : in std_logic; + + + SELECT_REC_FRAMES_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); + SELECT_SENT_FRAMES_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); + SELECT_PROTOS_DEBUG_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0); + + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end component; + +component trb_net16_gbe_transmit_control is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- signals to/from packet constructor + PC_READY_IN : in std_logic; + PC_DATA_IN : in std_logic_vector(7 downto 0); + PC_WR_EN_IN : in std_logic; + PC_IP_SIZE_IN : in std_logic_vector(15 downto 0); + PC_UDP_SIZE_IN : in std_logic_vector(15 downto 0); + PC_FLAGS_OFFSET_IN : in std_logic_vector(15 downto 0); + PC_SOD_IN : in std_logic; + PC_EOD_IN : in std_logic; + PC_FC_READY_OUT : out std_logic; + PC_FC_H_READY_OUT : out std_logic; + PC_TRANSMIT_ON_IN : in std_logic; + + -- signals from ip_configurator used by packet constructor + IC_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + IC_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + IC_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + IC_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + IC_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + IC_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + +-- signal to/from main controller + MC_TRANSMIT_CTRL_IN : in std_logic; -- slow control frame is waiting to be built and sent + MC_TRANSMIT_DATA_IN : in std_logic; + MC_DATA_IN : in std_logic_vector(8 downto 0); + MC_RD_EN_OUT : out std_logic; + MC_FRAME_SIZE_IN : in std_logic_vector(15 downto 0); + MC_FRAME_TYPE_IN : in std_logic_vector(15 downto 0); + + MC_DEST_MAC_IN : in std_logic_vector(47 downto 0); + MC_DEST_IP_IN : in std_logic_vector(31 downto 0); + MC_DEST_UDP_IN : in std_logic_vector(15 downto 0); + MC_SRC_MAC_IN : in std_logic_vector(47 downto 0); + MC_SRC_IP_IN : in std_logic_vector(31 downto 0); + MC_SRC_UDP_IN : in std_logic_vector(15 downto 0); + + MC_IP_PROTOCOL_IN : in std_logic_vector(7 downto 0); + + MC_BUSY_OUT : out std_logic; + MC_TRANSMIT_DONE_OUT : out std_logic; + +-- signal to/from frame constructor + FC_DATA_OUT : out std_logic_vector(7 downto 0); + FC_WR_EN_OUT : out std_logic; + FC_READY_IN : in std_logic; + FC_H_READY_IN : in std_logic; + FC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + FC_IP_SIZE_OUT : out std_logic_vector(15 downto 0); + FC_UDP_SIZE_OUT : out std_logic_vector(15 downto 0); + FC_IDENT_OUT : out std_logic_vector(15 downto 0); -- internal packet counter + FC_FLAGS_OFFSET_OUT : out std_logic_vector(15 downto 0); + FC_SOD_OUT : out std_logic; + FC_EOD_OUT : out std_logic; + FC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + + DEST_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0); + DEST_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0); + DEST_UDP_PORT_OUT : out std_logic_vector(15 downto 0); + SRC_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0); + SRC_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0); + SRC_UDP_PORT_OUT : out std_logic_vector(15 downto 0); + + +-- debug + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end component; + +component trb_net16_gbe_receive_control is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- signals to/from frame_receiver + RC_DATA_IN : in std_logic_vector(8 downto 0); + FR_RD_EN_OUT : out std_logic; + FR_FRAME_VALID_IN : in std_logic; + FR_GET_FRAME_OUT : out std_logic; + FR_FRAME_SIZE_IN : in std_logic_vector(15 downto 0); + FR_FRAME_PROTO_IN : in std_logic_vector(15 downto 0); + FR_IP_PROTOCOL_IN : in std_logic_vector(7 downto 0); + + FR_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + FR_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + FR_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + FR_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + FR_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + FR_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + +-- signals to the rest of the logic + RC_RD_EN_IN : in std_logic; + RC_Q_OUT : out std_logic_vector(8 downto 0); + RC_FRAME_WAITING_OUT : out std_logic; + RC_LOADING_DONE_IN : in std_logic; + RC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + RC_FRAME_PROTO_OUT : out std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0); + + RC_SRC_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0); + RC_DEST_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0); + RC_SRC_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0); + RC_DEST_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0); + RC_SRC_UDP_PORT_OUT : out std_logic_vector(15 downto 0); + RC_DEST_UDP_PORT_OUT : out std_logic_vector(15 downto 0); + +-- statistics + FRAMES_RECEIVED_OUT : out std_logic_vector(31 downto 0); + BYTES_RECEIVED_OUT : out std_logic_vector(31 downto 0); + + + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end component; + +component trb_net16_gbe_frame_receiver is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + LINK_OK_IN : in std_logic; + ALLOW_RX_IN : in std_logic; + RX_MAC_CLK : in std_logic; -- receiver serdes clock + +-- input signals from TS_MAC + MAC_RX_EOF_IN : in std_logic; + MAC_RX_ER_IN : in std_logic; + MAC_RXD_IN : in std_logic_vector(7 downto 0); + MAC_RX_EN_IN : in std_logic; + MAC_RX_FIFO_ERR_IN : in std_logic; + MAC_RX_FIFO_FULL_OUT : out std_logic; + MAC_RX_STAT_EN_IN : in std_logic; + MAC_RX_STAT_VEC_IN : in std_logic_vector(31 downto 0); +-- output signal to control logic + FR_Q_OUT : out std_logic_vector(8 downto 0); + FR_RD_EN_IN : in std_logic; + FR_FRAME_VALID_OUT : out std_logic; + FR_GET_FRAME_IN : in std_logic; + FR_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + FR_FRAME_PROTO_OUT : out std_logic_vector(15 downto 0); + FR_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + FR_ALLOWED_TYPES_IN : in std_logic_vector(31 downto 0); + FR_ALLOWED_IP_IN : in std_logic_vector(31 downto 0); + FR_ALLOWED_UDP_IN : in std_logic_vector(31 downto 0); + FR_VLAN_ID_IN : in std_logic_vector(31 downto 0); + + FR_SRC_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0); + FR_DEST_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0); + FR_SRC_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0); + FR_DEST_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0); + FR_SRC_UDP_PORT_OUT : out std_logic_vector(15 downto 0); + FR_DEST_UDP_PORT_OUT : out std_logic_vector(15 downto 0); + + DEBUG_OUT : out std_logic_vector(95 downto 0) +); +end component; + +-- gk 01.07.10 +component trb_net16_ipu2gbe is +port( + CLK : in std_logic; + RESET : in std_logic; + -- IPU interface directed toward the CTS + CTS_NUMBER_IN : in std_logic_vector (15 downto 0); + CTS_CODE_IN : in std_logic_vector (7 downto 0); + CTS_INFORMATION_IN : in std_logic_vector (7 downto 0); + CTS_READOUT_TYPE_IN : in std_logic_vector (3 downto 0); + CTS_START_READOUT_IN : in std_logic; + CTS_READ_IN : in std_logic; + CTS_DATA_OUT : out std_logic_vector (31 downto 0); + CTS_DATAREADY_OUT : out std_logic; + CTS_READOUT_FINISHED_OUT : out std_logic; --no more data, end transfer, send TRM + CTS_LENGTH_OUT : out std_logic_vector (15 downto 0); + CTS_ERROR_PATTERN_OUT : out std_logic_vector (31 downto 0); + -- Data from Frontends + FEE_DATA_IN : in std_logic_vector (15 downto 0); + FEE_DATAREADY_IN : in std_logic; + FEE_READ_OUT : out std_logic; + FEE_BUSY_IN : in std_logic; + FEE_STATUS_BITS_IN : in std_logic_vector (31 downto 0); + -- slow control interface + START_CONFIG_OUT : out std_logic; -- reconfigure MACs/IPs/ports/packet size + BANK_SELECT_OUT : out std_logic_vector(3 downto 0); -- configuration page address + CONFIG_DONE_IN : in std_logic; -- configuration finished + DATA_GBE_ENABLE_IN : in std_logic; -- IPU data is forwarded to GbE + DATA_IPU_ENABLE_IN : in std_logic; -- IPU data is forwarded to CTS / TRBnet + MULT_EVT_ENABLE_IN : in std_logic; + MAX_MESSAGE_SIZE_IN : in std_logic_vector(31 downto 0); -- the maximum size of one HadesQueue -- gk 08.04.10 + MIN_MESSAGE_SIZE_IN : in std_logic_vector(31 downto 0); -- gk 20.07.10 + READOUT_CTR_IN : in std_logic_vector(23 downto 0); -- gk 26.04.10 + READOUT_CTR_VALID_IN : in std_logic; -- gk 26.04.10 + -- PacketConstructor interface + ALLOW_LARGE_IN : in std_logic; -- gk 21.07.10 + PC_WR_EN_OUT : out std_logic; + PC_DATA_OUT : out std_logic_vector (7 downto 0); + PC_READY_IN : in std_logic; + PC_SOS_OUT : out std_logic; + PC_EOS_OUT : out std_logic; -- gk 07.10.10 + PC_EOD_OUT : out std_logic; + PC_SUB_SIZE_OUT : out std_logic_vector(31 downto 0); + PC_TRIG_NR_OUT : out std_logic_vector(31 downto 0); + PC_PADDING_OUT : out std_logic; + MONITOR_OUT : out std_logic_vector(223 downto 0); + DEBUG_OUT : out std_logic_vector(383 downto 0) +); +end component; + +component trb_net16_gbe_packet_constr is +port( + RESET : in std_logic; + CLK : in std_logic; + MULT_EVT_ENABLE_IN : in std_logic; -- gk 06.10.10 + -- ports for user logic + PC_WR_EN_IN : in std_logic; -- write into queueConstr from userLogic + PC_DATA_IN : in std_logic_vector(7 downto 0); + PC_READY_OUT : out std_logic; + PC_START_OF_SUB_IN : in std_logic; + PC_END_OF_SUB_IN : in std_logic; -- gk 07.10.10 + PC_END_OF_DATA_IN : in std_logic; + PC_TRANSMIT_ON_OUT : out std_logic; + -- queue and subevent layer headers + PC_SUB_SIZE_IN : in std_logic_vector(31 downto 0); -- store and swap + PC_PADDING_IN : in std_logic; -- gk 29.03.10 + PC_DECODING_IN : in std_logic_vector(31 downto 0); -- swap + PC_EVENT_ID_IN : in std_logic_vector(31 downto 0); -- swap + PC_TRIG_NR_IN : in std_logic_vector(31 downto 0); -- store and swap! + PC_QUEUE_DEC_IN : in std_logic_vector(31 downto 0); -- swap + PC_MAX_FRAME_SIZE_IN : in std_logic_vector(15 downto 0); -- DO NOT SWAP + PC_DELAY_IN : in std_logic_vector(31 downto 0); -- gk 28.04.10 + -- FrameConstructor ports + TC_WR_EN_OUT : out std_logic; + TC_DATA_OUT : out std_logic_vector(7 downto 0); + TC_H_READY_IN : in std_logic; + TC_READY_IN : in std_logic; + TC_IP_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_UDP_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FLAGS_OFFSET_OUT : out std_logic_vector(15 downto 0); + TC_SOD_OUT : out std_logic; + TC_EOD_OUT : out std_logic; + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end component; + +component trb_net16_gbe_frame_constr is +port( + -- ports for user logic + RESET : in std_logic; + CLK : in std_logic; + LINK_OK_IN : in std_logic; -- gk 03.08.10 + -- + WR_EN_IN : in std_logic; + DATA_IN : in std_logic_vector(7 downto 0); + START_OF_DATA_IN : in std_logic; + END_OF_DATA_IN : in std_logic; + IP_F_SIZE_IN : in std_logic_vector(15 downto 0); + UDP_P_SIZE_IN : in std_logic_vector(15 downto 0); -- needed for fragmentation + HEADERS_READY_OUT : out std_logic; + READY_OUT : out std_logic; + DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + FRAME_TYPE_IN : in std_logic_vector(15 downto 0); + IHL_VERSION_IN : in std_logic_vector(7 downto 0); + TOS_IN : in std_logic_vector(7 downto 0); + IDENTIFICATION_IN : in std_logic_vector(15 downto 0); + FLAGS_OFFSET_IN : in std_logic_vector(15 downto 0); + TTL_IN : in std_logic_vector(7 downto 0); + PROTOCOL_IN : in std_logic_vector(7 downto 0); + FRAME_DELAY_IN : in std_logic_vector(31 downto 0); + -- ports for packetTransmitter + RD_CLK : in std_logic; -- 125MHz clock!!! + FT_DATA_OUT : out std_logic_vector(8 downto 0); + FT_TX_EMPTY_OUT : out std_logic; + FT_TX_RD_EN_IN : in std_logic; + FT_START_OF_PACKET_OUT : out std_logic; + FT_TX_DONE_IN : in std_logic; + FT_TX_DISCFRM_IN : in std_logic; + -- debug ports + BSM_CONSTR_OUT : out std_logic_vector(7 downto 0); + BSM_TRANS_OUT : out std_logic_vector(3 downto 0); + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end component; + +component trb_net16_gbe_frame_trans is +port ( + CLK : in std_logic; + RESET : in std_logic; + LINK_OK_IN : in std_logic; -- gk 03.08.10 + TX_MAC_CLK : in std_logic; + TX_EMPTY_IN : in std_logic; + START_OF_PACKET_IN : in std_logic; + DATA_ENDFLAG_IN : in std_logic; -- (8) is end flag, rest is only for TSMAC + -- NEW PORTS +-- HADDR_OUT : out std_logic_vector(7 downto 0); +-- HDATA_OUT : out std_logic_vector(7 downto 0); +-- HCS_OUT : out std_logic; +-- HWRITE_OUT : out std_logic; +-- HREAD_OUT : out std_logic; +-- HREADY_IN : in std_logic; +-- HDATA_EN_IN : in std_logic; + TX_FIFOAVAIL_OUT : out std_logic; + TX_FIFOEOF_OUT : out std_logic; + TX_FIFOEMPTY_OUT : out std_logic; + TX_DONE_IN : in std_logic; + TX_STAT_EN_IN : in std_logic; + TX_STATVEC_IN : in std_logic_vector(30 downto 0); + TX_DISCFRM_IN : in std_logic; + -- Debug + BSM_INIT_OUT : out std_logic_vector(3 downto 0); + BSM_MAC_OUT : out std_logic_vector(3 downto 0); + BSM_TRANS_OUT : out std_logic_vector(3 downto 0); + DBG_RD_DONE_OUT : out std_logic; + DBG_INIT_DONE_OUT : out std_logic; + DBG_ENABLED_OUT : out std_logic; + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end component; + +component trb_net16_med_ecp_sfp_gbe_8b is +-- gk 28.04.10 +generic ( + USE_125MHZ_EXTCLK : integer range 0 to 1 := 1 +); +port( + RESET : in std_logic; + GSR_N : in std_logic; + CLK_125_OUT : out std_logic; + CLK_125_RX_OUT : out std_logic; + CLK_125_IN : in std_logic; -- gk 28.04.10 used when intclk + --SGMII connection to frame transmitter (tsmac) + FT_TX_CLK_EN_OUT : out std_logic; + FT_RX_CLK_EN_OUT : out std_logic; + FT_COL_OUT : out std_logic; + FT_CRS_OUT : out std_logic; + FT_TXD_IN : in std_logic_vector(7 downto 0); + FT_TX_EN_IN : in std_logic; + FT_TX_ER_IN : in std_logic; + FT_RXD_OUT : out std_logic_vector(7 downto 0); + FT_RX_EN_OUT : out std_logic; + FT_RX_ER_OUT : out std_logic; + --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; -- SFP disable + -- Autonegotiation stuff + MR_RESET_IN : in std_logic; + MR_MODE_IN : in std_logic; + MR_ADV_ABILITY_IN : in std_logic_vector(15 downto 0); + MR_AN_LP_ABILITY_OUT : out std_logic_vector(15 downto 0); + MR_AN_PAGE_RX_OUT : out std_logic; + MR_AN_COMPLETE_OUT : out std_logic; + MR_AN_ENABLE_IN : in std_logic; + MR_RESTART_AN_IN : in std_logic; + -- 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; + +component gbe_setup is +port( + CLK : in std_logic; + RESET : in std_logic; + + -- interface to regio bus + BUS_ADDR_IN : in std_logic_vector(7 downto 0); + BUS_DATA_IN : in std_logic_vector(31 downto 0); + BUS_DATA_OUT : out std_logic_vector(31 downto 0); -- gk 26.04.10 + BUS_WRITE_EN_IN : in std_logic; -- gk 26.04.10 + BUS_READ_EN_IN : in std_logic; -- gk 26.04.10 + BUS_ACK_OUT : out std_logic; -- gk 26.04.10 + + GBE_TRIG_NR_IN : in std_logic_vector(31 downto 0); + + -- output to gbe_buf + GBE_SUBEVENT_ID_OUT : out std_logic_vector(31 downto 0); + GBE_SUBEVENT_DEC_OUT : out std_logic_vector(31 downto 0); + GBE_QUEUE_DEC_OUT : out std_logic_vector(31 downto 0); + GBE_MAX_PACKET_OUT : out std_logic_vector(31 downto 0); + GBE_MIN_PACKET_OUT : out std_logic_vector(31 downto 0); + GBE_MAX_FRAME_OUT : out std_logic_vector(15 downto 0); + GBE_USE_GBE_OUT : out std_logic; + GBE_USE_TRBNET_OUT : out std_logic; + GBE_USE_MULTIEVENTS_OUT : out std_logic; + GBE_READOUT_CTR_OUT : out std_logic_vector(23 downto 0); -- gk 26.04.10 + GBE_READOUT_CTR_VALID_OUT : out std_logic; -- gk 26.04.10 + GBE_DELAY_OUT : out std_logic_vector(31 downto 0); + GBE_ALLOW_LARGE_OUT : out std_logic; + GBE_ALLOW_RX_OUT : out std_logic; + GBE_ALLOW_BRDCST_ETH_OUT : out std_logic; + GBE_ALLOW_BRDCST_IP_OUT : out std_logic; + GBE_FRAME_DELAY_OUT : out std_logic_vector(31 downto 0); + GBE_ALLOWED_TYPES_OUT : out std_logic_vector(31 downto 0); + GBE_ALLOWED_IP_OUT : out std_logic_vector(31 downto 0); + GBE_ALLOWED_UDP_OUT : out std_logic_vector(31 downto 0); + GBE_VLAN_ID_OUT : out std_logic_vector(31 downto 0); + -- gk 28.07.10 + MONITOR_BYTES_IN : in std_logic_vector(31 downto 0); + MONITOR_SENT_IN : in std_logic_vector(31 downto 0); + MONITOR_DROPPED_IN : in std_logic_vector(31 downto 0); + MONITOR_SM_IN : in std_logic_vector(31 downto 0); + MONITOR_LR_IN : in std_logic_vector(31 downto 0); + MONITOR_HDR_IN : in std_logic_vector(31 downto 0); + MONITOR_FIFOS_IN : in std_logic_vector(31 downto 0); + MONITOR_DISCFRM_IN : in std_logic_vector(31 downto 0); + MONITOR_LINK_DWN_IN : in std_logic_vector(31 downto 0); -- gk 30.09.10 + MONITOR_EMPTY_IN : in std_logic_vector(31 downto 0); -- gk 01.10.10 + MONITOR_RX_FRAMES_IN : in std_logic_vector(31 downto 0); + MONITOR_RX_BYTES_IN : in std_logic_vector(31 downto 0); + MONITOR_RX_BYTES_R_IN : in std_logic_vector(31 downto 0); + -- gk 01.06.10 + DBG_IPU2GBE1_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE2_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE3_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE4_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE5_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE6_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE7_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE8_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE9_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE10_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE11_IN : in std_logic_vector(31 downto 0); + DBG_IPU2GBE12_IN : in std_logic_vector(31 downto 0); + DBG_PC1_IN : in std_logic_vector(31 downto 0); + DBG_PC2_IN : in std_logic_vector(31 downto 0); + DBG_FC1_IN : in std_logic_vector(31 downto 0); + DBG_FC2_IN : in std_logic_vector(31 downto 0); + DBG_FT1_IN : in std_logic_vector(31 downto 0); + DBG_FT2_IN : in std_logic_vector(31 downto 0); + DBG_FR_IN : in std_logic_vector(95 downto 0); + DBG_RC_IN : in std_logic_vector(63 downto 0); + DBG_MC_IN : in std_logic_vector(63 downto 0); + DBG_TC_IN : in std_logic_vector(31 downto 0); + DBG_FIFO_RD_EN_OUT : out std_logic; + + DBG_SELECT_REC_IN : in std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); + DBG_SELECT_SENT_IN : in std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0); + DBG_SELECT_PROTOS_IN : in std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0); + + DBG_FIFO_Q_IN : in std_logic_vector(15 downto 0) + --DBG_FIFO_RESET_OUT : out std_logic +); +end component; + + +component ip_configurator is +port( + CLK : in std_logic; + RESET : in std_logic; + -- configuration interface + START_CONFIG_IN : in std_logic; -- start configuration run + BANK_SELECT_IN : in std_logic_vector(3 downto 0); -- selects config bank + CONFIG_DONE_OUT : out std_logic; -- configuration run ended, new values can be used + MEM_ADDR_OUT : out std_logic_vector(7 downto 0); -- address for + MEM_DATA_IN : in std_logic_vector(31 downto 0); -- data from IP memory + MEM_CLK_OUT : out std_logic; -- clock for BlockRAM + -- information for IP cores + DEST_MAC_OUT : out std_logic_vector(47 downto 0); -- destination MAC address + DEST_IP_OUT : out std_logic_vector(31 downto 0); -- destination IP address + DEST_UDP_OUT : out std_logic_vector(15 downto 0); -- destination port + SRC_MAC_OUT : out std_logic_vector(47 downto 0); -- source MAC address + SRC_IP_OUT : out std_logic_vector(31 downto 0); -- source IP address + SRC_UDP_OUT : out std_logic_vector(15 downto 0); -- source port + MTU_OUT : out std_logic_vector(15 downto 0); -- MTU size (max frame size) + -- Debug + DEBUG_OUT : out std_logic_vector(31 downto 0) +); +end component; + +component fifo_4096x9 is +port( + Data : in std_logic_vector(8 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(8 downto 0); + Empty : out std_logic; + Full : out std_logic +); +end component; + +component fifo_4096x32 is +port( + Data : in std_logic_vector(31 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(31 downto 0); + Empty : out std_logic; + Full : out std_logic +); +end component; + +component fifo_512x32 is +port( + Data : in std_logic_vector(31 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(31 downto 0); + Empty : out std_logic; + Full : out std_logic +); +end component; + +component fifo_512x72 is +port( + Data : in std_logic_vector(71 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(71 downto 0); + Empty : out std_logic; + Full : out std_logic +); +end component; + +component serdes_gbe_0_intclock_8b_ecp3 is + GENERIC (USER_CONFIG_FILE : String := "serdes_gbe_0_intclock_8b_ecp3.txt"); + port ( +------------------ +-- CH0 -- + hdinp_ch0, hdinn_ch0 : in std_logic; + hdoutp_ch0, hdoutn_ch0 : out std_logic; + rxiclk_ch0 : in std_logic; + txiclk_ch0 : in std_logic; + rx_full_clk_ch0 : out std_logic; + rx_half_clk_ch0 : out std_logic; + tx_full_clk_ch0 : out std_logic; + tx_half_clk_ch0 : out std_logic; + fpga_rxrefclk_ch0 : in std_logic; + txdata_ch0 : in std_logic_vector (7 downto 0); + tx_k_ch0 : in std_logic; + xmit_ch0 : in std_logic; + tx_disp_correct_ch0 : in std_logic; + rxdata_ch0 : out std_logic_vector (7 downto 0); + rx_k_ch0 : out std_logic; + rx_disp_err_ch0 : out std_logic; + rx_cv_err_ch0 : out std_logic; + sb_felb_ch0_c : in std_logic; + sb_felb_rst_ch0_c : in std_logic; + tx_pwrup_ch0_c : in std_logic; + rx_pwrup_ch0_c : in std_logic; + rx_los_low_ch0_s : out std_logic; + lsm_status_ch0_s : out std_logic; + rx_cdr_lol_ch0_s : out std_logic; +-- CH1 -- +-- CH2 -- +-- CH3 -- +---- Miscillaneous ports + fpga_txrefclk : in std_logic; + tx_serdes_rst_c : in std_logic; + tx_pll_lol_qd_s : out std_logic; + refclk2fpga : out std_logic; + rst_n : in std_logic; + serdes_rst_qd_c : in std_logic); + +end component; + +end package; \ No newline at end of file diff --git a/gbe2_ecp3/trb_net_gbe_protocols.vhd b/gbe2_ecp3/trb_net_gbe_protocols.vhd new file mode 100644 index 0000000..282a9e5 --- /dev/null +++ b/gbe2_ecp3/trb_net_gbe_protocols.vhd @@ -0,0 +1,324 @@ +library ieee; +use ieee.std_logic_1164.all; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; +library work; +use work.trb_net_std.all; + +package trb_net_gbe_protocols is + +-- g_MY_IP is being set by DHCP Response Constructor +signal g_MY_IP : std_logic_vector(31 downto 0); +-- g_MY_MAC is being set by Main Controller +signal g_MY_MAC : std_logic_vector(47 downto 0); + +constant c_MAX_FRAME_TYPES : integer range 1 to 16 := 3; +constant c_MAX_PROTOCOLS : integer range 1 to 16 := 5; +constant c_MAX_IP_PROTOCOLS : integer range 1 to 16 := 4; +constant c_MAX_UDP_PROTOCOLS : integer range 1 to 16 := 2; + +type frame_types_a is array(c_MAX_FRAME_TYPES - 1 downto 0) of std_logic_vector(15 downto 0); +constant FRAME_TYPES : frame_types_a := (x"0800", x"0806", x"08AA"); +-- IPv4, ARP, Test + +type ip_protos_a is array(c_MAX_IP_PROTOCOLS - 1 downto 0) of std_logic_vector(7 downto 0); +constant IP_PROTOCOLS : ip_protos_a := (x"11", x"01", x"dd", x"ee"); +-- UDP, ICMP, test1, test2 + +-- this are the destination ports of the incoming packet +type udp_protos_a is array(c_MAX_UDP_PROTOCOLS - 1 downto 0) of std_logic_vector(15 downto 0); +constant UDP_PROTOCOLS : udp_protos_a := (x"0044", x"7120"); +-- DHCP client, dummy + +component trb_net16_gbe_response_constructor_Forward is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- INTERFACE + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_ACTIVATE_IN : in std_logic; + PS_RESPONSE_READY_OUT : out std_logic; + PS_BUSY_OUT : out std_logic; + PS_SELECTED_IN : in std_logic; + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + + TC_RD_EN_IN : in std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + TC_BUSY_IN : in std_logic; + + RECEIVED_FRAMES_OUT : out std_logic_vector(15 downto 0); + SENT_FRAMES_OUT : out std_logic_vector(15 downto 0); +-- END OF INTERFACE + +-- debug + DEBUG_OUT : out std_logic_vector(31 downto 0) +); +end component; + +component trb_net16_gbe_response_constructor_ARP is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- INTERFACE + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_ACTIVATE_IN : in std_logic; + PS_RESPONSE_READY_OUT : out std_logic; + PS_BUSY_OUT : out std_logic; + PS_SELECTED_IN : in std_logic; + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + + TC_RD_EN_IN : in std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + TC_BUSY_IN : in std_logic; + + RECEIVED_FRAMES_OUT : out std_logic_vector(15 downto 0); + SENT_FRAMES_OUT : out std_logic_vector(15 downto 0); +-- END OF INTERFACE + +-- debug + DEBUG_OUT : out std_logic_vector(31 downto 0) +); +end component; + +component trb_net16_gbe_response_constructor_Test is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- INTERFACE + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_ACTIVATE_IN : in std_logic; + PS_RESPONSE_READY_OUT : out std_logic; + PS_BUSY_OUT : out std_logic; + PS_SELECTED_IN : in std_logic; + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + + TC_RD_EN_IN : in std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + TC_BUSY_IN : in std_logic; + + RECEIVED_FRAMES_OUT : out std_logic_vector(15 downto 0); + SENT_FRAMES_OUT : out std_logic_vector(15 downto 0); +-- END OF INTERFACE + +-- debug + DEBUG_OUT : out std_logic_vector(31 downto 0) +); +end component; + +component trb_net16_gbe_response_constructor_Trash is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- INTERFACE + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_ACTIVATE_IN : in std_logic; + PS_RESPONSE_READY_OUT : out std_logic; + PS_BUSY_OUT : out std_logic; + PS_SELECTED_IN : in std_logic; + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + + TC_RD_EN_IN : in std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + TC_BUSY_IN : in std_logic; + + RECEIVED_FRAMES_OUT : out std_logic_vector(15 downto 0); + SENT_FRAMES_OUT : out std_logic_vector(15 downto 0); +-- END OF INTERFACE + +-- debug + DEBUG_OUT : out std_logic_vector(31 downto 0) +); +end component; + +component trb_net16_gbe_response_constructor_DHCP is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- INTERFACE + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_ACTIVATE_IN : in std_logic; + PS_RESPONSE_READY_OUT : out std_logic; + PS_BUSY_OUT : out std_logic; + PS_SELECTED_IN : in std_logic; + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + + TC_RD_EN_IN : in std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + TC_BUSY_IN : in std_logic; + + RECEIVED_FRAMES_OUT : out std_logic_vector(15 downto 0); + SENT_FRAMES_OUT : out std_logic_vector(15 downto 0); +-- END OF INTERFACE + + DHCP_START_IN : in std_logic; + DHCP_DONE_OUT : out std_logic; +-- debug + DEBUG_OUT : out std_logic_vector(31 downto 0) +); +end component; + +component trb_net16_gbe_response_constructor_Ping is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- INTERFACE + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_ACTIVATE_IN : in std_logic; + PS_RESPONSE_READY_OUT : out std_logic; + PS_BUSY_OUT : out std_logic; + PS_SELECTED_IN : in std_logic; + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + + TC_RD_EN_IN : in std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + + TC_BUSY_IN : in std_logic; + + RECEIVED_FRAMES_OUT : out std_logic_vector(15 downto 0); + SENT_FRAMES_OUT : out std_logic_vector(15 downto 0); +-- END OF INTERFACE + +-- debug + DEBUG_OUT : out std_logic_vector(31 downto 0) +); +end component; + +component trb_net16_gbe_response_constructor_Test1 is +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- INTERFACE + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_ACTIVATE_IN : in std_logic; + PS_RESPONSE_READY_OUT : out std_logic; + PS_BUSY_OUT : out std_logic; + PS_SELECTED_IN : in std_logic; + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + + TC_RD_EN_IN : in std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + + TC_BUSY_IN : in std_logic; + + RECEIVED_FRAMES_OUT : out std_logic_vector(15 downto 0); + SENT_FRAMES_OUT : out std_logic_vector(15 downto 0); +-- END OF INTERFACE + +-- debug + DEBUG_OUT : out std_logic_vector(31 downto 0) +); +end component; + +end package; -- 2.43.0