AcquisitionDevice: Enable access to integration results

This commit is contained in:
2023-09-22 20:31:48 +02:00
parent 3f3ce6f354
commit 5cf0d30603
9 changed files with 140 additions and 5 deletions

View File

@@ -33,7 +33,7 @@ void *mmap_acquisition_buffer(size_t size, int16_t numa_node) {
}
AcquisitionDevice::AcquisitionDevice(uint16_t in_data_stream) :
buffer_err(RAW_MODULE_SIZE) {
buffer_err(FPGA_BUFFER_LOCATION_SIZE) {
logger = nullptr;
data_stream = in_data_stream;
}
@@ -161,6 +161,10 @@ const int16_t *AcquisitionDevice::GetFrameBuffer(size_t frame_number, uint16_t m
return GetErrorFrameBuffer();
}
const IntegrationResult *AcquisitionDevice::GetIntegrationResult(size_t frame_number, uint16_t module_number) const {
return reinterpret_cast<const IntegrationResult *>(GetFrameBuffer(frame_number, module_number) + RAW_MODULE_SIZE);
}
const int16_t *AcquisitionDevice::GetErrorFrameBuffer() const {
return buffer_err.data();
}
@@ -174,6 +178,9 @@ int16_t *AcquisitionDevice::GetDeviceBuffer(size_t handle) {
void AcquisitionDevice::InitializeCalibration(const DiffractionExperiment &experiment, const JFCalibration &calib) {}
void AcquisitionDevice::InitializeIntegrationMap(const DiffractionExperiment &experiment,
const std::vector<uint16_t> &v) {}
void AcquisitionDevice::MapBuffersStandard(size_t c2h_buffer_count, size_t h2c_buffer_count, int16_t numa_node) {
try {
for (int i = 0; i < std::max(c2h_buffer_count, h2c_buffer_count); i++)

View File

@@ -20,6 +20,11 @@
#include "AcquisitionCounters.h"
#include "Completion.h"
struct IntegrationResult {
int64_t sum;
int64_t count;
};
class AcquisitionDevice {
std::vector<int16_t> buffer_err;
@@ -71,6 +76,7 @@ public:
virtual JFJochProtoBuf::FPGAStatus GetStatus() const { return {}; };
const int16_t *GetFrameBuffer(size_t frame_number, uint16_t module_number) const;
const IntegrationResult *GetIntegrationResult(size_t frame_number, uint16_t module_number) const;
void FrameBufferRelease(size_t frame_number, uint16_t module_number);
const int16_t *GetErrorFrameBuffer() const;
@@ -79,7 +85,7 @@ public:
// Calibration
virtual void InitializeCalibration(const DiffractionExperiment &experiment, const JFCalibration &calib);
virtual void InitializeIntegrationMap(const DiffractionExperiment &experiment, const std::vector<uint16_t> &v);
const AcquisitionCounters& Counters() const;
virtual std::string GetIPv4Address() const;

View File

@@ -60,6 +60,26 @@ void FPGAAcquisitionDevice::SendWorkRequestThread() {
}
}
void FPGAAcquisitionDevice::InitializeIntegrationMap(const DiffractionExperiment &experiment,
const std::vector<uint16_t> &v) {
auto offset = experiment.GetFirstModuleOfDataStream(data_stream);
if (v.size() != experiment.GetModulesNum() * RAW_MODULE_SIZE)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Mismatch regarding integration map array");
size_t modules = experiment.GetModulesNum(data_stream);
if (modules > buffer_device.size())
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Not enough host/FPGA buffers to load all integration map values");
for (int m = 0; m < modules; m++)
memcpy(buffer_device[m], v.data() + (offset + m) * RAW_MODULE_SIZE, RAW_MODULE_SIZE * sizeof(uint16_t));
HW_LoadIntegrationMap(modules);
}
void FPGAAcquisitionDevice::InitializeCalibration(const DiffractionExperiment &experiment, const JFCalibration &calib) {
auto offset = experiment.GetFirstModuleOfDataStream(data_stream);
@@ -78,6 +98,11 @@ void FPGAAcquisitionDevice::InitializeCalibration(const DiffractionExperiment &e
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Not enough host/FPGA buffers to load all calibration constants");
if (modules * (3 + 3 * storage_cells) > LOAD_CALIBRATION_BRAM_SIZE)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"FPGA is not compatible with that many calibration constants");
for (int m = 0; m < modules; m++) {
calib.GainCalibration(m).ExportG0(buffer_device[m]);
calib.GainCalibration(m).ExportG1(buffer_device[m + modules]);

View File

@@ -27,6 +27,7 @@ class FPGAAcquisitionDevice : public AcquisitionDevice {
void SendWorkRequestThread();
virtual void HW_LoadCalibration(uint32_t modules, uint32_t storage_cells) = 0;
virtual void HW_LoadIntegrationMap(uint32_t modules) = 0;
virtual bool HW_ReadMailbox(uint32_t values[16]) = 0;
virtual bool HW_SendWorkRequest(uint32_t handle) = 0;
void StartSendingWorkRequests() override;
@@ -42,7 +43,7 @@ public:
ActionConfig ReadActionRegister();
JFJochProtoBuf::FPGAStatus GetStatus() const override;
void InitializeCalibration(const DiffractionExperiment &experiment, const JFCalibration &calib) override;
void InitializeIntegrationMap(const DiffractionExperiment &experiment, const std::vector<uint16_t> &v) override;
void SetCustomInternalGeneratorFrame(const std::vector<uint16_t> &v);
std::vector<uint16_t> GetInternalGeneratorFrame() const override;
};

View File

@@ -456,6 +456,33 @@ void HLSSimulatedDevice::HW_LoadCalibration(uint32_t modules, uint32_t storage_c
throw std::runtime_error("Datamover queue is not empty");
}
void HLSSimulatedDevice::HW_LoadIntegrationMap(uint32_t modules) {
if (logger)
logger->Info("Load calibration start");
auto in_mem_location32 = (uint32_t *) calibration_addr_bram;
for (int i = 0; i < modules; i++) {
in_mem_location32[2 * i ] = ((uint64_t) buffer_device[i]) & UINT32_MAX;
in_mem_location32[2 * i + 1] = ((uint64_t) buffer_device[i]) >> 32;
}
load_calibration(hbm.data(),
hbm.data(),
modules,
0,
hbm_if_size,
LOAD_CALIBRATION_DEST_INTEGRATION,
datamover_in.GetCtrlStream(),
datamover_in.GetDataStream(),
calibration_addr_bram);
if (logger)
logger->Info("Load integration_map");
if (!datamover_in.GetDataStream().empty())
throw std::runtime_error("Datamover queue is not empty");
}
uint32_t HLSSimulatedDevice::GetCompletedDescriptors() const {
return datamover_out.GetCompletedDescriptors();
}

View File

@@ -52,6 +52,7 @@ class HLSSimulatedDevice : public FPGAAcquisitionDevice {
bool HW_ReadMailbox(uint32_t values[16]) override;
bool HW_SendWorkRequest(uint32_t handle) override;
void HW_LoadCalibration(uint32_t modules, uint32_t storage_cells) override;
void HW_LoadIntegrationMap(uint32_t modules) override;
void HW_GetStatus(ActionStatus *status) const override;
void HLSMainThread() ;
void RunFrameGenerator(const FrameGeneratorConfig& config);

View File

@@ -234,8 +234,15 @@ void PCIExpressDevice::HW_LoadCalibration(uint32_t in_modules, uint32_t in_stora
.nstorage_cells = in_storage_cells
};
if (ioctl(fd, IOCTL_JFJOCH_LOAD_CALIB, &config) != 0)
throw JFJochException(JFJochExceptionCategory::PCIeError,
"Failed writing config", errno);
throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed uploading calibration", errno);
}
void PCIExpressDevice::HW_LoadIntegrationMap(uint32_t in_modules) {
ActionConfig config{
.nmodules = in_modules,
};
if (ioctl(fd, IOCTL_JFJOCH_LOAD_INT_MAP, &config) != 0)
throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed uploading integration map", errno);
}
uint32_t PCIExpressDevice::GetCompletedDescriptors() const {

View File

@@ -15,6 +15,7 @@ class PCIExpressDevice : public FPGAAcquisitionDevice {
void HW_WriteActionRegister(const ActionConfig *job) override;
void HW_ReadActionRegister(ActionConfig *job) override;
void HW_LoadCalibration(uint32_t modules, uint32_t storage_cells) override;
void HW_LoadIntegrationMap(uint32_t modules) override;
void FPGA_EndAction() override;
void Reset();

View File

@@ -1030,3 +1030,63 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_storage_cell_convert_G1",
}
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_integration", "[FPGA][Full]") {
const uint16_t nmodules = 4;
DiffractionExperiment x((DetectorGeometry(nmodules)));
x.Mode(DetectorMode::Raw);
x.UseInternalPacketGenerator(true).ImagesPerTrigger(1).PedestalG0Frames(0);
HLSSimulatedDevice test(0, 64);
std::vector<uint16_t> frame(RAW_MODULE_SIZE);
frame[0] = INT16_MAX;
frame[1] = INT16_MIN;
for (int i = 2; i < RAW_MODULE_SIZE; i++)
frame[i] = 32754;
test.SetCustomInternalGeneratorFrame(frame);
std::vector<uint16_t> integration_map(nmodules * RAW_MODULE_SIZE, 54);
for (int i = 0; i < RAW_MODULE_SIZE/2; i++) {
integration_map[2 * i] = 0;
integration_map[2 * i + 1] = FPGA_INTEGRATION_BIN_COUNT - 1;
}
integration_map[RAW_MODULE_SIZE - 1] = FPGA_INTEGRATION_BIN_COUNT;
test.InitializeIntegrationMap(x, integration_map);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.OutputStream().size() == 1);
JFJochProtoBuf::AcquisitionDeviceStatistics device_statistics;
REQUIRE_NOTHROW(test.SaveStatistics(x, device_statistics));
REQUIRE(device_statistics.bytes_received() == 128 * nmodules * JUNGFRAU_PACKET_SIZE_BYTES);
auto imageBuf = test.GetFrameBuffer(0, 0);
REQUIRE(memcmp(imageBuf, frame.data(), RAW_MODULE_SIZE * sizeof(uint16_t)) == 0);
auto integration_result = test.GetIntegrationResult(0, 0);
CHECK(integration_result[0].sum == 32754LU * (RAW_MODULE_SIZE / 2 - 1));
CHECK(integration_result[0].count == RAW_MODULE_SIZE / 2 - 1);
CHECK(integration_result[1].sum == 0);
CHECK(integration_result[1].count == 0);
CHECK(integration_result[FPGA_INTEGRATION_BIN_COUNT - 1].sum == 32754LU * (RAW_MODULE_SIZE / 2 - 2));
CHECK(integration_result[FPGA_INTEGRATION_BIN_COUNT - 1].count == RAW_MODULE_SIZE / 2 - 2);
integration_result = test.GetIntegrationResult(0, 1);
CHECK(integration_result[54].sum == 32754 * (RAW_MODULE_SIZE - 2));
CHECK(integration_result[54].count == RAW_MODULE_SIZE - 2);
integration_result = test.GetIntegrationResult(0, 2);
CHECK(integration_result[54].sum == 32754 * (RAW_MODULE_SIZE - 2));
CHECK(integration_result[54].count == RAW_MODULE_SIZE - 2);
integration_result = test.GetIntegrationResult(0, 3);
CHECK(integration_result[54].sum == 32754 * (RAW_MODULE_SIZE - 2));
CHECK(integration_result[54].count == RAW_MODULE_SIZE - 2);
}