Files
Jungfraujoch/fpga/hls/eiger_reorder.cpp
2024-11-22 21:25:20 +01:00

103 lines
3.5 KiB
C++

// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// 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<axis_completion> &s_axis_completion,
hls::stream<axis_completion> &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;
}