Files
Jungfraujoch/fpga/hls/load_calibration.cpp

107 lines
5.2 KiB
C++

// 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<ap_axiu<512,1,1,1> > &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<axis_datamover_ctrl> &datamover_in_cmd,
hls::stream<ap_axiu<512,1,1,1> > &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);
}
}
}