From 021e652dc67f2a14ed34cc66a40cfe8eae8156d1 Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Fri, 26 May 2023 16:11:07 +0200 Subject: [PATCH] FPGA: non-blocking mode (to be tested) --- common/Definitions.h | 4 ++ receiver/hls/host_writer.cpp | 67 +++++++++++++++-------------- receiver/host/AcquisitionDevice.cpp | 6 ++- receiver/host/AcquisitionDevice.h | 2 + receiver/host/Completion.cpp | 5 ++- tests/FPGAIntegrationTest.cpp | 20 +++++++++ 6 files changed, 69 insertions(+), 35 deletions(-) diff --git a/common/Definitions.h b/common/Definitions.h index db35df5f..45c43863 100644 --- a/common/Definitions.h +++ b/common/Definitions.h @@ -118,4 +118,8 @@ #define CTRL_REGISTER_IDLE (1<<1u) +#define HANDLE_START (UINT32_MAX - 1) +#define HANDLE_SKIP_FRAME (UINT32_MAX - 2) +#define HANDLE_END (UINT32_MAX ) + #endif //DEFINITIONS_H diff --git a/receiver/hls/host_writer.cpp b/receiver/hls/host_writer.cpp index 3dc17bfc..6167b0b9 100644 --- a/receiver/hls/host_writer.cpp +++ b/receiver/hls/host_writer.cpp @@ -8,18 +8,17 @@ #endif #define PACKET_SIZE 8192 -#define HANDLE_SKIP_FRAME (UINT32_MAX - 1) inline void write_completion(hls::stream > &m_axis_completion, - const ap_uint<32> &handle, - const ap_uint<8> &module, - const ap_uint<64> &frame_num, - const ap_uint<256> &packet_mask, - const ap_uint<16> &packet_count, - const ap_uint<32> &debug, - const ap_uint<64> ×tamp, - const ap_uint<64> &bunchid, - const ap_uint<32> &exptime) { + const ap_uint<32> &handle, + const ap_uint<8> &module_number, + const ap_uint<64> &frame_num, + const ap_uint<256> &packet_mask, + const ap_uint<16> &packet_count, + const ap_uint<32> &debug, + const ap_uint<64> ×tamp, + const ap_uint<64> &bunchid, + const ap_uint<32> &exptime) { #pragma HLS INLINE ap_uint<1> all_packets_ok = packet_mask.and_reduce(); ap_uint<1> any_packets_received = packet_mask.or_reduce(); @@ -27,28 +26,32 @@ inline void write_completion(hls::stream > &m_axis_completion, status[0] = all_packets_ok; status[1] = any_packets_received; - ap_uint<128> tmp = (handle, packet_count, status, module, frame_num); + ap_uint<128> tmp = (handle, packet_count, status, module_number, frame_num); status[7] = tmp.xor_reduce(); // ensure completion has even parity - m_axis_completion << handle; - m_axis_completion << (packet_count, status, module); - m_axis_completion << frame_num(63, 32); - m_axis_completion << frame_num(31, 0); + if (handle != HANDLE_SKIP_FRAME) { + m_axis_completion << handle; + m_axis_completion << (packet_count, status, module_number); + m_axis_completion << frame_num(63, 32); + m_axis_completion << frame_num(31, 0); - m_axis_completion << timestamp(63,32); - m_axis_completion << timestamp(31,0); - m_axis_completion << bunchid(63,32); - m_axis_completion << bunchid(31,0); + m_axis_completion << timestamp(63,32); + m_axis_completion << timestamp(31,0); + m_axis_completion << bunchid(63,32); + m_axis_completion << bunchid(31,0); - m_axis_completion << exptime; - m_axis_completion << debug; - m_axis_completion << 0; - m_axis_completion << 0; + m_axis_completion << + exptime; + m_axis_completion << + debug; + m_axis_completion << 0; + m_axis_completion << 0; - m_axis_completion << packet_mask(127,96); - m_axis_completion << packet_mask( 95,64); - m_axis_completion << packet_mask( 63,32); - m_axis_completion << packet_mask( 31, 0); + m_axis_completion << packet_mask(127,96); + m_axis_completion << packet_mask( 95,64); + m_axis_completion << packet_mask( 63,32); + m_axis_completion << packet_mask( 31, 0); + } } @@ -130,12 +133,12 @@ void host_writer(STREAM_512 &data_in, packet_512_t packet_in; data_in >> packet_in; ap_uint<32> data_collection_mode = ACT_REG_MODE(packet_in.data); - ap_uint<1> mode_nonblocking = data_collection_mode & MODE_NONBLOCKING_ON_WR; + ap_uint<1> mode_nonblocking = (data_collection_mode & MODE_NONBLOCKING_ON_WR) ? 1 : 0; ap_uint<8> internal_err_reg = 0; err_reg = internal_err_reg; - write_completion(m_axis_completion, UINT32_MAX - 1, 0, 0, 0, 0, 0, 0, 0, 0); + write_completion(m_axis_completion, HANDLE_START, 0, 0, 0, 0, 0, 0, 0, 0); uint64_t total_counter = 0; packets_processed = 0; @@ -161,7 +164,7 @@ void host_writer(STREAM_512 &data_in, ap_uint<5> id = module * 2 + (frame_number % 2); if (curr_frame[id] != frame_number) { - if ((packet_mask[id] != 0) && (handle[id] != HANDLE_SKIP_FRAME)) { + if (packet_mask[id] != 0) { ap_uint<32> comp_handle = handle[id]; ap_uint<64> comp_frame = curr_frame[id]; ap_uint<256> comp_packet_mask = packet_mask[id]; @@ -185,7 +188,7 @@ void host_writer(STREAM_512 &data_in, internal_err_reg[2] = 1; } - if (req_handle == UINT32_MAX) + if (req_handle >= HANDLE_START) internal_err_reg[4] = 1; handle[id] = req_handle; @@ -248,7 +251,7 @@ void host_writer(STREAM_512 &data_in, data_in >> packet_in; - write_completion(m_axis_completion, UINT32_MAX, 0, total_counter, 0, 0, 0, 0, 0, 0); + write_completion(m_axis_completion, HANDLE_END, 0, total_counter, 0, 0, 0, 0, 0, 0); read_request(s_axis_work_request, req_handle, req_host_offset); diff --git a/receiver/host/AcquisitionDevice.cpp b/receiver/host/AcquisitionDevice.cpp index 1426dd57..eaf55551 100644 --- a/receiver/host/AcquisitionDevice.cpp +++ b/receiver/host/AcquisitionDevice.cpp @@ -58,7 +58,7 @@ void AcquisitionDevice::FillActionRegister(const DiffractionExperiment& x, Actio job.nframes = x.GetFrameNum(); job.one_over_energy = std::lround((1<<20)/ x.GetPhotonEnergy_keV()); job.nstorage_cells = x.GetStorageCellNumber() - 1; - job.mode = 0; + job.mode = fpga_non_blocking_mode ? MODE_NONBLOCKING_ON_WR : 0; if ((x.GetDetectorMode() == DetectorMode::Conversion) && x.GetConversionOnFPGA()) job.mode |= MODE_CONV; @@ -434,4 +434,8 @@ uint32_t AcquisitionDevice::GetExptime(size_t curr_frame, uint16_t module_number uint64_t AcquisitionDevice::GetTimestamp(size_t curr_frame, uint16_t module_number) const { return counters.GetTimestamp(curr_frame, module_number); +} + +void AcquisitionDevice::SetFPGANonBlockingMode(bool input) { + fpga_non_blocking_mode = input; } \ No newline at end of file diff --git a/receiver/host/AcquisitionDevice.h b/receiver/host/AcquisitionDevice.h index e75ccb89..c8b7eb58 100644 --- a/receiver/host/AcquisitionDevice.h +++ b/receiver/host/AcquisitionDevice.h @@ -27,6 +27,7 @@ void *mmap_acquisition_buffer(size_t size, int16_t numa_node); class AcquisitionDevice { uint64_t bytes_received = 0; + bool fpga_non_blocking_mode = true; std::vector buffer_err; @@ -122,6 +123,7 @@ public: std::string GetMACAddress() const; virtual uint16_t GetUDPPort() const; virtual int32_t GetNUMANode() const; + void SetFPGANonBlockingMode(bool input); }; diff --git a/receiver/host/Completion.cpp b/receiver/host/Completion.cpp index f64a0056..7b1cddb4 100644 --- a/receiver/host/Completion.cpp +++ b/receiver/host/Completion.cpp @@ -5,6 +5,7 @@ #include "Completion.h" #include "../../common/JFJochException.h" +#include "../../common/Definitions.h" inline uint64_t bit_concat(uint32_t high, uint32_t low) { return (uint64_t(high) << 32) | low; @@ -25,9 +26,9 @@ Completion parse_hw_completion(uint32_t tmp[16]) { if (parity == 1) throw JFJochException(JFJochExceptionCategory::HardwareParityError, "Wrong parity in work completion"); - if (c.handle == UINT32_MAX -1) { + if (c.handle == HANDLE_START) { c.type = Completion::Type::Start; - } else if (c.handle == UINT32_MAX) { + } else if (c.handle == HANDLE_END) { c.type = Completion::Type::End; c.frame_number = detector_frame_number; } else { diff --git a/tests/FPGAIntegrationTest.cpp b/tests/FPGAIntegrationTest.cpp index 1647bc37..116fde64 100644 --- a/tests/FPGAIntegrationTest.cpp +++ b/tests/FPGAIntegrationTest.cpp @@ -39,6 +39,26 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator", "[FPGA][Full]") { } } +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;