Files
Jungfraujoch/fpga/hls/sls_detector.cpp

112 lines
4.0 KiB
C++

// Copyright (2019-2023) Paul Scherrer Institute
#include "hls_jfjoch.h"
void sls_detector(AXI_STREAM &udp_payload_in,
hls::stream<ap_uint<UDP_METADATA_STREAM_WIDTH> > &udp_metadata_in,
AXI_STREAM &data_out,
hls::stream<axis_addr> &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_STREAM_WIDTH> 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<1> module_part = column[0];
beat_counter = 0;
reminder = packet_in.data(511, 384);
axis_addr addr;
addr.frame_number = packet_in.data(63, 0);
addr.debug = packet_in.data(5 * 64 + 31, 5 * 64);
addr.timestamp = packet_in.data(3 * 64 + 63, 3 * 64);
addr.bunchid = packet_in.data(2 * 64 + 63, 2 * 64);
addr.module = (column % 32) / 2;
addr.eth_packet = (packet_in.data(127, 96) % 128) | (module_part * 64);
addr.exptime = packet_in.data(95, 64);
addr.last = 0;
addr_out << addr;
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;
}