// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: CERN-OHL-S-2.0 #include "hls_jfjoch.h" void eiger_reorder(STREAM_768 &data_in, STREAM_768 &data_out, hls::stream &s_axis_completion, hls::stream &m_axis_completion) { #pragma HLS INTERFACE ap_ctrl_none port=return #pragma HLS INTERFACE register both axis port=data_in #pragma HLS INTERFACE register both axis port=data_out #pragma HLS INTERFACE register both axis port=m_axis_completion #pragma HLS INTERFACE register both axis port=s_axis_completion packet_768_t packet; { #pragma HLS PROTOCOL fixed data_in >> packet; ap_wait(); data_out << packet; ap_wait(); } ap_uint<1> mode_eiger_8bit = (ACT_REG_MODE(packet.data) & MODE_EIGER_8BIT) ? 1 : 0; ap_uint<768> memory_0[256]; #pragma HLS BIND_STORAGE variable=memory_0 type=ram_t2p impl=bram latency=3 ap_uint<768> memory_1[256]; #pragma HLS BIND_STORAGE variable=memory_1 type=ram_t2p impl=bram latency=3 packet_768_t packet_out; packet_out.user = 0; packet_out.last = 0; packet_out.id = 0; axis_completion cmpl; s_axis_completion >> cmpl; while (!cmpl.last) { m_axis_completion << cmpl; if (cmpl.detector_type == SLS_DETECTOR_TYPE_EIGER) { size_t line_group_size; size_t lines_per_group; // Packets in EIGER stream are interleaved // Four* lines for left half and four lines for right half // This need to be regrouped into four continuous lines // * Eight lines in 8 bit mode (and 16 lines in 4 bit mode) if (mode_eiger_8bit) lines_per_group = 8; else lines_per_group = 4; line_group_size = lines_per_group * 32; for (int i = 0; i < 16384; i++) { #pragma HLS PIPELINE II=1 data_in >> packet; size_t line_group_number, line_group_beat, col0, line0; line_group_number = i / line_group_size; // 0 - 64 line_group_beat = i % line_group_size; // 0 - 255 col0 = (line_group_beat >= (line_group_size / 2)) ? 16 : 0; line0 = (line_group_beat / 16) % lines_per_group; if (i < 8192) line0 = lines_per_group - 1 - line0; // first half is reversed size_t pos = line0 * 32 + col0 + line_group_beat % 16; if (line_group_number % 2 == 0) { memory_0[pos] = packet.data; packet_out.data = memory_1[line_group_beat]; } else { memory_1[pos] = packet.data; packet_out.data = memory_0[line_group_beat]; } if (i >= line_group_size) data_out << packet_out; } for (int i = 0; i < line_group_size; i++) { #pragma HLS PIPELINE II=1 packet_out.data = memory_1[i]; if (i == line_group_size - 1) packet_out.last = 1; data_out << packet_out; } } else { for (int i = 0; i < 16384; i++) { #pragma HLS PIPELINE II=1 data_in >> packet; data_out << packet; } } s_axis_completion >> cmpl; } m_axis_completion << cmpl; data_in >> packet; data_out << packet; }