// Copyright (2019-2022) Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-or-later #include #include #include #include "../jungfrau/JFPedestalCalc.h" #include "../receiver/HLSSimulatedDevice.h" #include "FPGAUnitTest.h" using namespace std::literals::chrono_literals; TEST_CASE("HLS_C_Simulation_internal_packet_generator", "[FPGA][Full]") { const uint16_t nmodules = 4; DiffractionExperiment x((DetectorGeometry(nmodules))); x.Mode(DetectorMode::Raw); x.UseInternalPacketGenerator(true).ImagesPerTrigger(4).PedestalG0Frames(0); HLSSimulatedDevice test(0, 64); 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 * 4 * JUNGFRAU_PACKET_SIZE_BYTES); for (int image = 0; image < 4; image++) { for (int m = 0; m < nmodules; m++) { auto imageBuf = (uint16_t *) test.GetFrameBuffer(image, m); for (int i = 0; i < RAW_MODULE_SIZE; i++) REQUIRE(imageBuf[i] == i % 65536); } } } TEST_CASE("HLS_C_Simulation_internal_packet_generator_skip_packets", "[FPGA][Full]") { const uint16_t nmodules = 1; DiffractionExperiment x((DetectorGeometry(nmodules))); x.Mode(DetectorMode::Raw); x.UseInternalPacketGenerator(true).ImagesPerTrigger(1000).PedestalG0Frames(0); HLSSimulatedDevice test(0, 64); 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.efficiency() < 1.0); } TEST_CASE("HLS_C_Simulation_internal_packet_generator_custom_frame", "[FPGA][Full]") { const uint16_t nmodules = 4; DiffractionExperiment x((DetectorGeometry(nmodules))); std::vector test_frame(RAW_MODULE_SIZE); std::mt19937 g1(1387); std::uniform_int_distribution dist(0, 65535); for (auto &i: test_frame) i = dist(g1); x.Mode(DetectorMode::Raw); x.UseInternalPacketGenerator(true).ImagesPerTrigger(4).PedestalG0Frames(0); HLSSimulatedDevice test(0, 64); test.SetCustomInternalGeneratorFrame(test_frame); test.SetFPGANonBlockingMode(true); REQUIRE_NOTHROW(test.StartAction(x)); REQUIRE_NOTHROW(test.WaitForActionComplete()); REQUIRE(test.OutputStream().size() == 1); REQUIRE(test.GetBytesReceived() == 128 * nmodules * 4 * JUNGFRAU_PACKET_SIZE_BYTES); for (int image = 0; image < 4; image++) { for (int m = 0; m < nmodules; m++) { REQUIRE(test.Counters().GetCompletion(image, m).timestamp == INT_PKT_GEN_TIMESTAMP); REQUIRE(test.Counters().GetCompletion(image, m).bunchid == INT_PKT_GEN_BUNCHID); REQUIRE(test.Counters().GetCompletion(image, m).exptime == INT_PKT_GEN_EXPTTIME); auto imageBuf = (uint16_t *) test.GetFrameBuffer(image, m); for (int i = 0; i < RAW_MODULE_SIZE; i++) { if (imageBuf[i] != test_frame[i]) std::cout << m << " " << i << " " << imageBuf[i] << std::endl; REQUIRE(imageBuf[i] == test_frame[i]); } } } } TEST_CASE("HLS_C_Simulation_check_raw", "[FPGA][Full]") { std::vector raw_frames(RAW_MODULE_SIZE*20); for (int i = 0; i < 20; i++) { LoadBinaryFile("../../tests/test_data/mod5_raw" + std::to_string(i)+".bin", raw_frames.data() + i * RAW_MODULE_SIZE, RAW_MODULE_SIZE); } const uint16_t nmodules = 4; DiffractionExperiment x((DetectorGeometry(nmodules))); uint16_t data[4096]; x.Mode(DetectorMode::Raw); x.PedestalG0Frames(0).ImagesPerTrigger(5).NumTriggers(1); HLSSimulatedDevice test(0, 64); test.CreatePackets(x, 1, 5, 0, raw_frames.data(), true); test.CreateFinalPacket(x); REQUIRE_NOTHROW(test.StartAction(x)); REQUIRE_NOTHROW(test.WaitForActionComplete()); REQUIRE(test.Counters().GetSlowestHead() == 0); REQUIRE_NOTHROW(test.OutputStream().read()); REQUIRE(test.OutputStream().size() == 0); REQUIRE(test.GetBytesReceived() == 5 * 128 * JUNGFRAU_PACKET_SIZE_BYTES); JFJochProtoBuf::AcquisitionDeviceStatistics device_statistics; REQUIRE_NOTHROW(test.SaveStatistics(x, device_statistics)); REQUIRE(device_statistics.bytes_received() == 5 * 128 * JUNGFRAU_PACKET_SIZE_BYTES); REQUIRE(device_statistics.efficiency() == Approx(0.25)); uint64_t diffs = 0; for (int image = 0; image < 5; image++) { for (int j = 0; j < RAW_MODULE_SIZE; j++) { if (raw_frames[image*RAW_MODULE_SIZE+j] != ((uint16_t *) test.GetFrameBuffer(image, 0))[j]) diffs++; } } REQUIRE(diffs == 0); } TEST_CASE("HLS_C_Simulation_check_cancel", "[FPGA][Full]") { const uint16_t nmodules = 4; DiffractionExperiment x((DetectorGeometry(nmodules))); uint16_t data[4096]; x.Mode(DetectorMode::Raw); x.PedestalG0Frames(0).ImagesPerTrigger(5).NumTriggers(1); HLSSimulatedDevice test(0, 64); REQUIRE_NOTHROW(test.StartAction(x)); test.Cancel(); REQUIRE_NOTHROW(test.WaitForActionComplete()); REQUIRE(test.Counters().GetSlowestHead() == 0); REQUIRE_NOTHROW(test.OutputStream().read()); REQUIRE(test.OutputStream().size() == 0); REQUIRE(test.GetBytesReceived() == 0); } TEST_CASE("HLS_C_Simulation_check_cancel_conversion", "[FPGA][Full]") { const uint16_t nmodules = 4; DiffractionExperiment x((DetectorGeometry(nmodules))); uint16_t data[4096]; x.Mode(DetectorMode::Conversion); x.PedestalG0Frames(0).ImagesPerTrigger(5).NumTriggers(1); HLSSimulatedDevice test(0, 64); REQUIRE_NOTHROW(test.StartAction(x)); test.Cancel(); REQUIRE_NOTHROW(test.WaitForActionComplete()); REQUIRE(test.Counters().GetSlowestHead() == 0); REQUIRE_NOTHROW(test.OutputStream().read()); REQUIRE(test.OutputStream().size() == 0); REQUIRE(test.GetBytesReceived() == 0); } TEST_CASE("HLS_C_Simulation_check_delay", "[FPGA][Full]") { std::vector raw_frames(RAW_MODULE_SIZE*20); const uint16_t nmodules = 4; DiffractionExperiment x((DetectorGeometry(nmodules))); uint16_t data[4096]; x.Mode(DetectorMode::Raw); x.PedestalG0Frames(0).ImagesPerTrigger(3).NumTriggers(1); HLSSimulatedDevice test(0, 64); test.CreatePacketJF(x, 1, 0, 0, data, false); test.CreatePacketJF(x, 1, 0, 1, data, false); test.CreatePacketJF(x, 1, 0, 2, data, false); test.CreatePacketJF(x, 1, 0, 3, data, false); test.CreatePacketJF(x, 2, 0, 0, data, false); test.CreatePacketJF(x, 2, 0, 1, data, false); test.CreatePacketJF(x, 2, 0, 2, data, false); test.CreatePacketJF(x, 2, 0, 3, data, false); test.CreatePacketJF(x, 3, 0, 0, data, false); test.CreatePacketJF(x, 3, 0, 1, data, false); test.CreatePacketJF(x, 3, 0, 2, data, false); test.CreatePacketJF(x, 3, 0, 3, data, false); test.CreateFinalPacket(x); REQUIRE_NOTHROW(test.StartAction(x)); REQUIRE_NOTHROW(test.WaitForActionComplete()); REQUIRE(test.Counters().CalculateDelay(0) == 2); REQUIRE(test.Counters().CalculateDelay(0, 0) == 2); REQUIRE(test.Counters().CalculateDelay(1) == 1); REQUIRE(test.Counters().CalculateDelay(1, 0) == 1); REQUIRE(test.Counters().CalculateDelay(2) == 0); REQUIRE(test.Counters().CalculateDelay(2, 0) == 0); } TEST_CASE("HLS_C_Simulation_check_lost_frame_raw", "[FPGA][Full]") { std::vector raw_frames(RAW_MODULE_SIZE*20); const uint16_t nmodules = 4; DiffractionExperiment x((DetectorGeometry(nmodules))); uint16_t data[4096]; for (int i = 0; i < 4096; i++) data[i] = i; x.Mode(DetectorMode::Raw); x.PedestalG0Frames(0).ImagesPerTrigger(3).NumTriggers(1); HLSSimulatedDevice test(0, 64); test.CreatePacketJF(x, 1, 0, 0, data, false); test.CreateFinalPacket(x); REQUIRE_NOTHROW(test.StartAction(x)); REQUIRE_NOTHROW(test.WaitForActionComplete()); REQUIRE_NOTHROW(test.OutputStream().read()); REQUIRE(test.OutputStream().size() == 0); REQUIRE(test.GetBytesReceived() == JUNGFRAU_PACKET_SIZE_BYTES); REQUIRE(test.GetFrameBuffer(0,0)[0] == 0); REQUIRE(test.GetFrameBuffer(0,0)[1] == 1); REQUIRE(test.GetFrameBuffer(0,0)[4095] == 4095); REQUIRE(test.GetFrameBuffer(0,1)[0] == -1); REQUIRE(test.GetFrameBuffer(0,1)[RAW_MODULE_SIZE-1] == -1); } TEST_CASE("HLS_C_Simulation_check_lost_frame_conversion", "[FPGA][Full]") { std::vector raw_frames(RAW_MODULE_SIZE*20); const uint16_t nmodules = 4; DiffractionExperiment x((DetectorGeometry(nmodules))); uint16_t data[4096]; for (int i = 0; i < 4096; i++) data[i] = i; x.Mode(DetectorMode::Conversion); x.PedestalG0Frames(0).ImagesPerTrigger(3).NumTriggers(1); HLSSimulatedDevice test(0, 64); test.CreatePacketJF(x, 1, 0, 0, data, false); test.CreateFinalPacket(x); REQUIRE_NOTHROW(test.StartAction(x)); REQUIRE_NOTHROW(test.WaitForActionComplete()); REQUIRE_NOTHROW(test.OutputStream().read()); REQUIRE(test.OutputStream().size() == 0); REQUIRE(test.GetBytesReceived() == JUNGFRAU_PACKET_SIZE_BYTES); REQUIRE(test.GetFrameBuffer(0,1)[0] == PIXEL_OUT_LOST); REQUIRE(test.GetFrameBuffer(0,1)[RAW_MODULE_SIZE-1] == PIXEL_OUT_LOST); REQUIRE(test.GetFrameBuffer(1,0)[0] == PIXEL_OUT_LOST); REQUIRE(test.GetFrameBuffer(2,1)[556] == PIXEL_OUT_LOST); } TEST_CASE("HLS_C_Simulation_check_single_packet", "[FPGA][Full]") { std::vector raw_frames(RAW_MODULE_SIZE*20); const uint16_t nmodules = 4; DiffractionExperiment x((DetectorGeometry(nmodules))); uint16_t data[4096]; x.Mode(DetectorMode::Raw); x.PedestalG0Frames(0).ImagesPerTrigger(3).NumTriggers(1); HLSSimulatedDevice test(0, 64); test.CreatePacketJF(x, 1, 0, 0, data, false); test.CreatePacketJF(x, 1, 64, 0, data, false); test.CreatePacketJF(x, 1, 0, 2, data, false); test.CreatePacketJF(x, 1, 2, 3, data, false); test.CreatePacketJF(x, 1, 3, 3, data, false); test.CreatePacketJF(x, 1, 1, 3, data, false); test.CreatePacketJF(x, 1, 0, 3, data, false); test.CreatePacketJF(x, 1, 64, 3, data, false); test.CreatePacketJF(x, 1, 5, 0, data, false); test.CreatePacketJF(x, 1, 4, 0, data, false); test.CreatePacketJF(x, 1, 67, 1, data, false); test.CreatePacketJF(x, 1, 66, 1, data, false); test.CreatePacketJF(x, 1, 68, 1, data, false); test.CreatePacketJF(x, 3, 1, 0, data, false); test.CreatePacketJF(x, 2, 1, 0, data, false); test.CreatePacketJF(x, 4, 1, 0, data, false); test.CreateFinalPacket(x); REQUIRE_NOTHROW(test.StartAction(x)); REQUIRE_NOTHROW(test.WaitForActionComplete()); REQUIRE_NOTHROW(test.OutputStream().read()); REQUIRE(test.OutputStream().size() == 0); REQUIRE(test.GetBytesReceived() == 15 * JUNGFRAU_PACKET_SIZE_BYTES); JFJochProtoBuf::AcquisitionDeviceStatistics device_statistics; REQUIRE_NOTHROW(test.SaveStatistics(x, device_statistics)); REQUIRE(device_statistics.good_packets() == 15); REQUIRE(device_statistics.bytes_received() == 15 * JUNGFRAU_PACKET_SIZE_BYTES); } TEST_CASE("HLS_C_Simulation_check_convert_full_range", "[FPGA][Full]") { std::vector data(RAW_MODULE_SIZE); std::vector gain(3 * RAW_MODULE_SIZE); JFModulePedestal pedestal_g0(0), pedestal_g1(14500), pedestal_g2(14500); for (int i = 0; i < RAW_MODULE_SIZE; i++) { data[i] = i % UINT16_MAX; } std::vector energy_values = {6.0, 12.4, 17.7, 5, 4.5, 3.7}; const uint16_t nmodules = 1; DiffractionExperiment x((DetectorGeometry(nmodules))); x.Mode(DetectorMode::Conversion); HLSSimulatedDevice test(0, 64); auto gain_from_file = GainCalibrationFromTestFile(); for (const auto energy : energy_values) { x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).PhotonEnergy_keV(energy); REQUIRE(x.GetPhotonEnergy_keV() == Approx(energy)); JFCalibration c_in(x); c_in.Pedestal(0,0) = pedestal_g0; c_in.Pedestal(0,1) = pedestal_g1; c_in.Pedestal(0,2) = pedestal_g2; for (int i = 0; i < x.GetModulesNum(); i++) c_in.GainCalibration(i) = gain_from_file; test.InitializeCalibration(x, c_in); test.CreatePackets(x, 1, 1, 0, data.data(), false); test.CreateFinalPacket(x); REQUIRE_NOTHROW(test.StartAction(x)); REQUIRE_NOTHROW(test.WaitForActionComplete()); REQUIRE_NOTHROW(test.OutputStream().read()); REQUIRE(test.OutputStream().size() == 0); REQUIRE(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES); double mean_error = CheckConversion(x, c_in, data.data(), test.GetFrameBuffer(0,0)); REQUIRE(mean_error < 0.5); } } TEST_CASE("HLS_C_Simulation_internal_packet_generator_convert_full_range", "[FPGA][Full]") { double energy = 6.0; const uint16_t nmodules = 1; DiffractionExperiment x((DetectorGeometry(nmodules))); std::vector data(RAW_MODULE_SIZE); JFModulePedestal pedestal_g0, pedestal_g1, pedestal_g2; std::vector gain(3 * RAW_MODULE_SIZE); for (int i = 0; i < RAW_MODULE_SIZE; i++) { pedestal_g0.GetPedestal()[i] = 0 + (i / 65536) * 1000 + 100 * (i % 5); pedestal_g1.GetPedestal()[i] = 14500 - (i / 65536) * 1000 + 100 * (i % 3); pedestal_g2.GetPedestal()[i] = 14500 - + (i / 65536) * 1000; } for (int i = 0; i < RAW_MODULE_SIZE; i++) { data[i] = i % RAW_MODULE_SIZE; } x.Mode(DetectorMode::Conversion); x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).UseInternalPacketGenerator(true).PhotonEnergy_keV(energy); REQUIRE(x.GetPhotonEnergy_keV() == Approx(energy)); auto gain_from_file = GainCalibrationFromTestFile(); JFCalibration c(x); c.Pedestal(0,0) = pedestal_g0; c.Pedestal(0,1) = pedestal_g1; c.Pedestal(0,2) = pedestal_g2; for (int i = 0; i < x.GetModulesNum(); i++) c.GainCalibration(i) = gain_from_file; HLSSimulatedDevice test(0, 64); REQUIRE_NOTHROW(test.InitializeCalibration(x, c)); REQUIRE_NOTHROW(test.StartAction(x)); REQUIRE_NOTHROW(test.WaitForActionComplete()); REQUIRE_NOTHROW(test.OutputStream().read()); REQUIRE(test.OutputStream().size() == 0); REQUIRE(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES); double mean_error = CheckConversion(x, c, data.data(), test.GetFrameBuffer(0,0)); REQUIRE(mean_error < 0.5); } TEST_CASE("HLS_C_Simulation_internal_packet_generator_apply_pixel_mask", "[FPGA][Full]") { double energy = 6.0; const uint16_t nmodules = 1; DiffractionExperiment x((DetectorGeometry(nmodules))); JFModulePedestal pedestal_g0, pedestal_g1, pedestal_g2; std::vector gain(3 * RAW_MODULE_SIZE); std::vector test_frame(RAW_MODULE_SIZE); for (int i = 0; i < RAW_MODULE_SIZE; i++) { test_frame[i] = 5000 | ((i > 128*1024) ? 16384:0) | ((i > 256*1024) ? 32768 : 0); } for (int i = 0; i < RAW_MODULE_SIZE; i++) { pedestal_g0.GetPedestal()[i] = 3000; pedestal_g1.GetPedestal()[i] = 14000; pedestal_g2.GetPedestal()[i] = 15000; } pedestal_g0.GetPedestalMask()[0] = 1; pedestal_g1.GetPedestalMask()[1] = 1; pedestal_g2.GetPedestalMask()[2] = 1; pedestal_g0.GetPedestalMask()[128*1024+1] = 1; pedestal_g1.GetPedestalMask()[128*1024+2] = 1; pedestal_g2.GetPedestalMask()[128*1024+3] = 1; pedestal_g0.GetPedestalMask()[256*1024+1] = 1; pedestal_g1.GetPedestalMask()[256*1024+2] = 1; pedestal_g2.GetPedestalMask()[256*1024+3] = 1; x.Mode(DetectorMode::Conversion); x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).UseInternalPacketGenerator(true).PhotonEnergy_keV(energy) .ApplyPixelMaskInFPGA(true); REQUIRE(x.GetPhotonEnergy_keV() == Approx(energy)); JFCalibration c(x); c.Pedestal(0,0) = pedestal_g0; c.Pedestal(0,1) = pedestal_g1; c.Pedestal(0,2) = pedestal_g2; c.Mask(3) = UINT32_MAX; c.Mask(128*1024+3) = UINT32_MAX; c.Mask(256*1024+3) = UINT32_MAX; HLSSimulatedDevice test(0, 64); test.SetCustomInternalGeneratorFrame(test_frame); REQUIRE_NOTHROW(test.InitializeCalibration(x, c)); REQUIRE_NOTHROW(test.StartAction(x)); REQUIRE_NOTHROW(test.WaitForActionComplete()); REQUIRE_NOTHROW(test.OutputStream().read()); REQUIRE(test.OutputStream().size() == 0); REQUIRE(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES); size_t err = 0; auto frame = test.GetFrameBuffer(0, 0); auto mask = c.CalculateMask(x); for (int i = 0; i < RAW_MODULE_SIZE; i++) { if (mask[i] && (frame[i] != INT16_MIN)) err++; if (!mask[i] && (frame[i] == INT16_MIN)) err++; } REQUIRE(err == 0); } TEST_CASE("HLS_C_Simulation_check_2_trigger_convert", "[FPGA][Full]") { std::vector pedestal_g0(RAW_MODULE_SIZE), pedestal_g1(RAW_MODULE_SIZE), pedestal_g2(RAW_MODULE_SIZE); LoadBinaryFile("../../tests/test_data/mod5_pedeG0.bin", pedestal_g0.data(), RAW_MODULE_SIZE); LoadBinaryFile("../../tests/test_data/mod5_pedeG1.bin", pedestal_g1.data(), RAW_MODULE_SIZE); LoadBinaryFile("../../tests/test_data/mod5_pedeG2.bin", pedestal_g2.data(), RAW_MODULE_SIZE); std::vector raw_frames(RAW_MODULE_SIZE*20); std::vector conv_frames(RAW_MODULE_SIZE*20); for (int i = 0; i < 20; i++) { LoadBinaryFile("../../tests/test_data/mod5_raw" + std::to_string(i)+".bin", raw_frames.data() + i * RAW_MODULE_SIZE, RAW_MODULE_SIZE); LoadBinaryFile("../../tests/test_data/mod5_conv" + std::to_string(i)+".bin", conv_frames.data() + i * RAW_MODULE_SIZE, RAW_MODULE_SIZE); } const uint16_t nmodules = 4; DiffractionExperiment x((DetectorGeometry(nmodules))); uint16_t data[4096]; x.Mode(DetectorMode::Conversion); x.PedestalG0Frames(0).NumTriggers(2).ImagesPerTrigger(5); HLSSimulatedDevice test(0, 64); JFCalibration c(x); REQUIRE_NOTHROW(c.Pedestal(0, 0).LoadPedestal(pedestal_g0)); REQUIRE_NOTHROW(c.Pedestal(0, 1).LoadPedestal(pedestal_g1)); REQUIRE_NOTHROW(c.Pedestal(0, 2).LoadPedestal(pedestal_g2)); REQUIRE_NOTHROW(c.GainCalibration(0) = GainCalibrationFromTestFile()); REQUIRE_NOTHROW(test.InitializeCalibration(x, c)); // send some frames without trigger (to be ignored) test.CreatePackets(x, 1, 10, 0, raw_frames.data(), true); test.CreateFinalPacket(x); REQUIRE_NOTHROW(test.StartAction(x)); REQUIRE(!test.Counters().IsAcquisitionFinished()); test.WaitForActionComplete(); REQUIRE(test.Counters().IsAcquisitionFinished()); // address properly aligned REQUIRE((uint64_t) test.GetFrameBuffer(0, 0) % 128 == 0); REQUIRE(test.Counters().GetSlowestHead() == 0); REQUIRE(test.Counters().GetHead(0) == 9); REQUIRE_NOTHROW(test.OutputStream().read()); REQUIRE(test.OutputStream().size() == 0); JFJochProtoBuf::AcquisitionDeviceStatistics device_statistics; REQUIRE_NOTHROW(test.SaveStatistics(x, device_statistics)); REQUIRE(device_statistics.efficiency() == Approx(0.25)); REQUIRE(device_statistics.good_packets() == 128*10); REQUIRE(device_statistics.bytes_received() == 128 * 10 * JUNGFRAU_PACKET_SIZE_BYTES); double mean_error = 0.0; for (int image = 0; image < 10; image++) { for (int j = 0; j < RAW_MODULE_SIZE; j++) { if ((test.GetFrameBuffer(image, 0)[j] < 30000) && (test.GetFrameBuffer(image, 0)[j] > -30000)) { float diff = (conv_frames[image * RAW_MODULE_SIZE + j] - (float) test.GetFrameBuffer(image, 0)[j]); mean_error += diff * diff; } } } mean_error = sqrt(mean_error/ (10*RAW_MODULE_SIZE)); std::cout << "Mean error " << mean_error << std::endl; REQUIRE(mean_error < 0.30); } TEST_CASE("HLS_C_Simulation_check_detect_last_frame", "[FPGA][Full]") { const uint16_t nmodules = 4; DiffractionExperiment x((DetectorGeometry(nmodules))); uint16_t data[4096]; x.Mode(DetectorMode::Conversion); x.PedestalG0Frames(0).NumTriggers(2).ImagesPerTrigger(5); HLSSimulatedDevice test(0, 64); test.CreatePacketJF(x, 15, 0, 0, data, true); REQUIRE_NOTHROW(test.StartAction(x)); REQUIRE(!test.Counters().IsAcquisitionFinished()); test.WaitForActionComplete(); REQUIRE(test.Counters().IsAcquisitionFinished()); REQUIRE_NOTHROW(test.OutputStream().read()); REQUIRE(test.OutputStream().size() == 0); } TEST_CASE("HLS_C_Simulation_check_wrong_packet_size", "[FPGA][Full]") { const uint16_t nmodules = 1; DiffractionExperiment x((DetectorGeometry(nmodules))); uint16_t data[8192]; x.Mode(DetectorMode::Conversion); x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(5); HLSSimulatedDevice test(0, 64); // send some frames with wrong size or tuser=1 test.CreatePacketJF(x, 1, 0, 0, data, true, 0); test.CreatePacketJF(x, 1, 1, 0, data, true, -1); test.CreatePacketJF(x, 1, 2, 0, data, true, 2); test.CreatePacketJF(x, 1, 3, 0, data, true, 0); test.CreatePacketJF(x, 1, 4, 0, data, true, -5); test.CreatePacketJF(x, 1, 5, 0, data, true, 0, 1); test.CreatePacketJF(x, 1, 6, 0, data, true, 0); test.CreatePacketJF(x, 1, 7, 0, data, true, 0); test.CreatePacketJF(x, 1, 8, 0, data, true, 7); test.CreatePacketJF(x, 1, 9, 0, data, true, 100); test.CreatePacketJF(x, 1, 10, 0, data, true, 2); test.CreatePacketJF(x, 1, 11, 0, data, true, 0); test.CreatePacketJF(x, 1, 12, 0, data, true, -80); test.CreatePacketJF(x, 1, 13, 0, data, true, 100); test.CreatePacketJF(x, 1, 118, 0, data, true, 0); test.CreateFinalPacket(x); REQUIRE_NOTHROW(test.StartAction(x)); REQUIRE(!test.Counters().IsAcquisitionFinished()); test.WaitForActionComplete(); REQUIRE(test.Counters().IsAcquisitionFinished()); REQUIRE(test.GetBytesReceived() == 6 * JUNGFRAU_PACKET_SIZE_BYTES); } TEST_CASE("HLS_DataCollectionFSM","[OpenCAPI]") { ActionConfig act_reg; STREAM_512 raw0; STREAM_512 raw1; hls::stream > addr0; hls::stream > addr1; ap_uint<1> run_data_collection = 0; ap_uint<1> cancel_data_collection = 0; ap_uint<1> idle_data_collection; uint32_t save_data_collection_counter; act_reg.mode = MODE_CONV; // state = WAIT_FOR_START data_collection_fsm(raw0, raw1, addr0, addr1, run_data_collection, cancel_data_collection, idle_data_collection, act_reg.mode, act_reg.one_over_energy, act_reg.nframes, act_reg.nmodules, act_reg.nstorage_cells); REQUIRE(idle_data_collection == 1); REQUIRE(addr1.empty()); REQUIRE(raw1.empty()); run_data_collection = 1; // state = WAIT_FOR_START data_collection_fsm(raw0, raw1, addr0, addr1, run_data_collection, cancel_data_collection, idle_data_collection, act_reg.mode, act_reg.one_over_energy, act_reg.nframes, act_reg.nmodules, act_reg.nstorage_cells); REQUIRE(idle_data_collection == 0); REQUIRE(addr1.empty()); REQUIRE(raw1.empty()); // state = WAIT_FOR_START_LOW data_collection_fsm(raw0, raw1, addr0, addr1, run_data_collection, cancel_data_collection, idle_data_collection, act_reg.mode, act_reg.one_over_energy, act_reg.nframes, act_reg.nmodules, act_reg.nstorage_cells); REQUIRE(idle_data_collection == 0); REQUIRE(addr1.empty()); REQUIRE(raw1.empty()); // state = WAIT_FOR_START_LOW run_data_collection = 0; data_collection_fsm(raw0, raw1, addr0, addr1, run_data_collection, cancel_data_collection, idle_data_collection, act_reg.mode, act_reg.one_over_energy, act_reg.nframes, act_reg.nmodules, act_reg.nstorage_cells); REQUIRE(idle_data_collection == 0); REQUIRE(addr1.empty()); REQUIRE(raw1.empty()); // state = START data_collection_fsm(raw0, raw1, addr0, addr1, run_data_collection, cancel_data_collection, idle_data_collection, act_reg.mode, act_reg.one_over_energy, act_reg.nframes, act_reg.nmodules, act_reg.nstorage_cells); REQUIRE(idle_data_collection == 0); REQUIRE(addr1.size() == 1); REQUIRE(raw1.size() == 1); // state = INIT data_collection_fsm(raw0, raw1, addr0, addr1, run_data_collection, cancel_data_collection, idle_data_collection, act_reg.mode, act_reg.one_over_energy, act_reg.nframes, act_reg.nmodules, act_reg.nstorage_cells); REQUIRE(idle_data_collection == 0); REQUIRE(addr1.size() == 1); REQUIRE(raw1.size() == 1); // state = INIT cancel_data_collection = 1; data_collection_fsm(raw0, raw1, addr0, addr1, run_data_collection, cancel_data_collection, idle_data_collection, act_reg.mode, act_reg.one_over_energy, act_reg.nframes, act_reg.nmodules, act_reg.nstorage_cells); REQUIRE(idle_data_collection == 0); REQUIRE(addr1.size() == 1); REQUIRE(raw1.size() == 1); // state = LAST data_collection_fsm(raw0, raw1, addr0, addr1, run_data_collection, cancel_data_collection, idle_data_collection, act_reg.mode, act_reg.one_over_energy, act_reg.nframes, act_reg.nmodules, act_reg.nstorage_cells); REQUIRE(idle_data_collection == 0); REQUIRE(addr1.size() == 2); REQUIRE(raw1.size() == 2); // state = WAIT_FOR_START data_collection_fsm(raw0, raw1, addr0, addr1, run_data_collection, cancel_data_collection, idle_data_collection, act_reg.mode, act_reg.one_over_energy, act_reg.nframes, act_reg.nmodules, act_reg.nstorage_cells); REQUIRE(idle_data_collection == 1); REQUIRE(addr1.size() == 2); REQUIRE(raw1.size() == 2); auto packet = raw1.read(); REQUIRE(packet.last == 0); REQUIRE(packet.dest == 0); packet = raw1.read(); REQUIRE(packet.last); REQUIRE(packet.dest == 0); auto addr = addr1.read(); addr = addr1.read(); REQUIRE(addr_last_flag(addr)); } TEST_CASE("HLS_C_Simulation_internal_packet_generator_storage_cell_convert_G0", "[FPGA][Full]") { const uint16_t nmodules = 2; DiffractionExperiment x((DetectorGeometry(nmodules))); x.Mode(DetectorMode::Conversion); x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(16).UseInternalPacketGenerator(true) .PhotonEnergy_keV(10.0).StorageCells(16); HLSSimulatedDevice test(0, 64); std::vector tmp(3 * RAW_MODULE_SIZE, 50); JFModuleGainCalibration gain(tmp); std::vector data(RAW_MODULE_SIZE); for (auto &i: data) i = 16000; REQUIRE_NOTHROW(test.SetCustomInternalGeneratorFrame(data)); JFCalibration c(x); for (int i = 0; i < 16; i++) { for (int j = 0; j < RAW_MODULE_SIZE; j++) { c.Pedestal(0, 0, i).GetPedestal()[j] = (15 - i) * 500; c.Pedestal(1, 0, i).GetPedestal()[j] = i * 1000; } } c.GainCalibration(0) = gain; c.GainCalibration(1) = gain; REQUIRE_NOTHROW(test.InitializeCalibration(x, c)); REQUIRE_NOTHROW(test.StartAction(x)); REQUIRE_NOTHROW(test.WaitForActionComplete()); REQUIRE_NOTHROW(test.OutputStream().read()); REQUIRE(test.OutputStream().size() == 0); REQUIRE(test.GetBytesReceived() == 2*16*128 * JUNGFRAU_PACKET_SIZE_BYTES); for (int i = 0; i < 16; i++) { REQUIRE(test.GetFrameBuffer(i,0)[511*764] == 32 - 15 + (i % 16)); REQUIRE(test.GetFrameBuffer(i,1)[200*145] == 32 - 2 * (i % 16)); } } TEST_CASE("HLS_C_Simulation_internal_packet_generator_storage_cell_convert_G1", "[FPGA][Full]") { const uint16_t nmodules = 2; DiffractionExperiment x((DetectorGeometry(nmodules))); x.Mode(DetectorMode::Conversion); x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(16).UseInternalPacketGenerator(true) .PhotonEnergy_keV(10.0).StorageCells(16); HLSSimulatedDevice test(0, 64); std::vector data(RAW_MODULE_SIZE); for (auto &i: data) i = 16384 | 10; REQUIRE_NOTHROW(test.SetCustomInternalGeneratorFrame(data)); JFCalibration c(x); for (int i = 0; i < 16; i++) { for (int j = 0; j < RAW_MODULE_SIZE; j++) { c.Pedestal(0, 1, i).GetPedestal()[j] = (17 - i) * 10; c.Pedestal(1, 1, i).GetPedestal()[j] = i * 20; } } std::vector tmp(3 * RAW_MODULE_SIZE, -1); JFModuleGainCalibration gain(tmp); c.GainCalibration(0) = gain; c.GainCalibration(1) = gain; REQUIRE_NOTHROW(test.InitializeCalibration(x, c)); REQUIRE_NOTHROW(test.StartAction(x)); REQUIRE_NOTHROW(test.WaitForActionComplete()); REQUIRE_NOTHROW(test.OutputStream().read()); REQUIRE(test.OutputStream().size() == 0); REQUIRE(test.GetBytesReceived() == 32*128*JUNGFRAU_PACKET_SIZE_BYTES); for (int i = 0; i < 16; i++) { REQUIRE(test.GetFrameBuffer(i,0)[511*764] == 17 - (i % 16) - 1); REQUIRE(test.GetFrameBuffer(i,1)[200*145] == 2 * (i % 16) - 1); } }