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
-----------------------------------------------------------
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;
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
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
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;
-- 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
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);
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 )
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;
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
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
-- Debugging\r
ENABLE_CORRECTION_IN : in std_logic;\r
DEBUG_OUT : out std_logic_vector(31 downto 0);\r
- STAT_REG_OUT : out std_logic_vector(63 downto 0)\r
+ STAT_REG_OUT : out std_logic_vector(95 downto 0)\r
);\r
end entity;\r
\r
-- components\r
component trb_net16_rx_comma_handler is\r
port(\r
+ SYSCLK_IN : in std_logic;\r
RESET_IN : in std_logic;\r
QUAD_RST_IN : in std_logic;\r
-- raw data from SerDes receive path\r
START_POSITION_OUT : out std_logic_vector(7 downto 0);\r
START_GONE_WRONG_IN : in std_logic;\r
START_TIMEOUT_OUT : out std_logic;\r
+ RX_RESET_IN : in std_logic;\r
-- Check\r
COMMA_LOCKED_OUT : out std_logic;\r
-- reset handling\r
MAKE_TRBNET_RESET_OUT : out std_logic;\r
ENABLE_CORRECTION_IN : in std_logic;\r
-- Debugging\r
- STAT_REG_OUT : out std_logic_vector(15 downto 0);\r
+ STAT_REG_OUT : out std_logic_vector(39 downto 0);\r
DEBUG_OUT : out std_logic_vector(15 downto 0)\r
);\r
end component trb_net16_rx_comma_handler;\r
signal debug : std_logic_vector(31 downto 0);\r
\r
signal statreg_rxfullpackets : std_logic_vector(15 downto 0);\r
-signal statreg_rxcommahandler : std_logic_vector(15 downto 0);\r
+signal statreg_rxcommahandler : std_logic_vector(39 downto 0);\r
signal statreg_rxchecker : std_logic_vector(15 downto 0);\r
\r
signal start_position_mismatch : std_logic;\r
\r
signal stx_toc_found_x : std_logic;\r
signal stx_toc_found : std_logic;\r
+signal request_retransmit_q : std_logic;\r
\r
begin\r
\r
----------------------------------------------------------------------\r
THE_COMMA_HANDLER: trb_net16_rx_comma_handler\r
port map(\r
+ SYSCLK_IN => SYSCLK_IN,\r
RESET_IN => RESET_IN,\r
QUAD_RST_IN => QUAD_RST_IN,\r
-- raw data from SerDes receive path\r
START_POSITION_OUT => start_position,\r
START_GONE_WRONG_IN => start_position_mismatch,\r
START_TIMEOUT_OUT => stx_toc_found_x,\r
+ RX_RESET_IN => request_retransmit_q, --fifo is resetted, needed to handle single TOC\r
-- Check\r
COMMA_LOCKED_OUT => comma_locked,\r
-- reset handling\r
PULSE_B_OUT => stx_toc_found\r
);\r
\r
+THE_REQUEST_PULSE_SYNC: pulse_sync\r
+port map(\r
+ CLK_A_IN => SYSCLK_IN,\r
+ RESET_A_IN => RESET_IN,\r
+ PULSE_A_IN => request_retransmit,\r
+ CLK_B_IN => CLK_IN,\r
+ RESET_B_IN => RESET_IN,\r
+ PULSE_B_OUT => request_retransmit_q\r
+);\r
+\r
-- clock domain transfer for internal RX data counter\r
THE_LD_PULSE_SYNC: pulse_sync\r
port map(\r
STAT_REG_OUT(50) <= pkt_in_transit;\r
STAT_REG_OUT(55 downto 51) <= (others => '0');\r
STAT_REG_OUT(63 downto 56) <= request_position; --make request for resending\r
+STAT_REG_OUT(95 downto 64) <= statreg_rxcommahandler(39 downto 8);\r
\r
----------------------------------------------------------------------\r
-- Output signals\r
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 --
---------------------------------------------------------
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,
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';
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';
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;
if( reset = '1' ) then\r
div_counter <= (others => '0');\r
div_done <= '0';\r
- spi_sck <= '0';\r
+ spi_sck <= spi_sck_x;--'0';\r
else\r
div_counter <= div_counter + 1;\r
div_done <= div_done_x;\r
rx_ena <= '0';\r
tx_ena <= '0';\r
busy <= '0';\r
- spi_cs <= '1';\r
+ spi_cs <= spi_cs_x;--'1';\r
tx_load <= '0';\r
tx_sel <= "000";\r
rx_store <= '0';\r
begin\r
if( rising_edge(sysclk) ) then\r
if( reset = '1' ) then\r
- tx_sreg <= (others => '0');\r
+ tx_sreg(6 downto 0) <= (others => '0');\r
tx_bit_cnt <= (others => '0');\r
last_tx_bit <= '0';\r
elsif ( (clk_en = '1' ) and (tx_load = '1') ) then\r
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
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;
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;
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;
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;
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
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
---------------------------------------------------------------------
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;