77 lines
3.3 KiB
C++
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);
|
|
}
|
|
}
|
|
}
|