From cd9db02f18efd2ea44446debbed54587b643d272 Mon Sep 17 00:00:00 2001 From: Ingo Froehlich Date: Thu, 30 Aug 2018 14:45:23 +0200 Subject: [PATCH] changed logic in reader --- media_interfaces/sync/med_sync_control.vhd | 8 +- media_interfaces/sync/rx_control.vhd | 125 +++++++++++++++------ media_interfaces/sync/tb/med_sync_tb.vhd | 91 ++++++++++++--- media_interfaces/sync/tx_control.vhd | 21 ++-- 4 files changed, 183 insertions(+), 62 deletions(-) diff --git a/media_interfaces/sync/med_sync_control.vhd b/media_interfaces/sync/med_sync_control.vhd index a3123fd..db8045b 100644 --- a/media_interfaces/sync/med_sync_control.vhd +++ b/media_interfaces/sync/med_sync_control.vhd @@ -312,8 +312,8 @@ THE_TX : tx_control TX_ALLOW_IN => tx_allow, RX_ALLOW_IN => rx_allow, - --ENABLE_SEND_CHKSUM => '1', --SIM - ENABLE_SEND_CHKSUM => MEDIA_INT2MED.ctrl_op(8), + ENABLE_SEND_CHKSUM => '1', --SIM + --ENABLE_SEND_CHKSUM => MEDIA_INT2MED.ctrl_op(8), --RESET_RETRANSMIT_IN => send_link_reset_i, RESET_RETRANSMIT_IN => '0', @@ -411,10 +411,10 @@ STAT_RESET(31) <= start_timer(start_timer'left); gen_link_reset : if IS_SYNC_SLAVE = 1 generate - link_reset_pulse : pulse_sync port map( CLK_A_IN => CLK_RXI, CLK_B_IN => CLK_SYS, + link_reset_pulse : pulse_sync port map( CLK_A_IN => CLK_RXI, CLK_B_IN => CLK_SYS, RESET_A_IN => '0', RESET_B_IN => '0', PULSE_A_IN => make_link_reset_i, PULSE_B_OUT => make_link_reset_sys_i); - link_reset_send : signal_sync port map(RESET => '0',CLK0 => CLK_RXI,CLK1 => CLK_SYS, + link_reset_send : signal_sync port map(RESET => '0', CLK0 => CLK_RXI, CLK1 => CLK_SYS, D_IN(0) => send_link_reset_i, D_OUT(0) => send_link_reset_sys_i); end generate; diff --git a/media_interfaces/sync/rx_control.vhd b/media_interfaces/sync/rx_control.vhd index 5a99746..bac1f50 100644 --- a/media_interfaces/sync/rx_control.vhd +++ b/media_interfaces/sync/rx_control.vhd @@ -56,6 +56,7 @@ signal rx_state : rx_state_t; signal rx_state_bits : std_logic_vector(3 downto 0); signal rx_packet_num : std_logic_vector(2 downto 0); signal buf_rx_write_out : std_logic := '0'; +signal buf2_rx_write_out : std_logic := '0'; signal rx_data : std_logic_vector(17 downto 0); signal ct_fifo_write : std_logic := '0'; @@ -94,17 +95,24 @@ signal pulse_good : std_logic; signal pulse_bad : std_logic; signal got_pulse_good : std_logic := '0'; signal got_pulse_bad : std_logic := '0'; + +signal last_got_pulse_good : std_logic := '0'; +signal last_got_pulse_bad : std_logic := '0'; + signal pulse_good_100 : std_logic; signal pulse_bad_100 : std_logic; +signal latched_pulse_bad_100 : unsigned(1 downto 0) := "00"; +signal latched_pulse_good_100 : unsigned(1 downto 0) := "00"; signal waiting_for_retr : std_logic := '0'; signal good_pos_counter : std_logic_vector(7 downto 0) := (others => '0'); signal num_pakets : unsigned(3 downto 0) := (others => '0'); signal reg_num_pakets : unsigned(3 downto 0) := (others => '0'); +signal num_read_words : unsigned(2 downto 0) := (others => '0'); -signal use_crc : std_logic := '0'; +signal use_crc : std_logic := '0'; signal use_crc_200 : std_logic := '0'; signal last_use_crc : std_logic := '0'; -signal load_use_crc : std_logic := '0'; +signal load_use_crc : std_logic := '0'; signal load_use_crc_sys : std_logic := '0'; signal disable_crc : std_logic := '0'; @@ -126,50 +134,99 @@ begin ---------------------------------------------------------------------- -ct_fifo_read <= not ct_fifo_reset and not ct_fifo_empty and (pulse_good_100 or got_pulse_good or pulse_bad_100 or got_pulse_bad or not use_crc); -- when rising_edge(CLK_100); - -buf_rx_write_out <= last_ct_fifo_read and not last_ct_fifo_empty and (((pulse_good_100 or got_pulse_good) and not (pulse_bad_100 or got_pulse_bad)) or not use_crc) - when rising_edge(CLK_100); +--ct_fifo_read <= not ct_fifo_reset and not ct_fifo_empty and (pulse_good_100 or got_pulse_good or pulse_bad_100 or got_pulse_bad or not use_crc); -- when rising_edge(CLK_100); +ct_fifo_read <= not ct_fifo_reset and not ct_fifo_empty and (got_pulse_good or got_pulse_bad or not use_crc); + +--buf_rx_write_out <= last_ct_fifo_read and not last_ct_fifo_empty and (((pulse_good_100 or got_pulse_good) and not (pulse_bad_100 or got_pulse_bad)) or not use_crc) +--buf_rx_write_out <= last_ct_fifo_read and not last_ct_fifo_empty and not got_pulse_bad +-- when rising_edge(CLK_100); -RX_DATA_OUT <= ct_fifo_data_out(15 downto 0) ; -RX_WRITE_OUT <= buf_rx_write_out; +RX_DATA_OUT <= ct_fifo_data_out(15 downto 0) when rising_edge(CLK_100); +RX_WRITE_OUT <= buf2_rx_write_out; RX_PACKET_NUMBER_OUT <= rx_packet_num; -last_ct_fifo_read <= ct_fifo_read when rising_edge(CLK_100); -last_ct_fifo_empty <= ct_fifo_empty when rising_edge(CLK_100); -last_use_crc <= use_crc when rising_edge(CLK_100); -reset_retrans <= RESET_RETRANSMIT_IN when rising_edge(CLK_100); -load_use_crc_sys <= load_use_crc when rising_edge(CLK_100); +last_ct_fifo_read <= ct_fifo_read when rising_edge(CLK_100); +last_ct_fifo_empty <= ct_fifo_empty when rising_edge(CLK_100); +last_use_crc <= use_crc when rising_edge(CLK_100); +last_got_pulse_good <= got_pulse_good when rising_edge(CLK_100); +--last_got_pulse_bad <= got_pulse_bad when rising_edge(CLK_100); +reset_retrans <= RESET_RETRANSMIT_IN when rising_edge(CLK_100); +load_use_crc_sys <= load_use_crc when rising_edge(CLK_100); + force_crc_error_200 <= force_crc_error when rising_edge(CLK_200); CRC_ERROR_DELAY_200 <= CRC_ERROR_DELAY when rising_edge(CLK_200); -use_crc_200 <= use_crc when rising_edge(CLK_200); +use_crc_200 <= use_crc when rising_edge(CLK_200); process begin wait until rising_edge(CLK_100); - if ct_fifo_empty = '1' then - got_pulse_bad <= '0'; + --switch only when fifo is empty: + if ct_fifo_empty = '1' and load_use_crc_sys = '1' then + use_crc <= '1'; + elsif ct_fifo_empty = '1' and load_use_crc_sys = '0' then + use_crc <= '0'; + end if; + + --some logic to remember the state: + if (pulse_good_100 = '1' or latched_pulse_good_100 /= "00") and (ct_fifo_empty = '1' or num_read_words = 0) then + got_pulse_good <= '1'; + got_pulse_bad <= '0'; + if latched_pulse_good_100 /= "00" then + latched_pulse_good_100 <= latched_pulse_good_100 - 1; + end if; + elsif pulse_good_100 = '1' then + latched_pulse_good_100 <= latched_pulse_good_100 + 1; + elsif (pulse_bad_100 = '1' or latched_pulse_bad_100 /= "00") and (ct_fifo_empty = '1' or num_read_words = 0) then + got_pulse_bad <= '1'; got_pulse_good <= '0'; - if load_use_crc_sys = '1' then - use_crc <= '1'; - else - use_crc <= '0'; - end if; + if latched_pulse_bad_100 /= "00" then + latched_pulse_bad_100 <= latched_pulse_bad_100 - 1; + end if; + elsif pulse_bad_100 = '1' then + latched_pulse_bad_100 <= latched_pulse_bad_100 + 1; + end if; + + --switching the good/bad mode is only allowed after complete pakets + --(otherwise the current transfer is interrupted) + if ct_fifo_empty = '1' or num_read_words = 4 or use_crc = '0' then + if latched_pulse_bad_100 = "00" then + got_pulse_bad <= '0'; + end if; + if latched_pulse_good_100 = "00" then + got_pulse_good <= '0'; + end if; + num_read_words <= "000"; + elsif use_crc = '1' and ct_fifo_read = '1' then + num_read_words <= num_read_words + 1; end if; + --the following lines catches the case that an incomplete paket is merged + --with the fresh new paket after resubmit + --(see also pulse_bad in GET_RETR) + if (pulse_good_100 = '1' or latched_pulse_good_100 /= "00") and got_pulse_bad = '1' and num_read_words /= "010" and ct_fifo_data_out(16) = '1' then + buf2_rx_write_out <= '1'; + buf_rx_write_out <= '1'; + got_pulse_good <= '1'; + got_pulse_bad <= '0'; + num_read_words <= "011"; + latched_pulse_good_100 <= "00"; + last_got_pulse_bad <= '0'; + else + --thats like it should work in normal mode: + last_got_pulse_bad <= got_pulse_bad; + buf2_rx_write_out <= buf_rx_write_out; + buf_rx_write_out <= last_ct_fifo_read and not last_ct_fifo_empty and not got_pulse_bad; + if last_got_pulse_bad = '1' then + buf_rx_write_out <= '0'; + end if; + end if; + if last_use_crc = '0' and buf_rx_write_out = '1' then good_pos_counter <= std_logic_vector(unsigned(good_pos_counter)+1); elsif pulse_good_100 = '1' then good_pos_counter <= std_logic_vector(unsigned(good_pos_counter)+5); end if; - if pulse_good_100 = '1' then - got_pulse_good <= '1'; - end if; - if pulse_bad_100 = '1' then - got_pulse_bad <= '1'; - end if; - if RX_ALLOW_IN = '0' then rx_packet_num <= "100"; elsif buf_rx_write_out = '1' then @@ -335,10 +392,9 @@ PROC_RX_FSM : process begin or force_crc_error_int = '1') and disable_crc = '0' then -- bad if force_crc_error_int = '1' then --debug - reg_num_pakets <= reg_num_pakets + 1; - else - pulse_bad <= '1'; + reg_num_pakets <= reg_num_pakets + 1; end if; + pulse_bad <= '1'; if waiting_for_retr = '0' then --if crc_q /= reg_rx_data_in then --debug --num_crc <= num_crc+1; @@ -347,7 +403,6 @@ PROC_RX_FSM : process begin --end if; req_retr_i <= '1'; waiting_for_retr <= '1'; - --end if; end if; force_crc_error_int <= '0'; else @@ -370,11 +425,15 @@ PROC_RX_FSM : process begin if force_crc_error_200 = '1' then disable_crc <= '1'; end if; + if num_pakets /= "0000" then --incomplete packet + pulse_bad <= '1'; + end if; rx_state <= FIRST; waiting_for_retr <= '0'; crc_reset <= '1'; num_pakets <= (others => '0'); resub_mode <= '1'; + next_sop <= '1'; when GET_DLM => rx_state_bits <= x"5"; @@ -531,7 +590,7 @@ DEBUG_OUT(23 downto 20) <= (others => '0'); DEBUG_OUT(24) <= force_crc_error_int when rising_edge(clk_100); DEBUG_OUT(25) <= use_crc; DEBUG_OUT(27 downto 26) <= (others => '0'); -DEBUG_OUT(31 downto 28) <= reg_num_pakets when rising_edge(clk_100); +DEBUG_OUT(31 downto 28) <= std_logic_vector(reg_num_pakets) when rising_edge(clk_100); -- DEBUG_OUT(23 downto 16) <= rx_data(7 downto 0); diff --git a/media_interfaces/sync/tb/med_sync_tb.vhd b/media_interfaces/sync/tb/med_sync_tb.vhd index f0eaf14..33fd8d5 100644 --- a/media_interfaces/sync/tb/med_sync_tb.vhd +++ b/media_interfaces/sync/tb/med_sync_tb.vhd @@ -2,7 +2,8 @@ LIBRARY ieee ; LIBRARY work ; USE ieee.NUMERIC_STD.all ; -USE ieee.std_logic_1164.all ; +USE ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; USE work.med_sync_define.all ; USE work.trb_net_components.all ; USE work.trb_net_std.all ; @@ -44,6 +45,7 @@ component med_sync_control is TX_DATA : out std_logic_vector(7 downto 0); TX_K : out std_logic; + TX_CD : out std_logic; RX_DATA : in std_logic_vector(7 downto 0); RX_K : in std_logic; @@ -62,6 +64,9 @@ component med_sync_control is STAT_RESET : out std_logic_vector(31 downto 0); DEBUG_OUT : out std_logic_vector(31 downto 0); + DEBUG_RETRANS_OUT : out std_logic_vector(31 downto 0); + FORCE_CRC_ERROR_IN : in std_logic := '0'; + BUS_RX : in CTRLBUS_RX; BUS_TX : out CTRLBUS_TX @@ -77,7 +82,11 @@ signal clear_m : std_logic := '1'; signal reset_s : std_logic := '1'; signal clear_s : std_logic := '1'; -signal BUS_RX : CTRLBUS_RX; +signal BUS_RX_m : CTRLBUS_RX; +signal BUS_RX_s : CTRLBUS_RX; +signal BUS_TX_m : CTRLBUS_TX; +signal BUS_TX_s : CTRLBUS_TX; +--signal BUS_RX : CTRLBUS_RX; signal med2int_m, med2int_s : MED2INT; signal int2med_m, int2med_s : INT2MED; @@ -94,7 +103,7 @@ clear_m <= '0' after 51 ns; reset_s <= '0' after 201 ns; clear_s <= '0' after 51 ns; -process (tx_data_m) +process (tx_data_m, tx_k_m) begin if (tx_data_m = x"11") then rx_k_s <= transport tx_k_m after 250 ns; @@ -102,8 +111,7 @@ begin if do_once = "00" then rx_data_s(7 downto 1) <= transport tx_data_m(7 downto 1) after 250 ns; rx_data_s(0) <= transport '0' after 250 ns; - - --rx_k_s <= transport (not tx_k_m) after 250 ns; + ----rx_k_s <= transport (not tx_k_m) after 250 ns; do_once <= "01"; --2 errors, one good --do_once <= "10"; --1 error, 2 good elsif do_once = "01" then @@ -136,7 +144,33 @@ clk_100_s <= not clk_100_s after 4.8 ns; --clk_200_s <= not clk_200_s after 2.55 ns; clk_200_s <= not clk_200_s after 2.4 ns; +process begin + BUS_RX_s.addr <= x"0000"; + wait for 30000ns; + BUS_RX_s.write <= '1'; + BUS_RX_s.data <= x"00000050"; + wait for 20ns; + BUS_RX_s.write <= '0'; + BUS_RX_s.data <= x"00000000"; + + wait for 2000ns; + BUS_RX_s.write <= '1'; + BUS_RX_s.data <= x"00000001"; + wait for 20ns; + BUS_RX_s.write <= '0'; + BUS_RX_s.data <= x"00000000"; +end process; +process begin + BUS_RX_m.addr <= x"0000"; + wait for 32000ns; +-- BUS_RX_m.write <= '1'; + BUS_RX_m.data <= x"00000200"; + wait for 20ns; + BUS_RX_m.write <= '0'; + BUS_RX_m.data <= x"00000000"; +end process; + process begin int2med_m.ctrl_op <= x"0000"; int2med_s.ctrl_op <= x"0000"; @@ -145,11 +179,37 @@ process begin int2med_m.dataready <= '0'; wait for 30 us; + -- Initial packet to enable crc + wait until rising_edge(clk_100_m); wait for 1 ns; + int2med_m.data <= x"0001"; + int2med_m.packet_num <= "100"; + int2med_m.dataready <= '1'; + wait until rising_edge(clk_100_m); wait for 1 ns; + int2med_m.data <= x"0002"; + int2med_m.packet_num <= "000"; + int2med_m.dataready <= '1'; + wait until rising_edge(clk_100_m); wait for 1 ns; + int2med_m.data <= x"0003"; + int2med_m.packet_num <= "001"; + int2med_m.dataready <= '1'; + wait until rising_edge(clk_100_m); wait for 1 ns; + int2med_m.data <= x"0004"; + int2med_m.packet_num <= "010"; + int2med_m.dataready <= '1'; + wait until rising_edge(clk_100_m); wait for 1 ns; + int2med_m.data <= x"0005"; + int2med_m.packet_num <= "011"; + int2med_m.dataready <= '1'; + wait until rising_edge(clk_100_m); wait for 1 ns; + int2med_m.dataready <= '0'; + int2med_m.data <= x"0000"; + wait for 100ns; + -- generate good packages to test the RAM overflow --GEN_GOOD: for i in 0 to 3 loop - GEN_GOOD: for i in 0 to 0 loop + GEN_GOOD: for i in 0 to 24 loop wait until rising_edge(clk_100_m); wait for 1 ns; - int2med_m.data <= x"0001"; + int2med_m.data <= conv_std_logic_vector(i,8) & x"01"; int2med_m.packet_num <= "100"; int2med_m.dataready <= '1'; wait until rising_edge(clk_100_m); wait for 1 ns; @@ -171,11 +231,12 @@ process begin wait until rising_edge(clk_100_m); wait for 1 ns; int2med_m.dataready <= '0'; int2med_m.data <= x"0000"; + wait for 20ns; end loop; - GEN_BAD: for i in 0 to 2 loop + GEN_BAD: for i in 0 to 0 loop --bad packages - wait for 500ns; +-- wait for 500ns; wait until rising_edge(clk_100_m); wait for 1 ns; int2med_m.data <= x"1122"; --int2med_m.data <= x"1111"; --for k flip @@ -197,9 +258,9 @@ process begin int2med_m.data <= x"9900"; int2med_m.packet_num <= "011"; int2med_m.dataready <= '1'; - wait until rising_edge(clk_100_m); wait for 1 ns; - int2med_m.dataready <= '0'; - wait until rising_edge(clk_100_m); wait for 1 ns; +-- wait until rising_edge(clk_100_m); wait for 1 ns; +-- int2med_m.dataready <= '0'; +-- wait until rising_edge(clk_100_m); wait for 1 ns; end loop; -- wait until rising_edge(clk_100_m); wait for 1 ns; -- wait until rising_edge(clk_100_m); wait for 1 ns; @@ -283,7 +344,8 @@ THE_MASTER : med_sync_control STAT_RESET => open, DEBUG_OUT => open, - BUS_RX => BUS_RX + BUS_TX => BUS_TX_m, + BUS_RX => BUS_RX_m ); @@ -335,7 +397,8 @@ THE_SLAVE : med_sync_control STAT_RESET => open, DEBUG_OUT => open, - BUS_RX => BUS_RX + BUS_TX => BUS_TX_s, + BUS_RX => BUS_RX_s ); diff --git a/media_interfaces/sync/tx_control.vhd b/media_interfaces/sync/tx_control.vhd index 0a53b65..369513c 100644 --- a/media_interfaces/sync/tx_control.vhd +++ b/media_interfaces/sync/tx_control.vhd @@ -72,10 +72,6 @@ architecture arch of tx_control is signal ram_fill_level : unsigned(7 downto 0); signal ram_empty : std_logic; signal ram_afull : std_logic; - - --signal ram_read_addr1 : unsigned(7 downto 0) := (others => '0'); - --signal ram_read_addr2 : unsigned(7 downto 0) := (others => '0'); - signal request_position_q : std_logic_vector( 7 downto 0); signal restart_position_q : std_logic_vector( 7 downto 0); @@ -123,6 +119,7 @@ architecture arch of tx_control is signal resub_mode : std_logic := '0'; signal reset_retrans : std_logic; + signal GOT_FORCE_ERROR_reg : std_logic := '0'; signal FORCE_CRC_ERROR_200 : std_logic := '0'; signal FORCE_PAK_ERROR_200 : std_logic := '0'; @@ -167,6 +164,7 @@ begin FORCE_CRC_ERROR_200 <= FORCE_CRC_ERROR when rising_edge(CLK_200); FORCE_PAK_ERROR_200 <= FORCE_PAK_ERROR when rising_edge(CLK_200); + GOT_FORCE_ERROR <= GOT_FORCE_ERROR_reg; save_sop <= '1' when (TX_PACKET_NUMBER_IN = c_H0) else '0'; save_eop <= '1' when (TX_PACKET_NUMBER_IN = c_F3) else '0'; @@ -243,7 +241,8 @@ begin if tx_allow_qtx = '0' then ram_fill_level <= (others => '0'); else - ram_fill_level <= last_ram_write_addr - ram_read_addr; + --ram_fill_level <= last_ram_write_addr - ram_read_addr; + ram_fill_level <= (others => '0'); end if; end if; end process; @@ -271,8 +270,8 @@ begin when SEND_IDLE_L => TX_DATA_OUT <= K_IDLE; TX_K_OUT <= '1'; - if FORCE_PAK_ERROR_200 = '1' and GOT_FORCE_ERROR = '0' then - GOT_FORCE_ERROR <= '1'; + if FORCE_PAK_ERROR_200 = '1' and GOT_FORCE_ERROR_reg = '0' then + GOT_FORCE_ERROR_reg <= '1'; current_state <= SEND_DATA_H; else current_state <= SEND_IDLE_H; @@ -313,8 +312,8 @@ begin current_state <= SEND_CHKSUM_H; when SEND_CHKSUM_H => - if FORCE_CRC_ERROR_200 = '1' and GOT_FORCE_ERROR = '0' then - GOT_FORCE_ERROR <= '1'; + if FORCE_CRC_ERROR_200 = '1' and GOT_FORCE_ERROR_reg = '0' then + GOT_FORCE_ERROR_reg <= '1'; --TX_DATA_OUT <= std_logic_vector(unsigned(crc_q) + 1); TX_DATA_OUT <= x"ff"; else @@ -405,7 +404,7 @@ begin resub_mode <= '0'; end if; if FORCE_PAK_ERROR_200 = '0' and FORCE_CRC_ERROR_200 = '0' then - GOT_FORCE_ERROR <= '0'; + GOT_FORCE_ERROR_reg <= '0'; end if; end process; @@ -529,7 +528,7 @@ begin -- ---in this scheme the load pointer comes too late -- gk 05.10.10 - crc_reset <= '1' when ((RESET_IN = '1') or (current_state = SEND_CHKSUM_H) or (current_state = SEND_START_H)) else '0'; + crc_reset <= '1' when ((RESET_IN = '1') or (current_state = SEND_CHKSUM_H) or (current_state = SEND_START_H) or (current_state = SEND_IDLE_H)) else '0'; crc_en <= '1' when ((current_state = SEND_DATA_L) or (current_state = SEND_DATA_H)) else '0'; crc_data <= ram_dout(15 downto 8) when (current_state = SEND_DATA_H) else ram_dout(7 downto 0); -- 2.43.0