// Copyright (2019-2022) Paul Scherrer Institute // SPDX-License-Identifier: CERN-OHL-S-2.0 or GPL-3.0-or-later #include "hls_jfjoch.h" void udp(AXI_STREAM ð_in, AXI_STREAM &udp_payload_out, hls::stream > &udp_metadata_out, uint64_t& counter, volatile ap_uint<1> &in_clear_counters) { #pragma HLS INTERFACE ap_ctrl_none port=return #pragma HLS INTERFACE axis register both port=eth_in #pragma HLS INTERFACE axis register both port=udp_payload_out #pragma HLS INTERFACE axis register both port=udp_metadata_out #pragma HLS INTERFACE ap_vld register port=counter #pragma HLS INTERFACE ap_none register port=in_clear_counters #pragma HLS pipeline II=1 style=flp enum udp_state {INSPECT_HEADER, FORWARD, DISCARD}; static udp_state state = INSPECT_HEADER; static packet_512_t packet_in, packet_out; static uint16_t eth_packets_expected; static uint16_t eth_packets_analyzed; static ap_uint udp_metadata; static uint64_t internal_counter = 0; ap_uint<1> tmp = in_clear_counters; if (tmp) internal_counter = 0; #pragma HLS RESET variable=state #pragma HLS RESET variable=internal_counter ap_uint<16> udp_dest_port, udp_len; ap_uint<32> ipv4_source_ip; if (eth_in.read_nb(packet_in)) { packet_out.dest = 0; packet_out.user = 0; packet_out.id = 0; packet_out.last = packet_in.last; switch (state) { case INSPECT_HEADER: udp_len = get_header_field_16(packet_in.data, ipv4_payload_pos + 32); udp_dest_port = get_header_field_16(packet_in.data, ipv4_payload_pos + 16); udp_metadata_payload_size(udp_metadata) = udp_len - 8; // only payload udp_metadata_dest_port(udp_metadata) = udp_dest_port; eth_packets_expected = (udp_payload_pos / 8 + udp_len) / 64 + ((udp_payload_pos / 8 + udp_len) % 64 ? 1 : 0); eth_packets_analyzed = 1; packet_out.data(511 - udp_payload_pos, 0) = packet_in.data(511, udp_payload_pos); if (packet_in.last) udp_payload_out << packet_out; else state = FORWARD; break; case FORWARD: packet_out.data(511, 512 - udp_payload_pos) = packet_in.data(udp_payload_pos - 1, 0); if (eth_packets_analyzed > eth_packets_expected) { packet_out.last = 1; state = DISCARD; } udp_payload_out << packet_out; packet_out.data(511 - udp_payload_pos, 0) = packet_in.data(511, udp_payload_pos); eth_packets_analyzed++; break; case DISCARD: break; } if (packet_in.last) { udp_metadata_eth_err(udp_metadata) = packet_in.user; udp_metadata_len_err(udp_metadata) = ((eth_packets_analyzed != eth_packets_expected) ? 1 : 0); udp_metadata_out << udp_metadata; state = INSPECT_HEADER; internal_counter++; } } counter = internal_counter; }