Files
Jungfraujoch/fpga/hls/frame_summation.cpp
2025-05-14 23:28:10 +02:00

104 lines
3.7 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 frame_summation(STREAM_768 &data_in, STREAM_768 &data_out,
hls::stream<axis_completion > &s_axis_completion,
hls::stream<axis_completion > &m_axis_completion,
volatile ap_uint<1> &idle) {
#pragma HLS INTERFACE axis register both port=data_in
#pragma HLS INTERFACE axis register both port=data_out
#pragma HLS INTERFACE axis register both port=s_axis_completion
#pragma HLS INTERFACE axis register both port=m_axis_completion
#pragma HLS INTERFACE ap_none register port=idle
idle = 1;
ap_uint<24 * 32> memory_0[16384];
#pragma HLS BIND_STORAGE variable=memory_0 type=ram_t2p impl=uram latency=3
packet_768_t packet_in, packet_out;
{
#pragma HLS PROTOCOL fixed
data_in >> packet_in;
ap_wait();
data_out << packet_in;
ap_wait();
idle = 0;
ap_wait();
}
ap_uint<8> sum = ACT_REG_NSUMMATION(packet_in.data); // 0..255
data_in >> packet_in;
axis_completion cmpl, cmpl_out;
s_axis_completion >> cmpl;
while (!cmpl.last) {
later_frames:
if ((sum > 0) && (!cmpl.pedestal)) {
cmpl_out = cmpl;
cmpl_out.frame_number = cmpl.frame_number / (sum + 1);
for (int s = 0; s <= sum; s++) {
if (s > 0) {
cmpl_out.packet_mask = (cmpl_out.packet_mask & cmpl.packet_mask);
cmpl_out.packet_count += cmpl.packet_count;
}
if (s == sum)
m_axis_completion << cmpl_out;
for (int i = 0; i < 16384; i++) {
#pragma HLS PIPELINE II=1
ap_int<24> val_0[32];
ap_int<24> val_1[32];
unpack32(packet_in.data, val_0);
if (s == 0)
unpack32(0, val_1);
else
unpack32(memory_0[i], val_1);
for (int j = 0; j < 32; j++) {
if ((val_0[j] == INT24_MIN) || (val_1[j] == INT24_MIN))
val_1[j] = INT24_MIN;
else if ((val_0[j] == INT24_MAX) || (val_1[j] == INT24_MAX))
val_1[j] = INT24_MAX;
else {
ap_int<25> tmp = val_1[j] + val_0[j];
if (tmp > INT24_MAX)
val_1[j] = INT24_MAX;
else
val_1[j] = tmp;
}
}
if (s == sum) {
packet_out.data = pack32(val_1);
packet_out.last = ((i == 16383) ? 1 : 0);
packet_out.user = 0;
packet_out.strb = packet_in.strb;
// Taking mask for the last sent image, assuming that mask is the same for all image of the same module
data_out << packet_out;
} else
memory_0[i] = pack32(val_1);
data_in >> packet_in;
}
s_axis_completion >> cmpl;
}
} else {
m_axis_completion << cmpl;
for (int i = 0; i < 16384; i++) {
#pragma HLS PIPELINE II=1
data_out << packet_in;
data_in >> packet_in;
}
s_axis_completion >> cmpl;
}
}
m_axis_completion << cmpl;
data_out << packet_768_t{.data = packet_in.data, .user = 1, .last = 0};
idle = 1;
}