AcquisitionDevice: Enable access to integration results
This commit is contained in:
@@ -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++)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user