// Copyright (2019-2023) Paul Scherrer Institute #include "hls_jfjoch.h" // Loads calibration from host memory based on 64-bit memory addresses loaded in in_mem_location // Expected structure in in_mem_location array: // // * gain factors for module m at location: 2 + gain level * NMODULES + m // * pedestal factors for module m and storage cell s at location: 2 + 3 * NMODULES + (gain level * 16 + s ) * NMODULES + m void read_module(ap_uint<256> *d_hbm_p0, ap_uint<256> *d_hbm_p1, hls::stream > &host_memory_in, size_t offset_hbm_0, size_t offset_hbm_1) { #pragma HLS INLINE OFF for (int i = 0; i < RAW_MODULE_SIZE * sizeof(int16_t) / 64; i++) { #pragma HLS PIPELINE II=1 ap_axiu<512, 1, 1, 1> data_packet; host_memory_in >> data_packet; d_hbm_p0[offset_hbm_0 + i] = data_packet.data(255, 0); d_hbm_p1[offset_hbm_1 + i] = data_packet.data(511, 256); } } void load_calibration(ap_uint<256> *d_hbm_p0, ap_uint<256> *d_hbm_p1, ap_uint<8> modules, ap_uint<5> storage_cells, ap_uint<32> hbm_size_bytes, ap_uint<8> destination, hls::stream &datamover_in_cmd, hls::stream > &host_memory_in, uint64_t in_mem_location[(3 * 16 + 3) * MAX_MODULES_FPGA]) { #pragma HLS INTERFACE mode=s_axilite port=return #pragma HLS INTERFACE mode=s_axilite port=in_mem_location #pragma HLS INTERFACE register both axis port=datamover_in_cmd #pragma HLS INTERFACE register both axis port=host_memory_in #pragma HLS INTERFACE mode=s_axilite port=modules #pragma HLS INTERFACE mode=s_axilite port=storage_cells #pragma HLS INTERFACE mode=s_axilite port=destination #pragma HLS INTERFACE mode=ap_none port=hbm_size_bytes #pragma HLS INTERFACE mode=m_axi port=d_hbm_p0 bundle=d_hbm_p0 depth=512 offset=off \ max_read_burst_length=2 max_write_burst_length=16 latency=120 num_write_outstanding=8 num_read_outstanding=2 #pragma HLS INTERFACE mode=m_axi port=d_hbm_p1 bundle=d_hbm_p1 depth=512 offset=off \ max_read_burst_length=2 max_write_burst_length=16 latency=120 num_write_outstanding=8 num_read_outstanding=2 if (modules > MAX_MODULES_FPGA) return; if (destination == LOAD_CALIBRATION_DEST_CALIB) { if (storage_cells > 16) return; for (int c = 0; c < 3; c++) { for (int m = 0; m < modules; m++) { #pragma HLS PIPELINE OFF setup_datamover(datamover_in_cmd, in_mem_location[c * modules + m], RAW_MODULE_SIZE * sizeof(int16_t)); size_t offset_hbm_0 = (2 * c) * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; size_t offset_hbm_1 = (2 * c + 1) * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1); } } for (int c = 0; c < 3; c++) { for (int m = 0; m < modules * storage_cells; m++) { #pragma HLS PIPELINE OFF setup_datamover(datamover_in_cmd, in_mem_location[3 * modules + c * modules * storage_cells + m], RAW_MODULE_SIZE * sizeof(int16_t)); size_t offset_hbm_0 = (6 + 2 * c) * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; size_t offset_hbm_1 = (6 + 2 * c + 1) * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1); } } } else if (destination == LOAD_CALIBRATION_DEST_INTEGRATION) { // load maps for (int m = 0; m < modules; m++) { #pragma HLS PIPELINE OFF setup_datamover(datamover_in_cmd, in_mem_location[m], RAW_MODULE_SIZE * sizeof(int16_t)); size_t offset_hbm_0 = 16 * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; size_t offset_hbm_1 = 17 * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1); } // load weights for (int m = 0; m < modules; m++) { #pragma HLS PIPELINE OFF setup_datamover(datamover_in_cmd, in_mem_location[modules + m], RAW_MODULE_SIZE * sizeof(int16_t)); size_t offset_hbm_0 = 18 * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; size_t offset_hbm_1 = 19 * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1); } } else if (destination == LOAD_CALIBRATION_DEST_FRAME_GEN) { for (int m = 0; m < modules; m++) { #pragma HLS PIPELINE OFF setup_datamover(datamover_in_cmd, in_mem_location[m], RAW_MODULE_SIZE * sizeof(int16_t)); size_t offset_hbm_0 = 20 * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; size_t offset_hbm_1 = 21 * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1); } } }