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