From c6afbebd13dc3c0067a02d9d13ca6aa4043c96da Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Mon, 2 Oct 2023 22:18:07 +0200 Subject: [PATCH] FPGA: add old spot finder to the design (work in progress! - seems very high resource utilization + it is offset from proper result) --- fpga/hdl/action_config.v | 25 ++++ fpga/hls/CMakeLists.txt | 2 + fpga/hls/axis_256_to_512.cpp | 20 +++ fpga/hls/hls_jfjoch.h | 14 +- fpga/hls/spot_finder.cpp | 214 ++++++++++++++++++++++++++---- fpga/hls/spot_finder.h | 80 +++++++++++ fpga/scripts/jfjoch.tcl | 49 ++++--- receiver/HLSSimulatedDevice.cpp | 20 ++- tests/CMakeLists.txt | 3 +- tests/FPGASpotFindingUnitTest.cpp | 109 +++++++++++++++ 10 files changed, 475 insertions(+), 61 deletions(-) create mode 100644 fpga/hls/spot_finder.h create mode 100644 tests/FPGASpotFindingUnitTest.cpp diff --git a/fpga/hdl/action_config.v b/fpga/hdl/action_config.v index 5bc33afb..1acc6999 100644 --- a/fpga/hdl/action_config.v +++ b/fpga/hdl/action_config.v @@ -50,6 +50,9 @@ `define ADDR_NFRAMES 16'h0098 `define ADDR_NSTORAGE_CELLS 16'h009C +`define ADDR_SPOT_FINDER_THRESHOLD 16'h00A0 +`define ADDR_SPOT_FINDER_SNR 16'h00A4 + module action_config #(parameter C_S_AXI_ADDR_WIDTH = 16, @@ -90,6 +93,8 @@ module action_config output reg [7:0] nmodules , output reg [3:0] nstorage_cells , output wire [31:0] hbm_size_bytes , + output reg[15:0] spot_finder_threshold , + output reg[15:0] spot_finder_snr , output reg data_collection_start , output reg data_collection_cancel , @@ -378,6 +383,12 @@ always @(posedge clk) begin `ADDR_FIFO_STATUS: begin rdata <= reg_fifo_status; end + `ADDR_SPOT_FINDER_THRESHOLD: begin + rdata <= spot_finder_threshold; + end + `ADDR_SPOT_FINDER_SNR: begin + rdata <= spot_finder_snr; + end default: rdata <= 32'hffffffff; endcase @@ -513,6 +524,20 @@ always @(posedge clk) begin end end +always @(posedge clk) begin + if (!resetn) + spot_finder_snr <= 0; + else if (w_hs && waddr == `ADDR_SPOT_FINDER_SNR) + spot_finder_snr <= (s_axi_WDATA[15:0] & wmask[15:0]) | (spot_finder_snr & !wmask[3:0]); +end + +always @(posedge clk) begin + if (!resetn) + spot_finder_threshold <= 0; + else if (w_hs && waddr == `ADDR_SPOT_FINDER_THRESHOLD) + spot_finder_threshold <= (s_axi_WDATA[15:0] & wmask[15:0]) | (spot_finder_threshold & !wmask[3:0]); +end + always @ (posedge clk) begin if (!resetn) begin diff --git a/fpga/hls/CMakeLists.txt b/fpga/hls/CMakeLists.txt index 4a3bdc1a..2bbf389b 100644 --- a/fpga/hls/CMakeLists.txt +++ b/fpga/hls/CMakeLists.txt @@ -63,6 +63,7 @@ MAKE_HLS_MODULE(integration.cpp integration) MAKE_HLS_MODULE(spot_finder.cpp spot_finder) 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) MAKE_HLS_MODULE(adu_histo.cpp adu_histo) SET (HLS_IPS psi_ch_hls_data_collection_fsm_1_0.zip @@ -85,6 +86,7 @@ SET (HLS_IPS psi_ch_hls_data_collection_fsm_1_0.zip psi_ch_hls_integration_1_0.zip psi_ch_hls_axis_broadcast_1_0.zip psi_ch_hls_axis_256_to_512_1_0.zip + psi_ch_hls_axis_32_to_512_1_0.zip psi_ch_hls_adu_histo_1_0.zip psi_ch_hls_stream_merge_1_0.zip) diff --git a/fpga/hls/axis_256_to_512.cpp b/fpga/hls/axis_256_to_512.cpp index 2418a0aa..dc05a4a5 100644 --- a/fpga/hls/axis_256_to_512.cpp +++ b/fpga/hls/axis_256_to_512.cpp @@ -20,3 +20,23 @@ void axis_256_to_512(hls::stream> &data_in, } } +void axis_32_to_512(hls::stream> &data_in, + hls::stream> &data_out) { +#pragma HLS INTERFACE ap_ctrl_none port=return +#pragma HLS INTERFACE axis register both port=data_in +#pragma HLS INTERFACE axis register both port=data_out + ap_axiu<32,1,1,1> packet_32; + data_in >> packet_32; + + while (!packet_32.user) { +#pragma HLS PIPELINE II=16 + ap_uint<512> val = 0; + val(31,0) = packet_32.data; + for (int i = 1; i < 16; i++) { + data_in >> packet_32; + val(i * 32 + 31, i * 32) = packet_32.data; + } + data_out << val; + data_in >> packet_32; + } +} diff --git a/fpga/hls/hls_jfjoch.h b/fpga/hls/hls_jfjoch.h index 2da9377e..5332e2a8 100644 --- a/fpga/hls/hls_jfjoch.h +++ b/fpga/hls/hls_jfjoch.h @@ -27,6 +27,7 @@ typedef ap_ufixed<16,4, AP_RND_CONV> gainG1_t; typedef ap_ufixed<16,6, AP_RND_CONV> gainG2_t; typedef ap_ufixed<32,12,AP_RND_CONV> one_over_energy_t; +typedef ap_ufixed<16,12, AP_RND_CONV> strong_pixel_threshold_t; typedef ap_uint<256> hbm256_t; @@ -53,7 +54,6 @@ typedef hls::stream STREAM_512; #define ACT_REG_NFRAMES(x) ((x)(95 , 64)) // 32 bit #define ACT_REG_NMODULES(x) ((x)(132, 128)) // 5 bit (0..31) #define ACT_REG_NSTORAGE_CELLS(x) ((x)(148, 144)) // 5 bit -#define ACT_REG_SPOT_FINDER_THRESHOLD(x) ((x)(175, 160)) // 16 bit struct axis_datamover_ctrl { ap_uint<40+64> data; @@ -193,12 +193,14 @@ void integration(STREAM_512 &data_in, void axis_256_to_512(hls::stream> &data_in, hls::stream> &data_out); -void spot_finder(STREAM_512 &data_in, - hls::stream> &result_out); +void axis_32_to_512(hls::stream> &data_in, + hls::stream> &data_out); -void axis_broadcast(STREAM_512 &data_in, - STREAM_512 &data_out_0, - STREAM_512 &data_out_1); +void spot_finder(STREAM_512 &data_in, + STREAM_512 &data_out, + hls::stream> &strong_pixel_out, + volatile ap_int<16> &in_photon_count_threshold, + volatile strong_pixel_threshold_t &in_strong_pixel_threshold); void adu_histo(STREAM_512 &data_in, STREAM_512 &data_out, diff --git a/fpga/hls/spot_finder.cpp b/fpga/hls/spot_finder.cpp index 9e8b79fb..531c4ef4 100644 --- a/fpga/hls/spot_finder.cpp +++ b/fpga/hls/spot_finder.cpp @@ -1,40 +1,202 @@ // Copyright (2019-2023) Paul Scherrer Institute -#include "hls_jfjoch.h" +#include "spot_finder.h" + +void calc_sum(ap_uint &ext_column_sum, + const ap_uint<512> ext_old_value, + const ap_uint<512> ext_new_value) { +#pragma HLS PIPELINE II=1 + ap_int 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 &ext_column_sum2, + const ap_uint<512> ext_old_value, + const ap_uint<512> ext_new_value) { +#pragma HLS PIPELINE II=1 + ap_int 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); +} + +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) { +#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; + + 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))) && + (in_minus_mean > 0) && + (val > 1)) + 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, + 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]; + + unpack32(data_packed, data); + unpack32(sum_packed, sum); + unpack32(sum2_packed, sum2); + + 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); + + return tmp_output; +} void spot_finder(STREAM_512 &data_in, - hls::stream> &result_out) { + STREAM_512 &data_out, + 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 INTERFACE register both axis port=data_in -#pragma HLS INTERFACE register both axis port=result_out - packet_512_t packet; - data_in >> packet; - ap_int<16> threshold = ACT_REG_SPOT_FINDER_THRESHOLD(packet.data); +#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 - ap_uint<32> result[RAW_MODULE_SIZE * sizeof(uint16_t) / 64]; -#pragma HLS ARRAY_PARTITION variable=result type=cyclic factor=16 + ap_uint<512> array_mid_line[(FPGA_NBX) * 32]; + ap_uint<512> array_top_line[(FPGA_NBX + 1) * 32]; + ap_uint sum_array[32]; + ap_uint sum2_array[32]; +#pragma HLS RESOURCE variable=array_mid_line core=RAM_2P_BRAM latency=3 +#pragma HLS RESOURCE variable=array_top_line core=RAM_2P_BRAM latency=3 +#pragma HLS RESOURCE variable=sum_array core=RAM_2P_BRAM latency=3 +#pragma HLS RESOURCE variable=sum2_array core=RAM_2P_BRAM latency=3 - ap_int<16> val[32]; - data_in >> packet; - while (!packet.user) { - for (int i = 0; i < RAW_MODULE_SIZE * sizeof(uint16_t) / 64; i++) { -#pragma HLS PIPELINE II=1 - unpack32(packet.data, val); + ap_uint<16 * FPGA_NBX> mid_line_save = 0; - ap_uint<32> output; - for (int j = 0; j < 32; j++) - output[j] = ((val[j] > threshold) ? 1 : 0); + ap_uint column_sum_val_save = 0; + ap_uint column_sum2_val_save = 0; - data_in >> packet; - result[i] = output; + packet_512_t packet_in; + data_in >> packet_in; + data_out << packet_in; + + data_in >> packet_in; + + while (!packet_in.user) { + for (int i = 0; i < 32; i++) { +#pragma HLS pipeline II=1 + sum_array[i] = 0; + sum2_array[i] = 0; } - for (int i = 0; i < RAW_MODULE_SIZE * sizeof(uint16_t) / (64 * 16); i++) { -#pragma HLS PIPELINE II=1 - ap_uint<512> output = 0; - for (int j = 0; j < 16; j++) - output(j*32+31, j * 32) = result[i * 16 + j]; - result_out << output; + + for (int i = 0; i < (FPGA_NBX) * 32; i++) + array_mid_line[i] = 0; + + for (int i = 0; i < (FPGA_NBX + 1) * 32; i++) + array_top_line[i] = 0; + + strong_pixel_threshold_t strong_pixel_threshold = in_strong_pixel_threshold; + ap_int<16> photon_count_threshold = in_photon_count_threshold; + + for (int i = 0; i < RAW_MODULE_SIZE * sizeof(uint16_t) / 64; i++) { +#pragma HLS PIPELINE II = 1 + data_out << packet_in; + ap_axiu<32, 1, 1, 1> strong_pxl; + + if (strong_pixel_threshold > 0) { + uint16_t cell_number_mid = + (i / 32) % (FPGA_NBX) * 32 + (i % 32); // (axis_packet_line % (NBX)) * 32 + axis_packet_in_line; + uint16_t cell_number_top = (i / 32) % (FPGA_NBX + 1) * 32 + + (i % 32); // (axis_packet_line % (NBX + 1)) * 32 + axis_packet_in_line; + + uint16_t axis_packet_in_line = i % 32; + + ap_uint<512> mid_line_shifted; + ap_uint<512> mid_line = array_mid_line[cell_number_mid]; + mid_line_shifted(16 * FPGA_NBX - 1, 0) = mid_line_save; + mid_line_shifted(511, 16 * FPGA_NBX) = mid_line(16 * (32 - FPGA_NBX) - 1, 0); + mid_line_save = mid_line(511, 16 * (32 - FPGA_NBX)); + + ap_uint<512> top_line = array_top_line[cell_number_top]; + + ap_uint diff_sum; + ap_uint diff_sum2; + + ap_uint column_sum = sum_array[axis_packet_in_line]; + ap_uint column_sum2 = sum2_array[axis_packet_in_line]; + + calc_sum(diff_sum, top_line, packet_in.data); + calc_sum2(diff_sum2, top_line, packet_in.data); + + update_sum(column_sum, diff_sum); + update_sum(column_sum2, diff_sum2); + + ap_uint box_sum = prefix_sum(column_sum, column_sum_val_save); + ap_uint box_sum2 = prefix_sum(column_sum2, column_sum2_val_save); + + array_mid_line[cell_number_mid] = packet_in.data; + array_top_line[cell_number_top] = mid_line; + + sum_array[axis_packet_in_line] = column_sum; + sum2_array[axis_packet_in_line] = column_sum2; + + 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)); + + // Check threshold + strong_pxl.data = check_threshold(mid_line_shifted, + box_sum, + box_sum2, + strong_pixel_threshold, + photon_count_threshold); + + } else if (photon_count_threshold > 0) { + ap_int<16> val[32]; + unpack32(packet_in.data, val); + + ap_uint<32> output; + for (int j = 0; j < 32; j++) + output[j] = ((val[j] > photon_count_threshold) ? 1 : 0); + + strong_pxl.data = output; + } else { + strong_pxl.data = 0; + } + strong_pxl.user = 0; + strong_pixel_out << strong_pxl; + data_in >> packet_in; } } + + strong_pixel_out << ap_axiu<32,1,1,1>{.data = 0, .user = 1}; + + data_out << packet_in; } diff --git a/fpga/hls/spot_finder.h b/fpga/hls/spot_finder.h new file mode 100644 index 00000000..9a2a9537 --- /dev/null +++ b/fpga/hls/spot_finder.h @@ -0,0 +1,80 @@ +// Copyright (2019-2023) Paul Scherrer Institute + +#ifndef JUNGFRAUJOCH_SPOT_FINDER_H +#define JUNGFRAUJOCH_SPOT_FINDER_H + +#define AP_INT_MAX_W 2048 + +#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 (15*2+FPGA_NBX_CEIL_LOG2) + +template +void update_sum(ap_uint &ext_val1, const ap_uint ext_val2) { +#pragma HLS PIPELINE II=1 + + ap_int 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 +ap_uint prefix_sum(const ap_uint ext_column_sum, + const ap_uint ext_column_sum_old) { +#pragma HLS PIPELINE II=1 + ap_int column_sum[32 + 2 * FPGA_NBX]; + ap_uint retval; + ap_int line_sum[32]; + ap_int tmp_sum = 0; + + for (int i = 0; i < 2 * FPGA_NBX; i++) + column_sum[i] = ext_column_sum_old(i*N+(N-1), i*N); + + for (int i = 0; i < 32; i++) + column_sum[i+ 2 * FPGA_NBX] = ext_column_sum(i * N + (N - 1), i * N); + + 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]; + } + + return pack32(line_sum); +} + +void calc_sum2(ap_uint &ext_column_sum2, + const ap_uint<512> ext_old_value, + const ap_uint<512> ext_new_value); + +void calc_sum(ap_uint &ext_column_sum, + const ap_uint<512> ext_old_value, + const ap_uint<512> ext_new_value); + +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); + +inline strong_pixel_threshold_t fpga_strong_pixel_threshold(float strong_threshold) { + float x = strong_threshold * strong_threshold; + if ((x <= 0) || (x >= 4096)) + return 4096; + else + return x; +} + +#endif //JUNGFRAUJOCH_SPOT_FINDER_H diff --git a/fpga/scripts/jfjoch.tcl b/fpga/scripts/jfjoch.tcl index cd44fec8..ed2b97d8 100644 --- a/fpga/scripts/jfjoch.tcl +++ b/fpga/scripts/jfjoch.tcl @@ -154,6 +154,9 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } { # Create instance: axis_256_to_512_0, and set properties set axis_256_to_512_0 [ create_bd_cell -type ip -vlnv psi.ch:hls:axis_256_to_512:1.0 axis_256_to_512_0 ] + # Create instance: axis_32_to_512_0, and set properties + set axis_32_to_512_0 [ create_bd_cell -type ip -vlnv psi.ch:hls:axis_32_to_512:1.0 axis_32_to_512_0 ] + # Create instance: axis_addr_fifo_0, and set properties set axis_addr_fifo_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_addr_fifo_0 ] set_property -dict [ list \ @@ -169,9 +172,6 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } { CONFIG.FIFO_DEPTH {1024} \ ] $axis_adu_histo_result_fifo - # Create instance: axis_broadcast_0, and set properties - set axis_broadcast_0 [ create_bd_cell -type ip -vlnv psi.ch:hls:axis_broadcast:1.0 axis_broadcast_0 ] - # Create instance: axis_compl_fifo_0, and set properties set axis_compl_fifo_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_compl_fifo_0 ] set_property -dict [ list \ @@ -273,16 +273,6 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } { CONFIG.HAS_AFULL {1} \ ] $axis_data_fifo_9 - # Create instance: axis_data_fifo_10, and set properties - set axis_data_fifo_10 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_fifo_10 ] - - # Create instance: axis_data_fifo_11, and set properties - set axis_data_fifo_11 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_fifo_11 ] - set_property -dict [ list \ - CONFIG.FIFO_DEPTH {2048} \ - CONFIG.FIFO_MEMORY_TYPE {ultra} \ - ] $axis_data_fifo_11 - # Create instance: axis_data_fifo_c2h_cmd, and set properties set axis_data_fifo_c2h_cmd [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_fifo_c2h_cmd ] set_property -dict [ list \ @@ -437,6 +427,19 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } { CONFIG.REG_CONFIG {16} \ ] $axis_register_slice_udp + # Create instance: axis_spot_finder_fifo_0, and set properties + set axis_spot_finder_fifo_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_spot_finder_fifo_0 ] + set_property -dict [ list \ + CONFIG.FIFO_DEPTH {256} \ + ] $axis_spot_finder_fifo_0 + + # Create instance: axis_spot_finder_fifo_1, and set properties + set axis_spot_finder_fifo_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_spot_finder_fifo_1 ] + set_property -dict [ list \ + CONFIG.FIFO_DEPTH {2048} \ + CONFIG.FIFO_MEMORY_TYPE {ultra} \ + ] $axis_spot_finder_fifo_1 + # Create instance: axis_udp_addr_fifo_0, and set properties set axis_udp_addr_fifo_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_udp_addr_fifo_0 ] set_property -dict [ list \ @@ -551,10 +554,9 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } { connect_bd_intf_net -intf_net axi_datamover_1_M_AXI_MM2S [get_bd_intf_pins m_axi_d_hbm_p14] [get_bd_intf_pins axi_datamover_1/M_AXI_MM2S] connect_bd_intf_net -intf_net axi_datamover_1_M_AXI_S2MM [get_bd_intf_pins m_axi_d_hbm_p15] [get_bd_intf_pins axi_datamover_1/M_AXI_S2MM] connect_bd_intf_net -intf_net axis_256_to_512_0_data_out [get_bd_intf_pins axis_256_to_512_0/data_out] [get_bd_intf_pins axis_integration_result_fifo_1/S_AXIS] + connect_bd_intf_net -intf_net axis_32_to_512_0_data_out [get_bd_intf_pins axis_32_to_512_0/data_out] [get_bd_intf_pins axis_spot_finder_fifo_1/S_AXIS] connect_bd_intf_net -intf_net axis_addr_fifo_0_M_AXIS [get_bd_intf_pins axis_addr_fifo_0/M_AXIS] [get_bd_intf_pins axis_register_slice_1/S_AXIS] connect_bd_intf_net -intf_net axis_adu_histo_result_fifo_M_AXIS [get_bd_intf_pins axis_adu_histo_result_fifo/M_AXIS] [get_bd_intf_pins host_writer_0/adu_histo_in] - connect_bd_intf_net -intf_net axis_broadcast_0_data_out_0 [get_bd_intf_pins axis_broadcast_0/data_out_0] [get_bd_intf_pins axis_data_fifo_7/S_AXIS] - connect_bd_intf_net -intf_net axis_broadcast_0_data_out_1 [get_bd_intf_pins axis_broadcast_0/data_out_1] [get_bd_intf_pins axis_data_fifo_10/S_AXIS] connect_bd_intf_net -intf_net axis_compl_fifo_0_M_AXIS [get_bd_intf_pins axis_compl_fifo_0/M_AXIS] [get_bd_intf_pins load_from_hbm_0/s_axis_completion] connect_bd_intf_net -intf_net axis_compl_fifo_1_M_AXIS [get_bd_intf_pins adu_histo_0/s_axis_completion] [get_bd_intf_pins axis_compl_fifo_1/M_AXIS] connect_bd_intf_net -intf_net axis_compl_fifo_2_M_AXIS [get_bd_intf_pins axis_compl_fifo_4/M_AXIS] [get_bd_intf_pins integration_0/s_axis_completion] @@ -562,17 +564,16 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } { connect_bd_intf_net -intf_net axis_compl_fifo_2_M_AXIS2 [get_bd_intf_pins axis_compl_fifo_2/M_AXIS] [get_bd_intf_pins mask_missing_0/s_axis_completion] connect_bd_intf_net -intf_net axis_compl_fifo_3_M_AXIS [get_bd_intf_pins axis_compl_fifo_5/M_AXIS] [get_bd_intf_pins host_writer_0/s_axis_completion] connect_bd_intf_net -intf_net axis_data_fifo_0_M_AXIS [get_bd_intf_pins axis_data_fifo_0/M_AXIS] [get_bd_intf_pins timer_hbm/data_in] - connect_bd_intf_net -intf_net axis_data_fifo_10_M_AXIS [get_bd_intf_pins axis_data_fifo_11/M_AXIS] [get_bd_intf_pins host_writer_0/spot_finder_in] + connect_bd_intf_net -intf_net axis_data_fifo_10_M_AXIS [get_bd_intf_pins axis_spot_finder_fifo_1/M_AXIS] [get_bd_intf_pins host_writer_0/spot_finder_in] connect_bd_intf_net -intf_net axis_data_fifo_12_M_AXIS [get_bd_intf_pins axis_data_fifo_4/M_AXIS] [get_bd_intf_pins mask_missing_0/data_in] connect_bd_intf_net -intf_net axis_data_fifo_1_M_AXIS [get_bd_intf_pins axis_data_fifo_1/M_AXIS] [get_bd_intf_pins axis_register_slice_0/S_AXIS] connect_bd_intf_net -intf_net axis_data_fifo_3_M_AXIS [get_bd_intf_pins axis_data_fifo_2/M_AXIS] [get_bd_intf_pins load_from_hbm_0/data_in] connect_bd_intf_net -intf_net axis_data_fifo_3_M_AXIS1 [get_bd_intf_pins adu_histo_0/data_in] [get_bd_intf_pins axis_data_fifo_3/M_AXIS] connect_bd_intf_net -intf_net axis_data_fifo_4_M_AXIS1 [get_bd_intf_pins axis_data_fifo_5/M_AXIS] [get_bd_intf_pins jf_conversion_0/data_in] connect_bd_intf_net -intf_net axis_data_fifo_5_M_AXIS [get_bd_intf_pins axis_data_fifo_7/M_AXIS] [get_bd_intf_pins integration_0/data_in] - connect_bd_intf_net -intf_net axis_data_fifo_5_M_AXIS1 [get_bd_intf_pins axis_broadcast_0/data_in] [get_bd_intf_pins axis_data_fifo_6/M_AXIS] connect_bd_intf_net -intf_net axis_data_fifo_6_M_AXIS [get_bd_intf_pins axis_data_fifo_8/M_AXIS] [get_bd_intf_pins timer_host/data_in] + connect_bd_intf_net -intf_net axis_data_fifo_6_M_AXIS1 [get_bd_intf_pins axis_data_fifo_6/M_AXIS] [get_bd_intf_pins spot_finder_0/data_in] connect_bd_intf_net -intf_net axis_data_fifo_7_M_AXIS [get_bd_intf_pins axis_data_fifo_9/M_AXIS] [get_bd_intf_pins host_writer_0/data_in] - connect_bd_intf_net -intf_net axis_data_fifo_8_M_AXIS [get_bd_intf_pins axis_data_fifo_10/M_AXIS] [get_bd_intf_pins spot_finder_0/data_in] connect_bd_intf_net -intf_net axis_data_fifo_c2h_cmd_M_AXIS [get_bd_intf_pins m_axis_c2h_datamover_cmd] [get_bd_intf_pins axis_data_fifo_c2h_cmd/M_AXIS] connect_bd_intf_net -intf_net axis_data_fifo_c2h_data_M_AXIS [get_bd_intf_pins m_axis_c2h_data] [get_bd_intf_pins axis_data_fifo_c2h_data/M_AXIS] connect_bd_intf_net -intf_net axis_data_fifo_h2c_cmd_M_AXIS [get_bd_intf_pins m_axis_h2c_datamover_cmd] [get_bd_intf_pins axis_data_fifo_h2c_cmd/M_AXIS] @@ -595,6 +596,7 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } { connect_bd_intf_net -intf_net axis_register_slice_data_in_0_M_AXIS1 [get_bd_intf_pins axis_register_slice_data_in_0/M_AXIS] [get_bd_intf_pins load_calibration_0/host_memory_in] connect_bd_intf_net -intf_net axis_register_slice_host_mem_M_AXIS [get_bd_intf_pins axis_data_fifo_c2h_data/S_AXIS] [get_bd_intf_pins axis_register_slice_host_mem/M_AXIS] connect_bd_intf_net -intf_net axis_register_slice_udp_M_AXIS [get_bd_intf_pins axis_register_slice_udp/M_AXIS] [get_bd_intf_pins data_collection_fsm_0/eth_in] + connect_bd_intf_net -intf_net axis_spot_finder_fifo_0_M_AXIS [get_bd_intf_pins axis_32_to_512_0/data_in] [get_bd_intf_pins axis_spot_finder_fifo_0/M_AXIS] connect_bd_intf_net -intf_net axis_udp_addr_fifo_0_M_AXIS [get_bd_intf_pins axis_udp_addr_fifo_0/M_AXIS] [get_bd_intf_pins data_collection_fsm_0/addr_in] connect_bd_intf_net -intf_net axis_udp_fifo_0_M_AXIS [get_bd_intf_pins axis_register_slice_udp/S_AXIS] [get_bd_intf_pins axis_udp_fifo_0/M_AXIS] connect_bd_intf_net -intf_net axis_work_completion_fifo_0_M_AXIS [get_bd_intf_pins axis_work_completion_fifo_0/M_AXIS] [get_bd_intf_pins mailbox_0/S1_AXIS] @@ -653,7 +655,8 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } { connect_bd_intf_net -intf_net smartconnect_0_M04_AXI [get_bd_intf_pins frame_generator_0/s_axi_control] [get_bd_intf_pins smartconnect_0/M03_AXI] connect_bd_intf_net -intf_net smartconnect_1_M00_AXI [get_bd_intf_pins m_axi_d_hbm_p0] [get_bd_intf_pins smartconnect_1/M00_AXI] connect_bd_intf_net -intf_net smartconnect_2_M00_AXI [get_bd_intf_pins m_axi_d_hbm_p2] [get_bd_intf_pins smartconnect_2/M00_AXI] - connect_bd_intf_net -intf_net spot_finder_0_result_out [get_bd_intf_pins axis_data_fifo_11/S_AXIS] [get_bd_intf_pins spot_finder_0/result_out] + connect_bd_intf_net -intf_net spot_finder_0_data_out [get_bd_intf_pins axis_data_fifo_7/S_AXIS] [get_bd_intf_pins spot_finder_0/data_out] + connect_bd_intf_net -intf_net spot_finder_0_strong_pixel_out [get_bd_intf_pins axis_spot_finder_fifo_0/S_AXIS] [get_bd_intf_pins spot_finder_0/strong_pixel_out] connect_bd_intf_net -intf_net stream_merge_0_output_r [get_bd_intf_pins axis_eth_in_fifo/S_AXIS] [get_bd_intf_pins stream_merge_0/output_r] connect_bd_intf_net -intf_net timer_hbm_data_out [get_bd_intf_pins axis_data_fifo_1/S_AXIS] [get_bd_intf_pins timer_hbm/data_out] connect_bd_intf_net -intf_net timer_host_data_out [get_bd_intf_pins axis_data_fifo_9/S_AXIS] [get_bd_intf_pins timer_host/data_out] @@ -670,7 +673,9 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } { connect_bd_net -net action_config_0_nmodules [get_bd_pins action_config_0/nmodules] [get_bd_pins data_collection_fsm_0/nmodules] connect_bd_net -net action_config_0_nstorage_cells [get_bd_pins action_config_0/nstorage_cells] [get_bd_pins data_collection_fsm_0/nstorage_cells] connect_bd_net -net action_config_0_one_over_energy [get_bd_pins action_config_0/one_over_energy] [get_bd_pins data_collection_fsm_0/one_over_energy] - connect_bd_net -net ap_clk_1 [get_bd_pins axi_clk] [get_bd_pins action_config_0/clk] [get_bd_pins adu_histo_0/ap_clk] [get_bd_pins axi_datamover_0/m_axi_mm2s_aclk] [get_bd_pins axi_datamover_0/m_axi_s2mm_aclk] [get_bd_pins axi_datamover_0/m_axis_mm2s_cmdsts_aclk] [get_bd_pins axi_datamover_0/m_axis_s2mm_cmdsts_awclk] [get_bd_pins axi_datamover_1/m_axi_mm2s_aclk] [get_bd_pins axi_datamover_1/m_axi_s2mm_aclk] [get_bd_pins axi_datamover_1/m_axis_mm2s_cmdsts_aclk] [get_bd_pins axi_datamover_1/m_axis_s2mm_cmdsts_awclk] [get_bd_pins axis_256_to_512_0/ap_clk] [get_bd_pins axis_addr_fifo_0/s_axis_aclk] [get_bd_pins axis_adu_histo_result_fifo/s_axis_aclk] [get_bd_pins axis_broadcast_0/ap_clk] [get_bd_pins axis_compl_fifo_0/s_axis_aclk] [get_bd_pins axis_compl_fifo_1/s_axis_aclk] [get_bd_pins axis_compl_fifo_2/s_axis_aclk] [get_bd_pins axis_compl_fifo_3/s_axis_aclk] [get_bd_pins axis_compl_fifo_4/s_axis_aclk] [get_bd_pins axis_compl_fifo_5/s_axis_aclk] [get_bd_pins axis_data_fifo_0/s_axis_aclk] [get_bd_pins axis_data_fifo_1/s_axis_aclk] [get_bd_pins axis_data_fifo_10/s_axis_aclk] [get_bd_pins axis_data_fifo_11/s_axis_aclk] [get_bd_pins axis_data_fifo_2/s_axis_aclk] [get_bd_pins axis_data_fifo_3/s_axis_aclk] [get_bd_pins axis_data_fifo_4/s_axis_aclk] [get_bd_pins axis_data_fifo_5/s_axis_aclk] [get_bd_pins axis_data_fifo_6/s_axis_aclk] [get_bd_pins axis_data_fifo_7/s_axis_aclk] [get_bd_pins axis_data_fifo_8/s_axis_aclk] [get_bd_pins axis_data_fifo_9/s_axis_aclk] [get_bd_pins axis_data_fifo_c2h_cmd/s_axis_aclk] [get_bd_pins axis_data_fifo_c2h_data/s_axis_aclk] [get_bd_pins axis_data_fifo_h2c_cmd/s_axis_aclk] [get_bd_pins axis_data_fifo_h2c_data/s_axis_aclk] [get_bd_pins axis_datamover_cmd_fifo_0/s_axis_aclk] [get_bd_pins axis_datamover_cmd_fifo_1/s_axis_aclk] [get_bd_pins axis_datamover_cmd_fifo_2/s_axis_aclk] [get_bd_pins axis_datamover_cmd_fifo_3/s_axis_aclk] [get_bd_pins axis_datamover_fifo_0/s_axis_aclk] [get_bd_pins axis_datamover_fifo_1/s_axis_aclk] [get_bd_pins axis_datamover_fifo_2/s_axis_aclk] [get_bd_pins axis_datamover_fifo_3/s_axis_aclk] [get_bd_pins axis_eth_in_fifo/s_axis_aclk] [get_bd_pins axis_frame_generator_fifo_0/s_axis_aclk] [get_bd_pins axis_hbm_handles_fifo/s_axis_aclk] [get_bd_pins axis_integration_result_fifo_0/s_axis_aclk] [get_bd_pins axis_integration_result_fifo_1/s_axis_aclk] [get_bd_pins axis_register_slice_0/aclk] [get_bd_pins axis_register_slice_1/aclk] [get_bd_pins axis_register_slice_data_in_0/aclk] [get_bd_pins axis_register_slice_host_mem/aclk] [get_bd_pins axis_register_slice_udp/aclk] [get_bd_pins axis_udp_addr_fifo_0/s_axis_aclk] [get_bd_pins axis_udp_fifo_0/s_axis_aclk] [get_bd_pins axis_work_completion_fifo_0/s_axis_aclk] [get_bd_pins axis_work_request_fifo_0/s_axis_aclk] [get_bd_pins data_collection_fsm_0/ap_clk] [get_bd_pins frame_generator_0/ap_clk] [get_bd_pins host_writer_0/ap_clk] [get_bd_pins integration_0/ap_clk] [get_bd_pins jf_conversion_0/ap_clk] [get_bd_pins load_calibration_0/ap_clk] [get_bd_pins load_from_hbm_0/ap_clk] [get_bd_pins mailbox_0/M1_AXIS_ACLK] [get_bd_pins mailbox_0/S0_AXI_ACLK] [get_bd_pins mailbox_0/S1_AXIS_ACLK] [get_bd_pins mask_missing_0/ap_clk] [get_bd_pins network_stack/axiclk] [get_bd_pins save_to_hbm_0/ap_clk] [get_bd_pins smartconnect_0/aclk] [get_bd_pins smartconnect_1/aclk] [get_bd_pins smartconnect_2/aclk] [get_bd_pins spot_finder_0/ap_clk] [get_bd_pins stream_merge_0/ap_clk] [get_bd_pins timer_hbm/ap_clk] [get_bd_pins timer_host/ap_clk] + connect_bd_net -net action_config_0_spot_finder_snr [get_bd_pins action_config_0/spot_finder_snr] [get_bd_pins spot_finder_0/in_strong_pixel_threshold] + connect_bd_net -net action_config_0_spot_finder_threshold [get_bd_pins action_config_0/spot_finder_threshold] [get_bd_pins spot_finder_0/in_photon_count_threshold] + connect_bd_net -net ap_clk_1 [get_bd_pins axi_clk] [get_bd_pins action_config_0/clk] [get_bd_pins adu_histo_0/ap_clk] [get_bd_pins axi_datamover_0/m_axi_mm2s_aclk] [get_bd_pins axi_datamover_0/m_axi_s2mm_aclk] [get_bd_pins axi_datamover_0/m_axis_mm2s_cmdsts_aclk] [get_bd_pins axi_datamover_0/m_axis_s2mm_cmdsts_awclk] [get_bd_pins axi_datamover_1/m_axi_mm2s_aclk] [get_bd_pins axi_datamover_1/m_axi_s2mm_aclk] [get_bd_pins axi_datamover_1/m_axis_mm2s_cmdsts_aclk] [get_bd_pins axi_datamover_1/m_axis_s2mm_cmdsts_awclk] [get_bd_pins axis_256_to_512_0/ap_clk] [get_bd_pins axis_32_to_512_0/ap_clk] [get_bd_pins axis_addr_fifo_0/s_axis_aclk] [get_bd_pins axis_adu_histo_result_fifo/s_axis_aclk] [get_bd_pins axis_compl_fifo_0/s_axis_aclk] [get_bd_pins axis_compl_fifo_1/s_axis_aclk] [get_bd_pins axis_compl_fifo_2/s_axis_aclk] [get_bd_pins axis_compl_fifo_3/s_axis_aclk] [get_bd_pins axis_compl_fifo_4/s_axis_aclk] [get_bd_pins axis_compl_fifo_5/s_axis_aclk] [get_bd_pins axis_data_fifo_0/s_axis_aclk] [get_bd_pins axis_data_fifo_1/s_axis_aclk] [get_bd_pins axis_data_fifo_2/s_axis_aclk] [get_bd_pins axis_data_fifo_3/s_axis_aclk] [get_bd_pins axis_data_fifo_4/s_axis_aclk] [get_bd_pins axis_data_fifo_5/s_axis_aclk] [get_bd_pins axis_data_fifo_6/s_axis_aclk] [get_bd_pins axis_data_fifo_7/s_axis_aclk] [get_bd_pins axis_data_fifo_8/s_axis_aclk] [get_bd_pins axis_data_fifo_9/s_axis_aclk] [get_bd_pins axis_data_fifo_c2h_cmd/s_axis_aclk] [get_bd_pins axis_data_fifo_c2h_data/s_axis_aclk] [get_bd_pins axis_data_fifo_h2c_cmd/s_axis_aclk] [get_bd_pins axis_data_fifo_h2c_data/s_axis_aclk] [get_bd_pins axis_datamover_cmd_fifo_0/s_axis_aclk] [get_bd_pins axis_datamover_cmd_fifo_1/s_axis_aclk] [get_bd_pins axis_datamover_cmd_fifo_2/s_axis_aclk] [get_bd_pins axis_datamover_cmd_fifo_3/s_axis_aclk] [get_bd_pins axis_datamover_fifo_0/s_axis_aclk] [get_bd_pins axis_datamover_fifo_1/s_axis_aclk] [get_bd_pins axis_datamover_fifo_2/s_axis_aclk] [get_bd_pins axis_datamover_fifo_3/s_axis_aclk] [get_bd_pins axis_eth_in_fifo/s_axis_aclk] [get_bd_pins axis_frame_generator_fifo_0/s_axis_aclk] [get_bd_pins axis_hbm_handles_fifo/s_axis_aclk] [get_bd_pins axis_integration_result_fifo_0/s_axis_aclk] [get_bd_pins axis_integration_result_fifo_1/s_axis_aclk] [get_bd_pins axis_register_slice_0/aclk] [get_bd_pins axis_register_slice_1/aclk] [get_bd_pins axis_register_slice_data_in_0/aclk] [get_bd_pins axis_register_slice_host_mem/aclk] [get_bd_pins axis_register_slice_udp/aclk] [get_bd_pins axis_spot_finder_fifo_0/s_axis_aclk] [get_bd_pins axis_spot_finder_fifo_1/s_axis_aclk] [get_bd_pins axis_udp_addr_fifo_0/s_axis_aclk] [get_bd_pins axis_udp_fifo_0/s_axis_aclk] [get_bd_pins axis_work_completion_fifo_0/s_axis_aclk] [get_bd_pins axis_work_request_fifo_0/s_axis_aclk] [get_bd_pins data_collection_fsm_0/ap_clk] [get_bd_pins frame_generator_0/ap_clk] [get_bd_pins host_writer_0/ap_clk] [get_bd_pins integration_0/ap_clk] [get_bd_pins jf_conversion_0/ap_clk] [get_bd_pins load_calibration_0/ap_clk] [get_bd_pins load_from_hbm_0/ap_clk] [get_bd_pins mailbox_0/M1_AXIS_ACLK] [get_bd_pins mailbox_0/S0_AXI_ACLK] [get_bd_pins mailbox_0/S1_AXIS_ACLK] [get_bd_pins mask_missing_0/ap_clk] [get_bd_pins network_stack/axiclk] [get_bd_pins save_to_hbm_0/ap_clk] [get_bd_pins smartconnect_0/aclk] [get_bd_pins smartconnect_1/aclk] [get_bd_pins smartconnect_2/aclk] [get_bd_pins spot_finder_0/ap_clk] [get_bd_pins stream_merge_0/ap_clk] [get_bd_pins timer_hbm/ap_clk] [get_bd_pins timer_host/ap_clk] connect_bd_net -net axis_addr_fifo_0_almost_empty [get_bd_pins action_config_0/calib_addr_fifo_empty] [get_bd_pins axis_addr_fifo_0/almost_empty] connect_bd_net -net axis_addr_fifo_0_almost_full [get_bd_pins action_config_0/calib_addr_fifo_full] [get_bd_pins axis_addr_fifo_0/almost_full] connect_bd_net -net axis_compl_fifo_0_almost_empty [get_bd_pins action_config_0/hbm_compl_fifo_empty] [get_bd_pins axis_compl_fifo_0/almost_empty] @@ -722,8 +727,8 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } { connect_bd_net -net network_stack_packets_udp [get_bd_pins action_config_0/packets_udp] [get_bd_pins network_stack/packets_udp] connect_bd_net -net network_stack_packets_udp_ap_vld [get_bd_pins action_config_0/packets_udp_valid] [get_bd_pins network_stack/packets_udp_ap_vld] connect_bd_net -net one_dout [get_bd_pins axi_datamover_0/m_axis_mm2s_sts_tready] [get_bd_pins axi_datamover_0/m_axis_s2mm_sts_tready] [get_bd_pins axi_datamover_1/m_axis_mm2s_sts_tready] [get_bd_pins axi_datamover_1/m_axis_s2mm_sts_tready] [get_bd_pins one/dout] - connect_bd_net -net reset_axi [get_bd_pins axi_rst_n] [get_bd_pins action_config_0/resetn] [get_bd_pins axis_addr_fifo_0/s_axis_aresetn] [get_bd_pins axis_adu_histo_result_fifo/s_axis_aresetn] [get_bd_pins axis_compl_fifo_0/s_axis_aresetn] [get_bd_pins axis_compl_fifo_1/s_axis_aresetn] [get_bd_pins axis_compl_fifo_2/s_axis_aresetn] [get_bd_pins axis_compl_fifo_3/s_axis_aresetn] [get_bd_pins axis_compl_fifo_4/s_axis_aresetn] [get_bd_pins axis_compl_fifo_5/s_axis_aresetn] [get_bd_pins axis_data_fifo_0/s_axis_aresetn] [get_bd_pins axis_data_fifo_1/s_axis_aresetn] [get_bd_pins axis_data_fifo_10/s_axis_aresetn] [get_bd_pins axis_data_fifo_11/s_axis_aresetn] [get_bd_pins axis_data_fifo_2/s_axis_aresetn] [get_bd_pins axis_data_fifo_3/s_axis_aresetn] [get_bd_pins axis_data_fifo_4/s_axis_aresetn] [get_bd_pins axis_data_fifo_5/s_axis_aresetn] [get_bd_pins axis_data_fifo_6/s_axis_aresetn] [get_bd_pins axis_data_fifo_7/s_axis_aresetn] [get_bd_pins axis_data_fifo_8/s_axis_aresetn] [get_bd_pins axis_data_fifo_9/s_axis_aresetn] [get_bd_pins axis_data_fifo_c2h_cmd/s_axis_aresetn] [get_bd_pins axis_data_fifo_c2h_data/s_axis_aresetn] [get_bd_pins axis_data_fifo_h2c_cmd/s_axis_aresetn] [get_bd_pins axis_data_fifo_h2c_data/s_axis_aresetn] [get_bd_pins axis_datamover_cmd_fifo_0/s_axis_aresetn] [get_bd_pins axis_datamover_cmd_fifo_1/s_axis_aresetn] [get_bd_pins axis_datamover_cmd_fifo_2/s_axis_aresetn] [get_bd_pins axis_datamover_cmd_fifo_3/s_axis_aresetn] [get_bd_pins axis_datamover_fifo_0/s_axis_aresetn] [get_bd_pins axis_datamover_fifo_1/s_axis_aresetn] [get_bd_pins axis_datamover_fifo_2/s_axis_aresetn] [get_bd_pins axis_datamover_fifo_3/s_axis_aresetn] [get_bd_pins axis_eth_in_fifo/s_axis_aresetn] [get_bd_pins axis_frame_generator_fifo_0/s_axis_aresetn] [get_bd_pins axis_hbm_handles_fifo/s_axis_aresetn] [get_bd_pins axis_integration_result_fifo_0/s_axis_aresetn] [get_bd_pins axis_integration_result_fifo_1/s_axis_aresetn] [get_bd_pins axis_register_slice_0/aresetn] [get_bd_pins axis_register_slice_1/aresetn] [get_bd_pins axis_register_slice_data_in_0/aresetn] [get_bd_pins axis_register_slice_host_mem/aresetn] [get_bd_pins axis_register_slice_udp/aresetn] [get_bd_pins axis_udp_addr_fifo_0/s_axis_aresetn] [get_bd_pins axis_udp_fifo_0/s_axis_aresetn] [get_bd_pins axis_work_completion_fifo_0/s_axis_aresetn] [get_bd_pins axis_work_request_fifo_0/s_axis_aresetn] [get_bd_pins network_stack/resetn] [get_bd_pins smartconnect_0/aresetn] [get_bd_pins smartconnect_1/aresetn] [get_bd_pins smartconnect_2/aresetn] - connect_bd_net -net reset_hls [get_bd_pins ap_rst_n] [get_bd_pins adu_histo_0/ap_rst_n] [get_bd_pins axi_datamover_0/m_axi_mm2s_aresetn] [get_bd_pins axi_datamover_0/m_axi_s2mm_aresetn] [get_bd_pins axi_datamover_0/m_axis_mm2s_cmdsts_aresetn] [get_bd_pins axi_datamover_0/m_axis_s2mm_cmdsts_aresetn] [get_bd_pins axi_datamover_1/m_axi_mm2s_aresetn] [get_bd_pins axi_datamover_1/m_axi_s2mm_aresetn] [get_bd_pins axi_datamover_1/m_axis_mm2s_cmdsts_aresetn] [get_bd_pins axi_datamover_1/m_axis_s2mm_cmdsts_aresetn] [get_bd_pins axis_256_to_512_0/ap_rst_n] [get_bd_pins axis_broadcast_0/ap_rst_n] [get_bd_pins data_collection_fsm_0/ap_rst_n] [get_bd_pins frame_generator_0/ap_rst_n] [get_bd_pins host_writer_0/ap_rst_n] [get_bd_pins integration_0/ap_rst_n] [get_bd_pins jf_conversion_0/ap_rst_n] [get_bd_pins load_calibration_0/ap_rst_n] [get_bd_pins load_from_hbm_0/ap_rst_n] [get_bd_pins mailbox_0/S0_AXI_ARESETN] [get_bd_pins mask_missing_0/ap_rst_n] [get_bd_pins network_stack/ap_rst_n] [get_bd_pins save_to_hbm_0/ap_rst_n] [get_bd_pins spot_finder_0/ap_rst_n] [get_bd_pins stream_merge_0/ap_rst_n] [get_bd_pins timer_hbm/ap_rst_n] [get_bd_pins timer_host/ap_rst_n] + connect_bd_net -net reset_axi [get_bd_pins axi_rst_n] [get_bd_pins action_config_0/resetn] [get_bd_pins axis_addr_fifo_0/s_axis_aresetn] [get_bd_pins axis_adu_histo_result_fifo/s_axis_aresetn] [get_bd_pins axis_compl_fifo_0/s_axis_aresetn] [get_bd_pins axis_compl_fifo_1/s_axis_aresetn] [get_bd_pins axis_compl_fifo_2/s_axis_aresetn] [get_bd_pins axis_compl_fifo_3/s_axis_aresetn] [get_bd_pins axis_compl_fifo_4/s_axis_aresetn] [get_bd_pins axis_compl_fifo_5/s_axis_aresetn] [get_bd_pins axis_data_fifo_0/s_axis_aresetn] [get_bd_pins axis_data_fifo_1/s_axis_aresetn] [get_bd_pins axis_data_fifo_2/s_axis_aresetn] [get_bd_pins axis_data_fifo_3/s_axis_aresetn] [get_bd_pins axis_data_fifo_4/s_axis_aresetn] [get_bd_pins axis_data_fifo_5/s_axis_aresetn] [get_bd_pins axis_data_fifo_6/s_axis_aresetn] [get_bd_pins axis_data_fifo_7/s_axis_aresetn] [get_bd_pins axis_data_fifo_8/s_axis_aresetn] [get_bd_pins axis_data_fifo_9/s_axis_aresetn] [get_bd_pins axis_data_fifo_c2h_cmd/s_axis_aresetn] [get_bd_pins axis_data_fifo_c2h_data/s_axis_aresetn] [get_bd_pins axis_data_fifo_h2c_cmd/s_axis_aresetn] [get_bd_pins axis_data_fifo_h2c_data/s_axis_aresetn] [get_bd_pins axis_datamover_cmd_fifo_0/s_axis_aresetn] [get_bd_pins axis_datamover_cmd_fifo_1/s_axis_aresetn] [get_bd_pins axis_datamover_cmd_fifo_2/s_axis_aresetn] [get_bd_pins axis_datamover_cmd_fifo_3/s_axis_aresetn] [get_bd_pins axis_datamover_fifo_0/s_axis_aresetn] [get_bd_pins axis_datamover_fifo_1/s_axis_aresetn] [get_bd_pins axis_datamover_fifo_2/s_axis_aresetn] [get_bd_pins axis_datamover_fifo_3/s_axis_aresetn] [get_bd_pins axis_eth_in_fifo/s_axis_aresetn] [get_bd_pins axis_frame_generator_fifo_0/s_axis_aresetn] [get_bd_pins axis_hbm_handles_fifo/s_axis_aresetn] [get_bd_pins axis_integration_result_fifo_0/s_axis_aresetn] [get_bd_pins axis_integration_result_fifo_1/s_axis_aresetn] [get_bd_pins axis_register_slice_0/aresetn] [get_bd_pins axis_register_slice_1/aresetn] [get_bd_pins axis_register_slice_data_in_0/aresetn] [get_bd_pins axis_register_slice_host_mem/aresetn] [get_bd_pins axis_register_slice_udp/aresetn] [get_bd_pins axis_spot_finder_fifo_0/s_axis_aresetn] [get_bd_pins axis_spot_finder_fifo_1/s_axis_aresetn] [get_bd_pins axis_udp_addr_fifo_0/s_axis_aresetn] [get_bd_pins axis_udp_fifo_0/s_axis_aresetn] [get_bd_pins axis_work_completion_fifo_0/s_axis_aresetn] [get_bd_pins axis_work_request_fifo_0/s_axis_aresetn] [get_bd_pins network_stack/resetn] [get_bd_pins smartconnect_0/aresetn] [get_bd_pins smartconnect_1/aresetn] [get_bd_pins smartconnect_2/aresetn] + connect_bd_net -net reset_hls [get_bd_pins ap_rst_n] [get_bd_pins adu_histo_0/ap_rst_n] [get_bd_pins axi_datamover_0/m_axi_mm2s_aresetn] [get_bd_pins axi_datamover_0/m_axi_s2mm_aresetn] [get_bd_pins axi_datamover_0/m_axis_mm2s_cmdsts_aresetn] [get_bd_pins axi_datamover_0/m_axis_s2mm_cmdsts_aresetn] [get_bd_pins axi_datamover_1/m_axi_mm2s_aresetn] [get_bd_pins axi_datamover_1/m_axi_s2mm_aresetn] [get_bd_pins axi_datamover_1/m_axis_mm2s_cmdsts_aresetn] [get_bd_pins axi_datamover_1/m_axis_s2mm_cmdsts_aresetn] [get_bd_pins axis_256_to_512_0/ap_rst_n] [get_bd_pins axis_32_to_512_0/ap_rst_n] [get_bd_pins data_collection_fsm_0/ap_rst_n] [get_bd_pins frame_generator_0/ap_rst_n] [get_bd_pins host_writer_0/ap_rst_n] [get_bd_pins integration_0/ap_rst_n] [get_bd_pins jf_conversion_0/ap_rst_n] [get_bd_pins load_calibration_0/ap_rst_n] [get_bd_pins load_from_hbm_0/ap_rst_n] [get_bd_pins mailbox_0/S0_AXI_ARESETN] [get_bd_pins mask_missing_0/ap_rst_n] [get_bd_pins network_stack/ap_rst_n] [get_bd_pins save_to_hbm_0/ap_rst_n] [get_bd_pins spot_finder_0/ap_rst_n] [get_bd_pins stream_merge_0/ap_rst_n] [get_bd_pins timer_hbm/ap_rst_n] [get_bd_pins timer_host/ap_rst_n] connect_bd_net -net timer_hbm_counter [get_bd_pins action_config_0/stalls_hbm] [get_bd_pins timer_hbm/counter] connect_bd_net -net timer_hbm_counter_ap_vld [get_bd_pins action_config_0/stalls_hbm_valid] [get_bd_pins timer_hbm/counter_ap_vld] connect_bd_net -net timer_host_counter [get_bd_pins action_config_0/stalls_host] [get_bd_pins timer_host/counter] diff --git a/receiver/HLSSimulatedDevice.cpp b/receiver/HLSSimulatedDevice.cpp index bfe56c2a..2ab3ed02 100644 --- a/receiver/HLSSimulatedDevice.cpp +++ b/receiver/HLSSimulatedDevice.cpp @@ -240,9 +240,12 @@ void HLSSimulatedDevice::HLSMainThread() { hls::stream> hbm_handles; hls::stream> adu_histo_result; + hls::stream> integration_result_0; hls::stream> integration_result_1; - hls::stream> spot_finder_result; + + hls::stream> spot_finder_result_0; + hls::stream> spot_finder_result_1; hls::stream > udp_metadata; ap_uint<1> idle_data_collection; @@ -345,10 +348,16 @@ void HLSSimulatedDevice::HLSMainThread() { hbm_if_size); }); - hls_cores.emplace_back([&] { axis_broadcast(converted_5, converted_6, converted_9);}); + ap_int<16> photon_count_threshold = 5; + strong_pixel_threshold_t strong_pixel_threshold = 7; // 6. Spot finding - hls_cores.emplace_back([&] { spot_finder(converted_9, spot_finder_result);}); + hls_cores.emplace_back([&] { spot_finder(converted_5, converted_6, + spot_finder_result_0, + photon_count_threshold, + strong_pixel_threshold);}); + + hls_cores.emplace_back([&] { axis_32_to_512(spot_finder_result_0, spot_finder_result_1);}); // 7. Integration of pixels hls_cores.emplace_back([&] { integration(converted_6, converted_7, integration_result_0, compl4, compl5, @@ -356,13 +365,12 @@ void HLSSimulatedDevice::HLSMainThread() { hls_cores.emplace_back([&] { axis_256_to_512(integration_result_0, integration_result_1);}); - - // Timer procedure - count how many times write_data is not accepting input (to help track down latency issues) + // Timer procedure - count how many times write_data is not accepting input (to help track down latency issues) hls_cores.emplace_back([&] { timer_host(converted_7, converted_8, counter_host); }); // 8. Prepare data to write to host memory hls_cores.emplace_back([&] { - host_writer(converted_8, adu_histo_result, integration_result_1, spot_finder_result, + host_writer(converted_8, adu_histo_result, integration_result_1, spot_finder_result_1, compl5, datamover_out.GetDataStream(), datamover_out.GetCtrlStream(), work_request_stream, completion_stream, packets_processed, host_writer_idle, err_reg); }); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 66b49b45..a5955c27 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -26,7 +26,8 @@ ADD_EXECUTABLE(CatchTest StatusVectorTest.cpp ProcessRawPacketTest.cpp CBORTest.cpp ../tests/stream2.h ../tests/stream2.c JFConversionTest.cpp DetectorGeometryTest.cpp JFJochBrokerParserTest.cpp DetectorSetupTest.cpp DiffractionGeometryTest.cpp ROIFilterTest.cpp - FPGAHLSBitshuffleTest.cpp) + FPGAHLSBitshuffleTest.cpp + FPGASpotFindingUnitTest.cpp) target_link_libraries(CatchTest JFJochBroker JFJochReceiver JFJochWriter ImageAnalysis CommonFunctions HLSSimulation) target_include_directories(CatchTest PRIVATE .) diff --git a/tests/FPGASpotFindingUnitTest.cpp b/tests/FPGASpotFindingUnitTest.cpp new file mode 100644 index 00000000..384a17f3 --- /dev/null +++ b/tests/FPGASpotFindingUnitTest.cpp @@ -0,0 +1,109 @@ +// Copyright (2019-2023) Paul Scherrer Institute + +#include +#include + +#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 new_sum[32]; + ap_int new_sum2[32]; + + for (int i = 0; i < 32; i++) { + old_value[i] = i; + new_value[i] = 2; + } + + ap_uint diff_sum; + ap_uint 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_update_sum" , "[FPGA][SpotFinder]") { + ap_int 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 val1 = pack32(arr_val1); + ap_uint val2 = pack32(arr_val2); + update_sum(val1, val2); + unpack32(val1, arr_out); + for (int i = 0; i < 32; i++) + REQUIRE(arr_out[i] == 8 * i + 2); +} + +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, ap_uint sum2, float threshold) { + return check_threshold(val, sum, sum2, fpga_strong_pixel_threshold(threshold), -1); +} + +TEST_CASE("FPGA_spot_check_threshold","[FPGA][SpotFinder]") { + std::vector 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); + } +} +