Files
Jungfraujoch/receiver/hls/load_calibration.cpp
Filip Leonarski 1757d42182 Initial commit
Signed-off-by: Filip Leonarski <filip.leonarski@psi.ch>
2023-04-06 11:17:59 +02:00

85 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:
//
// * pixel mask for all modules(1 bit/pixel)
// * internal packet generator frame
// * 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_data(STREAM_512 &data_out,
hls::stream<axis_datamover_ctrl> &datamover_in_cmd,
hls::stream<ap_axiu<512,1,1,1> > &host_memory_in,
uint64_t memory_addr,
uint64_t size_in_512bit_packets) {
setup_datamover(datamover_in_cmd, memory_addr, size_in_512bit_packets * 64);
read_internal_pkt_gen_content:
for (int j = 0; j < size_in_512bit_packets; j++) {
#pragma HLS PIPELINE II=1
ap_axiu<512,1,1,1> data_packet;
host_memory_in >> data_packet;
packet_512_t packet_out;
packet_out.last = 0;
packet_out.user = 0;
packet_out.id = 0;
packet_out.data = data_packet.data;
data_out << packet_out;
}
}
void load_calibration(STREAM_512 &data_in, STREAM_512 &data_out,
hls::stream<axis_datamover_ctrl> &datamover_in_cmd,
hls::stream<ap_axiu<512,1,1,1> > &host_memory_in,
uint64_t in_mem_location[LOAD_CALIBRATION_BRAM_SIZE]) {
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE register both axis port=datamover_in_cmd
#pragma HLS INTERFACE register both axis port=host_memory_in
#pragma HLS INTERFACE register both axis port=data_in
#pragma HLS INTERFACE register both axis port=data_out
#pragma HLS INTERFACE bram port=in_mem_location storage_type=rom_1p
packet_512_t packet_in;
data_in >> packet_in;
ap_uint<5> modules = ACT_REG_NMODULES(packet_in.data);
ap_uint<5> storage_cells = ACT_REG_NSTORAGE_CELLS(packet_in.data);
ap_uint<1> conversion = (ACT_REG_MODE(packet_in.data) & MODE_CONV) ? 1 : 0;
data_out << packet_in;
load_data(data_out, datamover_in_cmd, host_memory_in, in_mem_location[0], RAW_MODULE_SIZE * sizeof(int16_t) / 64);
if (conversion) {
read_gain:
for (int c = 0; c < 3; c++) {
// 3 gain levels
for (int m = 0; m < modules; m++) {
load_data(data_out, datamover_in_cmd, host_memory_in, in_mem_location[m + c * modules + 1],
RAW_MODULE_SIZE * sizeof(int16_t) / 64);
}
}
read_pedestal:
for (int c = 0; c < 3; c++) {
ap_uint<16> offset = (c * 16 + 3) * modules + 1;
for (int s = 0; s < storage_cells; s++) {
for (int m = 0; m < modules; m++) {
load_data(data_out, datamover_in_cmd, host_memory_in,
in_mem_location[offset + s * modules + m],
RAW_MODULE_SIZE * sizeof(int16_t) / 64);
}
}
}
}
data_in >> packet_in;
while (!packet_in.user) {
#pragma HLS PIPELINE II=1
data_out << packet_in;
data_in >> packet_in;
}
data_out << packet_in;
}