// 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 sls_detector(AXI_STREAM &udp_payload_in, hls::stream > &udp_metadata_in, AXI_STREAM &data_out, hls::stream > &addr_out, uint64_t& counter, uint32_t& counter_eth_error, uint32_t& counter_len_error, volatile ap_uint<1> &in_clear_counters) { #pragma HLS INTERFACE ap_ctrl_none port=return #pragma HLS INTERFACE axis register both port=udp_payload_in #pragma HLS INTERFACE axis register both port=data_out #pragma HLS INTERFACE axis register both port=udp_metadata_in #pragma HLS INTERFACE axis register both port=addr_out #pragma HLS INTERFACE ap_vld register port=counter #pragma HLS INTERFACE ap_vld register port=counter_eth_error #pragma HLS INTERFACE ap_vld register port=counter_len_error #pragma HLS INTERFACE ap_none register port=in_clear_counters #pragma HLS pipeline II=1 style=flp enum sls_detector_state {INSPECT_HEADER, FORWARD, DISCARD}; static sls_detector_state state = INSPECT_HEADER; static ap_uint<128> reminder = 0; packet_512_t packet_in; packet_512_t packet_out; packet_out.user = 0; packet_out.dest = 0; packet_out.id = 0; ap_uint udp_metadata; static ap_uint<8> beat_counter; static uint64_t internal_counter = 0; static uint32_t internal_counter_eth_error = 0; static uint32_t internal_counter_len_error = 0; ap_uint<1> tmp = in_clear_counters; if (tmp) { internal_counter = 0; internal_counter_len_error = 0; internal_counter_eth_error = 0; } #pragma HLS RESET variable=internal_counter #pragma HLS RESET variable=internal_counter_eth_error #pragma HLS RESET variable=internal_counter_len_error #pragma HLS RESET variable=state if (udp_payload_in.read_nb(packet_in)) { switch (state) { case INSPECT_HEADER: udp_metadata_in >> udp_metadata; if ((udp_metadata_payload_size(udp_metadata) == 8240) && (udp_metadata_eth_err(udp_metadata) == 0) && (udp_metadata_len_err(udp_metadata) == 0)) { ap_uint<8> ipv4_addr_host = udp_metadata_src_ipv4(udp_metadata); ap_uint < 64 > frame_number = packet_in.data(63, 0); ap_uint < 32 > jf_debug = packet_in.data(5 * 64 + 31, 5 * 64); ap_uint < 64 > timestamp = packet_in.data(3 * 64 + 63, 3 * 64); ap_uint < 64 > bunchid = packet_in.data(2 * 64 + 63, 2 * 64); ap_uint < 5 > module = (ipv4_addr_host % 32) / 2; ap_uint < 1 > module_part = ipv4_addr_host[0]; ap_uint < 7 > eth_packet = (packet_in.data(127, 96) % 128) | (module_part * 64); beat_counter = 0; reminder = packet_in.data(511, 384); addr_out << addr_packet(eth_packet, module, frame_number, jf_debug, timestamp, bunchid); state = FORWARD; internal_counter++; } else { if (udp_metadata_eth_err(udp_metadata)) internal_counter_eth_error++; else if (udp_metadata_len_err(udp_metadata)) internal_counter_len_error++; state = DISCARD; } break; case FORWARD: packet_out.last = (beat_counter == 127); packet_out.data = (packet_in.data(383, 0), reminder); data_out << packet_out; reminder = packet_in.data(511, 384); beat_counter++; break; case DISCARD: break; } if (packet_in.last) state = INSPECT_HEADER; } counter = internal_counter; counter_eth_error = internal_counter_eth_error; counter_len_error = internal_counter_len_error; }