From b5780b2d8466f34bcecf81c62186e3b27521b046 Mon Sep 17 00:00:00 2001 From: Manuel Penschuck Date: Tue, 5 Aug 2014 20:08:35 +0200 Subject: [PATCH] CBMNet readout: Debug-Design for Periph-FPGA with Test-Pattern generator. Simulation proven. Scripts to verify data received by FLIB. Seems to work fine as long as there's no back-pressure --- cbmnet/code/cbmnet_readout.vhd | 16 +- cbmnet/code/cbmnet_readout_event_packer.vhd | 40 +- cbmnet/code/cbmnet_readout_fifo.vhd | 4 +- cbmnet/code/cbmnet_readout_trbnet_decoder.vhd | 98 ++-- cbmnet/code/cbmnet_readout_tx_fsm.vhd | 68 ++- cbmnet/code/tb_cbmnet_logger.vhd | 66 +++ cbmnet/code/tb_cbmnet_readout.vhd | 3 + cbmnet/code/tb_cbmnet_readout2.vhd | 314 +++++++++++++ .../code/tb_cbmnet_readout_trbnet_decoder.vhd | 2 +- cbmnet/compile_constraints.pl | 3 +- cbmnet/compile_periph_frankfurt.pl | 41 +- cbmnet/test/check_frames.pl | 117 +++++ cbmnet/trb3_periph_cbmnet.lpf | 227 +++++++++ cbmnet/trb3_periph_cbmnet.prj | 14 +- cbmnet/trb3_periph_cbmnet.vhd | 434 ++++++++++++++---- cbmnet/trb3_periph_cbmnet_constraints.lpf | 7 +- 16 files changed, 1240 insertions(+), 214 deletions(-) create mode 100644 cbmnet/code/tb_cbmnet_logger.vhd create mode 100644 cbmnet/code/tb_cbmnet_readout2.vhd create mode 100755 cbmnet/test/check_frames.pl create mode 100644 cbmnet/trb3_periph_cbmnet.lpf diff --git a/cbmnet/code/cbmnet_readout.vhd b/cbmnet/code/cbmnet_readout.vhd index e84fbae..3dc3250 100644 --- a/cbmnet/code/cbmnet_readout.vhd +++ b/cbmnet/code/cbmnet_readout.vhd @@ -205,7 +205,7 @@ begin THE_READOUT_FIFO: CBMNET_READOUT_FIFO generic map ( - ADDR_WIDTH => 10, + ADDR_WIDTH => 12, -- 8kb .. WATERMARK => 2 ) port map ( -- write port @@ -326,13 +326,13 @@ begin when 16#0# => regio_data_status_i(0) <= cfg_enabled_i; when 16#1# => regio_data_status_i(16 downto 0) <= cfg_source_override_i & cfg_source_i; - when 16#2# => regio_data_status_i <= stat_connections_i; - when 16#3# => regio_data_status_i <= stat_clks_dead_i; - when 16#4# => regio_data_status_i <= stat_num_send_completed_i; - when 16#5# => regio_data_status_i <= stat_num_packets_i; - when 16#6# => regio_data_status_i <= stat_num_recv_completed_i; - when 16#7# => regio_data_status_i <= stat_link_inactive_i; - when 16#8# => regio_data_status_i <= stat_num_packets_aborted_i; + when 16#2# => regio_data_status_i <= std_logic_vector(stat_connections_i); + when 16#3# => regio_data_status_i <= std_logic_vector(stat_clks_dead_i); + when 16#4# => regio_data_status_i <= std_logic_vector(stat_num_send_completed_i); + when 16#5# => regio_data_status_i <= std_logic_vector(stat_num_packets_i); + when 16#6# => regio_data_status_i <= std_logic_vector(stat_num_recv_completed_i); + when 16#7# => regio_data_status_i <= std_logic_vector(stat_link_inactive_i); + when 16#8# => regio_data_status_i <= std_logic_vector(stat_num_packets_aborted_i); -- debug only ports when 16#9# => regio_data_status_i <= debug_decorder_i; diff --git a/cbmnet/code/cbmnet_readout_event_packer.vhd b/cbmnet/code/cbmnet_readout_event_packer.vhd index b3720d3..4b804d4 100644 --- a/cbmnet/code/cbmnet_readout_event_packer.vhd +++ b/cbmnet/code/cbmnet_readout_event_packer.vhd @@ -42,20 +42,22 @@ end entity; architecture cbmnet_readout_event_packer_arch of CBMNET_READOUT_EVENT_PACKER is type FSM_STATES_T is ( - IDLE, + WAIT_FOR_IDLE, IDLE, HDR_SIZE_H, HDR_SIZE_L, HDR_DECODING_H, HDR_DECODING_L, HDR_ID_H, HDR_ID_L, HDR_NUMBER_H, HDR_NUMBER_L, PAYLOAD, - FTR_TRAILER_H, FTR_TRAILER_L, - FTR_STATUS_H, FTR_STATUS_L + TRL_TRAILER_H, TRL_TRAILER_L, + TRL_STATUS_H, TRL_STATUS_L ); signal fsm_i : FSM_STATES_T; signal header_data_i : std_logic_vector(15 downto 0); signal header_enqueue_i : std_logic; signal copy_payload_i : std_logic; + + signal data_read_i, data_read_delayed_i : std_logic; begin THE_PACKER: process is begin @@ -70,15 +72,20 @@ begin WPACKET_COMPLETE_OUT <= '0'; if RESET_IN='1' then - fsm_i <= IDLE; + fsm_i <= WAIT_FOR_IDLE; elsif fsm_i /= IDLE and (DEC_ERROR_IN = '1' or WFULL_IN = '1') then WADDR_RESTORE_OUT <= '1'; DEC_RESET_OUT <= '1'; - fsm_i <= IDLE; + fsm_i <= WAIT_FOR_IDLE; else case(fsm_i) is + when WAIT_FOR_IDLE => + if DEC_ACTIVE_IN='0' then + fsm_i <= IDLE; + end if; + when IDLE => if DEC_ACTIVE_IN='1' then WADDR_STORE_OUT <= '1'; @@ -123,25 +130,25 @@ begin when PAYLOAD => if DEC_ACTIVE_IN = '0' then - fsm_i <= FTR_TRAILER_H; + fsm_i <= TRL_TRAILER_H; else copy_payload_i <= '1'; end if; - when FTR_TRAILER_H => + when TRL_TRAILER_H => header_data_i <= x"0001"; header_enqueue_i <= '1'; - fsm_i <= FTR_TRAILER_L; - when FTR_TRAILER_L => + fsm_i <= TRL_TRAILER_L; + when TRL_TRAILER_L => header_data_i <= x"5555"; header_enqueue_i <= '1'; - fsm_i <= FTR_STATUS_H; + fsm_i <= TRL_STATUS_H; - when FTR_STATUS_H => + when TRL_STATUS_H => header_data_i <= GBE_CTS_STATUS_BITS_IN(31 downto 16); header_enqueue_i <= '1'; - fsm_i <= FTR_STATUS_L; - when FTR_STATUS_L => + fsm_i <= TRL_STATUS_L; + when TRL_STATUS_L => header_data_i <= GBE_CTS_STATUS_BITS_IN(15 downto 0); header_enqueue_i <= '1'; WPACKET_COMPLETE_OUT <= '1'; @@ -153,6 +160,9 @@ begin WDATA_OUT(15 downto 0) <= DEC_DATA_IN when copy_payload_i='1' else header_data_i; WDATA_OUT(17 downto 16) <= "00"; - WENQUEUE_OUT <= header_enqueue_i or DEC_DATA_READY_IN; - DEC_DATA_READ_OUT <= copy_payload_i and DEC_DATA_READY_IN; + WENQUEUE_OUT <= header_enqueue_i or data_read_i; + + data_read_i <= copy_payload_i and DEC_DATA_READY_IN; + DEC_DATA_READ_OUT <= data_read_i; + data_read_delayed_i <= data_read_i when rising_edge(CLK_IN); end architecture; \ No newline at end of file diff --git a/cbmnet/code/cbmnet_readout_fifo.vhd b/cbmnet/code/cbmnet_readout_fifo.vhd index fb9b6e7..5c9701f 100644 --- a/cbmnet/code/cbmnet_readout_fifo.vhd +++ b/cbmnet/code/cbmnet_readout_fifo.vhd @@ -43,7 +43,7 @@ architecture cbmnet_readout_fifo_arch of CBMNET_READOUT_FIFO is signal raddr_i, raddr_stored_i, rwrite_pointer_i, rpacket_counter_i : unsigned(ADDR_WIDTH-1 downto 0) := (others => '0'); signal rpacket_complete_xchange_i : std_logic := '0'; - + type FIFO_MEM_T is array(0 to 2**ADDR_WIDTH-1) of std_logic_vector(17 downto 0); signal mem_i : FIFO_MEM_T; begin @@ -100,7 +100,7 @@ begin if RRESET_IN = '1' then next_addr_v := raddr_stored_i; else - if RDEQUEUE_IN = '1' and raddr_i + 1 /= rwrite_pointer_i then + if RDEQUEUE_IN = '1' then -- and raddr_i + 1 /= rwrite_pointer_i then next_addr_v := next_addr_v + 1; end if; end if; diff --git a/cbmnet/code/cbmnet_readout_trbnet_decoder.vhd b/cbmnet/code/cbmnet_readout_trbnet_decoder.vhd index a819fbb..4a7ad1f 100644 --- a/cbmnet/code/cbmnet_readout_trbnet_decoder.vhd +++ b/cbmnet/code/cbmnet_readout_trbnet_decoder.vhd @@ -38,22 +38,27 @@ entity CBMNET_READOUT_TRBNET_DECODER is end entity; architecture cbmnet_readout_trbnet_decoder_arch of CBMNET_READOUT_TRBNET_DECODER is - component lattice_ecp3_fifo_16x16_dualport is - 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; - Q: out std_logic_vector(15 downto 0); - Empty: out std_logic; - Full: out std_logic; - AlmostFull: out std_logic - ); - end component; - +-- component lattice_ecp3_fifo_16x16_dualport is +-- 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; +-- Q: out std_logic_vector(15 downto 0); +-- Empty: out std_logic; +-- Full: out std_logic; +-- AlmostFull: out std_logic +-- ); +-- end component; +-- + constant FIFO_LENGTH_C : integer := 4; + type FIFO_MEM_T is array(0 to 2**FIFO_LENGTH_C-1) of std_logic_vector(15 downto 0); + signal fifo_mem_i : FIFO_MEM_T; + + type FSM_STATES_T is (WAIT_FOR_IDLE, IDLE, RECV_EVT_INFO_H, RECV_EVT_INFO_L, RECV_EVT_LENGTH, RECV_EVT_SOURCE, RECV_PAYLOAD, LAST_WORD, ERROR_COND); signal fsm_i : FSM_STATES_T; @@ -75,6 +80,9 @@ architecture cbmnet_readout_trbnet_decoder_arch of CBMNET_READOUT_TRBNET_DECODER signal fifo_empty_i : std_logic; signal fifo_data_i : std_logic_vector(15 downto 0); + + signal fifo_raddr_i : UNSIGNED(FIFO_LENGTH_C-1 downto 0); + signal fifo_waddr_i : UNSIGNED(FIFO_LENGTH_C-1 downto 0); begin data_i <= HUB_FEE_DATA_IN; @@ -133,7 +141,7 @@ begin if read_word_i = '1' then dec_source_i <= data_i; fsm_i <= RECV_PAYLOAD; - fifo_active_i <= '1'; + --fifo_active_i <= '1'; end if; when RECV_PAYLOAD => @@ -146,7 +154,7 @@ begin end if; if fifo_empty_i = '1' and word_counter_done_i = '1' then - fsm_i <= LAST_WORD; + fsm_i <= WAIT_FOR_IDLE; --LAST_WORD; end if; when LAST_WORD => @@ -171,7 +179,8 @@ begin wait until rising_edge(CLK_IN); if word_counter_set_i = '1' then - word_counter_i <= UNSIGNED("0" & dec_length_i(15 downto 1)); + word_counter_i(15) <= '0'; + word_counter_i(14 downto 0) <= UNSIGNED(dec_length_i(15 downto 1)); elsif word_counter_done_i = '0' and fifo_enqueue_i = '1' then word_counter_i <= word_counter_i - 1; @@ -183,24 +192,41 @@ begin word_counter_done_i <= '1' when word_counter_i = x"0000" else '0'; - THE_FIFO: lattice_ecp3_fifo_16x16_dualport - port map ( - WrClock => CLK_IN, -- in std_logic; - RdClock => CLK_IN, -- in std_logic; - Reset => RESET_IN, -- in std_logic; - RPReset => RESET_IN, -- in std_logic; - - Data => HUB_FEE_DATA_IN, -- in std_logic_vector(17 downto 0); - WrEn => fifo_enqueue_i, -- in std_logic; - - RdEn => DEC_DATA_READ_IN, -- in std_logic; - Q => fifo_data_i, -- out std_logic_vector(17 downto 0); + PROC_FIFO: process is + variable count_v : integer range 0 to 2**FIFO_LENGTH_C := 0; + begin + wait until rising_edge(CLK_IN); - Empty => fifo_empty_i, -- out std_logic; - Full => fifo_full_i, -- out std_logic; - AlmostFull => open -- out std_logic - ); - + if RESET_IN='1' then + count_v := 0; + fifo_waddr_i <= (others=>'0'); + fifo_raddr_i <= (others=>'0'); + else + if fifo_enqueue_i = '1' then + count_v := count_v + 1; + fifo_waddr_i <= fifo_waddr_i + TO_UNSIGNED(1,1); + fifo_mem_i(to_integer(fifo_waddr_i)) <= HUB_FEE_DATA_IN; + end if; + + if DEC_DATA_READ_IN = '1' then + count_v := count_v - 1; + fifo_raddr_i <= fifo_raddr_i + TO_UNSIGNED(1,1); + end if; + end if; + + fifo_empty_i <= '0'; + fifo_full_i <= '0'; + + if count_v = 0 then + fifo_empty_i <= '1'; + end if; + + if count_v >= 2**FIFO_LENGTH_C then + fifo_full_i <= '1'; + end if; + end process; + fifo_data_i <= fifo_mem_i(to_integer(fifo_raddr_i)); + read_word_i <= HUB_FEE_DATAREADY_IN and GBE_FEE_READ_IN; fifo_enqueue_i <= fifo_active_i and read_word_i; diff --git a/cbmnet/code/cbmnet_readout_tx_fsm.vhd b/cbmnet/code/cbmnet_readout_tx_fsm.vhd index 34cf8e2..3f51b73 100644 --- a/cbmnet/code/cbmnet_readout_tx_fsm.vhd +++ b/cbmnet/code/cbmnet_readout_tx_fsm.vhd @@ -29,12 +29,13 @@ architecture cbmnet_readout_tx_fsm_arch of CBMNET_READOUT_TX_FSM is constant PAYLOAD_PER_PACKET_C : integer := 62; -- bytes - type FSM_STATES_T is (WAIT_FOR_COMPL_PACKET, SETUP_TRANSACTION, SEND_HEADER, SEND_PAYLOAD, SEND_PACKET_GAP, FINISH_TRANSACTION, FINISH_WAIT1, FINISH_WAIT2); + type FSM_STATES_T is (WAIT_FOR_COMPL_PACKET, SETUP_TRANSACTION, SETUP_TRANSACTION_RECV_LENGTH, SETUP_SEND_START_HEADER, SEND_START_LENGTH_HIGH, SEND_START_LENGTH_LOW, SEND_HEADER, SEND_PAYLOAD, SEND_PACKET_GAP, FINISH_TRANSACTION, FINISH_WAIT1, FINISH_WAIT2); signal fsm_i : FSM_STATES_T; signal fsm_state_i : unsigned(3 downto 0); signal trans_num_i : unsigned(5 downto 0); + signal buffer_bytes_length_high_i : std_logic_vector(15 downto 0) := x"0000"; signal trans_bytes_length_i : unsigned(15 downto 0) := x"0000"; signal trans_bytes_send_i : unsigned(15 downto 0); @@ -48,6 +49,8 @@ architecture cbmnet_readout_tx_fsm_arch of CBMNET_READOUT_TX_FSM is begin + assert(buffer_bytes_length_high_i = x"0000"); + PROC_TX_CNTL: process is begin wait until rising_edge(CLK_IN); @@ -70,6 +73,7 @@ begin fsm_state_i <= x"1"; if FIFO_PACKET_COMPLETE_IN = '1' then fsm_i <= SETUP_TRANSACTION; + FIFO_DEQUEUE_OUT <= '1'; end if; when SETUP_TRANSACTION => @@ -77,22 +81,56 @@ begin trans_bytes_send_i <= (others => '0'); pack_num_i <= (others => '0'); pack_start_i <= '1'; - trans_bytes_length_i(15) <= '1'; -- dont really care which value as long as it's > 2, so it ensured that the first word of the SE-Hdr is sent! + buffer_bytes_length_high_i <= FIFO_DATA_IN; + fsm_i <= SETUP_TRANSACTION_RECV_LENGTH; + + when SETUP_TRANSACTION_RECV_LENGTH => + fsm_state_i <= x"7"; + trans_bytes_send_i <= (others => '0'); + trans_bytes_length_i <= UNSIGNED(FIFO_DATA_IN); + fsm_i <= SETUP_SEND_START_HEADER; + + when SETUP_SEND_START_HEADER => + fsm_state_i <= x"8"; + trans_bytes_send_i <= (others => '0'); + pack_payload_words_i <= (others => '0'); + CBMNET_DATA_OUT <= (others => '0'); + CBMNET_DATA_OUT( 5 downto 0) <= STD_LOGIC_VECTOR(pack_num_i); + CBMNET_DATA_OUT(11 downto 6) <= STD_LOGIC_VECTOR(trans_num_i); + CBMNET_DATA_OUT(14) <= '1'; + CBMNET_DATA_OUT(15) <= pack_stop_i; - fsm_i <= SEND_HEADER; + if CBMNET_STOP_IN = '0' then + CBMNET_START_OUT <= '1'; + fsm_i <= SEND_START_LENGTH_HIGH; + end if; + + when SEND_START_LENGTH_HIGH => + fsm_state_i <= x"9"; + pack_payload_words_i <= (others => '0'); + trans_bytes_send_i <= TO_UNSIGNED(4, 16); -- +2 so trans_complete computation becomes easier + pack_payload_words_i <= TO_UNSIGNED(1, 5); + CBMNET_DATA_OUT <= buffer_bytes_length_high_i; + fsm_i <= SEND_PAYLOAD; + FIFO_DEQUEUE_OUT <= '1'; + + when SEND_START_LENGTH_LOW => + fsm_state_i <= x"a"; + CBMNET_DATA_OUT <= STD_LOGIC_VECTOR(trans_bytes_length_i); + fsm_i <= SEND_PAYLOAD; when SEND_HEADER => fsm_state_i <= x"3"; + CBMNET_DATA_OUT <= (others => '0'); + CBMNET_DATA_OUT( 5 downto 0) <= STD_LOGIC_VECTOR(pack_num_i); + CBMNET_DATA_OUT(11 downto 6) <= STD_LOGIC_VECTOR(trans_num_i); + CBMNET_DATA_OUT(14) <= '0'; + CBMNET_DATA_OUT(15) <= pack_stop_i; + + pack_payload_words_i <= (others => '0'); + if CBMNET_STOP_IN = '0' then - CBMNET_DATA_OUT <= (others => '0'); - CBMNET_DATA_OUT( 5 downto 0) <= STD_LOGIC_VECTOR(pack_num_i); - CBMNET_DATA_OUT(11 downto 6) <= STD_LOGIC_VECTOR(trans_num_i); - CBMNET_DATA_OUT(14) <= pack_start_i; - CBMNET_DATA_OUT(15) <= pack_stop_i; CBMNET_START_OUT <= '1'; - - pack_payload_words_i <= (others => '0'); - FIFO_DEQUEUE_OUT <= '1'; fsm_i <= SEND_PAYLOAD; end if; @@ -113,10 +151,6 @@ begin FIFO_DEQUEUE_OUT <= '1'; end if; - if trans_bytes_send_i = 2 then - trans_bytes_length_i <= UNSIGNED(FIFO_DATA_IN); - end if; - pack_start_i <= '0'; pack_payload_words_i <= pack_payload_words_i + 1; trans_bytes_send_i <= trans_bytes_send_i + 2; @@ -145,8 +179,8 @@ begin end process; pack_stop_i <= '1' when trans_bytes_length_i - trans_bytes_send_i < PAYLOAD_PER_PACKET_C else '0'; - trans_complete_i <= '1' when trans_bytes_length_i = trans_bytes_send_i else '0'; + trans_complete_i <= '1' when trans_bytes_length_i = trans_bytes_send_i else '0'; - DEBUG_OUT(3 downto 0) <= fsm_state_i; + DEBUG_OUT(3 downto 0) <= STD_LOGIC_VECTOR(fsm_state_i); end architecture; diff --git a/cbmnet/code/tb_cbmnet_logger.vhd b/cbmnet/code/tb_cbmnet_logger.vhd new file mode 100644 index 0000000..d1b2a16 --- /dev/null +++ b/cbmnet/code/tb_cbmnet_logger.vhd @@ -0,0 +1,66 @@ +library ieee; +use ieee.std_logic_1164.all; +use std.textio.all; +use work.txt_util.all; + +entity TB_CBMNET_LOGGER is + generic ( + log_file : string + ); + port ( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + LINK_ACTIVE_IN : in std_logic; + + DATA2SEND_IN : std_logic_vector(15 downto 0); + DATA2SEND_STOP_IN : std_logic; + DATA2SEND_START_IN : std_logic; + DATA2SEND_END_IN : std_logic + ); +end entity; + +architecture TB of TB_CBMNET_LOGGER is + file l_file: TEXT open write_mode is log_file; + + + type fsm_states_t is (IDLE, SENDING); + signal fsm_i : fsm_states_t; + + signal word_count_i : integer; + +begin + PROC_RECV: process is + variable frame_line_v : line; + begin + wait until rising_edge(CLK_IN); + + if RESET_IN = '0' and LINK_ACTIVE_IN = '1' then + case (fsm_i) is + when IDLE => + word_count_i <= 1; + if DATA2SEND_START_IN = '1' and DATA2SEND_STOP_IN = '0' then + fsm_i <= SENDING; + write(frame_line_v, string'("DATA(")); + write(frame_line_v, time'image(now)); + write(frame_line_v, string'("): ")); + write(frame_line_v, hstr(DATA2SEND_IN)); + end if; + + when SENDING => + write(frame_line_v, " " & hstr(DATA2SEND_IN)); + word_count_i <= word_count_i + 1; + + if DATA2SEND_STOP_IN = '1' then + writeline(l_file, frame_line_v); + --println ("DATA(" & str(word_count_i*2) & ") :" & frame_str_i); + fsm_i <= IDLE; + end if; + + end case; + elsif RESET_IN = '1' then + fsm_i <= IDLE; + + end if; + end process; + +end architecture; \ No newline at end of file diff --git a/cbmnet/code/tb_cbmnet_readout.vhd b/cbmnet/code/tb_cbmnet_readout.vhd index be4f476..fd39dd5 100644 --- a/cbmnet/code/tb_cbmnet_readout.vhd +++ b/cbmnet/code/tb_cbmnet_readout.vhd @@ -79,6 +79,9 @@ begin HUB_CTS_READOUT_TYPE_IN <= x"e"; GBE_CTS_STATUS_BITS_IN <= x"12345678"; +00:00:00:70:00:03:00:62:00:00:00:64:00:02:00:11:00:00:f3:c0:00:09:45:f7: +00:12:f3:c0:20:06:f3:53:cf:0f:3c:7c:00:00:00:61:cf:0f:3c:7c:05:06:ac:6e:cf:0f:3c:7c:00:00:00:00:00:00:00:00:00:00:00:00:cf:0f:3c:7c:00:00:00:61:cf:0f:3c:7c:05:06:ac:6e:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00: +00:01:55:55:00:00:00:01: wait until rising_edge(CLK_IN); wait until rising_edge(CLK_IN); wait until rising_edge(CLK_IN); diff --git a/cbmnet/code/tb_cbmnet_readout2.vhd b/cbmnet/code/tb_cbmnet_readout2.vhd new file mode 100644 index 0000000..a96e90a --- /dev/null +++ b/cbmnet/code/tb_cbmnet_readout2.vhd @@ -0,0 +1,314 @@ +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + use work.cbmnet_interface_pkg.all; + +entity tb_cbmnet_readout2 is +end tb_cbmnet_readout2; + +architecture TB of tb_cbmnet_readout2 is + component TB_CBMNET_LOGGER is + generic ( + log_file : string + ); + port ( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + LINK_ACTIVE_IN : in std_logic; + + DATA2SEND_IN : std_logic_vector(15 downto 0); + DATA2SEND_STOP_IN : std_logic; + DATA2SEND_START_IN : std_logic; + DATA2SEND_END_IN : std_logic + ); + end component; + + + signal CLK_IN : std_logic := '0'; + signal RESET_IN : std_logic := '0'; + + -- connect to hub + signal HUB_CTS_NUMBER_IN : std_logic_vector (15 downto 0) := (others => '0'); + signal HUB_CTS_CODE_IN : std_logic_vector (7 downto 0) := (others => '0'); + signal HUB_CTS_INFORMATION_IN : std_logic_vector (7 downto 0) := (others => '0'); + signal HUB_CTS_READOUT_TYPE_IN : std_logic_vector (3 downto 0) := (others => '0'); + signal HUB_CTS_START_READOUT_IN : std_logic := '0'; + signal HUB_CTS_READOUT_FINISHED_OUT : std_logic := '0'; --no more data, end transfer, send TRM + signal HUB_CTS_STATUS_BITS_OUT : std_logic_vector (31 downto 0) := (others => '0'); + signal HUB_FEE_DATA_IN : std_logic_vector (15 downto 0) := (others => '0'); + signal HUB_FEE_DATAREADY_IN : std_logic := '0'; + signal HUB_FEE_READ_OUT : std_logic := '0'; --must be high when idle, otherwise you will never get a dataready + signal HUB_FEE_STATUS_BITS_IN : std_logic_vector (31 downto 0) := (others => '0'); + signal HUB_FEE_BUSY_IN : std_logic := '0'; + + -- connect to GbE + signal GBE_CTS_NUMBER_OUT : std_logic_vector (15 downto 0) := (others => '0'); + signal GBE_CTS_CODE_OUT : std_logic_vector (7 downto 0) := (others => '0'); + signal GBE_CTS_INFORMATION_OUT : std_logic_vector (7 downto 0) := (others => '0'); + signal GBE_CTS_READOUT_TYPE_OUT : std_logic_vector (3 downto 0) := (others => '0'); + signal GBE_CTS_START_READOUT_OUT : std_logic := '0'; + signal GBE_CTS_READOUT_FINISHED_IN : std_logic := '0'; --no more data, end transfer, send TRM + signal GBE_CTS_STATUS_BITS_IN : std_logic_vector (31 downto 0) := (others => '0'); + signal GBE_FEE_DATA_OUT : std_logic_vector (15 downto 0) := (others => '0'); + signal GBE_FEE_DATAREADY_OUT : std_logic := '0'; + signal GBE_FEE_READ_IN : std_logic := '0'; --must be high when idle, otherwise you will never get a dataready + signal GBE_FEE_STATUS_BITS_OUT : std_logic_vector (31 downto 0) := (others => '0'); + signal GBE_FEE_BUSY_OUT : std_logic := '0'; + + -- reg io + signal REGIO_ADDR_IN : std_logic_vector(15 downto 0) := (others => '0'); + signal REGIO_DATA_IN : std_logic_vector(31 downto 0) := (others => '0'); + signal REGIO_READ_ENABLE_IN : std_logic := '0'; + signal REGIO_WRITE_ENABLE_IN : std_logic := '0'; + signal REGIO_DATA_OUT : std_logic_vector(31 downto 0) := (others => '0'); + signal REGIO_DATAREADY_OUT : std_logic := '0'; + signal REGIO_WRITE_ACK_OUT : std_logic := '0'; + signal REGIO_UNKNOWN_ADDR_OUT : std_logic := '0'; + + -- CBMNet + signal CBMNET_CLK_IN : std_logic := '0'; + signal CBMNET_RESET_IN : std_logic := '0'; + signal CBMNET_LINK_ACTIVE_IN : std_logic := '0'; + + signal CBMNET_DATA2SEND_STOP_IN : std_logic := '0'; + signal CBMNET_DATA2SEND_START_OUT : std_logic := '0'; + signal CBMNET_DATA2SEND_END_OUT : std_logic := '0'; + signal CBMNET_DATA2SEND_DATA_OUT : std_logic_vector(15 downto 0) := (others => '0'); + + signal send_wait_counter_i : unsigned(31 downto 0); + signal send_wait_threshold_i : unsigned(31 downto 0) := x"0000_0010"; + + signal event_id : unsigned(15 downto 0) := x"0000"; + signal send_length_i : unsigned(15 downto 0) := x"0010"; + signal send_counter_i : unsigned(15 downto 0); + + signal send_enabled_i : std_logic := '0'; + + + type TRB_FSM_T is (IDLE, START_READOUT, START_READOUT_WAIT, FEE_BUSY, SEND_EINF_H, SEND_EINF_L, SEND_LENGTH, SEND_SOURCE, SEND_SOURCE_WAIT, SEND_PAYLOAD_H, SEND_PAYLOAD_L, COMPL_WAIT, COMPL_NOT_BUSY_WAIT, EVT_WAIT); + signal trb_fsm_i : TRB_FSM_T; + +begin + REGIO_ADDR_IN <= (others => '0'); + REGIO_DATA_IN <= x"0000_0001"; + REGIO_WRITE_ENABLE_IN <= '1'; + + CLK_IN <= not CLK_IN after 5 ns; + RESET_IN <= '1', '0' after 30 ns; + + CBMNET_CLK_IN <= not CBMNET_CLK_IN after 4 ns; + CBMNET_RESET_IN <= '1', '0' after 20 ns; + CBMNET_LINK_ACTIVE_IN <= '1'; + + gbe_fee_read_in <= '1'; + gbe_cts_status_bits_in <= x"beafc0de"; + + send_enabled_i <= '0', '1' after 100 ns; + + process is + variable wait_cnt_v : integer range 0 to 15 := 0; + begin + wait until rising_edge(CLK_IN); + + HUB_CTS_START_READOUT_IN <= '1'; + HUB_FEE_BUSY_IN <= '1'; + HUB_FEE_DATAREADY_IN <= '0'; + + case(trb_fsm_i) is + when IDLE => + HUB_CTS_START_READOUT_IN <= '0'; + HUB_FEE_BUSY_IN <= '0'; + if send_enabled_i = '1' then + trb_fsm_i <= START_READOUT; + end if; + + when START_READOUT => + trb_fsm_i <= START_READOUT_WAIT; + wait_cnt_v := 10; + HUB_FEE_BUSY_IN <= '0'; + event_id <= event_id + 1; + + when START_READOUT_WAIT => + if wait_cnt_v = 0 then + trb_fsm_i <= FEE_BUSY; + wait_cnt_v := 5; + else + wait_cnt_v := wait_cnt_v - 1; + end if; + + HUB_FEE_BUSY_IN <= '0'; + + when FEE_BUSY => + if wait_cnt_v = 0 then + trb_fsm_i <= SEND_EINF_H; + else + wait_cnt_v := wait_cnt_v - 1; + end if; + + HUB_FEE_BUSY_IN <= '1'; + + when SEND_EINF_H => + HUB_FEE_DATA_IN <= x"8765"; + HUB_FEE_DATAREADY_IN <= '1'; + trb_fsm_i <= SEND_EINF_L; + when SEND_EINF_L => + HUB_FEE_DATA_IN <= std_logic_vector(event_id); + HUB_FEE_DATAREADY_IN <= '1'; + trb_fsm_i <= SEND_LENGTH; + + when SEND_LENGTH => + HUB_FEE_DATA_IN <= std_logic_vector(send_length_i); + send_counter_i <= send_length_i; + HUB_FEE_DATAREADY_IN <= '1'; + trb_fsm_i <= SEND_SOURCE; + when SEND_SOURCE => + HUB_FEE_DATA_IN <= x"affe"; + HUB_FEE_DATAREADY_IN <= '1'; + trb_fsm_i <= SEND_SOURCE_WAIT; + + when SEND_SOURCE_WAIT => + trb_fsm_i <= SEND_PAYLOAD_H; + + when SEND_PAYLOAD_H => + HUB_FEE_DATA_IN <= x"bb" & std_logic_vector(event_id(7 downto 0)); + HUB_FEE_DATAREADY_IN <= '1'; + trb_fsm_i <= SEND_PAYLOAD_L; + + when SEND_PAYLOAD_L => + HUB_FEE_DATA_IN <= x"c" & std_logic_vector(send_counter_i(11 downto 0)); + HUB_FEE_DATAREADY_IN <= '1'; + trb_fsm_i <= SEND_PAYLOAD_H; + send_counter_i <= send_counter_i - 1; + + if send_counter_i = 1 then + trb_fsm_i <= COMPL_WAIT; + wait_cnt_v := 5; + end if; + + when COMPL_WAIT => + if wait_cnt_v = 0 then + wait_cnt_v := 5; + trb_fsm_i <= COMPL_NOT_BUSY_WAIT; + else + wait_cnt_v := wait_cnt_v - 1; + end if; + + HUB_FEE_BUSY_IN <= '1'; + + + when COMPL_NOT_BUSY_WAIT => + HUB_CTS_START_READOUT_IN <= '0'; + if wait_cnt_v = 0 then + trb_fsm_i <= EVT_WAIT; + wait_cnt_v := 5; + else + wait_cnt_v := wait_cnt_v - 1; + end if; + + HUB_FEE_BUSY_IN <= '0'; + send_wait_counter_i <= (others => '0'); + + + when EVT_WAIT => + HUB_CTS_START_READOUT_IN <= '0'; + HUB_FEE_BUSY_IN <= '0'; + + send_wait_counter_i <= send_wait_counter_i + 1; + if send_wait_counter_i >= UNSIGNED(send_wait_threshold_i) then + send_length_i(9 downto 0) <= send_length_i(9 downto 0) + 1; + if send_length_i = x"0000" then + send_length_i <= x"0001"; + end if; + trb_fsm_i <= IDLE; + end if; + + end case; + end process; + + + PROC_CBMNET: process is + variable wait_dur : integer range 0 to 10000 := 250; + begin + CBMNET_DATA2SEND_STOP_IN <= '0'; + wait until falling_edge(CBMNET_DATA2SEND_END_OUT); + CBMNET_DATA2SEND_STOP_IN <= '1'; + wait until rising_edge(CBMNET_CLK_IN); + wait for wait_dur * 8 ns; + + if wait_dur = 10000 then + wait_dur := 0; + else + wait_dur := wait_dur + 1; + end if; + end process; + + --GBE_FEE_READ_IN <= HUB_FEE_DATAREADY_IN; + + DUT: cbmnet_readout + port map ( + CLK_IN => CLK_IN, -- in std_logic; + RESET_IN => RESET_IN, -- in std_logic; + + -- connect to hub + HUB_CTS_NUMBER_IN => HUB_CTS_NUMBER_IN, -- in std_logic_vector (15 downto 0); + HUB_CTS_CODE_IN => HUB_CTS_CODE_IN, -- in std_logic_vector (7 downto 0); + HUB_CTS_INFORMATION_IN => HUB_CTS_INFORMATION_IN, -- in std_logic_vector (7 downto 0); + HUB_CTS_READOUT_TYPE_IN => HUB_CTS_READOUT_TYPE_IN, -- in std_logic_vector (3 downto 0); + HUB_CTS_START_READOUT_IN => HUB_CTS_START_READOUT_IN, -- in std_logic; + HUB_CTS_READOUT_FINISHED_OUT => HUB_CTS_READOUT_FINISHED_OUT, -- out std_logic; --no more data, end transfer, send TRM + HUB_CTS_STATUS_BITS_OUT => HUB_CTS_STATUS_BITS_OUT, -- out std_logic_vector (31 downto 0); + HUB_FEE_DATA_IN => HUB_FEE_DATA_IN, -- in std_logic_vector (15 downto 0); + HUB_FEE_DATAREADY_IN => HUB_FEE_DATAREADY_IN, -- in std_logic; + HUB_FEE_READ_OUT => HUB_FEE_READ_OUT, -- out std_logic; --must be high when idle, otherwise you will never get a dataready + HUB_FEE_STATUS_BITS_IN => HUB_FEE_STATUS_BITS_IN, -- in std_logic_vector (31 downto 0); + HUB_FEE_BUSY_IN => HUB_FEE_BUSY_IN, -- in std_logic; + + -- connect to GbE + GBE_CTS_NUMBER_OUT => GBE_CTS_NUMBER_OUT, -- out std_logic_vector (15 downto 0); + GBE_CTS_CODE_OUT => GBE_CTS_CODE_OUT, -- out std_logic_vector (7 downto 0); + GBE_CTS_INFORMATION_OUT => GBE_CTS_INFORMATION_OUT, -- out std_logic_vector (7 downto 0); + GBE_CTS_READOUT_TYPE_OUT => GBE_CTS_READOUT_TYPE_OUT, -- out std_logic_vector (3 downto 0); + GBE_CTS_START_READOUT_OUT => GBE_CTS_START_READOUT_OUT, -- out std_logic; + GBE_CTS_READOUT_FINISHED_IN => GBE_CTS_READOUT_FINISHED_IN, -- in std_logic; --no more data, end transfer, send TRM + GBE_CTS_STATUS_BITS_IN => GBE_CTS_STATUS_BITS_IN, -- in std_logic_vector (31 downto 0); + GBE_FEE_DATA_OUT => GBE_FEE_DATA_OUT, -- out std_logic_vector (15 downto 0); + GBE_FEE_DATAREADY_OUT => GBE_FEE_DATAREADY_OUT, -- out std_logic; + GBE_FEE_READ_IN => GBE_FEE_READ_IN, -- in std_logic; --must be high when idle, otherwise you will never get a dataready + GBE_FEE_STATUS_BITS_OUT => GBE_FEE_STATUS_BITS_OUT, -- out std_logic_vector (31 downto 0); + GBE_FEE_BUSY_OUT => GBE_FEE_BUSY_OUT, -- out std_logic; + + -- reg io + REGIO_ADDR_IN => REGIO_ADDR_IN, -- in std_logic_vector(15 downto 0); + REGIO_DATA_IN => REGIO_DATA_IN, -- in std_logic_vector(31 downto 0); + REGIO_READ_ENABLE_IN => REGIO_READ_ENABLE_IN, -- in std_logic; + REGIO_WRITE_ENABLE_IN => REGIO_WRITE_ENABLE_IN, -- in std_logic; + REGIO_DATA_OUT => REGIO_DATA_OUT, -- out std_logic_vector(31 downto 0); + REGIO_DATAREADY_OUT => REGIO_DATAREADY_OUT, -- out std_logic; + REGIO_WRITE_ACK_OUT => REGIO_WRITE_ACK_OUT, -- out std_logic; + REGIO_UNKNOWN_ADDR_OUT => REGIO_UNKNOWN_ADDR_OUT, -- out std_logic; + + -- CBMNet + CBMNET_CLK_IN => CBMNET_CLK_IN, -- in std_logic; + CBMNET_RESET_IN => CBMNET_RESET_IN, -- in std_logic; + CBMNET_LINK_ACTIVE_IN => CBMNET_LINK_ACTIVE_IN, -- in std_logic; + + CBMNET_DATA2SEND_STOP_IN => CBMNET_DATA2SEND_STOP_IN, -- in std_logic; + CBMNET_DATA2SEND_START_OUT => CBMNET_DATA2SEND_START_OUT, -- out std_logic; + CBMNET_DATA2SEND_END_OUT => CBMNET_DATA2SEND_END_OUT, -- out std_logic; + CBMNET_DATA2SEND_DATA_OUT =>CBMNET_DATA2SEND_DATA_OUT -- out std_logic_vector(15 downto 0) + ); + + THE_LOGGER : TB_CBMNET_LOGGER + generic map (log_file => "frames2.txt") + port map ( + CLK_IN => CBMNET_CLK_IN, -- in std_logic; + RESET_IN => CBMNET_RESET_IN, -- in std_logic; + LINK_ACTIVE_IN => CBMNET_LINK_ACTIVE_IN, -- in std_logic; + + DATA2SEND_IN => CBMNET_DATA2SEND_DATA_OUT, -- std_logic_vector(15 downto 0); + DATA2SEND_STOP_IN => CBMNET_DATA2SEND_STOP_IN, -- std_logic; + DATA2SEND_START_IN => CBMNET_DATA2SEND_START_OUT, -- std_logic; + DATA2SEND_END_IN => CBMNET_DATA2SEND_END_OUT -- std_logic + ); + +end architecture; \ No newline at end of file diff --git a/cbmnet/code/tb_cbmnet_readout_trbnet_decoder.vhd b/cbmnet/code/tb_cbmnet_readout_trbnet_decoder.vhd index 026d270..cf14367 100644 --- a/cbmnet/code/tb_cbmnet_readout_trbnet_decoder.vhd +++ b/cbmnet/code/tb_cbmnet_readout_trbnet_decoder.vhd @@ -36,8 +36,8 @@ begin port map ( CLK_IN => CLK_IN, RESET_IN => RESET_IN, + ENABLED_IN => '1', HUB_CTS_START_READOUT_IN => HUB_CTS_START_READOUT_IN, - HUB_CTS_READOUT_FINISHED_OUT => HUB_CTS_READOUT_FINISHED_OUT, HUB_FEE_DATA_IN => HUB_FEE_DATA_IN, HUB_FEE_DATAREADY_IN => HUB_FEE_DATAREADY_IN, GBE_FEE_READ_IN => GBE_FEE_READ_IN, diff --git a/cbmnet/compile_constraints.pl b/cbmnet/compile_constraints.pl index 04aafbc..c54ae42 100755 --- a/cbmnet/compile_constraints.pl +++ b/cbmnet/compile_constraints.pl @@ -27,8 +27,7 @@ unless(-e $workdir) { chdir($workdir); system ("$back/../../base/linkdesignfiles.sh '$back'"); -symlink "$back/../cores/cbmnet_sfp1.txt", 'cbmnet_sfp1.txt'; -symlink "$back/../cores/cbmnet_sfp1_slow.txt", 'cbmnet_sfp1_slow.txt'; +symlink "$back/../../base/cores/cbmnet_sfp1.txt", 'cbmnet_sfp1.txt'; chdir($script_dir); diff --git a/cbmnet/compile_periph_frankfurt.pl b/cbmnet/compile_periph_frankfurt.pl index 831d428..2dca5f1 100755 --- a/cbmnet/compile_periph_frankfurt.pl +++ b/cbmnet/compile_periph_frankfurt.pl @@ -20,7 +20,7 @@ my $lm_license_file_for_par = "1702\@hadeb05.gsi.de"; #my $synplify_path = '/d/jspc29/lattice/synplify/G-2012.09-SP1/'; my $synplify_path = '/d/jspc29/lattice/synplify/I-2013.09-SP1/'; -my $lattice_path = '/d/jspc29/lattice/diamond/3.1/'; +my $lattice_path = '/d/jspc29/lattice/diamond/3.2_x64/'; ################################################################################### my $btype = 'slave'; @@ -115,49 +115,24 @@ execute($c); system("rm $TOPNAME.ncd"); -# #$c=qq|$lattice_path/ispfpga/bin/lin/multipar -pr "$TOPNAME.prf" -o "mpar_$TOPNAME.rpt" -log "mpar_$TOPNAME.log" -p "../$TOPNAME.p2t" "$tpmap.ncd" "$TOPNAME.ncd"|; -# #$c=qq|$lattice_path/ispfpga/bin/lin/par -f "../$TOPNAME.p2t" "$tpmap.ncd" "$TOPNAME.dir" "$TOPNAME.prf"|; -# $c=qq|$lattice_path/bin/lin/mpartrce -p "../$TOPNAME.p2t" -f "../$TOPNAME.p3t" -tf "$TOPNAME.pt" "|.$TOPNAME.qq|_map.ncd" "$TOPNAME.ncd"|; -# execute($c); -# -# #Make Bitfile -# $c=qq|$lattice_path/ispfpga/bin/lin/ltxt2ptxt $TOPNAME.ncd|; -# execute($c); -# $c=qq|$lattice_path/ispfpga/bin/lin/bitgen -w "$TOPNAME.ncd" "$TOPNAME.prf"|; -# execute($c); -# -# -# # IOR IO Timing Report -# $c=qq|$lattice_path/ispfpga/bin/lin/iotiming -s "$TOPNAME.ncd" "$TOPNAME.prf"|; -# execute($c); -# -# # TWR Timing Report -# $c=qq|$lattice_path/ispfpga/bin/lin/trce -c -v 15 -o "$TOPNAME.twr.setup" "$TOPNAME.ncd" "$TOPNAME.prf"|; -# execute($c); -# -# $c=qq|$lattice_path/ispfpga/bin/lin/trce -hld -c -v 5 -o "$TOPNAME.twr.hold" "$TOPNAME.ncd" "$TOPNAME.prf"|; -# execute($c); - -#$c=qq|mpartrce -p "../$TOPNAME.p2t" -log "$TOPNAME.log" -o "$TOPNAME.rpt" -pr "$TOPNAME.prf" -tf "$TOPNAME.pt" "|.$TOPNAME.qq|_map.ncd" "$TOPNAME.ncd"|; -# $c=qq|$lattice_path/ispfpga/bin/lin/multipar -pr "$TOPNAME.prf" -o "mpar_$TOPNAME.rpt" -log "mpar_$TOPNAME.log" -p "../$TOPNAME.p2t" "$tpmap.ncd" "$TOPNAME.ncd"|; -$c=qq|$lattice_path/ispfpga/bin/lin/par -w -l 5 -i 6 -t 2 -e 0 -exp parCDP=1:parCDR=1:parPlcInLimit=0:parPlcInNeighborSize=1:parPathBased=ON:parHold=ON:parHoldLimit=10000:paruseNBR=1: $tpmap.ncd $TOPNAME.ncd $TOPNAME.prf|; +$c=qq|mpartrce -p "../$TOPNAME.p2t" -f "../$TOPNAME.p3t" -tf "$TOPNAME.pt" "|.$TOPNAME.qq|_map.ncd" "$TOPNAME.ncd"|; execute($c); + # IOR IO Timing Report -# $c=qq|$lattice_path/ispfpga/bin/lin/iotiming -s "$TOPNAME.ncd" "$TOPNAME.prf"|; -# execute($c); +$c=qq|$lattice_path/ispfpga/bin/lin/iotiming -s "$TOPNAME.ncd" "$TOPNAME.prf"|; +execute($c); # TWR Timing Report -$c=qq|$lattice_path/ispfpga/bin/lin/trce -c -v 50 -html -o "$TOPNAME.twr.setup" "$TOPNAME.ncd" "$TOPNAME.prf"|; +$c=qq|$lattice_path/ispfpga/bin/lin/trce -c -v 15 -o "$TOPNAME.twr.setup" "$TOPNAME.ncd" "$TOPNAME.prf"|; execute($c); -$c=qq|$lattice_path/ispfpga/bin/lin/trce -hld -c -v 50 -html -o "$TOPNAME.twr.hold" "$TOPNAME.ncd" "$TOPNAME.prf"|; +$c=qq|$lattice_path/ispfpga/bin/lin/trce -hld -c -v 5 -o "$TOPNAME.twr.hold" "$TOPNAME.ncd" "$TOPNAME.prf"|; execute($c); $c=qq|$lattice_path/ispfpga/bin/lin/ltxt2ptxt $TOPNAME.ncd|; execute($c); -$c=qq|$lattice_path/ispfpga/bin/lin/bitgen -w -g CfgMode:Disable -g RamCfg:Reset -g ES:No $TOPNAME.ncd $TOPNAME.bit $TOPNAME.prf|; -# $c=qq|$lattice_path/ispfpga/bin/lin/bitgen -w "$TOPNAME.ncd" "$TOPNAME.prf"|; +$c=qq|$lattice_path/ispfpga/bin/lin/bitgen -w "$TOPNAME.ncd" "$TOPNAME.prf"|; execute($c); chdir ".."; diff --git a/cbmnet/test/check_frames.pl b/cbmnet/test/check_frames.pl new file mode 100755 index 0000000..3bf4223 --- /dev/null +++ b/cbmnet/test/check_frames.pl @@ -0,0 +1,117 @@ +#!/usr/bin/env perl +use warnings; +use strict; +use Data::Dumper; + +my @packet = (); + +my $success = 0; +my $errors = 0; +my $skipped = 0; +my $line = 0; +my $ref = ""; + + +sub fassert { + my $cond = shift; + my $msg = shift; + + unless ($cond) { + @packet = (); + $errors++; + print "Error in $line ($ref): $msg\n"; + } + + return $cond; +} + +sub stats { + printf("Read: % 9d | Skipped: % 9d | Success: % 9d | Errors: % 9d\n", $line, $skipped, $success, $errors) +} + +my $lastFrameNo = -1; +my $lastTransNo = -1; + +my $lastInnerTransNo = -1; + +while(my $frame = ) { + $line++; + $frame =~ /DATA\((.*)\):/; + $ref = $1; + $frame =~ s/DATA\(.*\):\s+//; + $frame =~ s/\s+$//; + my @frameData = map {$_} split(" ", $frame); + print Dumper @frameData; + + next unless fassert($#frameData > 0, "Frame must no be empty"); + next unless fassert($#frameData <= 32, "Frame must no be longer than 64 bytes. Got " . (2*$#frameData)); + + my $hdr = shift @frameData; + + my $start = ($hdr & 0x4000) != 0; + my $end = ($hdr & 0x8000) != 0; + my $frameNo = $hdr & 0x3f; + my $transNo = ($hdr >> 6) & 0x3f; + + print "$#frameData\n"; + + next unless fassert($#frameData == 30 or $end, "Only last frame can be shorted than 64 bytes. Got " . (2*$#frameData+2)); + + + if ($start) { + my $exp = ($lastTransNo+1) & 0x3f; + fassert($lastTransNo == -1 or $exp == $transNo, "Expected sequential transaction numbers. Exp $exp. Got $transNo"); + fassert(-1 == $#packet, "Unexpected start"); + @packet = @frameData; + $lastTransNo = $transNo; + } else { + if ($#packet == -1) { + $skipped++; + } else { + next unless fassert($lastTransNo == $transNo, "TransNo mismatch"); + @packet = (@packet, @frameData); + } + } + + # print join(" ", map{sprintf("%04x", $_)} @packet) . "\n"; + + if ($end and $#packet > 0) { + my $expectLength = ($packet[0] << 16) | $packet[1]; + next unless fassert($expectLength == 2*$#packet+2, "Length mismatch. Packet says $expectLength. Got " . (2*$#packet+2)); + + my $payloadLength = ($expectLength - 16 - 8); + next unless fassert($payloadLength % 4 == 0, "Payload length has to be a multiple of 4. Got $payloadLength bytes"); + + my $payloadWords = $payloadLength / 4; + my $fail=0; + for(my $i = 0; $i < $payloadWords and !$fail; $i++) { + $fail=1 unless fassert($packet[$i*2 + 8] == $packet[8], "TrbTransactionNo mismatch"); + my $exp = ($payloadWords - $i) & 0xfff; + my $got = $packet[$i*2 + 8 + 1] & 0xfff; + $fail=1 unless fassert($fail or $exp == $got, "Payload-RunNo mismatch. Exp: $exp, Got: $got"); + } + + next unless fassert(($packet[8] & 0xff00) == 0xbb00, "Expected 0xbb-- as first word of payload"); + + if ($lastInnerTransNo != -1) { + my $exp = ($lastInnerTransNo + 1) & 0xff; + my $got = $packet[8] & 0xff; + # print "Error at $line: Inner TransNo mismatch. Exp: $exp, Got $got\n" unless ($exp == $got); + } + + $lastInnerTransNo = $packet[8] & 0xff; + + $fail=1 unless fassert($fail or $packet[-1] == 0xc0de, "Trailer mismatch"); + $fail=1 unless fassert($fail or $packet[-2] == 0xbeaf, "Trailer mismatch"); + $fail=1 unless fassert($fail or $packet[-3] == 0x5555, "Trailer mismatch"); + $fail=1 unless fassert($fail or $packet[-4] == 0x0001, "Trailer mismatch"); + + $success++ unless $fail; + #print "Sucessfully read packet with $expectLength bytes\n" unless $fail; + @packet = (); + } + + stats() unless ($line % 10000); +} + +stats(); \ No newline at end of file diff --git a/cbmnet/trb3_periph_cbmnet.lpf b/cbmnet/trb3_periph_cbmnet.lpf new file mode 100644 index 0000000..785ea82 --- /dev/null +++ b/cbmnet/trb3_periph_cbmnet.lpf @@ -0,0 +1,227 @@ +BLOCK RESETPATHS ; +BLOCK ASYNCPATHS ; +BLOCK RD_DURING_WR_PATHS ; +################################################################# +# Basic Settings +################################################################# +# SYSCONFIG MCCLK_FREQ = 2.5; +FREQUENCY PORT "CLK_PCLK_RIGHT" 200.000000 MHz ; +FREQUENCY PORT "CLK_PCLK_LEFT" 200.000000 MHz ; +FREQUENCY PORT "CLK_GPLL_RIGHT" 200.000000 MHz ; +FREQUENCY PORT "CLK_GPLL_LEFT" 125.000000 MHz ; +################################################################# +# Clock I/O +################################################################# +LOCATE COMP "CLK_PCLK_RIGHT" SITE "U20" ; +LOCATE COMP "CLK_PCLK_LEFT" SITE "M4" ; +LOCATE COMP "CLK_SERDES_INT_RIGHT" SITE "AC18" ; +LOCATE COMP "CLK_SERDES_INT_LEFT" SITE "AC10" ; +LOCATE COMP "CLK_GPLL_RIGHT" SITE "W1" ; +LOCATE COMP "CLK_GPLL_LEFT" SITE "U25" ; +DEFINE PORT GROUP "CLK_group" "CLK*" ; +IOBUF GROUP "CLK_group" IO_TYPE=LVDS25 ; +################################################################# +# Trigger I/O +################################################################# +#Trigger from fan-out +LOCATE COMP "TRIGGER_LEFT" SITE "V3" ; +LOCATE COMP "TRIGGER_RIGHT" SITE "N24" ; +IOBUF PORT "TRIGGER_RIGHT" IO_TYPE=LVDS25 ; +IOBUF PORT "TRIGGER_LEFT" IO_TYPE=LVDS25 ; +################################################################# +# To central FPGA +################################################################# +LOCATE COMP "FPGA5_COMM[0]" SITE "AD4" ; +LOCATE COMP "FPGA5_COMM[1]" SITE "AE3" ; +LOCATE COMP "FPGA5_COMM[2]" SITE "AA7" ; +LOCATE COMP "FPGA5_COMM[3]" SITE "AB7" ; +LOCATE COMP "FPGA5_COMM[4]" SITE "AD3" ; +LOCATE COMP "FPGA5_COMM[5]" SITE "AC4" ; +LOCATE COMP "FPGA5_COMM[6]" SITE "AE2" ; +LOCATE COMP "FPGA5_COMM[7]" SITE "AF3" ; +LOCATE COMP "FPGA5_COMM[8]" SITE "AE4" ; +LOCATE COMP "FPGA5_COMM[9]" SITE "AF4" ; +LOCATE COMP "FPGA5_COMM[10]" SITE "V10" ; +LOCATE COMP "FPGA5_COMM[11]" SITE "W10" ; +DEFINE PORT GROUP "FPGA_group" "FPGA*" ; +IOBUF GROUP "FPGA_group" IO_TYPE=LVCMOS25 PULLMODE=UP ; +LOCATE COMP "TEST_LINE[0]" SITE "A5" ; +LOCATE COMP "TEST_LINE[1]" SITE "A6" ; +LOCATE COMP "TEST_LINE[2]" SITE "G8" ; +LOCATE COMP "TEST_LINE[3]" SITE "F9" ; +LOCATE COMP "TEST_LINE[4]" SITE "D9" ; +LOCATE COMP "TEST_LINE[5]" SITE "D10" ; +LOCATE COMP "TEST_LINE[6]" SITE "F10" ; +LOCATE COMP "TEST_LINE[7]" SITE "E10" ; +LOCATE COMP "TEST_LINE[8]" SITE "A8" ; +LOCATE COMP "TEST_LINE[9]" SITE "B8" ; +LOCATE COMP "TEST_LINE[10]" SITE "G10" ; +LOCATE COMP "TEST_LINE[11]" SITE "G9" ; +LOCATE COMP "TEST_LINE[12]" SITE "C9" ; +LOCATE COMP "TEST_LINE[13]" SITE "C10" ; +LOCATE COMP "TEST_LINE[14]" SITE "H10" ; +LOCATE COMP "TEST_LINE[15]" SITE "H11" ; +DEFINE PORT GROUP "TEST_LINE_group" "TEST_LINE*" ; +IOBUF GROUP "TEST_LINE_group" IO_TYPE=LVCMOS25 PULLMODE=DOWN SLEWRATE=FAST DRIVE=20 ; +################################################################# +# Connection to AddOn +################################################################# +LOCATE COMP "LED_LINKOK[1]" SITE "P1" ;#DQLL0_0 #1 +LOCATE COMP "LED_RX[1]" SITE "P2" ;#DQLL0_1 #3 +LOCATE COMP "LED_TX[1]" SITE "T2" ;#DQLL0_2 #5 +LOCATE COMP "SFP_MOD0[1]" SITE "U3" ;#DQLL0_3 #7 +LOCATE COMP "SFP_MOD1[1]" SITE "R1" ;#DQLL0_4 #9 +LOCATE COMP "SFP_MOD2[1]" SITE "R2" ;#DQLL0_5 #11 +LOCATE COMP "SFP_RATESEL[1]" SITE "N3" ;#DQSLL0_T #13 +LOCATE COMP "SFP_TXDIS[1]" SITE "P3" ;#DQSLL0_C #15 +LOCATE COMP "SFP_LOS[1]" SITE "P5" ;#DQLL0_6 #17 +LOCATE COMP "SFP_TXFAULT[1]" SITE "P6" ;#DQLL0_7 #19 +LOCATE COMP "LED_LINKOK[2]" SITE "N5" ;#DQLL0_8 #21 +LOCATE COMP "LED_RX[2]" SITE "N6" ;#DQLL0_9 #23 +LOCATE COMP "LED_TX[2]" SITE "AC2" ;#DQLL2_0 #25 +LOCATE COMP "SFP_MOD0[2]" SITE "AC3" ;#DQLL2_1 #27 +LOCATE COMP "SFP_MOD1[2]" SITE "AB1" ;#DQLL2_2 #29 +LOCATE COMP "SFP_MOD2[2]" SITE "AC1" ;#DQLL2_3 #31 +LOCATE COMP "SFP_RATESEL[2]" SITE "AA1" ;#DQLL2_4 #33 +LOCATE COMP "SFP_TXDIS[2]" SITE "AA2" ;#DQLL2_5 #35 +LOCATE COMP "SFP_LOS[2]" SITE "W7" ;#DQLL2_T #37 #should be DQSLL2 +LOCATE COMP "SFP_TXFAULT[2]" SITE "W6" ;#DQLL2_C #39 #should be DQSLL2 +LOCATE COMP "LED_LINKOK[3]" SITE "AD1" ;#DQLL3_0 #2 +LOCATE COMP "LED_RX[3]" SITE "AD2" ;#DQLL3_1 #4 +LOCATE COMP "LED_TX[3]" SITE "AB5" ;#DQLL3_2 #6 +LOCATE COMP "SFP_MOD0[3]" SITE "AB6" ;#DQLL3_3 #8 +LOCATE COMP "SFP_MOD1[3]" SITE "AB3" ;#DQLL3_4 #10 +LOCATE COMP "SFP_MOD2[3]" SITE "AB4" ;#DQLL3_5 #12 +LOCATE COMP "SFP_RATESEL[3]" SITE "Y6" ;#DQLL3_T #14 #should be DQSLL3 +LOCATE COMP "SFP_TXDIS[3]" SITE "Y7" ;#DQLL3_C #16 #should be DQSLL3 +LOCATE COMP "SFP_LOS[3]" SITE "AA3" ;#DQLL3_6 #18 +LOCATE COMP "SFP_TXFAULT[3]" SITE "AA4" ;#DQLL3_7 #20 +LOCATE COMP "LED_LINKOK[4]" SITE "W8" ;#DQLL3_8 #22 +LOCATE COMP "LED_RX[4]" SITE "W9" ;#DQLL3_9 #24 +LOCATE COMP "LED_TX[4]" SITE "V1" ;#DQLL1_0 #26 +LOCATE COMP "SFP_MOD0[4]" SITE "U2" ;#DQLL1_1 #28 +LOCATE COMP "SFP_MOD1[4]" SITE "T1" ;#DQLL1_2 #30 +LOCATE COMP "SFP_MOD2[4]" SITE "U1" ;#DQLL1_3 #32 +LOCATE COMP "SFP_RATESEL[4]" SITE "P4" ;#DQLL1_4 #34 +LOCATE COMP "SFP_TXDIS[4]" SITE "R3" ;#DQLL1_5 #36 +LOCATE COMP "SFP_LOS[4]" SITE "T3" ;#DQSLL1_T #38 +LOCATE COMP "SFP_TXFAULT[4]" SITE "R4" ;#DQSLL1_C #40 +LOCATE COMP "LED_LINKOK[5]" SITE "W23" ;#DQLR1_0 #169 +LOCATE COMP "LED_RX[5]" SITE "W22" ;#DQLR1_1 #171 +LOCATE COMP "LED_TX[5]" SITE "AA25" ;#DQLR1_2 #173 +LOCATE COMP "SFP_MOD0[5]" SITE "Y24" ;#DQLR1_3 #175 +LOCATE COMP "SFP_MOD1[5]" SITE "AA26" ;#DQLR1_4 #177 +LOCATE COMP "SFP_MOD2[5]" SITE "AB26" ;#DQLR1_5 #179 +LOCATE COMP "SFP_RATESEL[5]" SITE "W21" ;#DQSLR1_T #181 +LOCATE COMP "SFP_TXDIS[5]" SITE "W20" ;#DQSLR1_C #183 +LOCATE COMP "SFP_LOS[5]" SITE "AA24" ;#DQLR1_6 #185 +LOCATE COMP "SFP_TXFAULT[5]" SITE "AA23" ;#DQLR1_7 #187 +LOCATE COMP "LED_LINKOK[6]" SITE "R25" ;#DQLR2_0 #170 +LOCATE COMP "LED_RX[6]" SITE "R26" ;#DQLR2_1 #172 +LOCATE COMP "LED_TX[6]" SITE "T25" ;#DQLR2_2 #174 +LOCATE COMP "SFP_MOD0[6]" SITE "T24" ;#DQLR2_3 #176 +LOCATE COMP "SFP_MOD1[6]" SITE "T26" ;#DQLR2_4 #178 +LOCATE COMP "SFP_MOD2[6]" SITE "U26" ;#DQLR2_5 #180 +LOCATE COMP "SFP_RATESEL[6]" SITE "V21" ;#DQSLR2_T #182 +LOCATE COMP "SFP_TXDIS[6]" SITE "V22" ;#DQSLR2_C #184 +LOCATE COMP "SFP_LOS[6]" SITE "U24" ;#DQLR2_6 #186 +LOCATE COMP "SFP_TXFAULT[6]" SITE "V24" ;#DQLR2_7 #188 +DEFINE PORT GROUP "SFP_group" "SFP*" ; +IOBUF GROUP "SFP_group" IO_TYPE=LVCMOS25 PULLMODE=UP ; +################################################################# +# Additional Lines to AddOn +################################################################# +#Lines 0/1 are terminated with 100 Ohm, pads available on 0-3 +#all lines are input only +#line 4/5 go to PLL input +LOCATE COMP "SPARE_LINE_0" SITE "M25" ;#194 +LOCATE COMP "SPARE_LINE_1" SITE "M26" ;#196 +LOCATE COMP "SPARE_LINE_2" SITE "W4" ;#198 +LOCATE COMP "SPARE_LINE_3" SITE "W5" ;#200 +LOCATE COMP "SPARE_LINE_4" SITE "M3" ;#DQUL3_8_OUTOFLANE_FPGA__3 #69 +LOCATE COMP "SPARE_LINE_5" SITE "M2" ;#DQUL3_9_OUTOFLANE_FPGA__3 #71 +################################################################# +# Flash ROM and Reboot +################################################################# +LOCATE COMP "FLASH_CLK" SITE "B12" ; +LOCATE COMP "FLASH_CS" SITE "E11" ; +LOCATE COMP "FLASH_DIN" SITE "E12" ; +LOCATE COMP "FLASH_DOUT" SITE "A12" ; +DEFINE PORT GROUP "FLASH_group" "FLASH*" ; +IOBUF GROUP "FLASH_group" IO_TYPE=LVCMOS25 PULLMODE=NONE ; +LOCATE COMP "PROGRAMN" SITE "B11" ; +IOBUF PORT "PROGRAMN" IO_TYPE=LVCMOS25 PULLMODE=UP DRIVE=8 ; +################################################################# +# Misc +################################################################# +LOCATE COMP "TEMPSENS" SITE "A13" ; +IOBUF PORT "TEMPSENS" IO_TYPE=LVCMOS25 PULLMODE=UP DRIVE=8 ; +#coding of FPGA number +LOCATE COMP "CODE_LINE[1]" SITE "AA20" ; +LOCATE COMP "CODE_LINE[0]" SITE "Y21" ; +IOBUF PORT "CODE_LINE[1]" IO_TYPE=LVCMOS25 PULLMODE=UP ; +IOBUF PORT "CODE_LINE[0]" IO_TYPE=LVCMOS25 PULLMODE=UP ; +#terminated differential pair to pads +LOCATE COMP "SUPPL" SITE "C14" ; +IOBUF PORT "SUPPL" IO_TYPE=LVDS25 ; +################################################################# +# LED +################################################################# +LOCATE COMP "LED_GREEN" SITE "F12" ; +LOCATE COMP "LED_ORANGE" SITE "G13" ; +LOCATE COMP "LED_RED" SITE "A15" ; +LOCATE COMP "LED_YELLOW" SITE "A16" ; +DEFINE PORT GROUP "LED_group" "LED*" ; +IOBUF GROUP "LED_group" IO_TYPE=LVCMOS25 PULLMODE=NONE DRIVE=12 ; +# BLOCK RESETPATHS ; +# BLOCK ASYNCPATHS ; +# BLOCK RD_DURING_WR_PATHS ; +################################################################# +# Basic Settings +################################################################# +SYSCONFIG MCCLK_FREQ=20 ; +# FREQUENCY NET "THE_CBM_PHY/CLK_TX_FULL_I" 250 MHz; +#FREQUENCY NET "THE_CBM_PHY/RCLK_250_I" 250.000000 MHz ; +#Change the next two lines to the clk_fast signal of the ADC +# USE PRIMARY2EDGE NET "THE_MAIN_PLL/PLLInst_0"; +# USE PRIMARY NET "THE_MAIN_PLL/PLLInst_0"; +#USE PRIMARY NET "CLK_GPLL_LEFT" ; +# USE PRIMARY NET "THE_CBM_PHY/RCLK_250_I"; +# USE SECONDARY NET "THE_CBM_PHY/CLK_TX_FULL_I"; +################################################################# +# Reset Nets +################################################################# +#GSR_NET NET "GSR_N"; +################################################################ +# Locate Serdes and media interfaces +################################################################# +LOCATE COMP "THE_MEDIA_UPLINK/gen_serdes_1_200.THE_SERDES/PCSD_INST" SITE "PCSA" ; +REGION "MEDIA_UPLINK" "R102C95D" 13 25 DEVSIZE; +LOCATE UGROUP "THE_MEDIA_UPLINK/media_interface_group" REGION "MEDIA_UPLINK" ; +LOCATE COMP "THE_CBM_PHY/THE_SERDES/PCSD_INST" SITE "PCSB" ; +#LOCATE COMP "THE_CBM_PHY/GEN_EASY_SERDES/THE_EASY_SERDES/PCSD_INST" SITE "PCSB" ; +#REGION "CBM_PHY" "R102C49D" 13 25; +#LOCATE UGROUP "THE_CBM_PHY/cbmnet_phy_group" REGION "CBM_PHY"; +#REGION "CBM_PHY_RX_GEAR" "R102C50D" 13 15 DEVSIZE; +#LOCATE UGROUP "THE_CBM_PHY/THE_RX_GEAR/cbmnet_phy_rx_gear" REGION "CBM_PHY_RX_GEAR" ; +#REGION "CBM_PHY_TX_GEAR" "R102C50D" 13 15 DEVSIZE; +#LOCATE UGROUP "THE_CBM_PHY/THE_TX_GEAR/cbmnet_phy_tx_gear" REGION "CBM_PHY_TX_GEAR" ; + +################################################################# +# Relax some of the timing constraints +################################################################# + +FREQUENCY PORT "CLK_GPLL_LEFT" 200.000000 MHz ; +FREQUENCY NET "clk_200_i" 200.000000 MHz ; +FREQUENCY NET "clk_100_i_c" 100.000000 MHz ; +FREQUENCY NET "CLK_RX_FULL_OUT" 250.000000 MHz ; +FREQUENCY NET "THE_CBM_PHY/clk_tx_full_i" 250.000000 MHz ; +FREQUENCY NET "THE_MEDIA_UPLINK/un1_THE_MEDIA_UPLINK_2_c" 100.000000 MHz ; +FREQUENCY NET "THE_CBM_PHY/THE_RX_GEAR/clk_125_i_i" 125.000000 MHz ; +FREQUENCY NET "rclk_125_i" 125.000000 MHz ; + +DEFINE BUS "rx_data" NET "THE_CBM_PHY/rx_data_from_serdes_i[0]" NET "THE_CBM_PHY/rx_data_from_serdes_i[1]" NET "THE_CBM_PHY/rx_data_from_serdes_i[2]" NET "THE_CBM_PHY/rx_data_from_serdes_i[3]" NET "THE_CBM_PHY/rx_data_from_serdes_i[4]" NET "THE_CBM_PHY/rx_data_from_serdes_i[5]" NET "THE_CBM_PHY/rx_data_from_serdes_i[6]" NET "THE_CBM_PHY/rx_data_from_serdes_i[7]" NET "THE_CBM_PHY/rx_data_from_serdes_i[8]"; +DEFINE BUS "tx_data" NET "THE_CBM_PHY/tx_data_to_serdes_i[0]" NET "THE_CBM_PHY/tx_data_to_serdes_i[1]" NET "THE_CBM_PHY/tx_data_to_serdes_i[2]" NET "THE_CBM_PHY/tx_data_to_serdes_i[3]" NET "THE_CBM_PHY/tx_data_to_serdes_i[4]" NET "THE_CBM_PHY/tx_data_to_serdes_i[5]" NET "THE_CBM_PHY/tx_data_to_serdes_i[6]" NET "THE_CBM_PHY/tx_data_to_serdes_i[7]" NET "THE_CBM_PHY/tx_data_to_serdes_i[8]"; + +PRIORITIZE BUS "rx_data" 51; +PRIORITIZE BUS "tx_data" 50; \ No newline at end of file diff --git a/cbmnet/trb3_periph_cbmnet.prj b/cbmnet/trb3_periph_cbmnet.prj index 2764571..cbf6a4c 100755 --- a/cbmnet/trb3_periph_cbmnet.prj +++ b/cbmnet/trb3_periph_cbmnet.prj @@ -145,6 +145,7 @@ add_file -vhdl -lib work "../../trbnet/special/handler_lvl1.vhd" add_file -vhdl -lib work "../../trbnet/trb_net16_endpoint_hades_full.vhd" add_file -vhdl -lib work "../../trbnet/basics/ram_dp_rw.vhd" add_file -vhdl -lib work "../../trbnet/lattice/ecp2m/fifo/fifo_var_oreg.vhd" +add_file -vhdl -lib work "../../trbnet/special/bus_register_handler.vhd" add_file -vhdl -lib work "../../trbnet/special/handler_data.vhd" add_file -vhdl -lib work "../../trbnet/special/handler_ipu.vhd" add_file -vhdl -lib work "../../trbnet/special/handler_trigger_and_data.vhd" @@ -159,8 +160,7 @@ add_file -vhdl -lib work "../../trbnet/media_interfaces/trb_net16_med_ecp3_sfp_4 add_file -vhdl -lib work "../../trbnet/media_interfaces/trb_net16_med_ecp3_sfp_4.vhd" add_file -vhdl -lib work "./code/cbmnet_interface_pkg.vhd" add_file -vhdl -lib work "./code/cbmnet_phy_pkg.vhd" -add_file -vhdl -lib work "./cores/cbmnet_sfp1.vhd" -add_file -vhdl -lib work "./cores/cbmnet_sfp1_slow.vhd" +add_file -vhdl -lib work "../base/cores/cbmnet_sfp1.vhd" add_file -vhdl -lib work "../../trbnet/media_interfaces/sync/med_sync_define.vhd" add_file -vhdl -lib work "./code/cbmnet_phy_ecp3_rx_reset_fsm.vhd" add_file -vhdl -lib work "./code/cbmnet_phy_ecp3_tx_reset_fsm.vhd" @@ -170,6 +170,12 @@ add_file -vhdl -lib work "./code/cbmnet_phy_ecp3.vhd" add_file -vhdl -lib work "./trb3_periph_cbmnet.vhd" +add_file -vhdl -lib work "./code/cbmnet_readout_trbnet_decoder.vhd" +add_file -vhdl -lib work "./code/cbmnet_readout_event_packer.vhd" +add_file -vhdl -lib work "./code/cbmnet_readout_fifo.vhd" +add_file -vhdl -lib work "./code/cbmnet_readout_tx_fsm.vhd" +add_file -vhdl -lib work "./code/cbmnet_readout.vhd" + #implementation: "workdir" impl -add workdir -type fpga @@ -191,7 +197,7 @@ set_option -part_companion "" set_option -top_module "trb3_periph_cbmnet" # mapper_options -set_option -frequency 200 +set_option -frequency 125 set_option -default_enum_encoding sequential set_option -write_verilog 0 set_option -write_vhdl 1 @@ -216,7 +222,7 @@ set_option -symbolic_fsm_compiler 1 # Compiler Options set_option -compiler_compatible 1 -set_option -resource_sharing 1 +set_option -resource_sharing 0 #automatic place and route (vendor) options set_option -write_apr_constraint 0 diff --git a/cbmnet/trb3_periph_cbmnet.vhd b/cbmnet/trb3_periph_cbmnet.vhd index ce4cc72..4d025ac 100755 --- a/cbmnet/trb3_periph_cbmnet.vhd +++ b/cbmnet/trb3_periph_cbmnet.vhd @@ -304,12 +304,14 @@ architecture trb3_periph_arch of trb3_periph_cbmnet is type SEND_FSM_T is (START, SEND_HEADER, SEND_PACK_NUM, SEND_LENGTH, SEND_DATA, SEND_FOOTER, AFTER_SEND_WAIT); signal send_fsm_i : SEND_FSM_T; - signal send_length_i : unsigned(4 downto 0); +-- signal send_length_i : unsigned(4 downto 0); signal send_num_pack_counter_i : unsigned(15 downto 0); signal send_enabled_i : std_logic := '0'; - signal send_wait_counter_i : std_logic_vector(31 downto 0); - signal send_wait_threshold_i : std_logic_vector(31 downto 0); + signal send_wait_counter_i : unsigned(31 downto 0); + signal send_wait_threshold_i : unsigned(31 downto 0); + signal send_burst_threshold_i : unsigned(31 downto 0); + signal send_burst_counter_i : unsigned(31 downto 0); signal dlm_counter_i : unsigned(31 downto 0); signal dlm_glob_counter_i : unsigned(31 downto 0); @@ -361,16 +363,63 @@ architecture trb3_periph_arch of trb3_periph_cbmnet is signal cbm_debug_overrides_i : std_logic_vector(1 downto 0) := "00"; + signal etm_trigger_i : std_logic; + + + signal hub_cts_number : std_logic_vector(15 downto 0); + signal hub_cts_code : std_logic_vector(7 downto 0); + signal hub_cts_information : std_logic_vector(7 downto 0); + signal hub_cts_start_readout : std_logic; + signal hub_cts_readout_type : std_logic_vector(3 downto 0); + signal hub_cts_readout_finished : std_logic; + signal hub_cts_status_bits : std_logic_vector(31 downto 0); + signal hub_fee_data : std_logic_vector(15 downto 0); + signal hub_fee_dataready : std_logic; + signal hub_fee_read : std_logic; + signal hub_fee_status_bits : std_logic_vector(31 downto 0); + signal hub_fee_busy : std_logic; + + signal gbe_cts_number : std_logic_vector(15 downto 0); + signal gbe_cts_code : std_logic_vector(7 downto 0); + signal gbe_cts_information : std_logic_vector(7 downto 0); + signal gbe_cts_start_readout : std_logic; + signal gbe_cts_readout_type : std_logic_vector(3 downto 0); + signal gbe_cts_readout_finished : std_logic; + signal gbe_cts_status_bits : std_logic_vector(31 downto 0); + signal gbe_fee_data : std_logic_vector(15 downto 0); + signal gbe_fee_dataready : std_logic; + signal gbe_fee_read : std_logic; + signal gbe_fee_status_bits : std_logic_vector(31 downto 0); + signal gbe_fee_busy : std_logic; + + + signal cbm_rdo_regio_addr_i : std_logic_vector(15 downto 0); + signal cbm_rdo_regio_data_status_i : std_logic_vector(31 downto 0); + signal cbm_rdo_regio_read_enable_i : std_logic; + signal cbm_rdo_regio_write_enable_i : std_logic; + signal cbm_rdo_regio_data_ctrl_i : std_logic_vector(31 downto 0); + signal cbm_rdo_regio_dataready_i : std_logic; + signal cbm_rdo_regio_write_ack_i : std_logic; + signal cbm_rdo_regio_unknown_addr_i : std_logic; + + signal event_id : unsigned(15 downto 0); + signal send_length_i : unsigned(15 downto 0); + signal send_counter_i : unsigned(15 downto 0); + + type TRB_FSM_T is (IDLE, START_READOUT, START_READOUT_WAIT1, START_READOUT_WAIT2, START_READOUT_WAIT3, FEE_BUSY, FEE_BUSY_WAIT1, FEE_BUSY_WAIT2, FEE_BUSY_WAIT3, SEND_EINF_H, SEND_EINF_L, SEND_LENGTH, SEND_SOURCE, SEND_SOURCE_WAIT, SEND_PAYLOAD_H, SEND_PAYLOAD_L, COMPL_WAIT1, COMPL_WAIT2, COMPL_WAIT3, COMPL_WAIT4, COMPL_NOT_BUSY_WAIT1, COMPL_NOT_BUSY_WAIT2, COMPL_NOT_BUSY_WAIT3, COMPL_NOT_BUSY_WAIT4, EVT_WAIT); + signal trb_fsm_i : TRB_FSM_T; + begin clk_125_i <= CLK_GPLL_LEFT; assert(INCLUDE_TRBNET = c_YES); - + + --------------------------------------------------------------------------- -- CBMNet and PHY --------------------------------------------------------------------------- THE_CBM_PHY: cbmnet_phy_ecp3 - generic map (IS_SYNC_SLAVE => CBM_FEE_MODE) + generic map (IS_SYNC_SLAVE => CBM_FEE_MODE, DETERMINISTIC_LATENCY => c_YES) port map ( CLK => clk_125_i, RESET => reset_i, @@ -411,9 +460,11 @@ begin DEBUG_OUT => phy_debug_i ); - TEST_LINE <= phy_stat_op; +-- TEST_LINE(7 downto 0) <= cbm_data2send_stop & cbm_data2send_start & cbm_data2send_end & cbm_dlm_rec_va & cbm_dlm_rec_type; +-- TEST_LINE(15 downto 8) <= phy_stat_debug(7 downto 0); + - SFP_RATESEL <= (others => '1'); + SFP_RATESEL <= (others => '0'); --TEST_LINE(1 downto 0) <= cbm_dlm2send_va & cbm_dlm_rec_va; @@ -433,7 +484,7 @@ begin THE_CBM_ENDPOINT: lp_top generic map ( NUM_LANES => 1, - TX_SLAVE => 1 + TX_SLAVE => 0 ) port map ( -- Clk & Reset @@ -443,8 +494,8 @@ begin -- Phy data_from_link => cbm_data_from_link, data2link => cbm_data2link, - link_activeovr => cbm_debug_overrides_i(0), - link_readyovr => cbm_debug_overrides_i(1), + link_activeovr => '0', --cbm_debug_overrides_i(0), + link_readyovr => '0', --cbm_debug_overrides_i(1), SERDES_ready => cbm_SERDES_ready, -- CBMNet Interface @@ -487,37 +538,37 @@ begin retrans_error_cntr_clr_0 => cbm_retrans_error_cntr_clr_0, -- in std_logic; -- diagnostics Lane1 - crc_error_cntr_flag_1 => cbm_crc_error_cntr_flag_1, -- out std_logic; - retrans_cntr_flag_1 => cbm_retrans_cntr_flag_1, -- out std_logic; - retrans_error_cntr_flag_1 => cbm_retrans_error_cntr_flag_1, -- out std_logic; - crc_error_cntr_1 => cbm_crc_error_cntr_1, -- out std_logic_vector(15 downto 0); - retrans_cntr_1 => cbm_retrans_cntr_1, -- out std_logic_vector(15 downto 0); - retrans_error_cntr_1 => cbm_retrans_error_cntr_1, -- out std_logic_vector(15 downto 0); - crc_error_cntr_clr_1 => cbm_crc_error_cntr_clr_1, -- in std_logic; - retrans_cntr_clr_1 => cbm_retrans_cntr_clr_1, -- in std_logic; - retrans_error_cntr_clr_1 => cbm_retrans_error_cntr_clr_1, -- in std_logic; + crc_error_cntr_flag_1 => open, -- out std_logic; + retrans_cntr_flag_1 => open, -- out std_logic; + retrans_error_cntr_flag_1 => open, -- out std_logic; + crc_error_cntr_1 => open, -- out std_logic_vector(15 downto 0); + retrans_cntr_1 => open, -- out std_logic_vector(15 downto 0); + retrans_error_cntr_1 => open, -- out std_logic_vector(15 downto 0); + crc_error_cntr_clr_1 => '0', -- in std_logic; + retrans_cntr_clr_1 => '0', -- in std_logic; + retrans_error_cntr_clr_1 => '0', -- in std_logic; -- diagnostics Lane2 - crc_error_cntr_flag_2 => cbm_crc_error_cntr_flag_2, -- out std_logic; - retrans_cntr_flag_2 => cbm_retrans_cntr_flag_2, -- out std_logic; - retrans_error_cntr_flag_2 => cbm_retrans_error_cntr_flag_2, -- out std_logic; - crc_error_cntr_2 => cbm_crc_error_cntr_2, -- out std_logic_vector(15 downto 0); - retrans_cntr_2 => cbm_retrans_cntr_2, -- out std_logic_vector(15 downto 0); - retrans_error_cntr_2 => cbm_retrans_error_cntr_2, -- out std_logic_vector(15 downto 0); - crc_error_cntr_clr_2 => cbm_crc_error_cntr_clr_2, -- in std_logic; - retrans_cntr_clr_2 => cbm_retrans_cntr_clr_2, -- in std_logic; - retrans_error_cntr_clr_2 => cbm_retrans_error_cntr_clr_2, -- in std_logic; + crc_error_cntr_flag_2 => open, -- out std_logic; + retrans_cntr_flag_2 => open, -- out std_logic; + retrans_error_cntr_flag_2 => open, -- out std_logic; + crc_error_cntr_2 => open, -- out std_logic_vector(15 downto 0); + retrans_cntr_2 => open, -- out std_logic_vector(15 downto 0); + retrans_error_cntr_2 => open, -- out std_logic_vector(15 downto 0); + crc_error_cntr_clr_2 => '0', -- in std_logic; + retrans_cntr_clr_2 => '0', -- in std_logic; + retrans_error_cntr_clr_2 => '0', -- in std_logic; -- diagnostics Lane3 - crc_error_cntr_flag_3 => cbm_crc_error_cntr_flag_3, -- out std_logic; - retrans_cntr_flag_3 => cbm_retrans_cntr_flag_3, -- out std_logic; - retrans_error_cntr_flag_3 => cbm_retrans_error_cntr_flag_3, -- out std_logic; - crc_error_cntr_3 => cbm_crc_error_cntr_3, -- out std_logic_vector(15 downto 0); - retrans_cntr_3 => cbm_retrans_cntr_3, -- out std_logic_vector(15 downto 0); - retrans_error_cntr_3 => cbm_retrans_error_cntr_3, -- out std_logic_vector(15 downto 0); - crc_error_cntr_clr_3 => cbm_crc_error_cntr_clr_3, -- in std_logic; - retrans_cntr_clr_3 => cbm_retrans_cntr_clr_3, -- in std_logic; - retrans_error_cntr_clr_3 => cbm_retrans_error_cntr_clr_3 -- in std_logic + crc_error_cntr_flag_3 => open, -- out std_logic; + retrans_cntr_flag_3 => open, -- out std_logic; + retrans_error_cntr_flag_3 => open, -- out std_logic; + crc_error_cntr_3 => open, -- out std_logic_vector(15 downto 0); + retrans_cntr_3 => open, -- out std_logic_vector(15 downto 0); + retrans_error_cntr_3 => open, -- out std_logic_vector(15 downto 0); + crc_error_cntr_clr_3 => '0', -- in std_logic; + retrans_cntr_clr_3 => '0', -- in std_logic; + retrans_error_cntr_clr_3 => '0' -- in std_logic ); @@ -547,75 +598,256 @@ begin dlm2send => cbm_dlm2send -- out std_logic_vector(3 downto 0) ); + THE_CBMNET_READOUT: cbmnet_readout + port map ( + CLK_IN => clk_100_i, -- in std_logic; + RESET_IN => reset_i, -- in std_logic; + + -- connect to hub + HUB_CTS_NUMBER_IN => hub_cts_number, -- in std_logic_vector (15 downto 0); + HUB_CTS_CODE_IN => hub_cts_code, -- in std_logic_vector (7 downto 0); + HUB_CTS_INFORMATION_IN => hub_cts_information, -- in std_logic_vector (7 downto 0); + HUB_CTS_READOUT_TYPE_IN => hub_cts_readout_type, -- in std_logic_vector (3 downto 0); + HUB_CTS_START_READOUT_IN => hub_cts_start_readout, -- in std_logic; + HUB_CTS_READOUT_FINISHED_OUT => hub_cts_readout_finished, -- out std_logic; --no more data, end transfer, send TRM + HUB_CTS_STATUS_BITS_OUT => hub_cts_status_bits, -- out std_logic_vector (31 downto 0); + HUB_FEE_DATA_IN => hub_fee_data, -- in std_logic_vector (15 downto 0); + HUB_FEE_DATAREADY_IN => hub_fee_dataready, -- in std_logic; + HUB_FEE_READ_OUT => hub_fee_read, -- out std_logic; --must be high when idle, otherwise you will never get a dataready + HUB_FEE_STATUS_BITS_IN => hub_fee_status_bits, -- in std_logic_vector (31 downto 0); + HUB_FEE_BUSY_IN => hub_fee_busy, -- in std_logic; + + -- connect to GbE + GBE_CTS_NUMBER_OUT => gbe_cts_number, -- out std_logic_vector (15 downto 0); + GBE_CTS_CODE_OUT => gbe_cts_code, -- out std_logic_vector (7 downto 0); + GBE_CTS_INFORMATION_OUT => gbe_cts_information, -- out std_logic_vector (7 downto 0); + GBE_CTS_READOUT_TYPE_OUT => gbe_cts_readout_type, -- out std_logic_vector (3 downto 0); + GBE_CTS_START_READOUT_OUT => gbe_cts_start_readout, -- out std_logic; + GBE_CTS_READOUT_FINISHED_IN => gbe_cts_readout_finished, -- in std_logic; --no more data, end transfer, send TRM + GBE_CTS_STATUS_BITS_IN => gbe_cts_status_bits, -- in std_logic_vector (31 downto 0); + GBE_FEE_DATA_OUT => gbe_fee_data, -- out std_logic_vector (15 downto 0); + GBE_FEE_DATAREADY_OUT => gbe_fee_dataready, -- out std_logic; + GBE_FEE_READ_IN => gbe_fee_read, -- in std_logic; --must be high when idle, otherwise you will never get a dataready + GBE_FEE_STATUS_BITS_OUT => gbe_fee_status_bits, -- out std_logic_vector (31 downto 0); + GBE_FEE_BUSY_OUT => gbe_fee_busy, -- out std_logic; + + -- reg io + REGIO_ADDR_IN => cbm_rdo_regio_addr_i, -- in std_logic_vector(15 downto 0); + REGIO_DATA_IN => cbm_rdo_regio_data_ctrl_i, -- in std_logic_vector(31 downto 0); + REGIO_READ_ENABLE_IN => cbm_rdo_regio_read_enable_i, -- in std_logic; + REGIO_WRITE_ENABLE_IN => cbm_rdo_regio_write_enable_i, -- in std_logic; + REGIO_DATA_OUT => cbm_rdo_regio_data_status_i, -- out std_logic_vector(31 downto 0); + REGIO_DATAREADY_OUT => cbm_rdo_regio_dataready_i, -- out std_logic; + REGIO_WRITE_ACK_OUT => cbm_rdo_regio_write_ack_i, -- out std_logic; + REGIO_UNKNOWN_ADDR_OUT => cbm_rdo_regio_unknown_addr_i, -- out std_logic; + + -- CBMNet + CBMNET_CLK_IN => rclk_125_i, -- in std_logic; + CBMNET_RESET_IN => rreset_i, -- in std_logic; + CBMNET_LINK_ACTIVE_IN => cbm_link_active, -- in std_logic; + + CBMNET_DATA2SEND_STOP_IN => cbm_data2send_stop(0), -- in std_logic; + CBMNET_DATA2SEND_START_OUT => cbm_data2send_start(0), -- out std_logic; + CBMNET_DATA2SEND_END_OUT => cbm_data2send_end(0), -- out std_logic; + CBMNET_DATA2SEND_DATA_OUT => cbm_data2send -- out std_logic_vector(15 downto 0) + ); - PROC_DATA_SEND: process begin - wait until rising_edge(rclk_125_i); + gbe_fee_read <= '1'; + gbe_cts_status_bits <= x"beafc0de"; + + process is + begin + wait until rising_edge(clk_100_i); - cbm_data2send <= (others => '0'); - cbm_data2send_start <= "0"; - cbm_data2send_end <= "0"; - - if reset_i = '1' or send_enabled_i = '0' then - send_fsm_i <= START; - send_num_pack_counter_i <= (others => '0'); + hub_cts_start_readout <= '1'; + hub_fee_busy <= '1'; + hub_fee_dataready <= '0'; + + if reset_i = '1' then + trb_fsm_i <= IDLE; + event_id <= 0; + + hub_cts_start_readout <= '0'; + hub_fee_busy <= '0'; + hub_fee_dataready <= '0'; else - case(send_fsm_i) is - when START => - if cbm_link_active='1' and cbm_data2send_stop = "0" then - send_fsm_i <= SEND_HEADER; - send_num_pack_counter_i <= send_num_pack_counter_i + 1; - send_length_i <= "0" & send_num_pack_counter_i(3 downto 0); + case(trb_fsm_i) is + when IDLE => + hub_cts_start_readout <= '0'; + hub_fee_busy <= '0'; + if send_enabled_i = '1' then + trb_fsm_i <= START_READOUT; end if; - - when SEND_HEADER => - cbm_data2send <= x"f123"; - cbm_data2send_start <= "1"; - send_fsm_i <= SEND_PACK_NUM; - when SEND_PACK_NUM => - cbm_data2send <= send_num_pack_counter_i; - send_fsm_i <= SEND_LENGTH; + when START_READOUT => + trb_fsm_i <= START_READOUT_WAIT1; + hub_fee_busy <= '0'; + event_id <= event_id + 1; + + when START_READOUT_WAIT1 => + trb_fsm_i <= START_READOUT_WAIT2; + hub_fee_busy <= '0'; + when START_READOUT_WAIT2 => + trb_fsm_i <= START_READOUT_WAIT3; + hub_fee_busy <= '0'; + when START_READOUT_WAIT3 => + trb_fsm_i <= FEE_BUSY; + hub_fee_busy <= '0'; + when FEE_BUSY => + trb_fsm_i <= FEE_BUSY_WAIT1; + when FEE_BUSY_WAIT1 => + trb_fsm_i <= FEE_BUSY_WAIT2; + when FEE_BUSY_WAIT2 => + trb_fsm_i <= FEE_BUSY_WAIT3; + when FEE_BUSY_WAIT3 => + trb_fsm_i <= SEND_EINF_H; + + when SEND_EINF_H => + hub_fee_data <= x"8765"; + hub_fee_dataready <= '1'; + trb_fsm_i <= SEND_EINF_L; + when SEND_EINF_L => + hub_fee_data <= event_id; + hub_fee_dataready <= '1'; + trb_fsm_i <= SEND_LENGTH; + when SEND_LENGTH => - cbm_data2send(send_length_i'range) <= send_length_i; - send_fsm_i <= SEND_DATA; + hub_fee_data <= send_length_i; + send_counter_i <= send_length_i; + hub_fee_dataready <= '1'; + trb_fsm_i <= SEND_SOURCE; + when SEND_SOURCE => + hub_fee_data <= x"affe"; + hub_fee_dataready <= '1'; + trb_fsm_i <= SEND_SOURCE_WAIT; + + when SEND_SOURCE_WAIT => + trb_fsm_i <= SEND_PAYLOAD_H; + + when SEND_PAYLOAD_H => + hub_fee_data <= x"bb" & std_logic_vector(event_id(7 downto 0)); + hub_fee_dataready <= '1'; + trb_fsm_i <= SEND_PAYLOAD_L; - when SEND_DATA => - send_length_i <= send_length_i - 1; - cbm_data2send(15 downto 8) <= "0" & std_logic_vector(send_length_i(2 downto 0)) & std_logic_vector(send_length_i(3 downto 0)); - cbm_data2send(send_length_i'high + 0 downto 0) <= send_length_i; + when SEND_PAYLOAD_L => + hub_fee_data <= x"c" & std_logic_vector(send_counter_i(11 downto 0)); + hub_fee_dataready <= '1'; + trb_fsm_i <= SEND_PAYLOAD_H; + send_counter_i <= send_counter_i - 1; - if send_length_i = TO_UNSIGNED(1, send_length_i'length) then - send_fsm_i <= SEND_FOOTER; + if send_counter_i = 1 then + trb_fsm_i <= COMPL_WAIT1; end if; - when SEND_FOOTER => - cbm_data2send <= x"f321"; - cbm_data2send_end <= "1"; + when COMPL_WAIT1 => trb_fsm_i <= COMPL_WAIT2; + when COMPL_WAIT2 => trb_fsm_i <= COMPL_WAIT3; + when COMPL_WAIT3 => trb_fsm_i <= COMPL_WAIT4; + when COMPL_WAIT4 => trb_fsm_i <= COMPL_NOT_BUSY_WAIT1; + + when COMPL_NOT_BUSY_WAIT1 => trb_fsm_i <= COMPL_NOT_BUSY_WAIT2; hub_fee_busy <= '0'; + when COMPL_NOT_BUSY_WAIT2 => trb_fsm_i <= COMPL_NOT_BUSY_WAIT3; hub_fee_busy <= '0'; + when COMPL_NOT_BUSY_WAIT3 => trb_fsm_i <= COMPL_NOT_BUSY_WAIT4; hub_fee_busy <= '0'; + when COMPL_NOT_BUSY_WAIT4 => + trb_fsm_i <= EVT_WAIT; + hub_fee_busy <= '0'; + hub_cts_start_readout <= '0'; + send_wait_counter_i <= 0; + - send_wait_counter_i <= (others => '0'); - send_fsm_i <= AFTER_SEND_WAIT; + when EVT_WAIT => + hub_cts_start_readout <= '0'; + hub_fee_busy <= '0'; - when AFTER_SEND_WAIT => - send_wait_counter_i <= STD_LOGIC_VECTOR( UNSIGNED(send_wait_counter_i) + 1 ); - if send_wait_counter_i >= send_wait_threshold_i then - send_fsm_i <= START; + send_wait_counter_i <= send_wait_counter_i + 1; + if send_wait_counter_i >= UNSIGNED(send_wait_threshold_i) then + trb_fsm_i <= IDLE; end if; - when others => - send_fsm_i <= START; - end case; + end if; + end process; + + + + +-- proc_data_send: process begin +-- wait until rising_edge(rclk_125_i); +-- +-- cbm_data2send <= (others => '0'); +-- cbm_data2send_start <= "0"; +-- cbm_data2send_end <= "0"; +-- +-- if reset_i = '1' or send_enabled_i = '0' then +-- send_fsm_i <= start; +-- send_num_pack_counter_i <= (others => '0'); +-- +-- else +-- case(send_fsm_i) is +-- when start => +-- if cbm_link_active='1' and cbm_data2send_stop = "0" then +-- send_fsm_i <= send_header; +-- send_num_pack_counter_i <= send_num_pack_counter_i + 1; +-- send_length_i(4 downto 0) <= unsigned("0" & send_num_pack_counter_i(3 downto 0)) + 1; +-- +-- if send_burst_counter_i = to_unsigned(0, send_burst_counter_i'length) then +-- send_burst_counter_i <= send_burst_threshold_i; +-- else +-- send_burst_counter_i <= send_burst_counter_i - 1; +-- end if; +-- end if; +-- +-- when send_header => +-- cbm_data2send <= x"f123"; +-- cbm_data2send_start <= "1"; +-- send_fsm_i <= send_pack_num; +-- +-- when send_pack_num => +-- cbm_data2send <= send_num_pack_counter_i; +-- send_fsm_i <= send_length; +-- +-- when send_length => +-- cbm_data2send(send_length_i'range) <= send_length_i; +-- send_fsm_i <= send_data; +-- +-- when send_data => +-- send_length_i <= send_length_i - 1; +-- cbm_data2send(15 downto 8) <= "0" & std_logic_vector(send_length_i(2 downto 0)) & std_logic_vector(send_length_i(3 downto 0)); +-- cbm_data2send(send_length_i'high + 0 downto 0) <= send_length_i; +-- +-- if send_length_i = to_unsigned(1, send_length_i'length) then +-- send_fsm_i <= send_footer; +-- end if; +-- +-- when send_footer => +-- cbm_data2send <= x"f321"; +-- cbm_data2send_end <= "1"; +-- +-- send_wait_counter_i <= (others => '0'); +-- send_fsm_i <= after_send_wait; +-- +-- when after_send_wait => +-- send_wait_counter_i <= std_logic_vector( unsigned(send_wait_counter_i) + 1 ); +-- if send_wait_counter_i(4 downto 0) >= send_wait_threshold_i or send_burst_counter_i /= to_unsigned(0, send_burst_counter_i'length) then +-- send_fsm_i <= start; +-- end if; +-- +-- when others => +-- send_fsm_i <= start; +-- +-- end case; +-- end if; +-- end process; PROC_DLM_COUNTER: process is variable dlm_type_v : integer range 15 downto 0; begin wait until rising_edge(rclk_125_i); - if reset_i = '1' then + if rreset_i = '1' then dlm_counter_i <= (others => '0'); dlm_glob_counter_i <= (others => '0'); elsif cbm_dlm_rec_va = '1' then @@ -669,8 +901,9 @@ begin when 16#2f# => debug_data_out <= phy_debug_i_buf(31+32*15 downto 32*15); + when 16#0f# => debug_data_out(15 downto 0) <= send_length_i; when 16#10# => debug_data_out <= send_wait_threshold_i; - when 16#11# => debug_data_out(20 downto 0) <= "000" & cbm_data_from_link; + when 16#11# => null;---debug_data_out(20 downto 0) <= "000" & cbm_data_from_link; when 16#12# => debug_data_out <= STD_LOGIC_VECTOR(dlm_counter_i); when 16#13# => debug_data_out <= STD_LOGIC_VECTOR(dlm_glob_counter_i); @@ -694,23 +927,27 @@ begin if debug_write_en = '1' then case (address) is - when 16#1# => phy_ctrl_op <= debug_data_in(15 downto 0); - when 16#4# => phy_ctrl_debug(31 downto 0) <= debug_data_in; - when 16#5# => phy_ctrl_debug(63 downto 32) <= debug_data_in; + when 16#01# => phy_ctrl_op <= debug_data_in(15 downto 0); + when 16#04# => phy_ctrl_debug(31 downto 0) <= debug_data_in; + when 16#05# => phy_ctrl_debug(63 downto 32) <= debug_data_in; + when 16#0f# => --send_burst_threshold_i <= debug_data_in; + send_length_i <= debug_data_in(15 downto 0); when 16#10# => send_wait_threshold_i <= debug_data_in; when 16#14# => send_enabled_i <= debug_data_in(18); - cbm_debug_overrides_i <= debug_data_in(21 downto 20); + --cbm_debug_overrides_i <= debug_data_in(21 downto 20); when others => debug_ack <= '0'; end case; end if; + + if cbm_res_n = '0' then + send_burst_threshold_i<= x"00000010"; + send_wait_threshold_i <= x"00010000"; + end if; end process; - - - --------------------------------------------------------------------------- -- Reset Generation --------------------------------------------------------------------------- @@ -915,9 +1152,9 @@ begin --------------------------------------------------------------------------- THE_BUS_HANDLER : trb_net16_regio_bus_handler generic map( - PORT_NUMBER => 3, - PORT_ADDRESSES => (0 => x"d000", 1 => x"d100", 2 => x"a000", others => x"0000"), - PORT_ADDR_MASK => (0 => 1, 1 => 6, 2 => 6, others => 0) + PORT_NUMBER => 4, + PORT_ADDRESSES => (0 => x"d000", 1 => x"d100", 2 => x"a000", 3=>x"a800", others => x"0000"), + PORT_ADDR_MASK => (0 => 1, 1 => 6, 2 => 6, 3=>6, others => 0) ) port map( CLK => clk_100_i, @@ -972,7 +1209,18 @@ begin BUS_WRITE_ACK_IN(2) => debug_ack, BUS_NO_MORE_DATA_IN(2) => '0', BUS_UNKNOWN_ADDR_IN(2) => '0', - + + --CBMNet (read-out) + BUS_READ_ENABLE_OUT(3) => cbm_rdo_regio_read_enable_i, + BUS_WRITE_ENABLE_OUT(3) => cbm_rdo_regio_write_enable_i, + BUS_DATA_OUT(3*32+31 downto 3*32) => cbm_rdo_regio_data_ctrl_i, + BUS_ADDR_OUT(3*16+15 downto 3*16) => cbm_rdo_regio_addr_i, + BUS_TIMEOUT_OUT(3) => open, + BUS_DATA_IN(3*32+31 downto 3*32) => cbm_rdo_regio_data_status_i, + BUS_DATAREADY_IN(3) => cbm_rdo_regio_dataready_i, + BUS_WRITE_ACK_IN(3) => cbm_rdo_regio_write_ack_i, + BUS_NO_MORE_DATA_IN(3) => '0', + BUS_UNKNOWN_ADDR_IN(3) => cbm_rdo_regio_unknown_addr_i, STAT_DEBUG => open ); diff --git a/cbmnet/trb3_periph_cbmnet_constraints.lpf b/cbmnet/trb3_periph_cbmnet_constraints.lpf index 808c963..d69cd0a 100755 --- a/cbmnet/trb3_periph_cbmnet_constraints.lpf +++ b/cbmnet/trb3_periph_cbmnet_constraints.lpf @@ -9,13 +9,12 @@ SYSCONFIG MCCLK_FREQ = 20; # FREQUENCY NET "THE_CBM_PHY/CLK_TX_FULL_I" 250 MHz; - FREQUENCY NET "THE_CBM_PHY/RCLK_250_I" 250 MHz; #Change the next two lines to the clk_fast signal of the ADC # USE PRIMARY2EDGE NET "THE_MAIN_PLL/PLLInst_0"; # USE PRIMARY NET "THE_MAIN_PLL/PLLInst_0"; -USE PRIMARY NET "CLK_GPLL_LEFT"; +# USE PRIMARY NET "CLK_GPLL_LEFT"; # USE PRIMARY NET "THE_CBM_PHY/RCLK_250_I"; # USE SECONDARY NET "THE_CBM_PHY/CLK_TX_FULL_I"; @@ -25,6 +24,8 @@ USE PRIMARY NET "CLK_GPLL_LEFT"; GSR_NET NET "GSR_N"; + + LOCATE COMP "THE_MEDIA_UPLINK/gen_serdes_1_200.THE_SERDES/PCSD_INST" SITE "PCSA" ; REGION "MEDIA_UPLINK" "R102C95D" 13 25 DEVSIZE; LOCATE UGROUP "THE_MEDIA_UPLINK/media_interface_group" REGION "MEDIA_UPLINK" ; @@ -50,7 +51,7 @@ DEFINE BUS "tx_data" NET "THE_CBM_PHY/tx_data_to_serdes_i[0]" NET "THE_CBM_PHY/ PRIORITIZE BUS "rx_data" 51; PRIORITIZE BUS "tx_data" 50; -FREQUENCY PORT "CLK_GPLL_LEFT" 200.0 MHz; +FREQUENCY PORT "CLK_GPLL_LEFT" 125.0 MHz; FREQUENCY NET "THE_MAIN_PLL/clk_200_i" 200.0 MHz; FREQUENCY NET "THE_MAIN_PLL/clk_100_i_c" 100.0 MHz; FREQUENCY NET "THE_CBM_PHY/THE_SERDES/CLK_RX_FULL_OUT" 250.0 MHz; -- 2.43.0