diff --git a/libraries/technology/mac_10g/tb_tech_mac_10g_pkg.vhd b/libraries/technology/mac_10g/tb_tech_mac_10g_pkg.vhd index ab7b63de797de75fe8525880c6dff69ebb6c51d3..9702be4a9067678e82b5af8543ed3614c571ecaf 100644 --- a/libraries/technology/mac_10g/tb_tech_mac_10g_pkg.vhd +++ b/libraries/technology/mac_10g/tb_tech_mac_10g_pkg.vhd @@ -202,89 +202,91 @@ PACKAGE BODY tb_tech_mac_10g_pkg IS VARIABLE v_num : UNSIGNED(c_tech_mac_10g_data_w-1 DOWNTO 0) := (OTHERS=>'0'); VARIABLE v_hdr_words_arr : t_network_total_header_64b_arr; BEGIN - -- Select header - CASE c_data_type IS - WHEN c_tb_tech_mac_10g_data_type_arp => v_hdr_words_arr := c_arp_words_arr; - WHEN c_tb_tech_mac_10g_data_type_ping => v_hdr_words_arr := c_icmp_words_arr; - WHEN OTHERS => v_hdr_words_arr := c_udp_words_arr; -- default via UDP - END CASE; - - ff_src_out.empty <= TO_DP_EMPTY(0); - IF c_data_type=c_tb_tech_mac_10g_data_type_arp THEN + ff_src_out <= c_dp_sosi_rst; + IF ff_src_in.xon='1' THEN -- Generate this packet - ---------------------------------------------------------------------------- - -- Header only frame - ---------------------------------------------------------------------------- - -- . sop - ff_src_out.data <= RESIZE_DP_DATA(v_hdr_words_arr(0)); - proc_dp_stream_ready_latency(c_ready_latency, ff_clk, ff_src_in.ready, ff_en, '0', '1', '1', '0', ff_src_out.sync, ff_src_out.valid, ff_src_out.sop, ff_src_out.eop); - ff_src_out.data <= RESIZE_DP_DATA(v_hdr_words_arr(1)); -- prepare data before loop, so proc_dp_stream_ready_latency can be called at start of the loops - FOR I IN 2 TO c_nof_hdr_beats-2 LOOP - proc_dp_stream_ready_latency(c_ready_latency, ff_clk, ff_src_in.ready, ff_en, '0', '1', '0', '0', ff_src_out.sync, ff_src_out.valid, ff_src_out.sop, ff_src_out.eop); - ff_src_out.data <= RESIZE_DP_DATA(v_hdr_words_arr(I)); - END LOOP; - proc_dp_stream_ready_latency(c_ready_latency, ff_clk, ff_src_in.ready, ff_en, '0', '1', '0', '0', ff_src_out.sync, ff_src_out.valid, ff_src_out.sop, ff_src_out.eop); - -- . eop - ff_src_out.data <= RESIZE_DP_DATA(v_hdr_words_arr(c_nof_hdr_beats-1)); - proc_dp_stream_ready_latency(c_ready_latency, ff_clk, ff_src_in.ready, ff_en, '0', '1', '0', '1', ff_src_out.sync, ff_src_out.valid, ff_src_out.sop, ff_src_out.eop); - - ELSE + -- Select header + CASE c_data_type IS + WHEN c_tb_tech_mac_10g_data_type_arp => v_hdr_words_arr := c_arp_words_arr; + WHEN c_tb_tech_mac_10g_data_type_ping => v_hdr_words_arr := c_icmp_words_arr; + WHEN OTHERS => v_hdr_words_arr := c_udp_words_arr; -- default via UDP + END CASE; - ---------------------------------------------------------------------------- - -- Header for frame with payload - ---------------------------------------------------------------------------- - - -- Header - -- . sop - ff_src_out.data <= RESIZE_DP_DATA(v_hdr_words_arr(0)); - proc_dp_stream_ready_latency(c_ready_latency, ff_clk, ff_src_in.ready, ff_en, '0', '1', '1', '0', ff_src_out.sync, ff_src_out.valid, ff_src_out.sop, ff_src_out.eop); - ff_src_out.data <= RESIZE_DP_DATA(v_hdr_words_arr(1)); -- prepare data before loop, so proc_dp_stream_ready_latency can be called at start of the loops - FOR I IN 2 TO c_nof_hdr_beats-1 LOOP - proc_dp_stream_ready_latency(c_ready_latency, ff_clk, ff_src_in.ready, ff_en, '0', '1', '0', '0', ff_src_out.sync, ff_src_out.valid, ff_src_out.sop, ff_src_out.eop); - ff_src_out.data <= RESIZE_DP_DATA(v_hdr_words_arr(I)); - END LOOP; - - -- Payload - FOR I IN 0 TO c_nof_data_beats-1 LOOP + ff_src_out.empty <= TO_DP_EMPTY(0); + IF c_data_type=c_tb_tech_mac_10g_data_type_arp THEN + + ---------------------------------------------------------------------------- + -- Header only frame + ---------------------------------------------------------------------------- + -- . sop + ff_src_out.data <= RESIZE_DP_DATA(v_hdr_words_arr(0)); + proc_dp_stream_ready_latency(c_ready_latency, ff_clk, ff_src_in.ready, ff_en, '0', '1', '1', '0', ff_src_out.sync, ff_src_out.valid, ff_src_out.sop, ff_src_out.eop); + ff_src_out.data <= RESIZE_DP_DATA(v_hdr_words_arr(1)); -- prepare data before loop, so proc_dp_stream_ready_latency can be called at start of the loops + FOR I IN 2 TO c_nof_hdr_beats-2 LOOP + proc_dp_stream_ready_latency(c_ready_latency, ff_clk, ff_src_in.ready, ff_en, '0', '1', '0', '0', ff_src_out.sync, ff_src_out.valid, ff_src_out.sop, ff_src_out.eop); + ff_src_out.data <= RESIZE_DP_DATA(v_hdr_words_arr(I)); + END LOOP; proc_dp_stream_ready_latency(c_ready_latency, ff_clk, ff_src_in.ready, ff_en, '0', '1', '0', '0', ff_src_out.sync, ff_src_out.valid, ff_src_out.sop, ff_src_out.eop); - CASE c_data_type IS - WHEN c_tb_tech_mac_10g_data_type_counter => - -- data : X"00000000_00000001", X"00000000_00000002", X"00000000_00000003", etc - v_num := v_num + 1; - ff_src_out.data <= RESIZE_DP_DATA(STD_LOGIC_VECTOR(v_num)); - WHEN OTHERS => - -- data : X"01020304_05060708", X"090A0B0C_0D0E0F10", X"11121314_15161718", etc - FOR J IN c_tech_mac_10g_symbols_per_beat-1 DOWNTO 0 LOOP - v_sym := v_sym + 1; - ff_src_out.data((J+1)*c_tech_mac_10g_symbol_w-1 DOWNTO J*c_tech_mac_10g_symbol_w) <= STD_LOGIC_VECTOR(v_sym); - END LOOP; - END CASE; - -- tb : pull valid low for some time during the middle of the payload - IF c_nof_not_valid > 0 AND I=c_nof_data_beats/2 THEN - ff_src_out.valid <= '0'; - FOR I IN 0 TO c_nof_not_valid LOOP WAIT UNTIL rising_edge(ff_clk); END LOOP; - ff_src_out.valid <= '1'; - END IF; - END LOOP; + -- . eop + ff_src_out.data <= RESIZE_DP_DATA(v_hdr_words_arr(c_nof_hdr_beats-1)); + proc_dp_stream_ready_latency(c_ready_latency, ff_clk, ff_src_in.ready, ff_en, '0', '1', '0', '1', ff_src_out.sync, ff_src_out.valid, ff_src_out.sop, ff_src_out.eop); + + ELSE + + ---------------------------------------------------------------------------- + -- Header for frame with payload + ---------------------------------------------------------------------------- - -- Last data - IF c_empty > 0 THEN - -- Overwrite empty data - ff_src_out.empty <= TO_DP_EMPTY(c_empty); - FOR J IN c_empty-1 DOWNTO 0 LOOP - ff_src_out.data((J+1)*c_tech_mac_10g_symbol_w-1 DOWNTO J*c_tech_mac_10g_symbol_w) <= (OTHERS=>'0'); + -- Header + -- . sop + ff_src_out.data <= RESIZE_DP_DATA(v_hdr_words_arr(0)); + proc_dp_stream_ready_latency(c_ready_latency, ff_clk, ff_src_in.ready, ff_en, '0', '1', '1', '0', ff_src_out.sync, ff_src_out.valid, ff_src_out.sop, ff_src_out.eop); + ff_src_out.data <= RESIZE_DP_DATA(v_hdr_words_arr(1)); -- prepare data before loop, so proc_dp_stream_ready_latency can be called at start of the loops + FOR I IN 2 TO c_nof_hdr_beats-1 LOOP + proc_dp_stream_ready_latency(c_ready_latency, ff_clk, ff_src_in.ready, ff_en, '0', '1', '0', '0', ff_src_out.sync, ff_src_out.valid, ff_src_out.sop, ff_src_out.eop); + ff_src_out.data <= RESIZE_DP_DATA(v_hdr_words_arr(I)); + END LOOP; + + -- Payload + FOR I IN 0 TO c_nof_data_beats-1 LOOP + proc_dp_stream_ready_latency(c_ready_latency, ff_clk, ff_src_in.ready, ff_en, '0', '1', '0', '0', ff_src_out.sync, ff_src_out.valid, ff_src_out.sop, ff_src_out.eop); + CASE c_data_type IS + WHEN c_tb_tech_mac_10g_data_type_counter => + -- data : X"00000000_00000001", X"00000000_00000002", X"00000000_00000003", etc + v_num := v_num + 1; + ff_src_out.data <= RESIZE_DP_DATA(STD_LOGIC_VECTOR(v_num)); + WHEN OTHERS => + -- data : X"01020304_05060708", X"090A0B0C_0D0E0F10", X"11121314_15161718", etc + FOR J IN c_tech_mac_10g_symbols_per_beat-1 DOWNTO 0 LOOP + v_sym := v_sym + 1; + ff_src_out.data((J+1)*c_tech_mac_10g_symbol_w-1 DOWNTO J*c_tech_mac_10g_symbol_w) <= STD_LOGIC_VECTOR(v_sym); + END LOOP; + END CASE; + -- tb : pull valid low for some time during the middle of the payload + IF c_nof_not_valid > 0 AND I=c_nof_data_beats/2 THEN + ff_src_out.valid <= '0'; + FOR I IN 0 TO c_nof_not_valid LOOP WAIT UNTIL rising_edge(ff_clk); END LOOP; + ff_src_out.valid <= '1'; + END IF; END LOOP; + + -- Last data + IF c_empty > 0 THEN + -- Overwrite empty data + ff_src_out.empty <= TO_DP_EMPTY(c_empty); + FOR J IN c_empty-1 DOWNTO 0 LOOP + ff_src_out.data((J+1)*c_tech_mac_10g_symbol_w-1 DOWNTO J*c_tech_mac_10g_symbol_w) <= (OTHERS=>'0'); + END LOOP; + END IF; + -- . eop + proc_dp_stream_ready_latency(c_ready_latency, ff_clk, ff_src_in.ready, ff_en, '0', '1', '0', '1', ff_src_out.sync, ff_src_out.valid, ff_src_out.sop, ff_src_out.eop); + END IF; - -- . eop - proc_dp_stream_ready_latency(c_ready_latency, ff_clk, ff_src_in.ready, ff_en, '0', '1', '0', '1', ff_src_out.sync, ff_src_out.valid, ff_src_out.sop, ff_src_out.eop); + ELSE + -- Wait until XON is active + proc_common_wait_until_high(ff_clk, ff_src_in.xon); END IF; - - -- Initialize for next tx packet - ff_src_out.data <= TO_DP_DATA(0); - ff_src_out.valid <= '0'; - ff_src_out.eop <= '0'; - ff_src_out.empty <= TO_DP_EMPTY(0); END proc_tech_mac_10g_tx_packet;