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',
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;
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';
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';
----------------------------------------------------------------------
-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
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;
--end if;
req_retr_i <= '1';
waiting_for_retr <= '1';
- --end if;
end if;
force_crc_error_int <= '0';
else
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";
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);
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 ;
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;
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
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;
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;
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
--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";
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;
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
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;
STAT_RESET => open,
DEBUG_OUT => open,
- BUS_RX => BUS_RX
+ BUS_TX => BUS_TX_m,
+ BUS_RX => BUS_RX_m
);
STAT_RESET => open,
DEBUG_OUT => open,
- BUS_RX => BUS_RX
+ BUS_TX => BUS_TX_s,
+ BUS_RX => BUS_RX_s
);
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);
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';
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';
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;
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;
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
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;
-- ---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);