From 44038ffdaeab95d4b63ad6ed1745519913e93f64 Mon Sep 17 00:00:00 2001 From: hadeshyp Date: Fri, 8 Oct 2010 14:09:11 +0000 Subject: [PATCH] *** empty log message *** --- media_interfaces/trb_net16_med_ecp_fot.vhd | 5 +- .../trb_net16_rx_comma_handler.vhd | 102 ++++++++++++++++-- media_interfaces/trb_net16_rx_control.vhd | 22 +++- special/spi_master.vhd | 22 +++- special/spi_slim.vhd | 6 +- testbenches/error_generator.vhd | 71 ++++++------ testbenches/tb_trb_net16_rxtx_control.vhd | 14 +++ trb_net_components.vhd | 2 +- 8 files changed, 194 insertions(+), 50 deletions(-) diff --git a/media_interfaces/trb_net16_med_ecp_fot.vhd b/media_interfaces/trb_net16_med_ecp_fot.vhd index b43d050..363234d 100644 --- a/media_interfaces/trb_net16_med_ecp_fot.vhd +++ b/media_interfaces/trb_net16_med_ecp_fot.vhd @@ -187,7 +187,7 @@ attribute HGROUP of trb_net16_med_ecp_fot_arch : architecture is "GROUP_PCS"; signal tx_lane_reset : std_logic; signal statreg_txcontrol_i : std_logic_vector(31 downto 0); - signal statreg_rxcontrol_i : std_logic_vector(63 downto 0); + signal statreg_rxcontrol_i : std_logic_vector(95 downto 0); begin @@ -620,8 +620,7 @@ MED_PACKET_NUM_OUT <= buf_med_packet_num_out; ----------------------------------------------------------- STAT_REG_OUT(31 downto 0) <= statreg_txcontrol_i; - STAT_REG_OUT(95 downto 32) <= statreg_rxcontrol_i; - STAT_REG_OUT(127 downto 96) <= (others => '0'); + STAT_REG_OUT(127 downto 32) <= statreg_rxcontrol_i; diff --git a/media_interfaces/trb_net16_rx_comma_handler.vhd b/media_interfaces/trb_net16_rx_comma_handler.vhd index 044cbe7..8d68ee3 100644 --- a/media_interfaces/trb_net16_rx_comma_handler.vhd +++ b/media_interfaces/trb_net16_rx_comma_handler.vhd @@ -8,6 +8,7 @@ use work.trb_net_components.all; entity trb_net16_rx_comma_handler is port( + SYSCLK_IN : in std_logic; RESET_IN : in std_logic; QUAD_RST_IN : in std_logic; -- raw data from SerDes receive path @@ -28,6 +29,7 @@ port( START_POSITION_OUT : out std_logic_vector(7 downto 0); START_GONE_WRONG_IN : in std_logic; START_TIMEOUT_OUT : out std_logic; -- gk 05.10.10 + RX_RESET_IN : in std_logic; -- Check COMMA_LOCKED_OUT : out std_logic; -- reset handling @@ -35,7 +37,7 @@ port( MAKE_TRBNET_RESET_OUT : out std_logic; ENABLE_CORRECTION_IN : in std_logic; -- Debugging - STAT_REG_OUT : out std_logic_vector(15 downto 0); + STAT_REG_OUT : out std_logic_vector(39 downto 0); DEBUG_OUT : out std_logic_vector(15 downto 0) ); end entity trb_net16_rx_comma_handler; @@ -123,6 +125,20 @@ signal start_toc_c : std_logic; -- gk 06.10.10 signal crc_comma_position : unsigned(3 downto 0); +signal crc_comma_pos_wrong : std_logic; + +signal counter_crc_mismatch : unsigned(7 downto 0); +signal counter_crc_wrong_pos: unsigned(7 downto 0); +signal counter_cv : unsigned(7 downto 0); +signal counter_invalid_k : unsigned(7 downto 0); + +signal inc_counter_crc_mismatch : std_logic; +signal inc_counter_crc_wrong_pos: std_logic; +signal inc_counter_cv : std_logic; +signal inc_counter_invalid_k : std_logic; +signal crc_wrong_pulse : std_logic; +signal invalid_k_pulse : std_logic; +signal cv_pulse : std_logic; begin @@ -236,10 +252,10 @@ rst_toggle <= '1' when ( ((comma_idle = '1') and (comma_toggle = '0') and (comma ce_toggle <= '1' when ( (comma_idle = '1') and (comma_toggle = '1') and (comma_locked_x = '0') ) else '0'; -- gk 06.10.10 -CRC_COMMA_POSITION_PROC : process +CRC_COMMA_POSITION_PROC : process( CLK_IN ) begin if rising_edge(CLK_IN) then - if (RESET_IN = '1') or (crc_active = '0') or (c_crc_x = '1') then + if (RESET_IN = '1') or (crc_active = '0') or (c_crc_x = '1') or fifo_inhibit = '1' then crc_comma_position <= (others => '0'); elsif (data_valid_x = '1') then crc_comma_position <= crc_comma_position + to_unsigned(1, 1); @@ -248,7 +264,7 @@ begin end process CRC_COMMA_POSITION_PROC; -- gk 06.10.10 -crc_comma_pos_wrong <= '1' when (crc_comma_position = to_unsigned(10, 4)) and (c_crc_x = '0') else '0'; +crc_comma_pos_wrong <= '1' after 1 ns when (crc_comma_position = to_unsigned(9, 4)) and ((c_crc_x = '0') or (buf_rx_cv = '1')) else '0'; -- reference toggle bit for 16bit reconstruction THE_COMMA_TOGGLE_PROC: process( CLK_IN ) @@ -296,8 +312,10 @@ begin fifo_inhibit <= '0'; elsif( (comma_locked = '1') and (comma_toggle = '1') and (comma_valid_x = '0') and (data_valid_x = '0') and c_reset_x = '0' ) or ((crc_match = '0' or buf_rx_cv = '1') and comma_crc_x = '1' and crc_active = '1') - or c_invalid_k_x = '1' +-- or c_invalid_k_x = '1' + or (comma_locked = '1' and comma_toggle = '0' and buf_rx_k = '1') or START_GONE_WRONG_IN = '1' + or RX_RESET_IN = '1' or crc_comma_pos_wrong = '1' then -- gk 06.10.10 fifo_inhibit <= '1'; end if; @@ -345,6 +363,75 @@ THE_CRC : trb_net_CRC8 crc_reset <= RESET_IN or (fifo_inhibit and not comma_stx) or (not crc_active and not comma_crc); crc_enable <= ((not buf_rx_k and not (comma_idle_x or comma_error_x or comma_stx_x or comma_crc_x)) or comma_crc_x) and not buf_rx_cv; +---------------------------------------------------------------------- +-- Statistics counters +---------------------------------------------------------------------- +crc_wrong_pulse <= (not crc_match) and comma_crc_x and crc_active; +cv_pulse <= buf_rx_cv and comma_locked; +invalid_k_pulse <= c_invalid_k_x and comma_locked; + +THE_CRC_MISM_PULSE_SYNC: pulse_sync +port map( + CLK_A_IN => CLK_IN, + RESET_A_IN => RESET_IN, + PULSE_A_IN => crc_wrong_pulse, + CLK_B_IN => SYSCLK_IN, + RESET_B_IN => RESET_IN, + PULSE_B_OUT => inc_counter_crc_mismatch +); +THE_CRC_POS_PULSE_SYNC: pulse_sync +port map( + CLK_A_IN => CLK_IN, + RESET_A_IN => RESET_IN, + PULSE_A_IN => crc_comma_pos_wrong, + CLK_B_IN => SYSCLK_IN, + RESET_B_IN => RESET_IN, + PULSE_B_OUT => inc_counter_crc_wrong_pos +); +THE_CV_PULSE_SYNC: pulse_sync +port map( + CLK_A_IN => CLK_IN, + RESET_A_IN => RESET_IN, + PULSE_A_IN => cv_pulse, + CLK_B_IN => SYSCLK_IN, + RESET_B_IN => RESET_IN, + PULSE_B_OUT => inc_counter_cv +); +THE_INV_K_PULSE_SYNC: pulse_sync +port map( + CLK_A_IN => CLK_IN, + RESET_A_IN => RESET_IN, + PULSE_A_IN => invalid_k_pulse, + CLK_B_IN => SYSCLK_IN, + RESET_B_IN => RESET_IN, + PULSE_B_OUT => inc_counter_invalid_k +); + +PROC_STAT: process(SYSCLK_IN) + begin + if rising_edge(SYSCLK_IN) then + if RESET_IN = '1' then + counter_crc_mismatch <= (others => '0'); + counter_crc_wrong_pos <= (others => '0'); + counter_cv <= (others => '0'); + counter_invalid_k <= (others => '0'); + else + if inc_counter_crc_mismatch = '1' then + counter_crc_mismatch <= counter_crc_mismatch + to_unsigned(1,1); + end if; + if inc_counter_crc_wrong_pos = '1' then + counter_crc_wrong_pos <= counter_crc_wrong_pos + to_unsigned(1,1); + end if; + if inc_counter_cv = '1' then + counter_cv <= counter_cv + to_unsigned(1,1); + end if; + if inc_counter_invalid_k = '1' then + counter_invalid_k <= counter_invalid_k + to_unsigned(1,1); + end if; + end if; + end if; + end process; + ---------------------------------------------------------------------- -- Debug signals @@ -360,7 +447,10 @@ STAT_REG_OUT(4 downto 0) <= std_logic_vector(reset_word_cnt); STAT_REG_OUT(5) <= fifo_inhibit; STAT_REG_OUT(6) <= comma_locked; STAT_REG_OUT(7) <= comma_crc; -STAT_REG_OUT(15 downto 8)<= (others => '0'); +STAT_REG_OUT(15 downto 8) <= std_logic_vector(counter_crc_mismatch); +STAT_REG_OUT(23 downto 16)<= std_logic_vector(counter_crc_wrong_pos); +STAT_REG_OUT(31 downto 24)<= std_logic_vector(counter_cv); +STAT_REG_OUT(39 downto 32)<= std_logic_vector(counter_invalid_k); ---------------------------------------------------------------------- -- Output signals diff --git a/media_interfaces/trb_net16_rx_control.vhd b/media_interfaces/trb_net16_rx_control.vhd index b5eda04..0512116 100644 --- a/media_interfaces/trb_net16_rx_control.vhd +++ b/media_interfaces/trb_net16_rx_control.vhd @@ -38,7 +38,7 @@ port( -- Debugging ENABLE_CORRECTION_IN : in std_logic; DEBUG_OUT : out std_logic_vector(31 downto 0); - STAT_REG_OUT : out std_logic_vector(63 downto 0) + STAT_REG_OUT : out std_logic_vector(95 downto 0) ); end entity; @@ -49,6 +49,7 @@ architecture arch of trb_net16_rx_control is -- components component trb_net16_rx_comma_handler is port( + SYSCLK_IN : in std_logic; RESET_IN : in std_logic; QUAD_RST_IN : in std_logic; -- raw data from SerDes receive path @@ -69,6 +70,7 @@ port( START_POSITION_OUT : out std_logic_vector(7 downto 0); START_GONE_WRONG_IN : in std_logic; START_TIMEOUT_OUT : out std_logic; + RX_RESET_IN : in std_logic; -- Check COMMA_LOCKED_OUT : out std_logic; -- reset handling @@ -76,7 +78,7 @@ port( MAKE_TRBNET_RESET_OUT : out std_logic; ENABLE_CORRECTION_IN : in std_logic; -- Debugging - STAT_REG_OUT : out std_logic_vector(15 downto 0); + STAT_REG_OUT : out std_logic_vector(39 downto 0); DEBUG_OUT : out std_logic_vector(15 downto 0) ); end component trb_net16_rx_comma_handler; @@ -212,7 +214,7 @@ signal comma_locked : std_logic; signal debug : std_logic_vector(31 downto 0); signal statreg_rxfullpackets : std_logic_vector(15 downto 0); -signal statreg_rxcommahandler : std_logic_vector(15 downto 0); +signal statreg_rxcommahandler : std_logic_vector(39 downto 0); signal statreg_rxchecker : std_logic_vector(15 downto 0); signal start_position_mismatch : std_logic; @@ -221,6 +223,7 @@ signal req_position_buffer : std_logic_vector(7 downto 0); signal stx_toc_found_x : std_logic; signal stx_toc_found : std_logic; +signal request_retransmit_q : std_logic; begin @@ -229,6 +232,7 @@ begin ---------------------------------------------------------------------- THE_COMMA_HANDLER: trb_net16_rx_comma_handler port map( + SYSCLK_IN => SYSCLK_IN, RESET_IN => RESET_IN, QUAD_RST_IN => QUAD_RST_IN, -- raw data from SerDes receive path @@ -249,6 +253,7 @@ port map( START_POSITION_OUT => start_position, START_GONE_WRONG_IN => start_position_mismatch, START_TIMEOUT_OUT => stx_toc_found_x, + RX_RESET_IN => request_retransmit_q, --fifo is resetted, needed to handle single TOC -- Check COMMA_LOCKED_OUT => comma_locked, -- reset handling @@ -282,6 +287,16 @@ port map( PULSE_B_OUT => stx_toc_found ); +THE_REQUEST_PULSE_SYNC: pulse_sync +port map( + CLK_A_IN => SYSCLK_IN, + RESET_A_IN => RESET_IN, + PULSE_A_IN => request_retransmit, + CLK_B_IN => CLK_IN, + RESET_B_IN => RESET_IN, + PULSE_B_OUT => request_retransmit_q +); + -- clock domain transfer for internal RX data counter THE_LD_PULSE_SYNC: pulse_sync port map( @@ -470,6 +485,7 @@ STAT_REG_OUT(49) <= rx_gone_wrong; STAT_REG_OUT(50) <= pkt_in_transit; STAT_REG_OUT(55 downto 51) <= (others => '0'); STAT_REG_OUT(63 downto 56) <= request_position; --make request for resending +STAT_REG_OUT(95 downto 64) <= statreg_rxcommahandler(39 downto 8); ---------------------------------------------------------------------- -- Output signals diff --git a/special/spi_master.vhd b/special/spi_master.vhd index 4e011bf..69ae43c 100755 --- a/special/spi_master.vhd +++ b/special/spi_master.vhd @@ -68,8 +68,22 @@ architecture Behavioral of spi_master is signal store_rd_x : std_logic; signal store_rd : std_logic; + signal reset_i : std_logic; + + attribute syn_preserve : boolean; + attribute syn_keep : boolean; + attribute syn_preserve of reset_i : signal is true; + attribute syn_keep of reset_i : signal is true; + begin +process(clk_in) + begin + if rising_edge(clk_in) then + reset_i <= reset_in; + end if; + end process; + --------------------------------------------------------- -- SPI master -- --------------------------------------------------------- @@ -77,7 +91,7 @@ begin THE_SPI_SLIM: spi_slim port map( SYSCLK => clk_in, - RESET => reset_in, + RESET => reset_i, -- Command interface START_IN => spi_start, -- not really nice, but should work BUSY_OUT => spi_busy, @@ -108,7 +122,7 @@ port map( STATE_MEM: process( clk_in ) begin if( rising_edge(clk_in) ) then - if( reset_in = '1' ) then + if( reset_i = '1' ) then CURRENT_STATE <= SLEEP; bus_busy <= '0'; bus_ack <= '0'; @@ -204,7 +218,7 @@ end process TRANSFORM; THE_WRITE_REG_PROC: process( clk_in ) begin if( rising_edge(clk_in) ) then - if ( reset_in = '1' ) then + if ( reset_i = '1' ) then reg_ctrl_data <= (others => '0'); reg_status_data <= (others => '0'); spi_start <= '0'; @@ -226,7 +240,7 @@ spi_start_x <= '1' when ( (store_wr = '1') and (bus_addr_in(0) = '0') ) else '0' THE_READ_REG_PROC: process( clk_in ) begin if( rising_edge(clk_in) ) then - if ( reset_in = '1' ) then + if ( reset_i = '1' ) then reg_bus_data_out <= (others => '0'); elsif( (store_rd = '1') and (bus_addr_in(0) = '0') ) then reg_bus_data_out <= reg_ctrl_data; diff --git a/special/spi_slim.vhd b/special/spi_slim.vhd index f0d2a92..0dcc3c0 100755 --- a/special/spi_slim.vhd +++ b/special/spi_slim.vhd @@ -175,7 +175,7 @@ begin if( reset = '1' ) then div_counter <= (others => '0'); div_done <= '0'; - spi_sck <= '0'; + spi_sck <= spi_sck_x;--'0'; else div_counter <= div_counter + 1; div_done <= div_done_x; @@ -228,7 +228,7 @@ begin rx_ena <= '0'; tx_ena <= '0'; busy <= '0'; - spi_cs <= '1'; + spi_cs <= spi_cs_x;--'1'; tx_load <= '0'; tx_sel <= "000"; rx_store <= '0'; @@ -529,7 +529,7 @@ THE_TX_SHIFT_AND_BITCOUNT: process( sysclk ) begin if( rising_edge(sysclk) ) then if( reset = '1' ) then - tx_sreg <= (others => '0'); + tx_sreg(6 downto 0) <= (others => '0'); tx_bit_cnt <= (others => '0'); last_tx_bit <= '0'; elsif ( (clk_en = '1' ) and (tx_load = '1') ) then diff --git a/testbenches/error_generator.vhd b/testbenches/error_generator.vhd index 27a8a97..1164991 100644 --- a/testbenches/error_generator.vhd +++ b/testbenches/error_generator.vhd @@ -36,6 +36,10 @@ architecture arch of error_generator is signal buf_RX1_K_OUT : std_logic; signal buf_RX1_CV_OUT : std_logic; + signal error_count_data : unsigned(31 downto 0) := (others => '0'); + signal error_count_cv : unsigned(31 downto 0) := (others => '0'); + signal doing_cv : std_logic; + begin CV1_PROC : process @@ -49,9 +53,16 @@ begin UNIFORM(seed1, seed2, rand); int_rand := INTEGER(TRUNC(rand * 1000000.0)); - + doing_cv <= '0'; if( (int_rand MOD 1000) = 0 ) then + doing_cv <= '1'; + buf_RX1_CV_OUT <= RX1_CV_IN; + wait until rising_edge(RXCLK_IN); + doing_cv <= '0'; + error_count_cv <= error_count_cv + to_unsigned(1,1); buf_RX1_CV_OUT <= not RX1_CV_IN; + + assert false report "RX1_CV" severity note; wait for 40 ns; buf_RX1_CV_OUT <= RX1_CV_IN; @@ -99,18 +110,20 @@ begin UNIFORM(seed1, seed2, rand); int_rand := INTEGER(TRUNC(rand * 1000000.0)); - - if( (int_rand MOD 200) = 0 ) then - + if( doing_cv = '1' or (int_rand MOD 1000) = 0 ) then + error_count_data <= error_count_data + to_unsigned(1,1); UNIFORM(seed1, seed2, rand); int_rand := INTEGER(TRUNC(rand * 256.0)); buf_RX1_DATA_OUT <= RX1_DATA_IN; buf_RX1_DATA_OUT(int_rand mod 8) <= not RX1_DATA_IN(int_rand mod 8); + if doing_cv = '1' then + buf_RX1_DATA_OUT <= x"EE"; + end if; - assert false report "RX1_DATA" severity note; + assert doing_cv = '1' report "RX1_DATA" severity note; - wait for 40 ns; + wait for 39 ns; buf_RX1_DATA_OUT <= RX1_DATA_IN; else buf_RX1_DATA_OUT <= RX1_DATA_IN; @@ -122,7 +135,7 @@ process begin wait until rising_edge(RXCLK_IN); -- buf_RX1_DATA_OUT <= RX1_DATA_IN; - buf_RX1_K_OUT <= RX1_K_IN; +-- buf_RX1_K_OUT <= RX1_K_IN; end process; RX1_DATA_OUT <= transport buf_RX1_DATA_OUT after 200 ns; @@ -165,31 +178,29 @@ RX2_DATA_OUT <= RX2_DATA_IN; RX2_CV_OUT <= RX2_CV_IN; RX2_K_OUT <= RX2_K_IN; --- K1_PROC : process --- variable seed1 : positive; --- variable seed2 : positive := 5; --- variable rand : real; --- variable int_rand : integer; --- begin --- --- wait until rising_edge(RXCLK_IN); --- --- UNIFORM(seed1, seed2, rand); --- int_rand := INTEGER(TRUNC(rand * 1000000.0)); --- --- if( (int_rand MOD 10000) = 0 ) then --- buf_RX1_K_OUT <= not RX1_K_IN; --- assert false report "RX1_K" severity note; --- -- assert false report int_rand'image(integer) severity note; --- wait for 39 ns; --- buf_RX1_K_OUT <= RX1_K_IN; --- else --- buf_RX1_K_OUT <= RX1_K_IN; --- end if; +K1_PROC : process +variable seed1 : positive; +variable seed2 : positive := 5; +variable rand : real; +variable int_rand : integer; +begin --- wait for 400 ns; + wait until rising_edge(RXCLK_IN); --- end process; + UNIFORM(seed1, seed2, rand); + int_rand := INTEGER(TRUNC(rand * 1000000.0)); + + if( doing_cv = '1' or (int_rand MOD 1000) = 0 ) then + buf_RX1_K_OUT <= not RX1_K_IN or doing_cv; + assert doing_cv = '1' report "RX1_K" severity note; + wait for 39 ns; + buf_RX1_K_OUT <= RX1_K_IN; + else + buf_RX1_K_OUT <= RX1_K_IN; + end if; + + +end process; -- K2_PROC : process -- variable seed1 : positive; diff --git a/testbenches/tb_trb_net16_rxtx_control.vhd b/testbenches/tb_trb_net16_rxtx_control.vhd index e16e569..7e40ba2 100644 --- a/testbenches/tb_trb_net16_rxtx_control.vhd +++ b/testbenches/tb_trb_net16_rxtx_control.vhd @@ -183,6 +183,8 @@ architecture arch of rxtxtb is signal rxpacketnum2_in : std_logic_vector(2 downto 0); signal rxread2_out : std_logic; + signal count1_retransmission : std_logic_vector(31 downto 0) := (others => '0'); + signal count2_retransmission : std_logic_vector(31 downto 0) := (others => '0'); begin @@ -403,6 +405,18 @@ THE_ERROR : error_generator RX2_CV_OUT => open ); +process(clk) + begin + if rising_edge(clk) then + if tx1_request_retransmit_in = '1' then + count1_retransmission <= count1_retransmission + 1; + end if; + if tx2_request_retransmit_in = '1' then + count2_retransmission <= count2_retransmission + 1; + end if; + end if; + end process; + --------------------------------------------------------------------- --Data input 1 --------------------------------------------------------------------- diff --git a/trb_net_components.vhd b/trb_net_components.vhd index 3614ed6..952e9b2 100644 --- a/trb_net_components.vhd +++ b/trb_net_components.vhd @@ -2368,7 +2368,7 @@ end component; ENABLE_CORRECTION_IN : in std_logic; -- Debugging DEBUG_OUT : out std_logic_vector(31 downto 0); - STAT_REG_OUT : out std_logic_vector(31 downto 0) + STAT_REG_OUT : out std_logic_vector(95 downto 0) ); end component; -- 2.43.0