Files
Jungfraujoch/fpga/hls/frame_summation_tb.cpp
2024-03-31 23:08:19 +02:00

138 lines
4.2 KiB
C++

// Copyright (2019-2023) Paul Scherrer Institute
#include <random>
#include "hls_jfjoch.h"
int test(size_t nframes, int16_t min, int16_t max) {
std::cout << "Nframes " << nframes << " min " << min << " max " << max << std::endl;
if ((nframes == 0) || (nframes > 16)) {
std::cerr << "summation amount must be between 1 and 16" << std::endl;
return 1;
}
std::vector<int16_t> input_frame(nframes * RAW_MODULE_SIZE);
STREAM_768 input;
STREAM_768 output;
hls::stream<axis_completion> compl_in;
hls::stream<axis_completion> compl_out;
std::vector<int32_t> output_frame_ref_32(RAW_MODULE_SIZE, 0);
std::vector<int32_t> output_frame_32(RAW_MODULE_SIZE, 0);
std::mt19937 g1(1387);
std::uniform_int_distribution<int16_t> dist(min, max);
for (auto &i: input_frame)
i = dist(g1);
for (int n = 0; n < nframes * RAW_MODULE_SIZE; n++) {
if ((input_frame[n] == INT16_MIN) || (output_frame_ref_32[n % RAW_MODULE_SIZE] == INT24_MIN))
output_frame_ref_32[n % RAW_MODULE_SIZE] = INT24_MIN;
else if ((input_frame[n] == INT16_MAX) || (output_frame_ref_32[n % RAW_MODULE_SIZE] == INT24_MAX))
output_frame_ref_32[n % RAW_MODULE_SIZE] = INT24_MAX;
else
output_frame_ref_32[n % RAW_MODULE_SIZE] += input_frame[n];
}
auto input_frame_512 = (ap_uint<512>*) input_frame.data();
ap_uint<768> action_control = 0;
ACT_REG_NSUMMATION(action_control) = nframes - 1;
input << packet_768_t { .data = action_control, .user = 0 };
for (int i = 0; i < nframes * RAW_MODULE_SIZE * sizeof(uint16_t) / 64; i++) {
ap_int<16> tmp1[32];
ap_int<24> tmp2[32];
unpack32(input_frame_512[i], tmp1);
for (int j = 0; j < 32; j++)
tmp2[j] = tmp1[j];
input << packet_768_t{.data = pack32(tmp2), .user = 0};
}
input << packet_768_t { .user = 1 };
ap_uint<128> packet_mask;
for (int i = 0; i < 128; i++)
packet_mask[i] = 1;
for (int i = 0; i < nframes; i++)
compl_in << axis_completion{.packet_mask = packet_mask, .frame_number = 100 + i, .packet_count = 128, .last = 0};
compl_in << axis_completion{.last = 1};
ap_uint<1> idle;
frame_summation(input, output, compl_in, compl_out, idle);
if (compl_in.size() != 0) {
std::cout << "compl_in should be empty: " << compl_in.size() << std::endl;
return 1;
}
if (compl_out.size() != 2) {
std::cout << "compl_out should be size 2: " << compl_out.size() << std::endl;
return 1;
}
if (input.size() != 0)
return 1;
if (output.size() != RAW_MODULE_SIZE * sizeof(uint16_t) / 64 + 2)
return 1;
output.read();
for (int i = 0; i < RAW_MODULE_SIZE * sizeof(uint16_t) / 64 ; i++) {
ap_int<24> tmp24[32];
ap_uint<768> tmp = output.read().data;
unpack32(tmp, tmp24);
for (int j = 0; j < 32; j++)
output_frame_32[i * 32 + j] = tmp24[j];
}
output.read();
axis_completion cmpl;
cmpl = compl_out.read();
if (cmpl.frame_number != 100/nframes) {
std::cout << "Wrong output frame number" << std::endl;
return 1;
}
if (cmpl.packet_count != 128*nframes) {
std::cout << "Wrong output frame number" << std::endl;
return 1;
}
if (cmpl.packet_mask != packet_mask) {
std::cout << "Wrong packet mask" << std::endl;
return 1;
}
compl_out.read();
if (output_frame_32 != output_frame_ref_32) {
std::cout << "Input and output don't match" << std::endl;
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
if (output_frame_32[i] != output_frame_ref_32[i]) {
std::cout << output_frame_32[i] << " " << output_frame_ref_32[i] << std::endl;
for (int n = 0; n < nframes; n++)
std::cout << input_frame[n * RAW_MODULE_SIZE + i] << " ";
std::cout << std::endl;
}
}
return 1;
}
return 0;
}
int main() {
size_t nframes = 5;
if (test(nframes, 0, 5000) != 0)
return 1;
if (test(nframes, 0, INT16_MAX-1) != 0)
return 1;
//if (test(nframes, INT16_MIN, INT16_MAX) != 0)
// return 1;
return 0;
}