Files
Jungfraujoch/fpga/hls/load_calibration.cpp

77 lines
3.3 KiB
C++

// Copyright (2019-2022) Paul Scherrer Institute
// SPDX-License-Identifier: CERN-OHL-S-2.0 or GPL-3.0-or-later
#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 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,
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=ap_none port=hbm_size_bytes
#pragma HLS INTERFACE 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 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 (storage_cells > 16)
return;
if (modules > MAX_MODULES_FPGA)
return;
ap_uint<16> addr = 0;
for (int c = 0; c < 3; c++) {
size_t offset_hbm_0 = (2 * c) * hbm_size_bytes / 32;
size_t offset_hbm_1 = (2 * c + 1) * hbm_size_bytes / 32;
read_gain:
for (int i = 0; i < modules * RAW_MODULE_SIZE * sizeof(int16_t) / 64; i++) {
#pragma HLS PIPELINE II=1
if (i % (RAW_MODULE_SIZE * sizeof(uint16_t) / 64) == 0) {
setup_datamover(datamover_in_cmd, in_mem_location[addr], RAW_MODULE_SIZE * sizeof(int16_t));
addr++;
}
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);
}
}
read_pedestal:
for (int c = 0; c < 3; c++) {
size_t offset_hbm_0 = (6 + 2 * c) * hbm_size_bytes / 32;
size_t offset_hbm_1 = (6 + 2 * c + 1) * hbm_size_bytes / 32;
for (int i = 0; i < modules * storage_cells * RAW_MODULE_SIZE * sizeof(int16_t) / 64; i++) {
#pragma HLS PIPELINE II=1
if (i % (RAW_MODULE_SIZE * sizeof(uint16_t) / 64) == 0) {
setup_datamover(datamover_in_cmd, in_mem_location[addr], RAW_MODULE_SIZE * sizeof(int16_t));
addr++;
}
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);
}
}
}