FPGA: Basic spot finder (i.e. only based on count threshold) as a placeholder
This commit is contained in:
+32
-410
@@ -2,323 +2,6 @@
|
||||
|
||||
#include "spot_finder.h"
|
||||
|
||||
void calc_sum(ap_uint<SUM_BITWIDTH*32> &ext_column_sum,
|
||||
const ap_uint<512> ext_old_value,
|
||||
const ap_uint<512> ext_new_value) {
|
||||
#pragma HLS PIPELINE II=1
|
||||
ap_int<SUM_BITWIDTH> column_sum[32];
|
||||
ap_int<16> new_value[32];
|
||||
ap_int<16> old_value[32];
|
||||
|
||||
unpack32(ext_new_value, new_value);
|
||||
unpack32(ext_old_value, old_value);
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
column_sum[i] = new_value[i] - old_value[i];
|
||||
}
|
||||
ext_column_sum = pack32(column_sum);
|
||||
}
|
||||
|
||||
void calc_sum2(ap_uint<SUM2_BITWIDTH*32> &ext_column_sum2,
|
||||
const ap_uint<512> ext_old_value,
|
||||
const ap_uint<512> ext_new_value) {
|
||||
#pragma HLS PIPELINE II=1
|
||||
ap_int<SUM2_BITWIDTH> column_sum2[32];
|
||||
ap_int<16> new_value[32];
|
||||
ap_int<16> old_value[32];
|
||||
|
||||
unpack32(ext_new_value, new_value);
|
||||
unpack32(ext_old_value, old_value);
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
column_sum2[i] = new_value[i]*new_value[i] - old_value[i] * old_value[i];
|
||||
// Apparently on FPGA this is easier, than using (new-old)*(new+old) - could it be DSP mapping?
|
||||
}
|
||||
ext_column_sum2 = pack32(column_sum2);
|
||||
}
|
||||
|
||||
void calc_mask_diff(ap_uint<MASK_SUM_BITWIDTH*32> &ext_column_valid,
|
||||
const ap_uint<32> ext_old_value,
|
||||
const ap_uint<32> ext_new_value) {
|
||||
#pragma HLS PIPELINE II=1
|
||||
ap_int<MASK_SUM_BITWIDTH> column_valid[32];
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
column_valid[i] = ap_int<MASK_SUM_BITWIDTH>(ext_new_value[i]) - ap_int<MASK_SUM_BITWIDTH>(ext_old_value[i]);
|
||||
|
||||
ext_column_valid = pack32(column_valid);
|
||||
}
|
||||
|
||||
void calc_mask(const ap_uint<512> &input, ap_uint<512> &output, ap_uint<32> &mask) {
|
||||
#pragma HLS PIPELINE II=1
|
||||
ap_int<16> value[32];
|
||||
ap_uint<32> tmp_mask;
|
||||
ap_uint<512> tmp_output;
|
||||
|
||||
unpack32(input, value);
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if ((value[i] == INT16_MAX) || (value[i] == INT16_MIN)) {
|
||||
tmp_mask[i] = 0;
|
||||
tmp_output(i * 16 + 15, i * 16) = 0;
|
||||
} else {
|
||||
tmp_mask[i] = 1;
|
||||
tmp_output(i * 16 + 15, i * 16) = input(i * 16 + 15, i * 16);
|
||||
}
|
||||
}
|
||||
mask = tmp_mask;
|
||||
output = tmp_output;
|
||||
}
|
||||
|
||||
|
||||
ap_uint<1> check_threshold(ap_int<16> val,
|
||||
ap_int<SUM_BITWIDTH> sum,
|
||||
ap_int<SUM2_BITWIDTH> sum2,
|
||||
ap_int<MASK_SUM_BITWIDTH> valid,
|
||||
strong_pixel_threshold_t strong_pixel_threshold,
|
||||
ap_int<16> photon_count_threshold) {
|
||||
#pragma HLS INLINE
|
||||
ap_int<SUM_BITWIDTH+5> in_minus_mean = val * valid - sum;
|
||||
ap_uint<SUM2_BITWIDTH+5> variance = valid * sum2 - sum * sum;
|
||||
|
||||
if ((in_minus_mean * in_minus_mean * (valid - 1) > variance * strong_pixel_threshold * valid) &&
|
||||
(in_minus_mean > 0) &&
|
||||
(val > photon_count_threshold))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
ap_uint<32> check_threshold(const ap_uint<512> data_packed,
|
||||
const ap_uint<SUM_BITWIDTH*32> sum_packed,
|
||||
const ap_uint<SUM2_BITWIDTH*32> sum2_packed,
|
||||
const ap_uint<MASK_SUM_BITWIDTH*32> valid_packed,
|
||||
strong_pixel_threshold_t strong_pixel_threshold,
|
||||
ap_int<16> photon_count_threshold) {
|
||||
#pragma HLS PIPELINE II=1
|
||||
ap_int<16> data[32];
|
||||
ap_int<SUM_BITWIDTH> sum[32];
|
||||
ap_int<SUM2_BITWIDTH> sum2[32];
|
||||
ap_int<MASK_SUM_BITWIDTH> valid[32];
|
||||
|
||||
unpack32(data_packed, data);
|
||||
unpack32(sum_packed, sum);
|
||||
unpack32(sum2_packed, sum2);
|
||||
unpack32(valid_packed, valid);
|
||||
|
||||
ap_uint<32> tmp_output = 0;
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
tmp_output[i] = check_threshold(data[i], sum[i], sum2[i], valid[i], strong_pixel_threshold, photon_count_threshold);
|
||||
|
||||
return tmp_output;
|
||||
}
|
||||
|
||||
void spot_finder_col_sum(STREAM_512 &data_in,
|
||||
hls::stream<spot_finder_packet> &data_out,
|
||||
hls::stream<ap_uint<SUM_BITWIDTH*32>> &sum_out,
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>> &sum2_out,
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>> &valid_out) {
|
||||
ap_uint<512> data_cache[(2 * FPGA_NBX + 1) * 32];
|
||||
ap_uint<32> mask_cache[(2 * FPGA_NBX + 1) * 32];
|
||||
|
||||
ap_uint<SUM_BITWIDTH*32> sum_cache[32];
|
||||
ap_uint<SUM2_BITWIDTH*32> sum2_cache[32];
|
||||
ap_uint<MASK_SUM_BITWIDTH*32> valid_cache[32];
|
||||
|
||||
packet_512_t packet_in;
|
||||
data_in >> packet_in;
|
||||
data_out << spot_finder_packet{.data=packet_in.data, .user=0};
|
||||
|
||||
data_in >> packet_in;
|
||||
while (!packet_in.user) {
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
#pragma HLS unroll
|
||||
sum_cache[i] = 0;
|
||||
sum2_cache[i] = 0;
|
||||
valid_cache[i] = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (2 * FPGA_NBX + 1) * 32; i++) {
|
||||
#pragma HLS unroll
|
||||
data_cache[i] = 0;
|
||||
mask_cache[i] = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (FPGA_NBX) * 32 + RAW_MODULE_SIZE * sizeof(uint16_t) / 64; i++) {
|
||||
#pragma HLS PIPELINE II = 1
|
||||
ap_uint<512> packet_in_data;
|
||||
ap_uint<32> packet_in_mask;
|
||||
|
||||
if (i < RAW_MODULE_SIZE * sizeof(uint16_t) / 64) {
|
||||
data_out << spot_finder_packet{.data=packet_in.data, .user=0};
|
||||
calc_mask(packet_in.data, packet_in_data, packet_in_mask);
|
||||
data_in >> packet_in;
|
||||
} else {
|
||||
packet_in_data = 0;
|
||||
packet_in_mask = 0;
|
||||
}
|
||||
|
||||
uint16_t cell_number_top = (i / 32) % (2 * FPGA_NBX + 1) * 32 + (i % 32);
|
||||
|
||||
ap_uint<512> top_line = data_cache[cell_number_top];
|
||||
ap_uint<32> top_line_mask = mask_cache[cell_number_top];
|
||||
|
||||
ap_uint<SUM_BITWIDTH * 32> diff_sum;
|
||||
ap_uint<SUM2_BITWIDTH * 32> diff_sum2;
|
||||
ap_uint<MASK_SUM_BITWIDTH * 32> diff_valid;
|
||||
|
||||
ap_uint<SUM_BITWIDTH * 32> column_sum = sum_cache[i % 32];
|
||||
ap_uint<SUM2_BITWIDTH * 32> column_sum2 = sum2_cache[i % 32];
|
||||
ap_uint<MASK_SUM_BITWIDTH * 32> column_valid = valid_cache[i % 32];
|
||||
|
||||
calc_sum(diff_sum, top_line, packet_in_data);
|
||||
calc_sum2(diff_sum2, top_line, packet_in_data);
|
||||
calc_mask_diff(diff_valid, top_line_mask, packet_in_mask);
|
||||
|
||||
update_sum<SUM_BITWIDTH>(column_sum, diff_sum);
|
||||
update_sum<SUM2_BITWIDTH>(column_sum2, diff_sum2);
|
||||
update_sum<MASK_SUM_BITWIDTH>(column_valid, diff_valid);
|
||||
|
||||
if (i >= (FPGA_NBX) * 32) {
|
||||
sum_out << column_sum;
|
||||
sum2_out << column_sum2;
|
||||
valid_out << column_valid;
|
||||
}
|
||||
|
||||
sum_cache[i % 32] = column_sum;
|
||||
sum2_cache[i % 32] = column_sum2;
|
||||
valid_cache[i % 32] = column_valid;
|
||||
|
||||
data_cache[cell_number_top] = packet_in_data;
|
||||
mask_cache[cell_number_top] = packet_in_mask;
|
||||
}
|
||||
}
|
||||
data_out << spot_finder_packet{.data=0, .user=1};
|
||||
}
|
||||
|
||||
void spot_finder_line_sum(hls::stream<spot_finder_packet> &data_in,
|
||||
hls::stream<spot_finder_packet> &data_out,
|
||||
hls::stream<ap_uint<SUM_BITWIDTH*32>> &sum_in,
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>> &sum2_in,
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>> &valid_in,
|
||||
hls::stream<ap_uint<SUM_BITWIDTH*32>> &sum_out,
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>> &sum2_out,
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>> &valid_out) {
|
||||
spot_finder_packet packet_in;
|
||||
data_in >> packet_in;
|
||||
data_out << packet_in;
|
||||
|
||||
ap_uint<SUM_BITWIDTH * 2 * FPGA_NBX> column_sum_val_save = 0;
|
||||
ap_uint<SUM2_BITWIDTH * 2 * FPGA_NBX> column_sum2_val_save = 0;
|
||||
ap_uint<MASK_SUM_BITWIDTH * 2 * FPGA_NBX> column_valid_val_save = 0;
|
||||
|
||||
data_in >> packet_in;
|
||||
while (!packet_in.user) {
|
||||
|
||||
ap_uint<SUM_BITWIDTH * 32> column_sum = 0;
|
||||
ap_uint<SUM2_BITWIDTH * 32> column_sum2 = 0;
|
||||
ap_uint<MASK_SUM_BITWIDTH * 32> column_valid = 0;
|
||||
|
||||
ap_uint<SUM_BITWIDTH * 32> line_sum;
|
||||
ap_uint<SUM2_BITWIDTH * 32> line_sum2;
|
||||
ap_uint<MASK_SUM_BITWIDTH * 32> line_valid;
|
||||
|
||||
#pragma HLS PIPELINE II=33
|
||||
for (int i = 0; i < 32; i++) {
|
||||
|
||||
data_out << packet_in;
|
||||
data_in >> packet_in;
|
||||
|
||||
sum_in >> column_sum;
|
||||
sum2_in >> column_sum2;
|
||||
valid_in >> column_valid;
|
||||
|
||||
sum_out << prefix_sum<SUM_BITWIDTH>((column_sum, column_sum_val_save));
|
||||
sum2_out << prefix_sum<SUM2_BITWIDTH>((column_sum2, column_sum2_val_save));
|
||||
valid_out << prefix_sum<MASK_SUM_BITWIDTH>((column_valid, column_valid_val_save));
|
||||
|
||||
column_sum_val_save = column_sum(SUM_BITWIDTH * 32 - 1, SUM_BITWIDTH * (32 - 2 * FPGA_NBX));
|
||||
column_sum2_val_save = column_sum2(SUM2_BITWIDTH * 32 - 1, SUM2_BITWIDTH * (32 - 2 * FPGA_NBX));
|
||||
column_valid_val_save = column_valid(MASK_SUM_BITWIDTH * 32 - 1, MASK_SUM_BITWIDTH * (32 - 2 * FPGA_NBX));
|
||||
}
|
||||
|
||||
sum_out << prefix_sum<SUM_BITWIDTH>((ap_uint<SUM_BITWIDTH * 2 * FPGA_NBX>(0), column_sum_val_save));
|
||||
sum2_out << prefix_sum<SUM2_BITWIDTH>((ap_uint<SUM2_BITWIDTH * 2 * FPGA_NBX>(0), column_sum2_val_save));
|
||||
valid_out << prefix_sum<MASK_SUM_BITWIDTH>((ap_uint<MASK_SUM_BITWIDTH + 2 * FPGA_NBX>(0), column_valid_val_save));
|
||||
|
||||
column_sum_val_save = 0;
|
||||
column_sum2_val_save = 0;
|
||||
column_valid_val_save = 0;
|
||||
}
|
||||
data_out << packet_in;
|
||||
}
|
||||
|
||||
void spot_finder_line_sum_align(hls::stream<spot_finder_packet> &data_in,
|
||||
hls::stream<spot_finder_packet> &data_out,
|
||||
hls::stream<ap_uint<SUM_BITWIDTH*32>> &sum_in,
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>> &sum2_in,
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>> &valid_in,
|
||||
hls::stream<ap_uint<SUM_BITWIDTH*32>> &sum_out,
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>> &sum2_out,
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>> &valid_out) {
|
||||
spot_finder_packet packet_in;
|
||||
data_in >> packet_in;
|
||||
data_out << packet_in;
|
||||
|
||||
data_in >> packet_in;
|
||||
while (!packet_in.user) {
|
||||
#pragma HLS PIPELINE II=33
|
||||
|
||||
ap_uint<SUM_BITWIDTH * (32 - FPGA_NBX)> line_sum_val_save = 0;
|
||||
ap_uint<SUM2_BITWIDTH * (32 - FPGA_NBX)> line_sum2_val_save = 0;
|
||||
ap_uint<MASK_SUM_BITWIDTH * (32 - FPGA_NBX)> line_valid_val_save = 0;
|
||||
|
||||
ap_uint<SUM_BITWIDTH * 32> line_sum = 0;
|
||||
ap_uint<SUM2_BITWIDTH * 32> line_sum2 = 0;
|
||||
ap_uint<MASK_SUM_BITWIDTH * 32> line_valid = 0;
|
||||
|
||||
sum_in >> line_sum;
|
||||
sum2_in >> line_sum2;
|
||||
valid_in >> line_valid;
|
||||
|
||||
line_sum_val_save = line_sum(SUM_BITWIDTH * 32 - 1, SUM_BITWIDTH * FPGA_NBX);
|
||||
line_sum2_val_save = line_sum2(SUM2_BITWIDTH * 32 - 1, SUM2_BITWIDTH * FPGA_NBX);
|
||||
line_valid_val_save = line_valid(MASK_SUM_BITWIDTH * 32 - 1, MASK_SUM_BITWIDTH * FPGA_NBX);
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
|
||||
data_out << packet_in;
|
||||
data_in >> packet_in;
|
||||
|
||||
sum_in >> line_sum;
|
||||
sum2_in >> line_sum2;
|
||||
valid_in >> line_valid;
|
||||
|
||||
sum_out << (line_sum(SUM_BITWIDTH * FPGA_NBX - 1, 0), line_sum_val_save);
|
||||
sum2_out << (line_sum2(SUM2_BITWIDTH * FPGA_NBX - 1, 0), line_sum2_val_save);
|
||||
valid_out << (line_valid(MASK_SUM_BITWIDTH * FPGA_NBX - 1, 0), line_valid_val_save);
|
||||
|
||||
line_sum_val_save = line_sum(SUM_BITWIDTH * 32 - 1, SUM_BITWIDTH * FPGA_NBX);
|
||||
line_sum2_val_save = line_sum2(SUM2_BITWIDTH * 32 - 1, SUM2_BITWIDTH * FPGA_NBX);
|
||||
line_valid_val_save = line_valid(MASK_SUM_BITWIDTH * 32 - 1, MASK_SUM_BITWIDTH * FPGA_NBX);
|
||||
}
|
||||
}
|
||||
data_out << packet_in;
|
||||
}
|
||||
|
||||
strong_pixel_threshold_t calculate_threshold(ap_uint<16> &in_snr_threshold) {
|
||||
#pragma HLS INLINE
|
||||
ap_uint<16> tmp = in_snr_threshold;
|
||||
strong_pixel_threshold_t snr_threshold = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
#pragma HLS UNROLL
|
||||
snr_threshold[i] = tmp[i];
|
||||
}
|
||||
return snr_threshold * snr_threshold;
|
||||
}
|
||||
|
||||
ap_uint<32> count_pixels(ap_uint<32> &in) {
|
||||
#pragma HLS INLINE
|
||||
ap_uint<32> ret = 0;
|
||||
@@ -327,109 +10,48 @@ ap_uint<32> count_pixels(ap_uint<32> &in) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void spot_finder_check_threshold(hls::stream<spot_finder_packet> &data_in,
|
||||
STREAM_512 &data_out,
|
||||
hls::stream<ap_uint<SUM_BITWIDTH*32>> &sum_in,
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>> &sum2_in,
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>> &valid_in,
|
||||
hls::stream<ap_axiu<32,1,1,1>> &strong_pixel_out,
|
||||
volatile ap_int<16> &in_count_threshold,
|
||||
volatile ap_uint<16> &in_snr_threshold) {
|
||||
spot_finder_packet packet_in;
|
||||
data_in >> packet_in;
|
||||
data_out << packet_512_t{.data=packet_in.data, .user=0, .last=0};
|
||||
ap_uint<SUM_BITWIDTH * 32> line_sum = 0;
|
||||
ap_uint<SUM2_BITWIDTH * 32> line_sum2 = 0;
|
||||
ap_uint<MASK_SUM_BITWIDTH * 32> line_valid = 0;
|
||||
|
||||
data_in >> packet_in;
|
||||
while (!packet_in.user) {
|
||||
ap_int<16> count_threshold = in_count_threshold;
|
||||
ap_uint<16> snr_threshold = in_snr_threshold;
|
||||
strong_pixel_threshold_t snr_threshold_sq = calculate_threshold(snr_threshold);
|
||||
uint32_t strong_pixel_count = 0;
|
||||
|
||||
for (int i = 0; i < RAW_MODULE_SIZE * sizeof(uint16_t) / 64; i++) {
|
||||
#pragma HLS PIPELINE II=1
|
||||
data_out << packet_512_t{.data=packet_in.data, .user=0, .last=0};
|
||||
sum_in >> line_sum;
|
||||
sum2_in >> line_sum2;
|
||||
valid_in >> line_valid;
|
||||
ap_axiu<32, 1, 1, 1> strong_pixel{.user = 0};
|
||||
|
||||
strong_pixel.data = check_threshold(packet_in.data, line_sum, line_sum2, line_valid, snr_threshold_sq, count_threshold);
|
||||
strong_pixel_count += count_pixels(strong_pixel.data);
|
||||
strong_pixel_out << strong_pixel;
|
||||
data_in >> packet_in;
|
||||
}
|
||||
|
||||
// Save parameters used for spot finding + count of
|
||||
strong_pixel_out << ap_axiu<32, 1, 1, 1>{.data = count_threshold, .user = 0};
|
||||
strong_pixel_out << ap_axiu<32, 1, 1, 1>{.data = snr_threshold, .user = 0};
|
||||
strong_pixel_out << ap_axiu<32, 1, 1, 1>{.data = strong_pixel_count, .user = 0};
|
||||
for (int i = 0; i < 13; i++)
|
||||
strong_pixel_out << ap_axiu<32, 1, 1, 1>{.data = 0, .user = 0};
|
||||
}
|
||||
strong_pixel_out << ap_axiu<32,1,1,1>{.data = 0, .user = 1};
|
||||
data_out << packet_512_t{.data=0, .user=1, .last=1};
|
||||
}
|
||||
|
||||
void spot_finder(STREAM_512 &data_in,
|
||||
STREAM_512 &data_out,
|
||||
hls::stream<ap_axiu<32,1,1,1>> &strong_pixel_out,
|
||||
volatile ap_int<16> &in_photon_count_threshold,
|
||||
volatile ap_uint<16> &in_strong_pixel_threshold) {
|
||||
#pragma HLS DATAFLOW
|
||||
|
||||
#pragma HLS INTERFACE axis port=data_in
|
||||
#pragma HLS INTERFACE axis port=data_out
|
||||
#pragma HLS INTERFACE axis port=strong_pixel_out
|
||||
#pragma HLS INTERFACE ap_none register port=in_photon_count_threshold
|
||||
#pragma HLS INTERFACE ap_none register port=in_strong_pixel_threshold
|
||||
packet_512_t packet;
|
||||
data_in >> packet;
|
||||
data_out << packet;
|
||||
|
||||
hls::stream<spot_finder_packet, 256> data_stream_0;
|
||||
hls::stream<spot_finder_packet, 8> data_stream_1, data_stream_2;
|
||||
hls::stream<ap_uint<SUM_BITWIDTH*32>, 16> sum_stream_0;
|
||||
hls::stream<ap_uint<SUM_BITWIDTH*32>, 8> sum_stream_1, sum_stream_2;
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>, 16> sum2_stream_0;
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>, 8> sum2_stream_1, sum2_stream_2;
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>, 16> valid_stream_0;
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>, 8> valid_stream_1, valid_stream_2;
|
||||
#pragma HLS bind_storage variable=data_stream_0 type=fifo impl=bram
|
||||
#pragma HLS bind_storage variable=data_stream_1 type=fifo impl=bram
|
||||
#pragma HLS bind_storage variable=data_stream_2 type=fifo impl=bram
|
||||
#pragma HLS bind_storage variable=sum_stream_0 type=fifo impl=bram
|
||||
#pragma HLS bind_storage variable=sum_stream_1 type=fifo impl=bram
|
||||
#pragma HLS bind_storage variable=sum_stream_2 type=fifo impl=bram
|
||||
#pragma HLS bind_storage variable=sum2_stream_0 type=fifo impl=bram
|
||||
#pragma HLS bind_storage variable=sum2_stream_1 type=fifo impl=bram
|
||||
#pragma HLS bind_storage variable=sum2_stream_2 type=fifo impl=bram
|
||||
#pragma HLS bind_storage variable=valid_stream_0 type=fifo impl=bram
|
||||
#pragma HLS bind_storage variable=valid_stream_1 type=fifo impl=bram
|
||||
#pragma HLS bind_storage variable=valid_stream_2 type=fifo impl=bram
|
||||
data_in >> packet;
|
||||
while (!packet.user) {
|
||||
ap_int<16> count_threshold = in_photon_count_threshold;
|
||||
ap_uint<16> snr_threshold = in_strong_pixel_threshold;
|
||||
ap_uint<32> strong_pixel_count = 0;
|
||||
for (int i = 0; i < RAW_MODULE_SIZE * sizeof(uint16_t) / 64; i++) {
|
||||
#pragma HLS PIPELINE II=1
|
||||
data_out << packet;
|
||||
ap_uint<32> strong_pixel = 0;
|
||||
ap_int<16> data_unpacked[32];
|
||||
unpack32(packet.data, data_unpacked);
|
||||
for (int j = 0; j < 32; j++) {
|
||||
if (data_unpacked[j] > count_threshold)
|
||||
strong_pixel[j] = 1;
|
||||
else
|
||||
strong_pixel[j] = 0;
|
||||
}
|
||||
strong_pixel_out << ap_axiu<32,1,1,1>{.data = strong_pixel, .user = 0};
|
||||
strong_pixel_count += count_pixels(strong_pixel);
|
||||
data_in >> packet;
|
||||
}
|
||||
strong_pixel_out << ap_axiu<32,1,1,1>{.data = count_threshold, .user = 0};
|
||||
strong_pixel_out << ap_axiu<32,1,1,1>{.data = snr_threshold, .user = 0};
|
||||
strong_pixel_out << ap_axiu<32,1,1,1>{.data = strong_pixel_count, .user = 0};
|
||||
|
||||
#ifndef JFJOCH_HLS_NOSYNTH
|
||||
spot_finder_col_sum(data_in, data_stream_0, sum_stream_0, sum2_stream_0, valid_stream_0);
|
||||
spot_finder_line_sum(data_stream_0, data_stream_1,
|
||||
sum_stream_0, sum2_stream_0, valid_stream_0,
|
||||
sum_stream_1, sum2_stream_1, valid_stream_1);
|
||||
spot_finder_line_sum_align(data_stream_1, data_stream_2,
|
||||
sum_stream_1, sum2_stream_1, valid_stream_1,
|
||||
sum_stream_2, sum2_stream_2, valid_stream_2);
|
||||
spot_finder_check_threshold(data_stream_2, data_out, sum_stream_2, sum2_stream_2, valid_stream_2,
|
||||
strong_pixel_out, in_photon_count_threshold, in_strong_pixel_threshold);
|
||||
#else
|
||||
std::vector<std::thread> spot_finder_cores;
|
||||
spot_finder_cores.emplace_back([&] {spot_finder_col_sum(data_in, data_stream_0, sum_stream_0, sum2_stream_0, valid_stream_0);});
|
||||
spot_finder_cores.emplace_back([&] {spot_finder_line_sum(data_stream_0, data_stream_1,
|
||||
sum_stream_0, sum2_stream_0, valid_stream_0,
|
||||
sum_stream_1, sum2_stream_1, valid_stream_1);});
|
||||
spot_finder_cores.emplace_back([&] {spot_finder_line_sum_align(data_stream_1, data_stream_2,
|
||||
sum_stream_1, sum2_stream_1, valid_stream_1,
|
||||
sum_stream_2, sum2_stream_2, valid_stream_2);});
|
||||
spot_finder_cores.emplace_back([&] {spot_finder_check_threshold(data_stream_2, data_out, sum_stream_2, sum2_stream_2, valid_stream_2,
|
||||
strong_pixel_out, in_photon_count_threshold, in_strong_pixel_threshold);});
|
||||
for (auto &i : spot_finder_cores)
|
||||
i.join();
|
||||
#endif
|
||||
for (int i = 0; i < 13; i++)
|
||||
strong_pixel_out << ap_axiu<32,1,1,1>{.data = 0, .user = 0};
|
||||
}
|
||||
strong_pixel_out << ap_axiu<32,1,1,1>{.data = 0, .user = 1};
|
||||
data_out << packet;
|
||||
}
|
||||
|
||||
@@ -7,113 +7,4 @@
|
||||
|
||||
#include "hls_jfjoch.h"
|
||||
|
||||
#define FPGA_NBX 5
|
||||
#define FPGA_NBX_CEIL_LOG2 7
|
||||
#define SUM_BITWIDTH (16+FPGA_NBX_CEIL_LOG2)
|
||||
#define SUM2_BITWIDTH (16*2+FPGA_NBX_CEIL_LOG2)
|
||||
#define MASK_SUM_BITWIDTH (FPGA_NBX_CEIL_LOG2+1)
|
||||
|
||||
struct spot_finder_packet {
|
||||
ap_uint<512> data;
|
||||
ap_uint<1> user;
|
||||
};
|
||||
|
||||
template <int N>
|
||||
void update_sum(ap_uint<N*32> &ext_val1, const ap_uint<N*32> ext_val2) {
|
||||
#pragma HLS PIPELINE II=1
|
||||
|
||||
ap_int<N> val1[32], val2[32];
|
||||
|
||||
unpack32(ext_val1, val1);
|
||||
unpack32(ext_val2, val2);
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
val1[i] += val2[i];
|
||||
|
||||
ext_val1 = pack32(val1);
|
||||
}
|
||||
|
||||
template <int N>
|
||||
ap_uint<N*32> prefix_sum(const ap_uint<N*(32+(2 * FPGA_NBX))> ext_column_sum) {
|
||||
#pragma HLS PIPELINE II=1
|
||||
ap_int<N> column_sum[32 + 2 * FPGA_NBX];
|
||||
ap_int<N> line_sum[32];
|
||||
|
||||
for (int i = 0; i < 32 + 2 * FPGA_NBX; i++)
|
||||
column_sum[i] = ext_column_sum(i * N + (N - 1), i * N);
|
||||
|
||||
ap_int<N> tmp_sum = 0;
|
||||
|
||||
for (int i = 0 ; i < 2 * FPGA_NBX; i++) {
|
||||
tmp_sum += column_sum[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
tmp_sum += column_sum[i + 2 * FPGA_NBX];
|
||||
line_sum[i] = tmp_sum;
|
||||
tmp_sum -= column_sum[i];
|
||||
}
|
||||
|
||||
//for (int i = 0; i < 32; i++) {
|
||||
// line_sum[i] = 0;
|
||||
// for (int j = 0; j < 2 * FPGA_NBX + 1; j++)
|
||||
// line_sum[i] += column_sum[i + j];
|
||||
//}
|
||||
|
||||
return pack32(line_sum);
|
||||
}
|
||||
|
||||
void calc_mask_diff(ap_uint<MASK_SUM_BITWIDTH*32> &ext_column_valid,
|
||||
const ap_uint<32> ext_old_value,
|
||||
const ap_uint<32> ext_new_value);
|
||||
|
||||
void calc_sum2(ap_uint<SUM2_BITWIDTH*32> &ext_column_sum2,
|
||||
const ap_uint<512> ext_old_value,
|
||||
const ap_uint<512> ext_new_value);
|
||||
|
||||
void calc_sum(ap_uint<SUM_BITWIDTH*32> &ext_column_sum,
|
||||
const ap_uint<512> ext_old_value,
|
||||
const ap_uint<512> ext_new_value);
|
||||
|
||||
void calc_mask(const ap_uint<512> &input, ap_uint<512> &output, ap_uint<32> &mask);
|
||||
|
||||
void spot_finder_col_sum(STREAM_512 &data_in,
|
||||
hls::stream<spot_finder_packet> &data_out,
|
||||
hls::stream<ap_uint<SUM_BITWIDTH*32>> &sum_out,
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>> &sum2_out,
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>> &valid_out);
|
||||
|
||||
void spot_finder_line_sum(hls::stream<spot_finder_packet> &data_in,
|
||||
hls::stream<spot_finder_packet> &data_out,
|
||||
hls::stream<ap_uint<SUM_BITWIDTH*32>> &sum_in,
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>> &sum2_in,
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>> &valid_in,
|
||||
hls::stream<ap_uint<SUM_BITWIDTH*32>> &sum_out,
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>> &sum2_out,
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>> &valid_out);
|
||||
|
||||
void spot_finder_line_sum_align(hls::stream<spot_finder_packet> &data_in,
|
||||
hls::stream<spot_finder_packet> &data_out,
|
||||
hls::stream<ap_uint<SUM_BITWIDTH*32>> &sum_in,
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>> &sum2_in,
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>> &valid_in,
|
||||
hls::stream<ap_uint<SUM_BITWIDTH*32>> &sum_out,
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>> &sum2_out,
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>> &valid_out);
|
||||
|
||||
void spot_finder_check_threshold(hls::stream<spot_finder_packet> &data_in,
|
||||
hls::stream<ap_uint<SUM_BITWIDTH*32>> &sum_in,
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>> &sum2_in,
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>> &valid_in,
|
||||
hls::stream<ap_axiu<32,1,1,1>> &strong_pixel_out,
|
||||
volatile ap_int<16> &in_photon_count_threshold,
|
||||
volatile ap_uint<16> &in_strong_pixel_threshold);
|
||||
|
||||
ap_uint<32> check_threshold(const ap_uint<512> data_packed,
|
||||
const ap_uint<SUM_BITWIDTH*32> sum_packed,
|
||||
const ap_uint<SUM2_BITWIDTH*32> sum2_packed,
|
||||
const ap_uint<MASK_SUM_BITWIDTH*32> valid_packed,
|
||||
strong_pixel_threshold_t strong_pixel_threshold,
|
||||
ap_int<16> photon_count_threshold);
|
||||
|
||||
#endif //JUNGFRAUJOCH_SPOT_FINDER_H
|
||||
|
||||
@@ -6,386 +6,6 @@
|
||||
#include "../fpga/hls/hls_jfjoch.h"
|
||||
#include "../fpga/hls/spot_finder.h"
|
||||
|
||||
TEST_CASE("Pack32_Unpack32","[FPGA][SpotFinder]") {
|
||||
ap_int<16> value[32];
|
||||
for (int i = 0; i < 32; i++)
|
||||
value[i] = i;
|
||||
|
||||
ap_int<512> packed = pack32(value);
|
||||
ap_int<16> restore[32];
|
||||
unpack32(packed, restore);
|
||||
for (int i = 0; i < 32; i++) {
|
||||
REQUIRE(value[i] == restore[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Pack32_Unpack32_36","[FPGA][SpotFinder]") {
|
||||
ap_int<36> value[32];
|
||||
for (int i = 0; i < 32; i++)
|
||||
value[i] = i;
|
||||
|
||||
ap_int<36*32> packed = pack32(value);
|
||||
ap_int<36> restore[32];
|
||||
unpack32(packed, restore);
|
||||
for (int i = 0; i < 32; i++) {
|
||||
REQUIRE(value[i] == restore[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("FPGA_calc_sum","[FPGA][SpotFinder]") {
|
||||
ap_int<16> old_value[32];
|
||||
ap_int<16> new_value[32];
|
||||
|
||||
ap_int<SUM_BITWIDTH> new_sum[32];
|
||||
ap_int<SUM2_BITWIDTH> new_sum2[32];
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
old_value[i] = i;
|
||||
new_value[i] = 2;
|
||||
}
|
||||
|
||||
ap_uint<SUM_BITWIDTH*32> diff_sum;
|
||||
ap_uint<SUM2_BITWIDTH*32> diff_sum2;
|
||||
|
||||
calc_sum(diff_sum, pack32(old_value), pack32(new_value));
|
||||
calc_sum2(diff_sum2, pack32(old_value), pack32(new_value));
|
||||
unpack32(diff_sum, new_sum);
|
||||
unpack32(diff_sum2, new_sum2);
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
REQUIRE(new_sum[i] == 2-i);
|
||||
REQUIRE(new_sum2[i] == 4-i*i);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("FPGA_calc_valid","[FPGA][SpotFinder]") {
|
||||
ap_uint<32> old_mask = UINT32_MAX;
|
||||
ap_uint<32> new_mask = UINT32_MAX;
|
||||
|
||||
old_mask[15] = 0;
|
||||
new_mask[13] = 0;
|
||||
|
||||
ap_uint<MASK_SUM_BITWIDTH*32> diff_mask;
|
||||
calc_mask_diff(diff_mask, old_mask, new_mask);
|
||||
|
||||
ap_int<MASK_SUM_BITWIDTH> diff_mask_32[32];
|
||||
unpack32(diff_mask, diff_mask_32);
|
||||
|
||||
REQUIRE(diff_mask_32[0] == 0);
|
||||
REQUIRE(diff_mask_32[1] == 0);
|
||||
|
||||
REQUIRE(diff_mask_32[13] == -1);
|
||||
REQUIRE(diff_mask_32[15] == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("FPGA_calc_mask","[FPGA][SpotFinder]") {
|
||||
ap_int<16> value_in[32], value_out[32];
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
value_in[i] = 154 + i;
|
||||
|
||||
value_in[15] = INT16_MAX;
|
||||
value_in[0] = INT16_MIN;
|
||||
value_in[1] = INT16_MIN + 1;
|
||||
value_in[2] = INT16_MAX - 1;
|
||||
|
||||
ap_uint<512> input = pack32(value_in);
|
||||
ap_uint<512> output = 0;
|
||||
ap_uint<32> mask = 0;
|
||||
|
||||
calc_mask(input, output, mask);
|
||||
|
||||
REQUIRE(mask[0] == 0);
|
||||
REQUIRE(mask[15] == 0);
|
||||
REQUIRE(mask[1] == 1);
|
||||
REQUIRE(mask[2] == 1);
|
||||
REQUIRE(mask[3] == 1);
|
||||
REQUIRE(mask[4] == 1);
|
||||
|
||||
unpack32(output, value_out);
|
||||
|
||||
REQUIRE(value_out[0] == 0);
|
||||
REQUIRE(value_out[15] == 0);
|
||||
REQUIRE(value_out[1] == value_in[1]);
|
||||
REQUIRE(value_out[2] == value_in[2]);
|
||||
REQUIRE(value_out[3] == value_in[3]);
|
||||
REQUIRE(value_out[4] == value_in[4]);
|
||||
}
|
||||
|
||||
TEST_CASE("FPGA_update_sum" , "[FPGA][SpotFinder]") {
|
||||
ap_int<SUM2_BITWIDTH> arr_val1[32], arr_val2[32], arr_out[32];
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
arr_val1[i] = 5 * i;
|
||||
arr_val2[i] = 3 * i + 2;
|
||||
}
|
||||
ap_uint<SUM2_BITWIDTH*32> val1 = pack32(arr_val1);
|
||||
ap_uint<SUM2_BITWIDTH*32> val2 = pack32(arr_val2);
|
||||
update_sum<SUM2_BITWIDTH>(val1, val2);
|
||||
unpack32(val1, arr_out);
|
||||
for (int i = 0; i < 32; i++)
|
||||
REQUIRE(arr_out[i] == 8 * i + 2);
|
||||
}
|
||||
|
||||
int sum_consecutive(int x0, int n) {
|
||||
int ret = 0;
|
||||
for (int i = 0; i < n; i++)
|
||||
ret += x0 + i;
|
||||
return ret;
|
||||
}
|
||||
|
||||
TEST_CASE("FPGA_prefix_sum" , "[FPGA][SpotFinder]") {
|
||||
ap_uint<16*(32+2*FPGA_NBX)> input = 0;
|
||||
for (int i = 0; i < 32+2*FPGA_NBX; i++)
|
||||
input(i*16+15, i*16) = i;
|
||||
|
||||
auto output = prefix_sum<16>(input);
|
||||
ap_uint<16> output_unpacked[32];
|
||||
unpack32(output, output_unpacked);
|
||||
REQUIRE(output_unpacked[0] == sum_consecutive(0, 2 * FPGA_NBX + 1));
|
||||
REQUIRE(output_unpacked[2] == sum_consecutive(2, 2 * FPGA_NBX + 1));
|
||||
REQUIRE(output_unpacked[7] == sum_consecutive(7, 2 * FPGA_NBX + 1));
|
||||
}
|
||||
|
||||
bool Isigma_cpu(double val, double sum, double sum2, float threshold) {
|
||||
double mean = sum / ((2*FPGA_NBX+1) * (2*FPGA_NBX+1));
|
||||
double mean2 = sum2 / ((2*FPGA_NBX+1) * (2*FPGA_NBX+1));
|
||||
double variance = mean2 - mean * mean;
|
||||
double sigma = sqrt(variance);
|
||||
double i_over_sigma = (val - mean) / sigma;
|
||||
return (i_over_sigma > threshold);
|
||||
}
|
||||
|
||||
bool Isigma_fpga(ap_int<16> val, ap_int<SUM_BITWIDTH> sum, ap_uint<SUM2_BITWIDTH> sum2, float threshold) {
|
||||
return check_threshold(val, sum, sum2, (FPGA_NBX *2 + 1) * (FPGA_NBX *2 + 1),
|
||||
threshold * threshold, -1);
|
||||
}
|
||||
|
||||
TEST_CASE("FPGA_spot_check_threshold","[FPGA][SpotFinder]") {
|
||||
std::vector<float> threshold_values = {1.0, 3.0, 6.0};
|
||||
|
||||
for (auto threshold: threshold_values) {
|
||||
uint32_t uniform_val = 10;
|
||||
uint32_t diff = 0;
|
||||
for (int16_t val = -100; val < INT16_MAX; val++) {
|
||||
uint32_t sum = val + ((2 * FPGA_NBX + 1) * (2 * FPGA_NBX + 1) - 1) * uniform_val;
|
||||
uint32_t sum2 = val * val + ((2 * FPGA_NBX + 1) * (2 * FPGA_NBX + 1) - 1) * uniform_val * uniform_val;
|
||||
bool cpu = Isigma_cpu(val, sum, sum2, threshold);
|
||||
bool fpga = Isigma_fpga(val, sum, sum2, threshold);
|
||||
if (cpu != fpga) {
|
||||
std::cout << "WRONG!!! " << threshold << " " << val << " " << sum << " " << sum2 << " CPU: " << cpu << " FPGA: " << fpga << std::endl;
|
||||
diff++;
|
||||
}
|
||||
}
|
||||
REQUIRE(diff == 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("FPGA_spot_finder_update_sum","[FPGA][SpotFinder]") {
|
||||
STREAM_512 input;
|
||||
hls::stream<spot_finder_packet> output;
|
||||
|
||||
hls::stream<ap_uint<(SUM_BITWIDTH*32)>> sum_out;
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>> sum2_out;
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>> valid_out;
|
||||
|
||||
std::vector<int16_t> input_frame(RAW_MODULE_SIZE), output_frame(RAW_MODULE_SIZE);
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
||||
if (i % RAW_MODULE_COLS == 1023)
|
||||
input_frame[i] = INT16_MIN;
|
||||
else
|
||||
input_frame[i] = i % RAW_MODULE_COLS;
|
||||
}
|
||||
auto input_frame_512 = (ap_uint<512> *) input_frame.data();
|
||||
auto output_frame_512 = (ap_uint<512> *) output_frame.data();
|
||||
|
||||
input << packet_512_t{.user = 0};
|
||||
for (int i = 0; i < RAW_MODULE_SIZE * sizeof(uint16_t) / 64; i++)
|
||||
input << packet_512_t{.data = input_frame_512[i], .user = 0};
|
||||
|
||||
input << packet_512_t{.user = 1};
|
||||
|
||||
spot_finder_col_sum(input, output, sum_out, sum2_out, valid_out);
|
||||
|
||||
REQUIRE(input.size() == 0);
|
||||
|
||||
REQUIRE(output.size() == RAW_MODULE_SIZE * sizeof(uint16_t) / 64 + 2);
|
||||
REQUIRE(sum_out.size() == RAW_MODULE_SIZE * sizeof(uint16_t) / 64);
|
||||
REQUIRE(sum2_out.size() == RAW_MODULE_SIZE * sizeof(uint16_t) / 64);
|
||||
REQUIRE(valid_out.size() == RAW_MODULE_SIZE * sizeof(uint16_t) / 64);
|
||||
|
||||
std::vector<int64_t> sum(RAW_MODULE_SIZE);
|
||||
std::vector<int64_t> sum2(RAW_MODULE_SIZE);
|
||||
std::vector<int64_t> valid(RAW_MODULE_SIZE);
|
||||
|
||||
for (int i = 0; i < RAW_MODULE_SIZE * sizeof(uint16_t) / 64; i++) {
|
||||
ap_uint<32 * SUM_BITWIDTH> tmp_sum;
|
||||
ap_uint<32 * SUM2_BITWIDTH> tmp_sum2;
|
||||
ap_uint<32 * MASK_SUM_BITWIDTH> tmp_valid;
|
||||
sum_out >> tmp_sum;
|
||||
sum2_out >> tmp_sum2;
|
||||
valid_out >> tmp_valid;
|
||||
|
||||
ap_uint<SUM_BITWIDTH> tmp_sum_unpacked[32];
|
||||
ap_uint<SUM2_BITWIDTH> tmp_sum2_unpacked[32];
|
||||
ap_uint<MASK_SUM_BITWIDTH> tmp_valid_unpacked[32];
|
||||
unpack32(tmp_sum, tmp_sum_unpacked);
|
||||
unpack32(tmp_sum2, tmp_sum2_unpacked);
|
||||
unpack32(tmp_valid, tmp_valid_unpacked);
|
||||
|
||||
for (int j = 0; j < 32; j++) {
|
||||
sum[i * 32 + j] = tmp_sum_unpacked[j];
|
||||
sum2[i * 32 + j] = tmp_sum2_unpacked[j];
|
||||
valid[i * 32 + j] = tmp_valid_unpacked[j];
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(sum[1] == (FPGA_NBX+1) * 1);
|
||||
CHECK(sum[3] == (FPGA_NBX+1) * 3);
|
||||
CHECK(sum[1023] == 0);
|
||||
CHECK(sum[1022+200*1024] == (2 * FPGA_NBX+1) * 1022);
|
||||
|
||||
CHECK(sum2[3] == (FPGA_NBX+1) * 3 * 3);
|
||||
CHECK(sum2[1023] == 0);
|
||||
CHECK(sum2[1022+200*1024] == (2 * FPGA_NBX+1) * 1022 * 1022);
|
||||
|
||||
CHECK(valid[1] == FPGA_NBX + 1);
|
||||
CHECK(valid[3] == FPGA_NBX + 1);
|
||||
CHECK(valid[1023] == 0);
|
||||
CHECK(valid[1023 + 323*1024] == 0);
|
||||
|
||||
CHECK(valid[1+1024] == FPGA_NBX + 1 + 1);
|
||||
CHECK(valid[1+1024] == FPGA_NBX + 1 + 1);
|
||||
CHECK(valid[1+3*1024] == FPGA_NBX + 1 + 3);
|
||||
CHECK(valid[1+200*1024] == 2 * FPGA_NBX + 1);
|
||||
|
||||
CHECK(valid[1+509*1024] == FPGA_NBX + 1 + 2);
|
||||
CHECK(valid[1+510*1024] == FPGA_NBX + 1 + 1);
|
||||
CHECK(valid[1+511*1024] == FPGA_NBX + 1);
|
||||
|
||||
spot_finder_packet packet_out;
|
||||
output >> packet_out;
|
||||
for (int i = 0; i < RAW_MODULE_SIZE * sizeof(uint16_t) / 64; i++) {
|
||||
output >> packet_out;
|
||||
output_frame_512[i] = packet_out.data;
|
||||
}
|
||||
REQUIRE(output_frame == input_frame);
|
||||
}
|
||||
|
||||
TEST_CASE("FPGA_spot_finder_line_sum","[FPGA][SpotFinder]") {
|
||||
hls::stream<spot_finder_packet> input;
|
||||
hls::stream<spot_finder_packet> stream_0;
|
||||
hls::stream<spot_finder_packet> output;
|
||||
|
||||
hls::stream<ap_uint<SUM_BITWIDTH*32>> sum_in;
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>> sum2_in;
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>> valid_in;
|
||||
|
||||
hls::stream<ap_uint<SUM_BITWIDTH*32>> sum_stream;
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>> sum2_stream;
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>> valid_stream;
|
||||
|
||||
hls::stream<ap_uint<SUM_BITWIDTH*32>> sum_out;
|
||||
hls::stream<ap_uint<SUM2_BITWIDTH*32>> sum2_out;
|
||||
hls::stream<ap_uint<MASK_SUM_BITWIDTH*32>> valid_out;
|
||||
|
||||
ap_int<SUM_BITWIDTH> sum_unpacked[32];
|
||||
ap_int<SUM2_BITWIDTH> sum2_unpacked[32];
|
||||
ap_int<MASK_SUM_BITWIDTH> valid_unpacked[32];
|
||||
|
||||
std::vector<int16_t> input_frame(RAW_MODULE_COLS), output_frame(RAW_MODULE_COLS);
|
||||
for (int i = 0; i < RAW_MODULE_COLS; i++) {
|
||||
if (i % RAW_MODULE_COLS == 1023)
|
||||
input_frame[i] = INT16_MIN;
|
||||
else
|
||||
input_frame[i] = i % RAW_MODULE_COLS;
|
||||
}
|
||||
auto input_frame_512 = (ap_uint<512> *) input_frame.data();
|
||||
auto output_frame_512 = (ap_uint<512> *) output_frame.data();
|
||||
|
||||
input << spot_finder_packet{.user = 0};
|
||||
for (int i = 0; i < 32; i++)
|
||||
input << spot_finder_packet{.data = input_frame_512[i], .user = 0};
|
||||
|
||||
input << spot_finder_packet{.user = 1};
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
for (int j = 0; j < 32; j++) {
|
||||
sum_unpacked[j] = i * 32 + j;
|
||||
sum2_unpacked[j] = 8934 + (i * 32 + j);
|
||||
valid_unpacked[j] = 1;
|
||||
}
|
||||
sum_in << pack32(sum_unpacked);
|
||||
sum2_in << pack32(sum2_unpacked);
|
||||
valid_in << pack32(valid_unpacked);
|
||||
}
|
||||
|
||||
spot_finder_line_sum(input, stream_0, sum_in, sum2_in, valid_in, sum_stream, sum2_stream, valid_stream);
|
||||
REQUIRE(input.size() == 0);
|
||||
|
||||
REQUIRE(stream_0.size() == 32 + 2);
|
||||
REQUIRE(sum_stream.size() == 33);
|
||||
REQUIRE(sum2_stream.size() == 33);
|
||||
REQUIRE(valid_stream.size() == 33);
|
||||
|
||||
spot_finder_line_sum_align(stream_0, output, sum_stream, sum2_stream, valid_stream, sum_out, sum2_out, valid_out);
|
||||
|
||||
REQUIRE(stream_0.size() == 0);
|
||||
|
||||
REQUIRE(output.size() == 32 + 2);
|
||||
REQUIRE(sum_out.size() == 32);
|
||||
REQUIRE(sum2_out.size() == 32);
|
||||
REQUIRE(valid_out.size() == 32);
|
||||
|
||||
std::vector<int64_t> sum_output(RAW_MODULE_COLS);
|
||||
std::vector<int64_t> sum2_output(RAW_MODULE_COLS);
|
||||
std::vector<int64_t> valid_output(RAW_MODULE_COLS);
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
ap_uint<32 * SUM_BITWIDTH> sum_tmp;
|
||||
sum_out >> sum_tmp;
|
||||
unpack32(sum_tmp, sum_unpacked);
|
||||
for (int j = 0; j < 32; j++)
|
||||
sum_output[i * 32 + j] = sum_unpacked[j];
|
||||
|
||||
ap_uint<32 * SUM2_BITWIDTH> sum2_tmp;
|
||||
sum2_out >> sum2_tmp;
|
||||
unpack32(sum2_tmp, sum2_unpacked);
|
||||
for (int j = 0; j < 32; j++)
|
||||
sum2_output[i * 32 + j] = sum2_unpacked[j];
|
||||
|
||||
ap_uint<32 * MASK_SUM_BITWIDTH> valid_tmp;
|
||||
valid_out >> valid_tmp;
|
||||
unpack32(valid_tmp, valid_unpacked);
|
||||
for (int j = 0; j < 32; j++)
|
||||
valid_output[i * 32 + j] = valid_unpacked[j];
|
||||
}
|
||||
|
||||
CHECK(sum_output[0] == sum_consecutive(0, FPGA_NBX+1));
|
||||
CHECK(sum_output[1] == sum_consecutive(0, FPGA_NBX+2));
|
||||
CHECK(sum_output[2] == sum_consecutive(0, FPGA_NBX+3));
|
||||
CHECK(sum_output[FPGA_NBX] == sum_consecutive(0, FPGA_NBX*2+1));
|
||||
CHECK(sum_output[FPGA_NBX+1] == sum_consecutive(1, FPGA_NBX*2+1));
|
||||
CHECK(sum_output[FPGA_NBX+5] == sum_consecutive(5, FPGA_NBX*2+1));
|
||||
CHECK(sum_output[1023] == sum_consecutive(1023-FPGA_NBX, FPGA_NBX+1));
|
||||
|
||||
CHECK(sum2_output[0] == sum_consecutive(8934, FPGA_NBX+1));
|
||||
|
||||
CHECK(valid_output[0] == FPGA_NBX+1);
|
||||
CHECK(valid_output[1] == FPGA_NBX+2);
|
||||
|
||||
CHECK(valid_output[1022] == FPGA_NBX+2);
|
||||
CHECK(valid_output[1023] == FPGA_NBX+1);
|
||||
|
||||
spot_finder_packet packet_out;
|
||||
output >> packet_out;
|
||||
for (int i = 0; i < 32; i++) {
|
||||
output >> packet_out;
|
||||
output_frame_512[i] = packet_out.data;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("FPGA_spot_finder_core","[FPGA][SpotFinder]") {
|
||||
STREAM_512 input;
|
||||
STREAM_512 output;
|
||||
|
||||
Reference in New Issue
Block a user