// 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<16> column = packet_in.data(4 * 64 + 31, 4 * 64 + 16); 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 = (column % 32) / 2; ap_uint<1> module_part = column[0]; ap_uint<7> eth_packet = (packet_in.data(127, 96) % 128) | (module_part * 64); ap_uint<32> exptime = packet_in.data(95, 64); beat_counter = 0; reminder = packet_in.data(511, 384); addr_out << addr_packet(eth_packet, module, frame_number, jf_debug, timestamp, bunchid,exptime); 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; }