diff --git a/fpga/hls/CMakeLists.txt b/fpga/hls/CMakeLists.txt index 052914e8..f8ed1445 100644 --- a/fpga/hls/CMakeLists.txt +++ b/fpga/hls/CMakeLists.txt @@ -61,8 +61,7 @@ MAKE_HLS_MODULE(save_to_hbm.cpp save_to_hbm) MAKE_HLS_MODULE(mask_missing.cpp mask_missing) MAKE_HLS_MODULE(integration.cpp integration) MAKE_HLS_MODULE(spot_finder.cpp spot_finder) -MAKE_HLS_MODULE(spot_finder.cpp spot_finder_update_sum) -MAKE_HLS_MODULE(spot_finder.cpp spot_finder_line_sum) +MAKE_HLS_MODULE(spot_finder.cpp spot_finder_2) MAKE_HLS_MODULE(axis_broadcast.cpp axis_broadcast) MAKE_HLS_MODULE(axis_256_to_512.cpp axis_256_to_512) MAKE_HLS_MODULE(axis_256_to_512.cpp axis_32_to_512) @@ -84,8 +83,7 @@ SET (HLS_IPS psi_ch_hls_data_collection_fsm_1_0.zip psi_ch_hls_save_to_hbm_1_0.zip psi_ch_hls_mask_missing_1_0.zip psi_ch_hls_frame_generator_1_0.zip - psi_ch_hls_spot_finder_update_sum_1_0.zip - psi_ch_hls_spot_finder_line_sum_1_0.zip + psi_ch_hls_spot_finder_2_1_0.zip psi_ch_hls_spot_finder_1_0.zip psi_ch_hls_integration_1_0.zip psi_ch_hls_axis_broadcast_1_0.zip diff --git a/fpga/hls/spot_finder.cpp b/fpga/hls/spot_finder.cpp index 40a0d923..4994ec27 100644 --- a/fpga/hls/spot_finder.cpp +++ b/fpga/hls/spot_finder.cpp @@ -38,8 +38,8 @@ void calc_sum2(ap_uint &ext_column_sum2, } void calc_mask_diff(ap_uint &ext_column_valid, - const ap_uint<32> ext_old_value, - const ap_uint<32> ext_new_value) { + const ap_uint<32> ext_old_value, + const ap_uint<32> ext_new_value) { #pragma HLS PIPELINE II=1 ap_int column_valid[32]; @@ -74,54 +74,51 @@ void calc_mask(const ap_uint<512> &input, ap_uint<512> &output, ap_uint<32> &mas ap_uint<1> check_threshold(ap_int<16> val, ap_int sum, ap_int sum2, + ap_int valid, strong_pixel_threshold_t strong_pixel_threshold, ap_int<16> photon_count_threshold) { #pragma HLS INLINE - ap_int in_minus_mean = val * ((2 * FPGA_NBX + 1) * (2 * FPGA_NBX + 1)) - sum; - ap_uint variance = ((2 * FPGA_NBX + 1) * (2 * FPGA_NBX + 1)) * sum2 - sum * sum; + ap_int in_minus_mean = val * valid - sum; + ap_uint variance = valid * sum2 - sum * sum; - if ((in_minus_mean * in_minus_mean * (((2 * FPGA_NBX + 1) * (2 * FPGA_NBX + 1)) - 1) > variance * strong_pixel_threshold * ((2 * FPGA_NBX + 1) * (2 * FPGA_NBX + 1))) && + if ((in_minus_mean * in_minus_mean * (valid - 1) > variance * strong_pixel_threshold * valid) && (in_minus_mean > 0) && - (val > 1)) + (val > photon_count_threshold)) return 1; else return 0; - } ap_uint<32> check_threshold(const ap_uint<512> data_packed, const ap_uint sum_packed, const ap_uint sum2_packed, + const ap_uint valid_packed, strong_pixel_threshold_t strong_pixel_threshold, ap_int<16> photon_count_threshold) { #pragma HLS PIPELINE ap_int<16> data[32]; ap_int sum[32]; ap_int sum2[32]; + ap_int 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], strong_pixel_threshold, photon_count_threshold); + 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_update_sum(STREAM_512 &data_in, - STREAM_512 &data_out, + hls::stream &data_out, hls::stream> &sum_out, hls::stream> &sum2_out, hls::stream> &valid_out) { -#pragma HLS INTERFACE axis port=data_in -#pragma HLS INTERFACE axis port=data_out -#pragma HLS INTERFACE axis port=sum_out -#pragma HLS INTERFACE axis port=sum2_out -#pragma HLS INTERFACE axis port=valid_out - ap_uint<512> data_cache[(2 * FPGA_NBX + 1) * 32]; ap_uint<32> mask_cache[(2 * FPGA_NBX + 1) * 32]; @@ -131,7 +128,7 @@ void spot_finder_update_sum(STREAM_512 &data_in, packet_512_t packet_in; data_in >> packet_in; - data_out << packet_in; + data_out << spot_finder_packet{.data=packet_in.data, .user=0}; data_in >> packet_in; while (!packet_in.user) { @@ -155,7 +152,7 @@ void spot_finder_update_sum(STREAM_512 &data_in, ap_uint<32> packet_in_mask; if (i < RAW_MODULE_SIZE * sizeof(uint16_t) / 64) { - data_out << packet_in; + data_out << spot_finder_packet{.data=packet_in.data, .user=0}; calc_mask(packet_in.data, packet_in_data, packet_in_mask); } else { packet_in_data = 0; @@ -200,26 +197,18 @@ void spot_finder_update_sum(STREAM_512 &data_in, data_in >> packet_in; } } - data_out << packet_in; + data_out << spot_finder_packet{.data=0, .user=1}; } -void spot_finder_line_sum(STREAM_512 &data_in, - STREAM_512 &data_out, +void spot_finder_line_sum(hls::stream &data_in, + hls::stream &data_out, hls::stream> &sum_in, hls::stream> &sum2_in, hls::stream> &valid_in, hls::stream> &sum_out, hls::stream> &sum2_out, hls::stream> &valid_out) { -#pragma HLS INTERFACE axis port=data_in -#pragma HLS INTERFACE axis port=data_out -#pragma HLS INTERFACE axis port=sum_in -#pragma HLS INTERFACE axis port=sum2_in -#pragma HLS INTERFACE axis port=valid_in -#pragma HLS INTERFACE axis port=sum_out -#pragma HLS INTERFACE axis port=sum2_out -#pragma HLS INTERFACE axis port=valid_out - packet_512_t packet_in; + spot_finder_packet packet_in; data_in >> packet_in; data_out << packet_in; @@ -237,8 +226,8 @@ void spot_finder_line_sum(STREAM_512 &data_in, ap_uint line_sum; ap_uint line_sum2; ap_uint line_valid; -#pragma HLS PIPELINE II=33 +#pragma HLS PIPELINE II=33 for (int i = 0; i < 32; i++) { data_out << packet_in; @@ -268,6 +257,115 @@ void spot_finder_line_sum(STREAM_512 &data_in, data_out << packet_in; } +void spot_finder_line_sum_align(hls::stream &data_in, + hls::stream &data_out, + hls::stream> &sum_in, + hls::stream> &sum2_in, + hls::stream> &valid_in, + hls::stream> &sum_out, + hls::stream> &sum2_out, + hls::stream> &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 line_sum_val_save = 0; + ap_uint line_sum2_val_save = 0; + ap_uint line_valid_val_save = 0; + + ap_uint line_sum = 0; + ap_uint line_sum2 = 0; + ap_uint 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; +} + +void spot_finder_apply_threshold(hls::stream &data_in, + hls::stream> &sum_in, + hls::stream> &sum2_in, + hls::stream> &valid_in, + hls::stream> &strong_pixel_out, + volatile ap_int<16> &in_photon_count_threshold, + volatile strong_pixel_threshold_t &in_strong_pixel_threshold) { + spot_finder_packet packet_in; + data_in >> packet_in; + + ap_uint line_sum = 0; + ap_uint line_sum2 = 0; + ap_uint line_valid = 0; + + data_in >> packet_in; + while (!packet_in.user) { + data_in >> packet_in; + 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, + in_strong_pixel_threshold, in_photon_count_threshold); + strong_pixel_out << strong_pixel; + } + strong_pixel_out << ap_axiu<32,1,1,1>{.data = 0, .user = 1}; +} + +void spot_finder_2(STREAM_512 &data_in, + hls::stream> &strong_pixel_out, + volatile ap_int<16> &in_photon_count_threshold, + volatile strong_pixel_threshold_t &in_strong_pixel_threshold) { +#pragma HLS INTERFACE ap_ctrl_none port=return +#pragma HLS DATAFLOW + +#pragma HLS INTERFACE axis port=data_in +#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 + + hls::stream data_stream_0, data_stream_1, data_stream_2, data_stream_3; + hls::stream> sum_stream_0, sum_stream_1, sum_stream_2, sum_stream_3; + hls::stream> sum2_stream_0, sum2_stream_1, sum2_stream_2, sum2_stream_3; + hls::stream> valid_stream_0, valid_stream_1, valid_stream_2, valid_stream_3; + + spot_finder_update_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_apply_threshold(data_stream_2, sum_stream_2, sum2_stream_2, valid_stream_2, + strong_pixel_out, in_photon_count_threshold, in_strong_pixel_threshold); +} void spot_finder(STREAM_512 &data_in, STREAM_512 &data_out, @@ -367,6 +465,7 @@ void spot_finder(STREAM_512 &data_in, strong_pxl.data = check_threshold(mid_line_shifted, box_sum, box_sum2, + (2 * FPGA_NBX + 1) * (2 * FPGA_NBX + 1), strong_pixel_threshold, photon_count_threshold); diff --git a/fpga/hls/spot_finder.h b/fpga/hls/spot_finder.h index c05025f6..3b31d1d3 100644 --- a/fpga/hls/spot_finder.h +++ b/fpga/hls/spot_finder.h @@ -13,6 +13,11 @@ #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 void update_sum(ap_uint &ext_val1, const ap_uint ext_val2) { #pragma HLS PIPELINE II=1 @@ -37,10 +42,16 @@ ap_uint prefix_sum(const ap_uint ext_column_sum) { for (int i = 0; i < 32 + 2 * FPGA_NBX; i++) column_sum[i] = ext_column_sum(i * N + (N - 1), i * N); + ap_int tmp_sum = 0; + + for (int i = 0 ; i < 2 * FPGA_NBX; i++) { + tmp_sum += column_sum[i]; + } + for (int i = 0; i < 32; i++) { - line_sum[i] = column_sum[i]; - for (int j = 1; j < 2 * FPGA_NBX + 1; j++) - line_sum[i] += column_sum[i + j]; + tmp_sum += column_sum[i + 2 * FPGA_NBX]; + line_sum[i] = tmp_sum; + tmp_sum -= column_sum[i]; } return pack32(line_sum); @@ -77,8 +88,8 @@ ap_uint prefix_sum(const ap_uint ext_column_sum, } void calc_mask_diff(ap_uint &ext_column_valid, - const ap_uint<32> ext_old_value, - const ap_uint<32> ext_new_value); + const ap_uint<32> ext_old_value, + const ap_uint<32> ext_new_value); void calc_sum2(ap_uint &ext_column_sum2, const ap_uint<512> ext_old_value, @@ -91,13 +102,13 @@ void calc_sum(ap_uint &ext_column_sum, void calc_mask(const ap_uint<512> &input, ap_uint<512> &output, ap_uint<32> &mask); void spot_finder_update_sum(STREAM_512 &data_in, - STREAM_512 &data_out, + hls::stream &data_out, hls::stream> &sum_out, hls::stream> &sum2_out, hls::stream> &valid_out); -void spot_finder_line_sum(STREAM_512 &data_in, - STREAM_512 &data_out, +void spot_finder_line_sum(hls::stream &data_in, + hls::stream &data_out, hls::stream> &sum_in, hls::stream> &sum2_in, hls::stream> &valid_in, @@ -105,11 +116,29 @@ void spot_finder_line_sum(STREAM_512 &data_in, hls::stream> &sum2_out, hls::stream> &valid_out); -ap_uint<1> check_threshold(ap_int<16> val, - ap_int sum, - ap_int sum2, - strong_pixel_threshold_t strong_pixel_threshold, - ap_int<16> photon_count_threshold); +void spot_finder_line_sum_align(hls::stream &data_in, + hls::stream &data_out, + hls::stream> &sum_in, + hls::stream> &sum2_in, + hls::stream> &valid_in, + hls::stream> &sum_out, + hls::stream> &sum2_out, + hls::stream> &valid_out); + +void spot_finder_apply_threshold(hls::stream &data_in, + hls::stream> &sum_in, + hls::stream> &sum2_in, + hls::stream> &valid_in, + hls::stream> &strong_pixel_out, + volatile ap_int<16> &in_photon_count_threshold, + volatile strong_pixel_threshold_t &in_strong_pixel_threshold); + +ap_uint<32> check_threshold(const ap_uint<512> data_packed, + const ap_uint sum_packed, + const ap_uint sum2_packed, + const ap_uint valid_packed, + strong_pixel_threshold_t strong_pixel_threshold, + ap_int<16> photon_count_threshold); inline strong_pixel_threshold_t fpga_strong_pixel_threshold(float strong_threshold) { float x = strong_threshold * strong_threshold; diff --git a/tests/FPGASpotFindingUnitTest.cpp b/tests/FPGASpotFindingUnitTest.cpp index 488f051e..c8476cb0 100644 --- a/tests/FPGASpotFindingUnitTest.cpp +++ b/tests/FPGASpotFindingUnitTest.cpp @@ -158,7 +158,8 @@ bool Isigma_cpu(double val, double sum, double sum2, float threshold) { } bool Isigma_fpga(ap_int<16> val, ap_int sum, ap_uint sum2, float threshold) { - return check_threshold(val, sum, sum2, fpga_strong_pixel_threshold(threshold), -1); + return check_threshold(val, sum, sum2, (FPGA_NBX *2 + 1) * (FPGA_NBX *2 + 1), + fpga_strong_pixel_threshold(threshold), -1); } TEST_CASE("FPGA_spot_check_threshold","[FPGA][SpotFinder]") { @@ -183,7 +184,7 @@ TEST_CASE("FPGA_spot_check_threshold","[FPGA][SpotFinder]") { TEST_CASE("FPGA_spot_finder_update_sum","[FPGA][SpotFinder]") { STREAM_512 input; - STREAM_512 output; + hls::stream output; hls::stream> sum_out; hls::stream> sum2_out; @@ -264,13 +265,18 @@ TEST_CASE("FPGA_spot_finder_update_sum","[FPGA][SpotFinder]") { } TEST_CASE("FPGA_spot_finder_line_sum","[FPGA][SpotFinder]") { - STREAM_512 input; - STREAM_512 output; + hls::stream input; + hls::stream stream_0; + hls::stream output; hls::stream> sum_in; hls::stream> sum2_in; hls::stream> valid_in; + hls::stream> sum_stream; + hls::stream> sum2_stream; + hls::stream> valid_stream; + hls::stream> sum_out; hls::stream> sum2_out; hls::stream> valid_out; @@ -279,33 +285,77 @@ TEST_CASE("FPGA_spot_finder_line_sum","[FPGA][SpotFinder]") { ap_int sum2_unpacked[32]; ap_int valid_unpacked[32]; - input << packet_512_t{.user = 0}; + input << spot_finder_packet{.user = 0}; for (int i = 0; i < 32; i++) - input << packet_512_t{.data = 0, .user = 0}; + input << spot_finder_packet{.data = 0, .user = 0}; - input << packet_512_t{.user = 1}; + 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] = i; + valid_unpacked[j] = 1; } sum_in << pack32(sum_unpacked); sum2_in << pack32(sum2_unpacked); valid_in << pack32(valid_unpacked); } - spot_finder_line_sum(input, output, sum_in, sum2_in, valid_in, sum_out, sum2_out, valid_out); - + 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() == 33); - REQUIRE(sum2_out.size() == 33); - REQUIRE(valid_out.size() == 33); + REQUIRE(sum_out.size() == 32); + REQUIRE(sum2_out.size() == 32); + REQUIRE(valid_out.size() == 32); + + std::vector sum_output(RAW_MODULE_COLS); + std::vector sum2_output(RAW_MODULE_COLS); + std::vector 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]; } -} \ No newline at end of file + + 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); +}