* Enhancements for XFEL

* Enhancements for EIGER
* Writer is more flexible and capable of handling DECTRIS data
This commit is contained in:
2024-03-05 20:41:47 +01:00
parent 71d862b706
commit d315506633
165 changed files with 5440 additions and 2230 deletions
+33 -2
View File
@@ -18,7 +18,7 @@ build:x86:gcc:
- cd build
- source /opt/rh/gcc-toolset-12/enable
- cmake -DCMAKE_BUILD_TYPE=Release ..
- make -j48 jfjoch
- make -j48
build:x86:gcc_writer:
stage: build
@@ -223,6 +223,37 @@ synthesis:vivado_pcie_100g:
- mkdir -p build
- cd build
- /usr/bin/cmake ..
- make action_pcie
- make pcie_100g
- mv fpga/*.mcs ..
needs: ["build:x86:gcc", "build:x86:vitis_hls", "test:x86:gcc"]
synthesis:vivado_pcie_8x10g:
stage: synthesis
variables:
GIT_SUBMODULE_STRATEGY: recursive
CC: gcc
CXX: g++
allow_failure: true
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
changes:
- fpga/hls/*
- fpga/hdl/*
- fpga/scripts/*
- fpga/xdc/*
- fpga/include/jfjoch_fpga.h
tags:
- vivado
artifacts:
paths:
- "*.mcs"
expire_in: 1 week
script:
- source /opt/rh/gcc-toolset-12/enable
- source /opt/Xilinx/Vivado/2022.1/settings64.sh
- mkdir -p build
- cd build
- /usr/bin/cmake ..
- make pcie_8x10g
- mv fpga/*.mcs ..
needs: [ "build:x86:gcc", "build:x86:vitis_hls", "test:x86:gcc" ]
+1
View File
@@ -1,6 +1,7 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.19)
PROJECT(Jungfraujoch VERSION 1.0 LANGUAGES C CXX)
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
SET(CMAKE_CXX_STANDARD 20)
SET(CMAKE_CXX_STANDARD_REQUIRED True)
+1 -3
View File
@@ -30,12 +30,11 @@ Required:
* C++20 compiler and C++20 standard library; recommended GCC 11+ or clang 14+ (Intel OneAPI, AMD AOCC)
* CMake version 3.21 or newer + GNU make tool
* HDF5 library version 1.10 or newer
* OpenSSL library
* TIFF library (with C++ headers)
* JPEG library (turbo-jpeg is also OK)
Optional:
* CUDA compiler version 11 or newer - image analysis features won't work without it
* CUDA compiler version 11 or newer - MX indexing won't work without it
* NUMA library
* Node.js - to make frontend
* libtorch - for resolution estimation using model from Stanford - see below
@@ -103,4 +102,3 @@ Version 2.1.0 can be downloaded with the following command:
```
wget https://download.pytorch.org/libtorch/cu121/libtorch-cxx11-abi-shared-with-deps-2.1.0%2Bcu121.zip
```
+2 -2
View File
@@ -35,7 +35,7 @@ void AcquisitionCounters::Reset(const DiffractionExperiment &experiment, uint16_
saved_completions = std::vector<Completion>(expected_frames * nmodules);
packets_per_module = std::vector<uint64_t>(nmodules);
total_packets = 0;
expected_packets_per_module = 128 * experiment.GetSummation();
expected_packets_per_module = 256 * experiment.GetSummation();
}
void AcquisitionCounters::UpdateCounters(const Completion *c) {
@@ -201,7 +201,7 @@ uint64_t AcquisitionCounters::GetTotalPackets(uint16_t module_number) const {
if (module_number >= nmodules)
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds,
"GetTotalPackets Wrong module number: " + std::to_string(module_number));\
"GetTotalPackets Wrong module number: " + std::to_string(module_number));
return packets_per_module[module_number];
}
+15 -7
View File
@@ -141,7 +141,7 @@ void AcquisitionDevice::SendWorkRequest(uint32_t handle) {
}
uint64_t AcquisitionDevice::GetBytesReceived() const {
return counters.GetTotalPackets() * 8192LU;
return counters.GetTotalPackets() * 4096LU;
}
const DeviceOutput *AcquisitionDevice::GetDeviceOutput(size_t frame_number, uint16_t module_number) const {
@@ -176,15 +176,15 @@ DeviceOutput *AcquisitionDevice::GetDeviceOutput(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::InitializeIntegrationMap(const DiffractionExperiment &experiment,
const std::vector<uint16_t> &v,
const std::vector<float> &weights) {}
void AcquisitionDevice::InitializeSpotFinderResolutionMap(const DiffractionExperiment &experiment,
const std::vector<float> &v) {}
void AcquisitionDevice::InitializeIntegrationMap(const uint16_t *map, const float *weights, size_t module_number) {}
void AcquisitionDevice::InitializeSpotFinderResolutionMap(const float *data, size_t module_number) {}
void AcquisitionDevice::InitializeROIMap(const uint16_t *map, size_t module_number) {}
void AcquisitionDevice::MapBuffersStandard(size_t c2h_buffer_count, int16_t numa_node) {
try {
@@ -286,11 +286,19 @@ void AcquisitionDevice::RunInternalGenerator(const DiffractionExperiment &experi
FrameGeneratorConfig config{};
config.frames = experiment.GetFrameNum() + DELAY_FRAMES_STOP_AND_QUIT + 1;
config.modules = experiment.GetModulesNum(data_stream);
config.bunchid = INT_PKT_GEN_BUNCHID;
config.pulse_id = INT_PKT_GEN_BUNCHID;
config.exptime = INT_PKT_GEN_EXPTTIME;
config.debug = INT_PKT_GEN_DEBUG;
config.dest_mac_addr = MacAddressFromStr(GetMACAddress());
config.dest_ipv4_addr = IPv4AddressFromStr(GetIPv4Address());
switch (experiment.GetDetectorSetup().GetDetectorType()) {
case DetectorType::JUNGFRAU:
config.detector_type = SLS_DETECTOR_TYPE_JUNGFRAU;
break;
case DetectorType::EIGER:
config.detector_type = SLS_DETECTOR_TYPE_EIGER;
break;
}
HW_RunInternalGenerator(config);
}
+6 -6
View File
@@ -31,7 +31,7 @@ struct AcquisitionDeviceStatistics {
std::vector<uint64_t> packets_received_per_module;
};
enum class AcquisitionDeviceSource {MAC_100G, MAC_4x10G, FRAME_GENERATOR, NONE};
enum class AcquisitionDeviceSource {NETWORK, FRAME_GENERATOR, NONE};
class AcquisitionDevice {
std::chrono::time_point<std::chrono::system_clock> start_time;
@@ -92,10 +92,12 @@ public:
// Calibration
virtual void InitializeCalibration(const DiffractionExperiment &experiment, const JFCalibration &calib);
virtual void InitializeIntegrationMap(const DiffractionExperiment &experiment, const std::vector<uint16_t> &v);
virtual void InitializeIntegrationMap(const DiffractionExperiment &experiment, const std::vector<uint16_t> &v,
const std::vector<float> &weights);
virtual void InitializeSpotFinderResolutionMap(const DiffractionExperiment &experiment, const std::vector<float>& v);
virtual void InitializeIntegrationMap(const uint16_t *map, const float *weights, size_t module_number);
virtual void InitializeSpotFinderResolutionMap(const float *data, size_t module_number);
virtual void InitializeROIMap(const uint16_t *map, size_t module_number);
const AcquisitionCounters& Counters() const;
void SetSpotFinderParameters(const SpotFindingSettings &settings);
@@ -105,9 +107,7 @@ public:
virtual std::string GetMACAddress() const;
virtual uint16_t GetUDPPort() const;
virtual int32_t GetNUMANode() const;
virtual std::vector<uint16_t> GetInternalGeneratorFrame() const {
return {};
}
virtual void SetInternalGeneratorFrame(const uint16_t *input, size_t module_number) {}
virtual void SetDefaultDataSource(AcquisitionDeviceSource id);
virtual AcquisitionDeviceSource GetDataSource();
+33 -121
View File
@@ -2,6 +2,7 @@
#include <random>
#include "FPGAAcquisitionDevice.h"
#include "../common/DiffractionGeometry.h"
void FPGAAcquisitionDevice::StartSendingWorkRequests() {
stop_work_requests = false;
@@ -82,27 +83,11 @@ void FPGAAcquisitionDevice::SendWorkRequestThread() {
}
}
void FPGAAcquisitionDevice::InitializeSpotFinderResolutionMap(const DiffractionExperiment &experiment, const std::vector<float> &v) {
auto offset = experiment.GetFirstModuleOfDataStream(data_stream);
size_t modules = experiment.GetModulesNum(data_stream);
if (v.size() != experiment.GetModulesNum() * RAW_MODULE_SIZE)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Mismatch regarding integration map array");
for (uint32_t m = 0; m < modules; m++) {
memcpy(buffer_device[0]->pixels, v.data() + (offset + m) * RAW_MODULE_SIZE, RAW_MODULE_SIZE * sizeof(float));
buffer_device[0]->module_statistics.module_number = m;
buffer_device[0]->module_statistics.load_calibration_destination
= LOAD_CALIBRATION_DEST_SPOT_FINDER_RESOLUTION_MAP;
LoadCalibration(0);
}
}
void FPGAAcquisitionDevice::InitializeIntegrationMap(const DiffractionExperiment &experiment,
const std::vector<uint16_t> &v) {
std::vector<float> weights(experiment.GetModulesNum() * RAW_MODULE_SIZE, 1.0);
InitializeIntegrationMap(experiment, v, weights);
void FPGAAcquisitionDevice::InitializeSpotFinderResolutionMap(const float *data, size_t module_number) {
memcpy(buffer_device[0]->pixels, data, RAW_MODULE_SIZE * sizeof(float));
buffer_device[0]->module_statistics.module_number = module_number;
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_SPOT_FINDER_RES_MAP;
LoadCalibration(0);
}
void FPGAAcquisitionDevice::InitializeIntegrationMap(const DiffractionExperiment &experiment,
@@ -120,93 +105,36 @@ void FPGAAcquisitionDevice::InitializeIntegrationMap(const DiffractionExperiment
"Mismatch regarding weights array");
for (uint32_t m = 0; m < modules; m++) {
memcpy(buffer_device[0]->pixels, v.data() + (offset + m) * RAW_MODULE_SIZE, RAW_MODULE_SIZE * sizeof(uint16_t));
buffer_device[0]->module_statistics.module_number = m;
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_INTEGRATION_MAP;
LoadCalibration(0);
}
for (uint32_t m = 0; m < modules; m++) {
for (int i = 0; i < RAW_MODULE_SIZE; i++)
((float *)buffer_device[0]->pixels)[i] = weights[(offset + m) * RAW_MODULE_SIZE + i];
buffer_device[0]->module_statistics.module_number = m;
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_INTEGRATION_WEIGHTS;
LoadCalibration(0);
InitializeIntegrationMap(v.data() + (offset + m) * RAW_MODULE_SIZE,
weights.data() + (offset + m) * RAW_MODULE_SIZE,
m);
}
}
void FPGAAcquisitionDevice::SetInternalGeneratorFrameForAllModules(const std::vector<uint16_t> &v) {
if (v.size() != RAW_MODULE_SIZE) {
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Error in size of custom internal generator frame");
}
void FPGAAcquisitionDevice::InitializeIntegrationMap(const uint16_t *map, const float *weights, size_t module_number) {
memcpy(buffer_device[0]->pixels, map, RAW_MODULE_SIZE * sizeof(uint16_t));
buffer_device[0]->module_statistics.module_number = module_number;
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_INTEGRATION_MAP;
LoadCalibration(0);
for (int m = 0; m < max_modules; m++) {
memcpy(internal_pkt_gen_frame.data() + m * RAW_MODULE_SIZE,
v.data(), RAW_MODULE_SIZE * sizeof(uint16_t));
}
memcpy(buffer_device[0]->pixels, internal_pkt_gen_frame.data(), RAW_MODULE_SIZE * sizeof(uint16_t));
memcpy(buffer_device[0]->pixels, weights, RAW_MODULE_SIZE * sizeof(float));
buffer_device[0]->module_statistics.module_number = module_number;
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_INTEGRATION_WEIGHTS;
LoadCalibration(0);
}
void FPGAAcquisitionDevice::SetInternalGeneratorFrame(const uint16_t *input, size_t module_number) {
memcpy(buffer_device[0], input, RAW_MODULE_SIZE * sizeof(uint16_t));
buffer_device[0]->module_statistics.module_number = module_number;
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_FRAME_GEN;
for (uint32_t m = 0; m < max_modules; m++) {
buffer_device[0]->module_statistics.module_number = m;
LoadCalibration(0);
}
LoadCalibration(0);
}
void FPGAAcquisitionDevice::SetInternalGeneratorFrame(const std::vector<uint16_t> &v) {
if (v.empty() || (v.size() % RAW_MODULE_SIZE != 0)) {
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Error in size of custom internal generator frame");
}
size_t nmodules = v.size() / RAW_MODULE_SIZE;
if (nmodules > max_modules) {
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Max number of modules exceeded");
}
memcpy(internal_pkt_gen_frame.data(), v.data(), nmodules * RAW_MODULE_SIZE * sizeof(uint16_t));
if (nmodules > buffer_device.size())
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Not enough host/FPGA buffers to load all integration map values");
for (uint32_t m = 0; m < nmodules; m++) {
memcpy(buffer_device[0], internal_pkt_gen_frame.data() + m * RAW_MODULE_SIZE,
RAW_MODULE_SIZE * sizeof(uint16_t));
buffer_device[0]->module_statistics.module_number = m;
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_FRAME_GEN;
LoadCalibration(0);
}
}
void FPGAAcquisitionDevice::SetInternalGeneratorFrame(const std::vector<int16_t> &v) {
if (v.empty() || (v.size() % RAW_MODULE_SIZE != 0)) {
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Error in size of custom internal generator frame");
}
size_t nmodules = v.size() / RAW_MODULE_SIZE;
if (nmodules > max_modules) {
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Max number of modules exceeded");
}
memcpy(internal_pkt_gen_frame.data(), v.data(), nmodules * RAW_MODULE_SIZE * sizeof(int16_t));
if (nmodules > buffer_device.size())
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Not enough host/FPGA buffers to load all integration map values");
for (uint32_t m = 0; m < nmodules; m++) {
memcpy(buffer_device[0], internal_pkt_gen_frame.data() + m * RAW_MODULE_SIZE, RAW_MODULE_SIZE * sizeof(int16_t));
buffer_device[0]->module_statistics.module_number = m;
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_FRAME_GEN;
LoadCalibration(0);
}
void FPGAAcquisitionDevice::InitializeROIMap(const uint16_t *map, size_t module_number) {
memcpy(buffer_device[0]->pixels, map, RAW_MODULE_SIZE * sizeof(uint16_t));
buffer_device[0]->module_statistics.module_number = module_number;
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_ROI_CALC;
LoadCalibration(0);
}
void FPGAAcquisitionDevice::InitializeCalibration(const DiffractionExperiment &experiment, const JFCalibration &calib) {
@@ -303,7 +231,7 @@ void FPGAAcquisitionDevice::FillActionRegister(const DiffractionExperiment& x, D
job.nmodules = x.GetModulesNum(data_stream) - 1;
job.nframes = x.GetFrameNum();
job.energy_kev = x.GetPhotonEnergy_keV();
job.energy_kev = x.GetPhotonEnergyForConversion_keV();
job.nstorage_cells = x.GetStorageCellNumber() - 1;
job.mode = data_collection_id << 16;
job.nsummation = x.GetSummation() - 1;
@@ -371,17 +299,6 @@ void FPGAAcquisitionDevice::Start(const DiffractionExperiment &experiment, uint3
read_work_completion_future = std::async(std::launch::async, &FPGAAcquisitionDevice::ReadWorkCompletionThread, this);
}
std::vector<uint16_t> FPGAAcquisitionDevice::GetInternalGeneratorFrame() const {
return internal_pkt_gen_frame;
}
void FPGAAcquisitionDevice::SetInternalGeneratorFrame() {
std::vector<uint16_t> tmp(RAW_MODULE_SIZE);
for (int i = 0; i < RAW_MODULE_SIZE; i++)
tmp[i] = i % 65536;
SetInternalGeneratorFrameForAllModules(tmp);
}
FPGAAcquisitionDevice::FPGAAcquisitionDevice(uint16_t data_stream)
: AcquisitionDevice(data_stream),
internal_pkt_gen_frame(RAW_MODULE_SIZE * MAX_MODULES_FPGA) {
@@ -389,10 +306,8 @@ FPGAAcquisitionDevice::FPGAAcquisitionDevice(uint16_t data_stream)
AcquisitionDeviceSource FPGAAcquisitionDevice::GetDataSource() {
switch (HW_GetDataSource()) {
case STREAM_MERGE_SRC_100G:
return AcquisitionDeviceSource::MAC_100G;
case STREAM_MERGE_SRC_4x10G:
return AcquisitionDeviceSource::MAC_4x10G;
case STREAM_MERGE_SRC_NETWORK:
return AcquisitionDeviceSource::NETWORK;
case STREAM_MERGE_SRC_FRAME_GEN:
return AcquisitionDeviceSource::FRAME_GENERATOR;
default:
@@ -407,11 +322,8 @@ void FPGAAcquisitionDevice::SetDefaultDataSource(AcquisitionDeviceSource id) {
void FPGAAcquisitionDevice::SetDataSource(AcquisitionDeviceSource id) {
switch (id) {
case AcquisitionDeviceSource::MAC_100G:
HW_SetDataSource(STREAM_MERGE_SRC_100G);
break;
case AcquisitionDeviceSource::MAC_4x10G:
HW_SetDataSource(STREAM_MERGE_SRC_4x10G);
case AcquisitionDeviceSource::NETWORK:
HW_SetDataSource(STREAM_MERGE_SRC_NETWORK);
break;
case AcquisitionDeviceSource::FRAME_GENERATOR:
HW_SetDataSource(STREAM_MERGE_SRC_FRAME_GEN);
+5 -9
View File
@@ -10,7 +10,7 @@ class FPGAAcquisitionDevice : public AcquisitionDevice {
uint16_t data_collection_id = 0;
uint32_t expected_descriptors_per_module = 1;
AcquisitionDeviceSource default_data_source = AcquisitionDeviceSource::MAC_100G;
AcquisitionDeviceSource default_data_source = AcquisitionDeviceSource::NETWORK;
virtual void FPGA_StartAction(const DiffractionExperiment &experiment) = 0;
virtual void FPGA_EndAction() = 0;
@@ -41,22 +41,18 @@ class FPGAAcquisitionDevice : public AcquisitionDevice {
protected:
std::vector<uint16_t> internal_pkt_gen_frame;
explicit FPGAAcquisitionDevice(uint16_t data_stream);
virtual void HW_GetStatus(DataCollectionStatus *status) const = 0;
virtual void HW_GetEnvParams(DeviceStatus *status) const {
memset(status, 0, sizeof(DeviceStatus));
}
public:
void InitializeCalibration(const DiffractionExperiment &experiment, const JFCalibration &calib) override;
void InitializeIntegrationMap(const DiffractionExperiment &experiment, const std::vector<uint16_t> &v) override;
void InitializeIntegrationMap(const DiffractionExperiment &experiment, const std::vector<uint16_t> &v,
const std::vector<float> &weights) override;
void InitializeSpotFinderResolutionMap(const DiffractionExperiment &experiment, const std::vector<float>& v);
void SetInternalGeneratorFrame(const std::vector<uint16_t> &v);
void SetInternalGeneratorFrame(const std::vector<int16_t> &v);
void InitializeIntegrationMap(const uint16_t *map, const float *weights, size_t module_number) override;
void InitializeSpotFinderResolutionMap(const float *data, size_t module_number) override;
void InitializeROIMap(const uint16_t *map, size_t module_number) override;
void SetInternalGeneratorFrame(const uint16_t *input, size_t module_number) override;
void SetInternalGeneratorFrameForAllModules(const std::vector<uint16_t> &v);
void SetInternalGeneratorFrame();
std::vector<uint16_t> GetInternalGeneratorFrame() const override;
AcquisitionDeviceSource GetDataSource() override;
void SetDefaultDataSource(AcquisitionDeviceSource id) override;
uint32_t GetExpectedDescriptorsPerModule() const override;
+210 -131
View File
@@ -53,7 +53,7 @@ HLSSimulatedDevice::HLSSimulatedDevice(uint16_t data_stream, size_t in_frame_buf
}
void HLSSimulatedDevice::CreateFinalPacket(const DiffractionExperiment& experiment) {
CreatePacketJF(experiment, UINT64_MAX, 0, 0, nullptr, false);
CreateJFPacket(experiment, UINT64_MAX, 0, 0, nullptr, false);
}
void HLSSimulatedDevice::SendPacket(char *buffer, int len, uint8_t user) {
@@ -68,11 +68,10 @@ void HLSSimulatedDevice::SendPacket(char *buffer, int len, uint8_t user) {
packet_in.data = obuff[i];
din_eth.write(packet_in);
}
}
void HLSSimulatedDevice::CreatePacketJF(const DiffractionExperiment& experiment, uint64_t frame_number, uint32_t eth_packet,
uint32_t module_number, const uint16_t *data, bool trigger, int8_t adjust_axis, uint8_t user) {
void HLSSimulatedDevice::CreateJFPacket(const DiffractionExperiment& experiment, uint64_t frame_number, uint32_t eth_packet,
uint32_t module_number, const uint16_t *data, int8_t adjust_axis, uint8_t user) {
char buff[256*64];
memset(buff, 0, 256*64);
@@ -100,12 +99,13 @@ void HLSSimulatedDevice::CreatePacketJF(const DiffractionExperiment& experiment,
packet->udp_length = htons(8248);
// JF headers are little endian
packet->jf.detectortype = SLS_DETECTOR_TYPE_JUNGFRAU;
packet->jf.timestamp = 0xABCDEF0000FEDCBAL;
packet->jf.bunchid = 0x1234567898765431L;
packet->jf.xCoord = half_module;
packet->jf.row = half_module;
packet->jf.column = 0;
packet->jf.framenum = frame_number;
packet->jf.packetnum = eth_packet % 64;
if (trigger) packet->jf.debug = 1<<31;
if (data != nullptr) {
for (int i = 0; i < 4096; i++)
packet->jf.data[i] = data[i];
@@ -115,16 +115,58 @@ void HLSSimulatedDevice::CreatePacketJF(const DiffractionExperiment& experiment,
SendPacket(buff, (130+adjust_axis)*64, user);
}
void HLSSimulatedDevice::CreatePackets(const DiffractionExperiment& experiment, uint64_t frame_number_0, uint64_t frames,
uint32_t module_number, const uint16_t *data, bool trigger, int8_t adjust_axis,
uint8_t user) {
void HLSSimulatedDevice::CreateJFPackets(const DiffractionExperiment& experiment, uint64_t frame_number_0, uint64_t frames,
uint32_t module_number, const uint16_t *data) {
for (uint64_t i = 0; i < frames; i++) {
for (int j = 0; j < 128; j++)
CreatePacketJF(experiment, frame_number_0 + i, j, module_number, data + (i * 128 + j) * 4096, trigger, adjust_axis,
user);
CreateJFPacket(experiment, frame_number_0 + i, j, module_number, data + (i * 128 + j) * 4096, 0, 0);
}
}
void HLSSimulatedDevice::CreateEIGERPacket(const DiffractionExperiment &experiment, uint64_t frame_number,
uint32_t eth_packet, uint32_t module_number, uint32_t col, uint32_t row,
const uint16_t *data) {
char buff[256*64];
memset(buff, 0, 256*64);
auto packet = (eiger_raw_packet *)buff;
packet->ether_type = htons(0x0800);
packet->sour_mac[0] = 0x00; // module 0
uint64_t tmp_mac = mac_addr;
for (int i = 0; i < 6; i++)
packet->dest_mac[i] = (tmp_mac >> (8*i)) % 256;
packet->ipv4_header_h = htons(0x4500); // Big endian in IP header!
packet->ipv4_header_total_length = htons(4172); // Big endian in IP header!
packet->ipv4_header_dest_ip = ipv4_addr;
packet->ipv4_header_sour_ip = experiment.GetSrcIPv4Address(data_stream, 0);
packet->ipv4_header_ttl_protocol = htons(0x0011);
packet->ipv4_header_checksum = checksum( (uint16_t *) &packet->ipv4_header_h, 20); // checksum is already in network order
packet->udp_dest_port = htons(GetUDPPort()); // module number
packet->udp_sour_port = htons(0xDFAC);
packet->udp_length = htons(4152);
// JF headers are little endian
packet->eiger.detectortype = SLS_DETECTOR_TYPE_EIGER;
packet->eiger.timestamp = 0xABCDEF0000FEDCBAL;
packet->eiger.bunchid = 0x1234567898765431L;
packet->eiger.row = (2 * module_number) | (row % 2);
packet->eiger.column = col % 2;
packet->eiger.framenum = frame_number;
packet->eiger.packetnum = eth_packet % 64;
if (data != nullptr) {
for (int i = 0; i < 2048; i++)
packet->eiger.data[i] = data[i];
}
packet->udp_checksum = htons(checksum( (uint16_t *) (buff+42), 4096+48));
SendPacket(buff, 66*64, 0);
}
AXI_STREAM & HLSSimulatedDevice::OutputStream() {
return dout_eth;
}
@@ -159,16 +201,10 @@ void HLSSimulatedDevice::FrameGeneratorFuture(FrameGeneratorConfig config) {
hbm.data(),
hbm.data(),
hbm_if_size,
config.frames,
config.modules,
mac_addr,
config.dest_mac_addr,
ipv4_addr,
config.dest_ipv4_addr,
config.bunchid,
config.exptime,
config.debug,
cancel_data_collection);
cancel_data_collection,
config);
}
void HLSSimulatedDevice::HW_RunInternalGenerator(const FrameGeneratorConfig &config) {
@@ -227,15 +263,6 @@ inline uint32_t float2uint(float f) {
}
void HLSSimulatedDevice::HLSMainThread() {
uint64_t counter_hbm;
uint64_t counter_host;
uint64_t eth_packets;
uint64_t icmp_packets;
uint64_t udp_packets;
uint64_t sls_packets;
uint32_t udp_len_err;
uint32_t udp_eth_err;
ap_uint<1> clear_counters = 0;
uint64_t packets_processed;
@@ -246,34 +273,33 @@ void HLSSimulatedDevice::HLSMainThread() {
STREAM_512 network0;
STREAM_512 raw0;
STREAM_512 raw1;
STREAM_512 raw2;
STREAM_512 raw3;
STREAM_768 stream_768_0;
STREAM_768 stream_768_1;
STREAM_768 stream_768_2;
STREAM_768 stream_768_3;
STREAM_768 stream_768_4;
STREAM_512 converted_0;
STREAM_512 converted_1;
STREAM_512 converted_2;
STREAM_512 converted_3;
STREAM_512 converted_3a;
STREAM_512 converted_4;
STREAM_512 converted_5;
STREAM_512 converted_5a;
STREAM_576 converted_6;
STREAM_512 converted_7;
STREAM_512 converted_8;
STREAM_512 data_0;
hls::stream<ap_axiu<512, 1, 1, 1>, 2> data_1;
hls::stream<ap_axiu<512, 1, 1, 1>, 2> data_2;
STREAM_512 data_3;
STREAM_512 data_4;
STREAM_512 data_5;
STREAM_512 data_6;
STREAM_512 data_7;
STREAM_512 data_8;
STREAM_512 data_9;
STREAM_512 data_10;
STREAM_576 data_11;
STREAM_512 data_12;
STREAM_512 data_13;
hls::stream<axis_addr> addr0;
hls::stream<axis_addr> addr1;
hls::stream<axis_addr> addr2;
hls::stream<axis_addr> addr3;
hls::stream<axis_completion> compl0, compl1, compl2, compl2a, compl3, compl4, compl5, compl6, compl7, compl8;
hls::stream<axis_completion> axi_compl[12];
hls::stream<ap_uint<16>> hbm_handles;
hls::stream<ap_uint<512>> adu_histo_result;
@@ -287,6 +313,8 @@ void HLSSimulatedDevice::HLSMainThread() {
hls::stream<ap_uint<512>> spot_finder_result_2;
hls::stream<ap_uint<32>> spot_finder_mask_0;
hls::stream<ap_uint<256>> roi_calc_result_0;
hls::stream<ap_uint<UDP_METADATA_STREAM_WIDTH> > udp_metadata;
volatile ap_uint<1> idle_data_collection = 1;
ap_uint<1> load_to_hbm_idle;
@@ -306,7 +334,7 @@ void HLSSimulatedDevice::HLSMainThread() {
volatile rcv_state_t state = RCV_INIT;
// Start data collection
data_collection_fsm(raw0, raw1,
data_collection_fsm(data_0, data_1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
@@ -319,7 +347,7 @@ void HLSSimulatedDevice::HLSMainThread() {
cfg.nsummation , state);
run_data_collection = 0;
data_collection_fsm(raw0, raw1,
data_collection_fsm(data_0, data_1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
@@ -333,10 +361,10 @@ void HLSSimulatedDevice::HLSMainThread() {
hls_cores.emplace_back([&] {
while (!udp_done) {
if (din_eth.empty() && din_eth_4x10G.empty() && din_frame_generator.empty())
if (din_eth.empty() && din_frame_generator.empty())
std::this_thread::sleep_for(std::chrono::microseconds(10));
else
stream_merge(din_eth, din_eth_4x10G, din_frame_generator, network0, data_source);
stream_merge(din_eth, din_frame_generator, network0, data_source);
}
logger_hls.Info("Stream_merge done");
});
@@ -379,7 +407,8 @@ void HLSSimulatedDevice::HLSMainThread() {
if (udp2.empty())
std::this_thread::sleep_for(std::chrono::microseconds (10));
else
sls_detector(udp2, udp_metadata, raw0, addr0, sls_packets, udp_eth_err, udp_len_err, clear_counters, sls_idle);
sls_detector(udp2, udp_metadata, data_0, addr0, sls_packets, udp_eth_err, udp_len_err, current_pulse_id,
clear_counters, sls_idle);
}
sls_done = true;
logger_hls.Info("sls_detector done");
@@ -387,8 +416,8 @@ void HLSSimulatedDevice::HLSMainThread() {
// 1. Parse incoming UDP packets
hls_cores.emplace_back([&] {
while ((state != RCV_WAIT_FOR_START) || (idle_data_collection.read() == 0) || (!raw0.empty())) {
data_collection_fsm(raw0, raw1,
while ((state != RCV_WAIT_FOR_START) || (idle_data_collection.read() == 0) || (!data_0.empty())) {
data_collection_fsm(data_0, data_1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
@@ -407,18 +436,25 @@ void HLSSimulatedDevice::HLSMainThread() {
});
// 2. Cache images in HBM
hls_cores.emplace_back([&] { save_to_hbm(raw1, converted_1, addr1, compl0, hbm_handles,
datamover_out_hbm_0.GetDataStream(), datamover_out_hbm_1.GetDataStream(),
datamover_out_hbm_0.GetCtrlStream(), datamover_out_hbm_1.GetCtrlStream(),
save_to_hbm_idle, hbm_if_size);});
hls_cores.emplace_back([&] {frame_summation_reorder_compl(converted_1, converted_2, compl0, compl1);});
hls_cores.emplace_back([&] { save_to_hbm(addr1, axi_compl[0], hbm_handles,
datamover_out_hbm_0.GetCtrlStream(),
datamover_out_hbm_1.GetCtrlStream(),
save_to_hbm_idle,
hbm_if_size);});
hls_cores.emplace_back([&] { load_from_hbm(converted_2, converted_3, compl1, compl2, hbm_handles,
hls_cores.emplace_back([&] { save_to_hbm_data(data_1,
data_3,
datamover_out_hbm_0.GetDataStream(),
datamover_out_hbm_1.GetDataStream());});
hls_cores.emplace_back([&] {frame_summation_reorder_compl(data_3, data_4, axi_compl[0], axi_compl[1]);});
hls_cores.emplace_back([&] { load_from_hbm(data_4, data_5, axi_compl[1], axi_compl[2], hbm_handles,
datamover_in_hbm_0.GetDataStream(), datamover_in_hbm_1.GetDataStream(),
datamover_in_hbm_0.GetCtrlStream(), datamover_in_hbm_1.GetCtrlStream(),
load_to_hbm_idle, hbm_if_size);});
hls_cores.emplace_back([&] { pedestal(converted_3, converted_3a, compl2, compl2a,
hls_cores.emplace_back([&] { pedestal(data_5, data_6, axi_compl[2], axi_compl[3],
hbm.data(),
hbm.data(),
hbm.data(),
@@ -435,14 +471,17 @@ void HLSSimulatedDevice::HLSMainThread() {
// 3. Calculate histogram of ADU values
hls_cores.emplace_back([&] { adu_histo(converted_3a, converted_4, adu_histo_result, compl2a, compl3);});
hls_cores.emplace_back([&] { adu_histo(data_6, data_7, adu_histo_result, axi_compl[3], axi_compl[4]);});
// 4. Mask missing pixels
hls_cores.emplace_back([&] { mask_missing(converted_4, converted_5, compl3, compl4);});
hls_cores.emplace_back([&] { mask_missing(data_7, data_8, axi_compl[4], axi_compl[5]);});
// 5. Apply pedestal & gain corrections
hls_cores.emplace_back([&] { jf_conversion(converted_5, converted_6,
compl4, compl5,
// 5. Handle EIGER packets properly
hls_cores.emplace_back([&] { eiger_reorder(data_8, data_9, axi_compl[5], axi_compl[6]);});
// 6. Apply pedestal & gain corrections
hls_cores.emplace_back([&] { jf_conversion(data_9, data_11,
axi_compl[6], axi_compl[7],
hbm.data(),
hbm.data(),
hbm.data(),
@@ -457,15 +496,15 @@ void HLSSimulatedDevice::HLSMainThread() {
hbm.data(),
hbm_if_size); });
// 6. Frame summation
hls_cores.emplace_back([&] { frame_summation(converted_6, stream_768_0, compl5, compl6, frame_summation_idle);});
// 7. Frame summation
hls_cores.emplace_back([&] { frame_summation(data_11, stream_768_0, axi_compl[7], axi_compl[8], frame_summation_idle);});
// 7. Integration of pixels
hls_cores.emplace_back([&] { integration(stream_768_0, stream_768_1, integration_result_0, compl6, compl7,
// 8. Integration of pixels
hls_cores.emplace_back([&] { integration(stream_768_0, stream_768_1, integration_result_0, axi_compl[8], axi_compl[9],
hbm.data(), hbm.data(), hbm.data(), hbm.data(), integration_idle, hbm_if_size);});
hls_cores.emplace_back([&] { axis_64_to_512(integration_result_0, integration_result_1);});
// 8. Spot finding
// 9. Spot finding
ap_uint<32> tmp_snr_threshold = float2uint(spot_finder_parameters.snr_threshold);
ap_uint<32> min_d = float2uint(spot_finder_parameters.min_d);
ap_uint<32> max_d = float2uint(spot_finder_parameters.max_d);
@@ -476,8 +515,8 @@ void HLSSimulatedDevice::HLSMainThread() {
spot_finder_mask(stream_768_1,
stream_768_2,
spot_finder_mask_0,
compl7,
compl8,
axi_compl[9],
axi_compl[10],
hbm.data(),
hbm.data(),
min_d,
@@ -506,16 +545,30 @@ void HLSSimulatedDevice::HLSMainThread() {
logger_hls.Info("spot_finder_merge done");
});
// 9. Reduce/extend 24-bit stream
hls_cores.emplace_back([&] { stream_24bit_conv(stream_768_3, converted_7, stream_conv_idle);});
hls_cores.emplace_back([&] {
roi_calc(stream_768_3,
stream_768_4,
roi_calc_result_0,
axi_compl[10],
axi_compl[11],
hbm.data(),
hbm.data(),
hbm_if_size);
logger_hls.Info("roi_calc done");
});
// 10. Prepare data to write to host memory
// 10. Reduce/extend 24-bit stream
hls_cores.emplace_back([&] { stream_24bit_conv(stream_768_4, data_12, stream_conv_idle);});
// 11. Prepare data to write to host memory
hls_cores.emplace_back([&] {
ap_uint<3> state;
host_writer(converted_7, adu_histo_result, integration_result_1, spot_finder_result_2,
compl8, datamover_out.GetDataStream(),
host_writer(data_12, adu_histo_result, integration_result_1, spot_finder_result_2, roi_calc_result_0,
axi_compl[11], datamover_out.GetDataStream(),
datamover_out.GetCtrlStream(), work_request_stream, completion_stream,
dma_address_table.data(), packets_processed, host_writer_idle, cancel_data_collection, state);});
dma_address_table.data(), packets_processed, host_writer_idle, cancel_data_collection, state);
logger_hls.Info("host_writer done");
});
for (auto &i : hls_cores)
i.join();
@@ -538,65 +591,46 @@ void HLSSimulatedDevice::HLSMainThread() {
if (!addr3.empty())
throw std::runtime_error("Addr3 queue not empty");
if (!raw1.empty())
throw std::runtime_error("Raw1 queue not empty");
if (!data_1.empty())
throw std::runtime_error("data_1 queue not empty");
if (!raw2.empty())
throw std::runtime_error("Raw2 queue not empty");
if (!data_2.empty())
throw std::runtime_error("data_2 queue not empty");
if (!raw3.empty())
throw std::runtime_error("Raw3 queue not empty");
if (!data_3.empty())
throw std::runtime_error("data_3 queue not empty");
if (!converted_0.empty())
throw std::runtime_error("Converted_0 queue not empty");
if (!data_4.empty())
throw std::runtime_error("data_4 queue not empty");
if (!converted_1.empty())
throw std::runtime_error("Converted_1 queue not empty");
if (!data_5.empty())
throw std::runtime_error("data_5 queue not empty");
if (!converted_2.empty())
throw std::runtime_error("Converted_2 queue not empty");
if (!data_7.empty())
throw std::runtime_error("data_7 queue not empty");
if (!converted_3.empty())
throw std::runtime_error("Converted_3 queue not empty");
if (!data_8.empty())
throw std::runtime_error("data_8 queue not empty");
if (!converted_4.empty())
throw std::runtime_error("Converted_4 queue not empty");
if (!data_9.empty())
throw std::runtime_error("data_9 queue not empty");
if (!converted_5.empty())
throw std::runtime_error("Converted_5 queue not empty");
if (!data_10.empty())
throw std::runtime_error("data_10 queue not empty");
if (!converted_6.empty())
throw std::runtime_error("Converted_6 queue not empty");
if (!data_11.empty())
throw std::runtime_error("data_11 queue not empty");
if (!converted_7.empty())
throw std::runtime_error("Converted_7 queue not empty");
if (!data_12.empty())
throw std::runtime_error("data_12 queue not empty");
if (!converted_8.empty())
throw std::runtime_error("Converted_8 queue not empty");
if (!data_13.empty())
throw std::runtime_error("data_13 queue not empty");
if (!compl0.empty())
throw std::runtime_error("Compl0 queue not empty");
if (!compl1.empty())
throw std::runtime_error("Compl1 queue not empty");
if (!compl2.empty())
throw std::runtime_error("Compl2 queue not empty");
if (!compl3.empty())
throw std::runtime_error("Compl3 queue not empty");
if (!compl4.empty())
throw std::runtime_error("Compl4 queue not empty");
if (!compl5.empty())
throw std::runtime_error("Compl5 queue not empty");
if (!compl6.empty())
throw std::runtime_error("Compl6 queue not empty");
if (!compl7.empty())
throw std::runtime_error("Compl7 queue not empty");
for (auto &c: axi_compl) {
if (!c.empty())
throw std::runtime_error("Compl queue not empty");
}
if (!stream_768_0.empty())
throw std::runtime_error("Stream_768_0 queue not empty");
@@ -628,17 +662,28 @@ void HLSSimulatedDevice::HLSMainThread() {
}
if (logger)
logger->Info("Packets Eth {} UDP {} SLS {} Proc {}", eth_packets, udp_packets, sls_packets, packets_processed);
idle = true;
}
void HLSSimulatedDevice::HW_GetStatus(DataCollectionStatus *status) const {
memset(status, 0, sizeof(DataCollectionStatus));
DataCollectionStatus HLSSimulatedDevice::GetDataCollectionStatus() const {
DataCollectionStatus status{};
status->ctrl_reg = ap_uint<1>(host_writer_idle) ? (1 << 4) : 0;
status->max_modules = max_modules;
status->hbm_size_bytes = hbm_if_size;
status->run_counter = run_counter;
union {
uint64_t u64;
double d;
} pulse_id_conv;
pulse_id_conv.u64 = current_pulse_id;
status.ctrl_reg = ap_uint<1>(host_writer_idle) ? (1 << 4) : 0;
status.max_modules = max_modules;
status.hbm_size_bytes = hbm_if_size;
status.run_counter = run_counter;
status.current_pulseid = pulse_id_conv.d;
status.packets_udp = udp_packets;
status.packets_eth = eth_packets;
status.packets_sls = sls_packets;
return status;
}
void HLSSimulatedDevice::HW_LoadCalibration(const LoadCalibrationConfig &config) {
@@ -667,3 +712,37 @@ void HLSSimulatedDevice::HW_SetDataSource(uint32_t val) {
uint32_t HLSSimulatedDevice::HW_GetDataSource() {
return data_source;
}
void HLSSimulatedDevice::CreateXfelBunchIDPacket(double pulse_id, uint32_t event_code) {
union {
uint64_t u64;
double d;
} pulse_id_conv;
pulse_id_conv.d = pulse_id;
bunchid_raw_packet packet{};
packet.ether_type = htons(0x0800);
for (int i = 0; i < 6; i++)
packet.dest_mac[i] = 0xFF;
packet.ipv4_header_h = htons(0x4500); // Big endian in IP header!
packet.ipv4_header_total_length = htons(sizeof(bunchid_payload) + 8 + 20); // Big endian in IP header!
packet.ipv4_header_dest_ip = UINT32_MAX;
packet.ipv4_header_ttl_protocol = htons(0x0011);
packet.ipv4_header_checksum = checksum( (uint16_t *) &packet.ipv4_header_h, 20); // checksum is already in network order
packet.udp_length = htons(sizeof(bunchid_payload) + 8);
packet.payload.magicn[0] = BUNCHID_MAGICN;
packet.payload.magicn[1] = BUNCHID_MAGICN;
packet.payload.magicn[2] = BUNCHID_MAGICN;
packet.payload.bunchid_msb[0] = (pulse_id_conv.u64 >> 32) & UINT32_MAX;
packet.payload.bunchid_msb[1] = (pulse_id_conv.u64 >> 32) & UINT32_MAX;
packet.payload.bunchid_lsb[0] = pulse_id_conv.u64 & UINT32_MAX;
packet.payload.bunchid_lsb[1] = pulse_id_conv.u64 & UINT32_MAX;
packet.payload.montrig = event_code;
SendPacket((char *) &packet, sizeof(bunchid_raw_packet));
}
+21 -11
View File
@@ -9,26 +9,27 @@
#include "../fpga/hls/datamover_model.h"
#include "../common/DiffractionExperiment.h"
#include "FPGAAcquisitionDevice.h"
#include "../jungfrau/jf_packet.h"
#include "../jungfrau/sls_packet.h"
uint16_t checksum(const uint16_t *addr, size_t count);
class HLSSimulatedDevice : public FPGAAcquisitionDevice {
AXI_STREAM din_eth;
AXI_STREAM din_eth_4x10G; // Not used
AXI_STREAM din_frame_generator;
AXI_STREAM dout_eth;
uint32_t run_counter = 0;
ap_uint<2> data_source = STREAM_MERGE_SRC_100G;
ap_uint<2> data_source = STREAM_MERGE_SRC_NETWORK;
SpotFinderParameters spot_finder_parameters;
uint64_t current_pulse_id = 0;
DataCollectionConfig cfg;
volatile bool idle;
constexpr static const size_t hbm_if_count = 30;
constexpr static const size_t hbm_if_count = 32;
constexpr static const size_t hbm_if_size = 32*1024*1024LU;
std::vector<ap_uint<256>> hbm;
@@ -53,6 +54,13 @@ class HLSSimulatedDevice : public FPGAAcquisitionDevice {
std::vector<uint64_t> dma_address_table;
uint64_t eth_packets = 0;
uint64_t icmp_packets = 0;
uint64_t udp_packets = 0;
uint64_t sls_packets = 0;
uint32_t udp_len_err = 0;
uint32_t udp_eth_err = 0;
void HW_ReadActionRegister(DataCollectionConfig *job) override;
void HW_WriteActionRegister(const DataCollectionConfig *job) override;
@@ -62,7 +70,6 @@ class HLSSimulatedDevice : public FPGAAcquisitionDevice {
bool HW_ReadMailbox(uint32_t *values) override;
bool HW_SendWorkRequest(uint32_t handle) override;
void HW_LoadCalibration(const LoadCalibrationConfig &config) override;
void HW_GetStatus(DataCollectionStatus *status) const override;
void HW_SetSpotFinderParameters(const SpotFinderParameters &params) override;
uint32_t HW_GetDataSource() override;
void HW_SetDataSource(uint32_t val) override;
@@ -73,13 +80,16 @@ public:
HLSSimulatedDevice(uint16_t data_stream, size_t in_frame_buffer_size_modules, int16_t numa_node = -1);
~HLSSimulatedDevice() override;
void SendPacket(char *buffer, int len, uint8_t user = 0);
void CreatePacketJF(const DiffractionExperiment& experiment, uint64_t frame_number, uint32_t eth_packet,
uint32_t module_number, const uint16_t *data, bool trigger, int8_t adjust_axis = 0,
uint8_t user = 0);
void CreatePackets(const DiffractionExperiment& experiment, uint64_t frame_number_0, uint64_t frames,
uint32_t module_number, const uint16_t *data, bool trigger, int8_t adjust_axis = 0,
uint8_t user = 0);
void CreateJFPacket(const DiffractionExperiment& experiment, uint64_t frame_number, uint32_t eth_packet,
uint32_t module_number, const uint16_t *data, int8_t adjust_axis = 0, uint8_t user = 0);
void CreateJFPackets(const DiffractionExperiment& experiment, uint64_t frame_number_0, uint64_t frames,
uint32_t module_number, const uint16_t *data);
void CreateEIGERPacket(const DiffractionExperiment& experiment, uint64_t frame_number, uint32_t eth_packet,
uint32_t module_number, uint32_t col, uint32_t row,
const uint16_t *data);
void CreateXfelBunchIDPacket(double bunchid, uint32_t event_code);
void CreateFinalPacket(const DiffractionExperiment& experiment);
DataCollectionStatus GetDataCollectionStatus() const override;
AXI_STREAM &OutputStream();
void Cancel() override;
};
-4
View File
@@ -74,10 +74,6 @@ void PCIExpressDevice::SetMACAddress(uint64_t mac_addr_network_order) {
dev.SetMACAddress(mac_addr_network_order);
}
void PCIExpressDevice::HW_GetStatus(DataCollectionStatus *status) const {
*status = dev.GetDataCollectionStatus();
}
void PCIExpressDevice::HW_GetEnvParams(DeviceStatus *status) const {
*status = dev.GetDeviceStatus();
}
-1
View File
@@ -28,7 +28,6 @@ public:
PCIExpressDevice(uint16_t data_stream, const std::string &device_name);
void Cancel() override;
void HW_GetStatus(DataCollectionStatus *status) const override;
void HW_GetEnvParams(DeviceStatus *status) const override;
int32_t GetNUMANode() const override;
+3
View File
@@ -165,6 +165,7 @@ inline org::openapitools::server::model::Detector_status Convert(const DetectorS
output.setServerVersion(input.detector_server_version);
output.setNumberOfTriggersLeft(input.remaining_triggers);
output.setFpgaTempDegC(input.temperature_fpga_degC);
output.setHighVoltageV(input.high_voltage_V);
switch (input.power_state) {
case DetectorPowerState::ON:
output.setPowerchip("On");
@@ -302,6 +303,8 @@ inline DatasetSettings Convert(const org::openapitools::server::model::Dataset_s
ret.detector_distance_mm = input.getDetectorDistanceMm();
ret.photon_energy_keV = input.getPhotonEnergyKeV();
ret.photon_energy_multiplier = input.getPhotonEnergyMultiplier();
ret.file_prefix = input.filePrefixIsSet() ? input.getFilePrefix() : "";
ret.data_file_count = input.dataFileCountIsSet() ? input.getDataFileCount() : 1;
+23 -13
View File
@@ -198,7 +198,7 @@ DetectorGeometry ParseStandardDetectorGeometry(const nlohmann::json &j) {
return {nmodules, h_stacking, gap_x, gap_y, mirror_y};
}
DetectorGeometry ParseCustomDetectorGeometry(const nlohmann::json &j) {
DetectorGeometry ParseCustomDetectorGeometry(const nlohmann::json &j, bool mirror_y) {
std::vector<DetectorModuleGeometry> modules;
for (const auto &iter: j) {
if (!iter.is_object())
@@ -210,15 +210,15 @@ DetectorGeometry ParseCustomDetectorGeometry(const nlohmann::json &j) {
auto slow = GET_DIRECTION(iter, "slow_axis");
modules.emplace_back(x0, y0, fast, slow);
}
return {modules};
return {modules, mirror_y};
}
DetectorGeometry ParseDetectorGeometry(const nlohmann::json &j) {
if (CHECK_OBJECT(j, "standard_geometry"))
return ParseStandardDetectorGeometry(j["standard_geometry"]);
else if (CHECK_ARRAY(j, "custom_geometry"))
return ParseCustomDetectorGeometry(j["custom_geometry"]);
else
else if (CHECK_ARRAY(j, "custom_geometry")) {
return ParseCustomDetectorGeometry(j["custom_geometry"], GET_BOOL(j, "custom_geometry_mirror_y", false));
} else
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"It is compulsory to have either standard_detector or custom_detector declared.");
}
@@ -231,12 +231,23 @@ DetectorSetup ParseDetectorSetup(const nlohmann::json &j) {
std::string description = GET_STR(j, "description");
auto module_hostname = GET_STR_ARR(j, "module_hostname");
auto gain_files = GET_STR_ARR(j, "gain_files");
auto tx_delay = GET_I64_ARR(j, "tx_delay");
DetectorSetup setup(geom, description, module_hostname);
if (!gain_files.empty())
setup.LoadGain(gain_files);
DetectorType detector_type;
const std::string detector_type_str = GET_STR(j, "type", "jungfrau");
if (detector_type_str == "jungfrau")
detector_type = DetectorType::JUNGFRAU;
else if (detector_type_str == "eiger")
detector_type = DetectorType::EIGER;
else
throw JFJochException(JFJochExceptionCategory::JSON, "type must be \"jungfrau\" or \"eiger\" ");
DetectorSetup setup(geom, detector_type, description, module_hostname);
if (detector_type == DetectorType::JUNGFRAU) {
auto gain_files = GET_STR_ARR(j, "gain_files");
if (!gain_files.empty())
setup.LoadGain(gain_files);
}
setup.UDPInterfaceCount(GET_I64(j, "udp_interface_count", 2))
.SensorThickness_um(GET_FLOAT(j, "sensor_thickness_um", 320.0f))
@@ -263,6 +274,8 @@ void ParseFacilityConfiguration(const nlohmann::json &input, const std::string&
experiment.InstrumentName(GET_STR(j, "instrument_name"));
experiment.InstrumentNameShort(GET_STR(j, "instrument_name_short"));
experiment.PulsedSource(GET_BOOL(j, "pulsed_source", false));
if (j.contains("omega_axis")) {
if (j["omega_axis"].is_array() && (j["omega_axis"].size() == 3))
experiment.DefaultOmegaAxis(Coord(j["omega_axis"][0].get<float>(),
@@ -313,10 +326,7 @@ void ParseAcquisitionDeviceGroup(const nlohmann::json &input, const std::string&
} else
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Device type unknown");
if (use_4x10g)
aq_devices.SetDefaultDataSource(AcquisitionDeviceSource::MAC_4x10G);
else
aq_devices.SetDefaultDataSource(AcquisitionDeviceSource::MAC_100G);
aq_devices.SetDefaultDataSource(AcquisitionDeviceSource::NETWORK);
std::vector<std::string> ipv4_addr = GET_STR_ARR(j, "ipv4_addr");
if (ipv4_addr.size() != aq_devices.size())
+22 -14
View File
@@ -33,7 +33,7 @@ void JFJochServices::On(const DiffractionExperiment &x) {
logger.Info("Detector on");
if (detector && (receiver != nullptr))
detector->Configure(x, receiver->GetNetworkConfig());
detector->Initialize(x, receiver->GetNetworkConfig());
logger.Info(" ... done");
}
@@ -45,6 +45,21 @@ JFJochServicesOutput JFJochServices::Stop() {
if (receiver != nullptr) {
try {
if (detector) {
logger.Info("Wait for detector done");
DetectorState state = detector->GetState();
while ((state == DetectorState::WAITING) || (state == DetectorState::BUSY)) {
// check detector state every 5 ms
std::this_thread::sleep_for(std::chrono::milliseconds(5));
state = detector->GetState();
}
if (state == DetectorState::ERROR) {
logger.Error(" ... detector in error state");
receiver->Cancel(false);
} else if (state == DetectorState::IDLE) {
receiver->Cancel(true); // cancel silently
}
}
logger.Info("Wait for receiver done");
ret.receiver_output = receiver->Stop();
@@ -64,18 +79,6 @@ JFJochServicesOutput JFJochServices::Stop() {
exception = std::make_unique<JFJochException>(e);
}
logger.Info("Receiver finished with success");
if (detector) {
logger.Info("Stopping detector");
try {
detector->Stop();
logger.Info(" ... done");
} catch (JFJochException &e) {
logger.Error(" ... finished with error {}", e.what());
exception = std::make_unique<JFJochException>(e);
}
}
} else {
logger.Info("No receiver - sleeping for 30 seconds");
std::this_thread::sleep_for(std::chrono::seconds(30));
@@ -93,7 +96,7 @@ void JFJochServices::Cancel() {
if (receiver != nullptr) {
if (detector)
detector->Stop();
receiver->Cancel();
receiver->Cancel(false);
}
}
@@ -166,3 +169,8 @@ std::string JFJochServices::GetPreviewTIFF(bool calibration) const {
else
return "";
}
void JFJochServices::ConfigureDetector(const DiffractionExperiment &experiment) {
if (detector)
detector->Configure(experiment);
}
+1
View File
@@ -22,6 +22,7 @@ public:
explicit JFJochServices(Logger &in_logger);
void On(const DiffractionExperiment& experiment);
void Off();
void ConfigureDetector(const DiffractionExperiment& experiment);
void Start(const DiffractionExperiment& experiment, const JFCalibration &calibration);
JFJochServicesOutput Stop();
void Cancel();
+14 -3
View File
@@ -9,12 +9,16 @@ void LoadDatasetSettings(DiffractionExperiment& experiment, const DatasetSetting
auto tmp = experiment;
try {
if (experiment.IsPulsedSource() && (settings.images_per_trigger != 1))
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"No point to set image_per_trigger for a pulsed source");
experiment.ImagesPerTrigger(settings.images_per_trigger);
experiment.NumTriggers(settings.ntrigger);
experiment.BeamX_pxl(settings.beam_x_pxl);
experiment.BeamY_pxl(settings.beam_y_pxl);
experiment.DetectorDistance_mm(settings.detector_distance_mm);
experiment.PhotonEnergy_keV(settings.photon_energy_keV);
experiment.PhotonEnergyMultiplayer(settings.photon_energy_multiplier);
experiment.FilePrefix(settings.file_prefix);
experiment.DataFileCount(settings.data_file_count);
experiment.SetUnitCell(settings.unit_cell);
@@ -159,6 +163,7 @@ void JFJochStateMachine::TakePedestalInternalAll(std::unique_lock<std::mutex> &u
TakePedestalInternalG2(ul, i);
}
}
services.ConfigureDetector(experiment);
} catch (const std::exception &e) {
logger.Error("Pedestal sequence error {}", e.what());
state = JFJochState::Error;
@@ -190,8 +195,10 @@ void JFJochStateMachine::TakePedestalInternalG0(std::unique_lock<std::mutex> &ul
}
state = JFJochState::Pedestal;
services.ConfigureDetector(local_experiment);
services.Start(local_experiment, *calibration);
services.Trigger();
if (!experiment.IsPulsedSource())
services.Trigger();
ul.unlock();
// Allow to cancel/abort during the pedestal data collection
// Must ensure that while state is Pedestal, nothing can take lock for longer time, to avoid deadlock
@@ -226,8 +233,10 @@ void JFJochStateMachine::TakePedestalInternalG1(std::unique_lock<std::mutex> &ul
}
state = JFJochState::Pedestal;
services.ConfigureDetector(local_experiment);
services.Start(local_experiment, *calibration);
services.Trigger();
if (!experiment.IsPulsedSource())
services.Trigger();
ul.unlock();
// Allow to cancel/abort during the pedestal data collection
// Must ensure that while state is Pedestal, nothing can take lock for longer time, to avoid deadlock
@@ -262,8 +271,10 @@ void JFJochStateMachine::TakePedestalInternalG2(std::unique_lock<std::mutex> &ul
}
state = JFJochState::Pedestal;
services.ConfigureDetector(local_experiment);
services.Start(local_experiment, *calibration);
services.Trigger();
if (!experiment.IsPulsedSource())
services.Trigger();
ul.unlock();
// Allow to cancel/abort during the pedestal data collection
// Must ensure that while state is Pedestal, nothing can take lock for longer time, to avoid deadlock
+2
View File
@@ -67,6 +67,8 @@ struct DatasetSettings {
float detector_distance_mm;
float photon_energy_keV;
float photon_energy_multiplier;
std::string file_prefix;
int64_t data_file_count;
+73 -10
View File
@@ -21,7 +21,8 @@ namespace org::openapitools::server::model
Dataset_settings::Dataset_settings()
{
m_Images_per_trigger = 0L;
m_Images_per_trigger = 1L;
m_Images_per_triggerIsSet = false;
m_Ntrigger = 1L;
m_NtriggerIsSet = false;
m_Summation = 1L;
@@ -52,6 +53,8 @@ Dataset_settings::Dataset_settings()
m_Header_appendixIsSet = false;
m_Image_appendix = "";
m_Image_appendixIsSet = false;
m_Photon_energy_multiplier = 1.0f;
m_Photon_energy_multiplierIsSet = false;
m_Roi_sum_areaIsSet = false;
m_Unit_cellIsSet = false;
@@ -77,16 +80,16 @@ bool Dataset_settings::validate(std::stringstream& msg, const std::string& pathP
const std::string _pathPrefix = pathPrefix.empty() ? "Dataset_settings" : pathPrefix;
/* Images_per_trigger */ {
if (imagesPerTriggerIsSet())
{
const int64_t& value = m_Images_per_trigger;
const std::string currentValuePath = _pathPrefix + ".imagesPerTrigger";
if (value < 0ll)
if (value < 1ll)
{
success = false;
msg << currentValuePath << ": must be greater than or equal to 0;";
msg << currentValuePath << ": must be greater than or equal to 1;";
}
}
@@ -203,7 +206,26 @@ bool Dataset_settings::validate(std::stringstream& msg, const std::string& pathP
}
}
if (photonEnergyMultiplierIsSet())
{
const float& value = m_Photon_energy_multiplier;
const std::string currentValuePath = _pathPrefix + ".photonEnergyMultiplier";
if (value < static_cast<float>(0.015625))
{
success = false;
msg << currentValuePath << ": must be greater than or equal to 0.015625;";
}
if (value > static_cast<float>(4.0))
{
success = false;
msg << currentValuePath << ": must be less than or equal to 4.0;";
}
}
return success;
}
@@ -212,8 +234,8 @@ bool Dataset_settings::operator==(const Dataset_settings& rhs) const
return
(getImagesPerTrigger() == rhs.getImagesPerTrigger())
&&
((!imagesPerTriggerIsSet() && !rhs.imagesPerTriggerIsSet()) || (imagesPerTriggerIsSet() && rhs.imagesPerTriggerIsSet() && getImagesPerTrigger() == rhs.getImagesPerTrigger())) &&
((!ntriggerIsSet() && !rhs.ntriggerIsSet()) || (ntriggerIsSet() && rhs.ntriggerIsSet() && getNtrigger() == rhs.getNtrigger())) &&
@@ -270,6 +292,9 @@ bool Dataset_settings::operator==(const Dataset_settings& rhs) const
((!imageAppendixIsSet() && !rhs.imageAppendixIsSet()) || (imageAppendixIsSet() && rhs.imageAppendixIsSet() && getImageAppendix() == rhs.getImageAppendix())) &&
((!photonEnergyMultiplierIsSet() && !rhs.photonEnergyMultiplierIsSet()) || (photonEnergyMultiplierIsSet() && rhs.photonEnergyMultiplierIsSet() && getPhotonEnergyMultiplier() == rhs.getPhotonEnergyMultiplier())) &&
((!roiSumAreaIsSet() && !rhs.roiSumAreaIsSet()) || (roiSumAreaIsSet() && rhs.roiSumAreaIsSet() && getRoiSumArea() == rhs.getRoiSumArea())) &&
@@ -286,7 +311,8 @@ bool Dataset_settings::operator!=(const Dataset_settings& rhs) const
void to_json(nlohmann::json& j, const Dataset_settings& o)
{
j = nlohmann::json();
j["images_per_trigger"] = o.m_Images_per_trigger;
if(o.imagesPerTriggerIsSet())
j["images_per_trigger"] = o.m_Images_per_trigger;
if(o.ntriggerIsSet())
j["ntrigger"] = o.m_Ntrigger;
if(o.summationIsSet())
@@ -318,6 +344,8 @@ void to_json(nlohmann::json& j, const Dataset_settings& o)
j["header_appendix"] = o.m_Header_appendix;
if(o.imageAppendixIsSet())
j["image_appendix"] = o.m_Image_appendix;
if(o.photonEnergyMultiplierIsSet())
j["photon_energy_multiplier"] = o.m_Photon_energy_multiplier;
if(o.roiSumAreaIsSet())
j["roi_sum_area"] = o.m_Roi_sum_area;
if(o.unitCellIsSet())
@@ -327,7 +355,11 @@ void to_json(nlohmann::json& j, const Dataset_settings& o)
void from_json(const nlohmann::json& j, Dataset_settings& o)
{
j.at("images_per_trigger").get_to(o.m_Images_per_trigger);
if(j.find("images_per_trigger") != j.end())
{
j.at("images_per_trigger").get_to(o.m_Images_per_trigger);
o.m_Images_per_triggerIsSet = true;
}
if(j.find("ntrigger") != j.end())
{
j.at("ntrigger").get_to(o.m_Ntrigger);
@@ -398,6 +430,11 @@ void from_json(const nlohmann::json& j, Dataset_settings& o)
j.at("image_appendix").get_to(o.m_Image_appendix);
o.m_Image_appendixIsSet = true;
}
if(j.find("photon_energy_multiplier") != j.end())
{
j.at("photon_energy_multiplier").get_to(o.m_Photon_energy_multiplier);
o.m_Photon_energy_multiplierIsSet = true;
}
if(j.find("roi_sum_area") != j.end())
{
j.at("roi_sum_area").get_to(o.m_Roi_sum_area);
@@ -418,6 +455,15 @@ int64_t Dataset_settings::getImagesPerTrigger() const
void Dataset_settings::setImagesPerTrigger(int64_t const value)
{
m_Images_per_trigger = value;
m_Images_per_triggerIsSet = true;
}
bool Dataset_settings::imagesPerTriggerIsSet() const
{
return m_Images_per_triggerIsSet;
}
void Dataset_settings::unsetImages_per_trigger()
{
m_Images_per_triggerIsSet = false;
}
int64_t Dataset_settings::getNtrigger() const
{
@@ -680,6 +726,23 @@ void Dataset_settings::unsetImage_appendix()
{
m_Image_appendixIsSet = false;
}
float Dataset_settings::getPhotonEnergyMultiplier() const
{
return m_Photon_energy_multiplier;
}
void Dataset_settings::setPhotonEnergyMultiplier(float const value)
{
m_Photon_energy_multiplier = value;
m_Photon_energy_multiplierIsSet = true;
}
bool Dataset_settings::photonEnergyMultiplierIsSet() const
{
return m_Photon_energy_multiplierIsSet;
}
void Dataset_settings::unsetPhoton_energy_multiplier()
{
m_Photon_energy_multiplierIsSet = false;
}
org::openapitools::server::model::Dataset_settings_roi_sum_area Dataset_settings::getRoiSumArea() const
{
return m_Roi_sum_area;
+15 -4
View File
@@ -62,19 +62,21 @@ public:
/// Dataset_settings members
/// <summary>
///
/// For standard synchrotron data collection - this is number of images collected per one TTL trigger For XFEL mode - this number is ignored and set to 1 For storage cell mode - this number is ignored and set to number of storage cells
/// </summary>
int64_t getImagesPerTrigger() const;
void setImagesPerTrigger(int64_t const value);
bool imagesPerTriggerIsSet() const;
void unsetImages_per_trigger();
/// <summary>
///
/// Number of TTL trigger that the detector is expected to receive during data collection
/// </summary>
int64_t getNtrigger() const;
void setNtrigger(int64_t const value);
bool ntriggerIsSet() const;
void unsetNtrigger();
/// <summary>
///
/// FPGA frame summation. For summation above two 32-bit pixel format will be used, unless explicitly specified.
/// </summary>
int64_t getSummation() const;
void setSummation(int64_t const value);
@@ -183,6 +185,13 @@ public:
bool imageAppendixIsSet() const;
void unsetImage_appendix();
/// <summary>
/// For JUNGFRAU conversion it is possible to multiply energy by a given factor to get fractional/multiplied photon counts
/// </summary>
float getPhotonEnergyMultiplier() const;
void setPhotonEnergyMultiplier(float const value);
bool photonEnergyMultiplierIsSet() const;
void unsetPhoton_energy_multiplier();
/// <summary>
///
/// </summary>
org::openapitools::server::model::Dataset_settings_roi_sum_area getRoiSumArea() const;
@@ -201,7 +210,7 @@ public:
friend void from_json(const nlohmann::json& j, Dataset_settings& o);
protected:
int64_t m_Images_per_trigger;
bool m_Images_per_triggerIsSet;
int64_t m_Ntrigger;
bool m_NtriggerIsSet;
int64_t m_Summation;
@@ -238,6 +247,8 @@ protected:
bool m_Header_appendixIsSet;
std::string m_Image_appendix;
bool m_Image_appendixIsSet;
float m_Photon_energy_multiplier;
bool m_Photon_energy_multiplierIsSet;
org::openapitools::server::model::Dataset_settings_roi_sum_area m_Roi_sum_area;
bool m_Roi_sum_areaIsSet;
org::openapitools::server::model::Dataset_settings_unit_cell m_Unit_cell;
+34
View File
@@ -63,6 +63,27 @@ bool Detector_status::validate(std::stringstream& msg, const std::string& pathPr
i++;
}
}
}
/* High_voltage_V */ {
const std::vector<int64_t>& value = m_High_voltage_V;
const std::string currentValuePath = _pathPrefix + ".highVoltageV";
{ // Recursive validation of array elements
const std::string oldValuePath = currentValuePath;
int i = 0;
for (const int64_t& value : value)
{
const std::string currentValuePath = oldValuePath + "[" + std::to_string(i) + "]";
i++;
}
}
@@ -90,6 +111,9 @@ bool Detector_status::operator==(const Detector_status& rhs) const
&&
(getFpgaTempDegC() == rhs.getFpgaTempDegC())
&&
(getHighVoltageV() == rhs.getHighVoltageV())
;
@@ -108,6 +132,7 @@ void to_json(nlohmann::json& j, const Detector_status& o)
j["server_version"] = o.m_Server_version;
j["number_of_triggers_left"] = o.m_Number_of_triggers_left;
j["fpga_temp_degC"] = o.m_Fpga_temp_degC;
j["high_voltage_V"] = o.m_High_voltage_V;
}
@@ -118,6 +143,7 @@ void from_json(const nlohmann::json& j, Detector_status& o)
j.at("server_version").get_to(o.m_Server_version);
j.at("number_of_triggers_left").get_to(o.m_Number_of_triggers_left);
j.at("fpga_temp_degC").get_to(o.m_Fpga_temp_degC);
j.at("high_voltage_V").get_to(o.m_High_voltage_V);
}
@@ -161,6 +187,14 @@ void Detector_status::setFpgaTempDegC(std::vector<int64_t> const value)
{
m_Fpga_temp_degC = value;
}
std::vector<int64_t> Detector_status::getHighVoltageV() const
{
return m_High_voltage_V;
}
void Detector_status::setHighVoltageV(std::vector<int64_t> const value)
{
m_High_voltage_V = value;
}
} // namespace org::openapitools::server::model
+7
View File
@@ -84,6 +84,11 @@ public:
/// </summary>
std::vector<int64_t> getFpgaTempDegC() const;
void setFpgaTempDegC(std::vector<int64_t> const value);
/// <summary>
/// High voltage for detector modules
/// </summary>
std::vector<int64_t> getHighVoltageV() const;
void setHighVoltageV(std::vector<int64_t> const value);
friend void to_json(nlohmann::json& j, const Detector_status& o);
friend void from_json(const nlohmann::json& j, Detector_status& o);
@@ -98,6 +103,8 @@ protected:
std::vector<int64_t> m_Fpga_temp_degC;
std::vector<int64_t> m_High_voltage_V;
};
+25 -2
View File
@@ -34,7 +34,6 @@ components:
dataset_settings:
type: object
required:
- images_per_trigger
- beam_x_pxl
- beam_y_pxl
- detector_distance_mm
@@ -44,18 +43,27 @@ components:
images_per_trigger:
type: integer
format: int64
minimum: 0
minimum: 1
default: 1
description: |
For standard synchrotron data collection - this is number of images collected per one TTL trigger
For XFEL mode - this number is ignored and set to 1
For storage cell mode - this number is ignored and set to number of storage cells
ntrigger:
type: integer
format: int64
default: 1
minimum: 1
description: |
Number of TTL trigger that the detector is expected to receive during data collection
summation:
type: integer
format: int64
minimum: 1
maximum: 256
default: 1
description:
FPGA frame summation. For summation above two 32-bit pixel format will be used, unless explicitly specified.
beam_x_pxl:
type: number
format: float
@@ -149,6 +157,13 @@ components:
image_appendix:
type: string
description: Image appendix, added as user_data to image message
photon_energy_multiplier:
type: number
format: float
default: 1.0
minimum: 0.015625
maximum: 4.0
description: For JUNGFRAU conversion it is possible to multiply energy by a given factor to get fractional/multiplied photon counts
roi_sum_area:
type: object
description: Rectangle for ROI summation
@@ -209,6 +224,7 @@ components:
type: number
format: float
example: 90
detector_status:
type: object
required:
@@ -217,6 +233,7 @@ components:
- server_version
- number_of_triggers_left
- fpga_temp_degC
- high_voltage_V
properties:
state:
type: string
@@ -246,6 +263,12 @@ components:
items:
type: integer
format: int64
high_voltage_V:
type: array
description: High voltage for detector modules
items:
type: integer
format: int64
detector_settings:
type: object
required:
-1
View File
@@ -96,7 +96,6 @@ int main (int argc, char **argv) {
receiver->NUMAPolicy(numa_policy);
receiver->NumThreads(ParseInt64(input, "receiver_threads", 64));
receiver->SendBufferCount(ParseInt64(input, "send_buffer_count", 128));
}
ParseFacilityConfiguration(input, "cfg", experiment);
+12
View File
@@ -0,0 +1,12 @@
[Unit]
Description=jfjoch_broker
After=network.target
[Service]
ExecStart=/opt/jfjoch/bin/jfjoch_broker /opt/jfjoch/etc/broker.json
Environment=LD_LIBRARY_PATH=/opt/jfjoch/lib64
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
File diff suppressed because one or more lines are too long
+2 -1
View File
@@ -43,7 +43,8 @@ ADD_LIBRARY( JFJochCommon STATIC
RawToConvertedGeometryCore.h
Plot.h
../fpga/include/jfjoch_fpga.h
ZMQWrappers.cpp ZMQWrappers.h)
ZMQWrappers.cpp ZMQWrappers.h
)
TARGET_LINK_LIBRARIES(JFJochCommon Compression JFCalibration "$<BUILD_INTERFACE:libzmq-static>" -lrt)
+17 -12
View File
@@ -4,8 +4,8 @@
#include "JFJochException.h"
#include "Definitions.h"
DetectorGeometry::DetectorGeometry(const std::vector<DetectorModuleGeometry> &in_modules)
: modules(in_modules) {
DetectorGeometry::DetectorGeometry(const std::vector<DetectorModuleGeometry> &in_modules, bool vertical_flip)
: modules(in_modules) {
if (modules.empty())
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Module number must be positive");
@@ -16,6 +16,11 @@ DetectorGeometry::DetectorGeometry(const std::vector<DetectorModuleGeometry> &in
width = std::max<int64_t>(width, m.GetMaxX()+1);
height = std::max<int64_t>(height, m.GetMaxY()+1);
}
if (vertical_flip) {
for (auto &m: modules) m.VerticalFlip(height);
}
}
DetectorGeometry::DetectorGeometry(int32_t nmodules, int32_t horizontal_stacking, int32_t gap_x,
@@ -35,22 +40,22 @@ DetectorGeometry::DetectorGeometry(int32_t nmodules, int32_t horizontal_stacking
int64_t conv_lines = nmodules / horizontal_stacking + (nmodules % horizontal_stacking > 0 ? 1 : 0);
height = conv_lines * CONVERTED_MODULE_LINES + (conv_lines - 1) * gap_y;
for (int module = 0; module < nmodules; module++) {
int64_t module_x = module % horizontal_stacking;
int64_t module_y = module / horizontal_stacking;
for (int m = 0; m < nmodules; m++) {
int64_t module_x = m % horizontal_stacking;
int64_t module_y = m / horizontal_stacking;
int64_t x0 = module_x * (CONVERTED_MODULE_COLS + gap_x);
int64_t y0 = module_y * (CONVERTED_MODULE_LINES + gap_y);
DetectorModuleGeometry::Direction fast = DetectorModuleGeometry::Direction::Xpos;
DetectorModuleGeometry::Direction slow;
if (mirror_y) {
y0 = height - y0 - 1;
slow = DetectorModuleGeometry::Direction::Yneg;
} else
slow = DetectorModuleGeometry::Direction::Ypos;
DetectorModuleGeometry::Direction slow = DetectorModuleGeometry::Direction::Ypos;
modules.emplace_back(x0, y0, fast, slow);
DetectorModuleGeometry mgeom(x0,y0,fast, slow);
if (mirror_y)
mgeom.VerticalFlip(height);
modules.emplace_back(mgeom);
}
}
+1 -1
View File
@@ -15,7 +15,7 @@ class DetectorGeometry {
[[nodiscard]] int64_t GetDirectionStep(DetectorModuleGeometry::Direction direction) const;
[[nodiscard]] static Coord GetDirection(DetectorModuleGeometry::Direction direction) ;
public:
DetectorGeometry(const std::vector<DetectorModuleGeometry> &pixel_0);
DetectorGeometry(const std::vector<DetectorModuleGeometry> &pixel_0, bool vertical_flip = false);
DetectorGeometry(int32_t nmodules,
int32_t horizontal_stacking = 1,
int32_t gap_x = 0,
+17
View File
@@ -68,3 +68,20 @@ DetectorModuleGeometry::Direction DetectorModuleGeometry::GetSlowAxis() const {
DetectorModuleGeometry::Direction DetectorModuleGeometry::GetFastAxis() const {
return fast;
}
void DetectorModuleGeometry::VerticalFlip(std::size_t detector_height) {
if (detector_height - 1 < y0)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Something wrong with detector_height");
if (fast == Direction::Yneg)
fast = Direction::Ypos;
else if (fast == Direction::Ypos)
fast = Direction::Yneg;
if (slow == Direction::Yneg)
slow = Direction::Ypos;
else if (slow == Direction::Ypos)
slow = Direction::Yneg;
y0 = detector_height - y0 - 1;
}
+3
View File
@@ -4,6 +4,7 @@
#define JUNGFRAUJOCH_DETECTORMODULEGEOMETRY_H
#include <cstdint>
#include <cstddef>
#include "Definitions.h"
class DetectorModuleGeometry {
@@ -27,6 +28,8 @@ public:
[[nodiscard]] int64_t GetPixel0_Y() const;
[[nodiscard]] Direction GetSlowAxis() const;
[[nodiscard]] Direction GetFastAxis() const;
void VerticalFlip(size_t detector_height);
};
+16 -2
View File
@@ -4,14 +4,19 @@
#include "JFJochException.h"
DetectorSetup::DetectorSetup(const DetectorGeometry &in_geometry)
: DetectorSetup(in_geometry, "Detector", std::vector<std::string>()) {}
: DetectorSetup(in_geometry, DetectorType::JUNGFRAU, "Detector", std::vector<std::string>()) {}
DetectorSetup::DetectorSetup(const DetectorGeometry &in_geometry, DetectorType in_detector_type)
: DetectorSetup(in_geometry, in_detector_type, "Detector", std::vector<std::string>()) {}
DetectorSetup::DetectorSetup(const DetectorGeometry &in_geometry,
DetectorType in_detector_type,
const std::string &in_description,
const std::vector<std::string> &in_det_modules_hostname) :
geometry(in_geometry),
description(in_description),
det_modules_hostname(in_det_modules_hostname) {
det_modules_hostname(in_det_modules_hostname),
detector_type(in_detector_type) {
if (!det_modules_hostname.empty() && (geometry.GetModulesNum() != det_modules_hostname.size()))
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Mismatch between number of modules in detector geometry and hostname");
@@ -49,6 +54,7 @@ void DetectorSetup::LoadGain(const std::vector<std::string> &filenames) {
if (filenames.size() != GetModulesNum())
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Mismatch in number of gain calibration files");
gain_file_names = filenames;
for (const auto& i: filenames)
gain_calibration.emplace_back(i);
}
@@ -99,3 +105,11 @@ DetectorSetup &DetectorSetup::TxDelay(const std::vector<int64_t> &v) {
const std::vector<int64_t> &DetectorSetup::GetTxDelay() const {
return tx_delay;
}
const std::vector<std::string> &DetectorSetup::GetGainFileNames() const {
return gain_file_names;
}
DetectorType DetectorSetup::GetDetectorType() const {
return detector_type;
}
+10
View File
@@ -6,19 +6,27 @@
#include "DetectorGeometry.h"
#include "../jungfrau/JFModuleGainCalibration.h"
enum class DetectorType {EIGER, JUNGFRAU};
class DetectorSetup {
std::string description;
DetectorGeometry geometry;
std::vector<std::string> det_modules_hostname;
std::vector<std::string> gain_file_names;
std::vector<JFModuleGainCalibration> gain_calibration;
int64_t udp_interface_count = 2;
float pixel_size_um = 75.0f;
std::string sensor_material = "Si";
float sensor_thickness_um = 320.0f;
std::vector<int64_t> tx_delay;
DetectorType detector_type;
public:
// This is implicit constructor from DetectorGeometry with JUNGFRAU!
// TODO: Remove implicit constructor
DetectorSetup(const DetectorGeometry& geom);
DetectorSetup(const DetectorGeometry& geom, DetectorType detector_type);
DetectorSetup(const DetectorGeometry& geom,
DetectorType detector_type,
const std::string &description,
const std::vector<std::string> &det_modules_hostname);
@@ -30,6 +38,7 @@ public:
DetectorSetup& SensorThickness_um(float input);
DetectorSetup& PixelSize_um(float input);
[[nodiscard]] DetectorType GetDetectorType() const;
[[nodiscard]] const DetectorGeometry& GetGeometry() const;
[[nodiscard]] const std::vector<std::string>& GetDetectorModuleHostname() const;
[[nodiscard]] uint64_t GetModulesNum() const;
@@ -40,6 +49,7 @@ public:
[[nodiscard]] const std::vector<JFModuleGainCalibration> &GetGainCalibration() const;
[[nodiscard]] int64_t GetUDPInterfaceCount() const;
[[nodiscard]] const std::vector<int64_t> &GetTxDelay() const; // can be empty for default
[[nodiscard]] const std::vector<std::string> &GetGainFileNames() const;
};
+85 -46
View File
@@ -18,6 +18,8 @@ DiffractionExperiment::DiffractionExperiment(const DetectorSetup& det_setup) : d
dataset.photon_energy_keV = WVL_1A_IN_KEV;
dataset.detector_distance_mm = 100;
dataset.beam_x_pxl = 0.0;
dataset.beam_y_pxl = 0.0;
dataset.data_file_count = 1;
dataset.file_prefix = "test";
@@ -35,6 +37,8 @@ DiffractionExperiment::DiffractionExperiment(const DetectorSetup& det_setup) : d
dataset.save_calibration = false;
dataset.omega_rotation_axis = default_omega_axis;
dataset.photon_energy_multiplier = 1.0f;
internal_fpga_packet_generator = false;
debug_pixel_mask = false;
@@ -73,6 +77,7 @@ DiffractionExperiment::DiffractionExperiment(const DetectorSetup& det_setup) : d
series_id = 0;
conversion_on_fpga = true;
pulsed_source = false;
Mode(DetectorMode::Conversion);
}
@@ -315,17 +320,17 @@ int64_t DiffractionExperiment::GetNumTriggers() const {
case DetectorMode::Raw:
return dataset.ntrigger;
case DetectorMode::PedestalG0:
if (GetPedestalWithExternalTrigger())
if (IsPulsedSource())
return pedestal_g0_frames;
else
return 1;
case DetectorMode::PedestalG1:
if (GetPedestalWithExternalTrigger())
if (IsPulsedSource())
return pedestal_g1_frames;
else
return 1;
case DetectorMode::PedestalG2:
if (GetPedestalWithExternalTrigger())
if (IsPulsedSource())
return pedestal_g2_frames;
else
return 1;
@@ -382,8 +387,6 @@ int64_t DiffractionExperiment::GetImageNumPerTrigger() const {
switch (GetDetectorMode()) {
case DetectorMode::Conversion:
case DetectorMode::Raw:
if (GetStorageCellNumber() > 1)
return GetStorageCellNumber();
return GetFrameNumPerTrigger() / GetSummation();
case DetectorMode::PedestalG0:
case DetectorMode::PedestalG1:
@@ -398,24 +401,17 @@ int64_t DiffractionExperiment::GetFrameNum() const {
}
int64_t DiffractionExperiment::GetFrameNumPerTrigger() const {
if (IsPulsedSource())
return GetStorageCellNumber() * GetSummation();
switch (GetDetectorMode()) {
case DetectorMode::Conversion:
case DetectorMode::Raw:
if (GetStorageCellNumber() > 1)
return GetStorageCellNumber();
else
return dataset.images_per_trigger * GetSummation();
return dataset.images_per_trigger * GetSummation();
case DetectorMode::PedestalG0:
if (GetPedestalWithExternalTrigger())
return GetStorageCellNumber();
return pedestal_g0_frames * GetStorageCellNumber();
case DetectorMode::PedestalG1:
if (GetPedestalWithExternalTrigger())
return GetStorageCellNumber();
return pedestal_g1_frames * GetStorageCellNumber();
case DetectorMode::PedestalG2:
if (GetPedestalWithExternalTrigger())
return GetStorageCellNumber();
return pedestal_g2_frames * GetStorageCellNumber();
default:
return 0;
@@ -512,7 +508,8 @@ bool DiffractionExperiment::IsPixelSigned() const {
return false;
default:
case FPGAPixelOutput::Auto:
if (GetDetectorMode() == DetectorMode::Conversion)
if ((GetDetectorMode() == DetectorMode::Conversion)
&& (detector.GetDetectorType() == DetectorType::JUNGFRAU))
return true;
else
return false;
@@ -577,12 +574,15 @@ int64_t DiffractionExperiment::GetPixel0OfModule(uint16_t module_number) const {
int64_t DiffractionExperiment::GetOverflow() const {
if (GetPixelDepth() == 2)
return INT16_MAX;
return IsPixelSigned() ? INT16_MAX : UINT16_MAX;
else
return INT32_MAX;
return IsPixelSigned() ? INT32_MAX : UINT32_MAX;
}
int64_t DiffractionExperiment::GetUnderflow() const {
if (!IsPixelSigned())
return -1;
if (GetPixelDepth() == 2)
return INT16_MIN;
else
@@ -590,11 +590,10 @@ int64_t DiffractionExperiment::GetUnderflow() const {
}
std::chrono::microseconds DiffractionExperiment::GetPreviewPeriod() const {
return preview_period;
}
int64_t DiffractionExperiment::GetPreviewStride() const {
return GetPreviewStride(GetPreviewPeriod());
if (GetDetectorMode() == DetectorMode::Conversion)
return preview_period;
else
return std::chrono::microseconds(0);
}
int64_t DiffractionExperiment::GetSpotFindingBin() const {
@@ -604,15 +603,6 @@ int64_t DiffractionExperiment::GetSpotFindingBin() const {
return 200*1000 / GetImageTime().count(); // 1 bin = 1 second
}
int64_t DiffractionExperiment::GetPreviewStride(std::chrono::microseconds period) const {
switch (GetDetectorMode()) {
case DetectorMode::Conversion:
return CalculateStride(GetImageTime(), period);
default:
return 0;
}
}
bool DiffractionExperiment::IsUsingInternalPacketGen() const {
return internal_fpga_packet_generator;
}
@@ -620,10 +610,10 @@ bool DiffractionExperiment::IsUsingInternalPacketGen() const {
uint32_t DiffractionExperiment::GetSrcIPv4Address(uint32_t data_stream, uint32_t half_module) const {
if (data_stream >= GetDataStreamsNum())
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Non existing data stream");
if (half_module >= 2 * GetModulesNum(data_stream))
if (half_module >= detector.GetUDPInterfaceCount() * GetModulesNum(data_stream))
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Non existing module");
uint32_t host = half_module + 2 * GetFirstModuleOfDataStream(data_stream);
uint32_t host = half_module + detector.GetUDPInterfaceCount() * GetFirstModuleOfDataStream(data_stream);
return ipv4_base_addr + (host << 24);
}
@@ -747,8 +737,6 @@ void DiffractionExperiment::FillMessage(StartMessage &message) const {
message.pixel_size_y = GetPixelSize_mm() * 1e-3f;
message.sensor_material = detector.GetSensorMaterial();
message.sensor_thickness = detector.GetSensorThickness_um() * 1e-6f;
message.compression_algorithm = GetCompressionAlgorithm();
message.compression_block_size = JFJochBitShuffleCompressor::DefaultBlockSize;
message.pixel_bit_depth = GetPixelDepth() * 8;
message.storage_cell_number = GetStorageCellNumber();
message.storage_cell_delay_ns = GetStorageCellDelay().count();
@@ -776,12 +764,19 @@ void DiffractionExperiment::FillMessage(StartMessage &message) const {
message.user_data = GetHeaderAppendix();
message.roi_summation_area = GetROISummation();
message.countrate_correction_enabled = false;
message.flatfield_enabled = false;
if (GetOmegaStep())
message.goniometer["omega"] = GoniometerAxis{.increment = GetOmegaStep().value(), .start = GetOmegaStart(),
.axis = {GetOmegaAxis().x, GetOmegaAxis().y, GetOmegaAxis().z}};
message.omega = GoniometerAxis{.increment = GetOmegaStep().value(), .start = GetOmegaStart(),
.axis = {GetOmegaAxis().x, GetOmegaAxis().y, GetOmegaAxis().z}};
else
message.omega = GoniometerAxis{.increment = 0.0f};
message.series_id = GetSeriesID();
message.series_unique_id = GetSeriesIDString();
message.gain_file_names = detector.GetGainFileNames();
}
DiffractionExperiment &DiffractionExperiment::ApplyPixelMaskInFPGA(bool input) {
@@ -858,10 +853,6 @@ std::string DiffractionExperiment::GetDetectorDescription() const {
return detector.GetDescription();
}
bool DiffractionExperiment::GetPedestalWithExternalTrigger() const {
return (GetStorageCellNumber() > 1);
}
DiffractionExperiment &DiffractionExperiment::ApplySolidAngleCorr(bool input) {
dataset.rad_int_solid_angle_corr = input;
return *this;
@@ -961,8 +952,13 @@ DiffractionExperiment::GetDetectorModuleConfig(const std::vector<AcquisitionDevi
DetectorModuleConfig mod_cfg;
mod_cfg.udp_dest_port_1 = net_config[d].udp_port;
mod_cfg.udp_dest_port_2 = net_config[d].udp_port;
mod_cfg.ipv4_src_addr_1 = IPv4AddressToStr(GetSrcIPv4Address(d, 2 * m));
mod_cfg.ipv4_src_addr_2 = IPv4AddressToStr(GetSrcIPv4Address(d, 2 * m + 1));
if (detector.GetUDPInterfaceCount() == 2) {
mod_cfg.ipv4_src_addr_1 = IPv4AddressToStr(GetSrcIPv4Address(d, 2 * m));
mod_cfg.ipv4_src_addr_2 = IPv4AddressToStr(GetSrcIPv4Address(d, 2 * m + 1));
} else {
mod_cfg.ipv4_src_addr_1 = IPv4AddressToStr(GetSrcIPv4Address(d, m));
mod_cfg.ipv4_src_addr_2 = IPv4AddressToStr(GetSrcIPv4Address(d, m)); // not used, settings just in case
}
mod_cfg.ipv4_dest_addr_1 = net_config[d].ipv4_addr;
mod_cfg.ipv4_dest_addr_2 = net_config[d].ipv4_addr;
mod_cfg.mac_addr_dest_1 = net_config[d].mac_addr;
@@ -1008,7 +1004,7 @@ DiffractionExperiment &DiffractionExperiment::OmegaStep(const std::optional<floa
return *this;
}
DiffractionExperiment &DiffractionExperiment::OmegaStart(const float input) {
DiffractionExperiment &DiffractionExperiment::OmegaStart(float input) {
dataset.omega_start = input;
return *this;
}
@@ -1129,7 +1125,8 @@ DiffractionExperiment &DiffractionExperiment::ConversionOnFPGA(bool input) {
}
bool DiffractionExperiment::IsConversionOnFPGA() const {
if (GetDetectorMode() == DetectorMode::Conversion)
if ((GetDetectorMode() == DetectorMode::Conversion)
&& (detector.GetDetectorType() == DetectorType::JUNGFRAU))
return conversion_on_fpga;
else
return false;
@@ -1156,3 +1153,45 @@ DiffractionExperiment &DiffractionExperiment::NeuralNetModelPath(const std::stri
std::string DiffractionExperiment::GetNeuralNetModelPath() const {
return neural_net_model_path;
}
DiffractionExperiment &DiffractionExperiment::PulsedSource(bool input) {
pulsed_source = input;
return *this;
}
bool DiffractionExperiment::IsPulsedSource() const {
if (GetStorageCellNumber() > 1)
return true;
else
return pulsed_source;
}
bool DiffractionExperiment::IsSpotFindingEnabled() const {
if (GetDetectorMode() == DetectorMode::Conversion)
return true;
else
return false;
}
DiffractionExperiment &DiffractionExperiment::PhotonEnergyMultiplayer(float input) {
check_min("Photon energy multiplier", input, 1/64.f);
check_max("Photon energy multiplier", input, 4.f);
if ((GetDetectorSetup().GetDetectorType() == DetectorType::EIGER)
&& (input != 1.0f))
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"For EIGER cannot set photon energy multiplier");
dataset.photon_energy_multiplier = input;
return *this;
}
float DiffractionExperiment::GetPhotonEnergyForConversion_keV() const {
return GetPhotonEnergyMultiplier() * GetPhotonEnergy_keV();
}
float DiffractionExperiment::GetPhotonEnergyMultiplier() const {
if ((GetDetectorSetup().GetDetectorType() == DetectorType::JUNGFRAU)
&& (GetDetectorMode() == DetectorMode::Conversion))
return dataset.photon_energy_multiplier;
else
return 1.0f;
}
+13 -4
View File
@@ -83,6 +83,7 @@ class DiffractionExperiment {
std::string source_name_short;
std::string instrument_name;
std::string instrument_name_short;
bool pulsed_source;
bool debug_pixel_mask;
Coord default_omega_axis;
@@ -105,6 +106,7 @@ class DiffractionExperiment {
float beam_y_pxl;
float detector_distance_mm;
float photon_energy_keV;
float photon_energy_multiplier;
std::string file_prefix;
int64_t data_file_count;
@@ -187,7 +189,7 @@ public:
DiffractionExperiment& AttenuatorTransmission(const std::optional<float> &input);
DiffractionExperiment& TotalFlux(const std::optional<float> &input);
DiffractionExperiment& OmegaStep(const std::optional<float> &input);
DiffractionExperiment& OmegaStart(const float input);
DiffractionExperiment& OmegaStart(float input);
DiffractionExperiment& OmegaAxis(const Coord &c);
DiffractionExperiment& OmegaAxis();
DiffractionExperiment& DefaultOmegaAxis(const Coord &c);
@@ -200,6 +202,8 @@ public:
DiffractionExperiment& ROISummation(const std::optional<ROIRectangle>& input);
DiffractionExperiment& ConversionOnFPGA(bool input);
DiffractionExperiment& NeuralNetModelPath(const std::string& input);
DiffractionExperiment& PulsedSource(bool input);
DiffractionExperiment& PhotonEnergyMultiplayer(float input);
void FillMessage(StartMessage &message) const;
@@ -266,11 +270,9 @@ public:
Coord GetModuleSlowDirection(uint16_t module_number) const;
std::chrono::microseconds GetPreviewPeriod() const;
int64_t GetPreviewStride() const;
int64_t GetSpotFindingBin() const;
int64_t GetPreviewStride(std::chrono::microseconds period) const;
bool IsUsingInternalPacketGen() const;
uint32_t GetSrcIPv4Address(uint32_t data_stream, uint32_t half_module) const;
@@ -308,7 +310,6 @@ public:
std::string GetDetectorDescription() const;
std::vector<std::string> GetDetectorModuleHostname() const;
bool GetPedestalWithExternalTrigger() const;
DiffractionExperiment& ApplySolidAngleCorr(bool input);
DiffractionExperiment& ApplyPolarizationCorr(bool input);
@@ -347,6 +348,14 @@ public:
const DetectorSetup& GetDetectorSetup() const;
std::string GetNeuralNetModelPath() const;
bool IsPulsedSource() const;
bool IsSpotFindingEnabled() const;
float GetPhotonEnergyForConversion_keV() const;
float GetPhotonEnergyMultiplier() const;
};
inline int64_t CalculateStride(const std::chrono::microseconds &frame_time, const std::chrono::microseconds &preview_time) {
+17 -51
View File
@@ -6,6 +6,7 @@
#include "DiffractionExperiment.h"
#include <cmath>
#include "RawToConvertedGeometry.h"
#include "JFJochException.h"
inline Coord DetectorToRecip(const DiffractionExperiment &experiment, float x, float y) {
return experiment.LabCoord(x, y).Normalize() / experiment.GetWavelength_A() - experiment.GetScatteringVector();
@@ -56,78 +57,43 @@ inline float DistFromEwaldSphere(const DiffractionExperiment& experiment, const
return fabsf(S.Length() - (1.0f/experiment.GetWavelength_A()));
}
inline float CalcRadIntSolidAngleCorr(const DiffractionExperiment& experiment, float q) {
inline float CalcAzIntSolidAngleCorr(const DiffractionExperiment& experiment, float q) {
float sin_theta = q * experiment.GetWavelength_A() / (4 * static_cast<float>(M_PI));
float cos_2theta = 1.0f - 2.0f * sin_theta * sin_theta; // cos(2*alpha) = 1 - 2 * sin(alpha)^2
float cos_2theta_3 = cos_2theta * cos_2theta * cos_2theta;
return cos_2theta_3;
}
inline float CalcRadIntSolidAngleCorr(const DiffractionExperiment& experiment, float x, float y) {
inline float CalcAzIntSolidAngleCorr(const DiffractionExperiment& experiment, float x, float y) {
float cos_2theta = CosTwoTheta(experiment, x, y);
float cos_2theta_3 = cos_2theta * cos_2theta * cos_2theta;
return cos_2theta_3;
}
inline float CalcRadIntPolarizationCorr(const DiffractionExperiment& experiment, float x, float y) {
inline float CalcAzIntPolarizationCorr(const DiffractionExperiment& experiment, float x, float y) {
auto cos_2theta = CosTwoTheta(experiment, x, y);
float cos_2theta_2 = cos_2theta * cos_2theta;
float cos_2phi = cosf(2.0f * Phi(experiment, x, y));
return 0.5f * (1.0f + cos_2theta_2 - experiment.GetPolarizationFactor() * cos_2phi * (1.0f - cos_2theta_2));
}
inline std::vector<float> CalcRadIntCorr(const DiffractionExperiment& experiment) {
std::vector<float> corr(experiment.GetPixelsNum(), 1.0);
auto xpixels = experiment.GetXPixelsNum();
auto ypixels = experiment.GetYPixelsNum();
for (int y = 0; y < ypixels; y++) {
for (int x = 0; x < xpixels; x++) {
if (experiment.GetApplySolidAngleCorr())
corr[y * xpixels + x] *= CalcRadIntSolidAngleCorr(experiment,
static_cast<float>(x),
static_cast<float>(y));
if (experiment.GetApplyPolarizationCorr())
corr[y * xpixels + x] *= CalcRadIntPolarizationCorr(experiment,
static_cast<float>(x),
static_cast<float>(y));
}
inline void CalcAzIntCorrRawCoord(float *output, const DiffractionExperiment& experiment, size_t module_number) {
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
auto [x,y] = RawToConvertedCoordinate(experiment, module_number, i);
if (experiment.GetApplySolidAngleCorr())
output[i] *= CalcAzIntSolidAngleCorr(experiment, static_cast<float>(x), static_cast<float>(y));
if (experiment.GetApplyPolarizationCorr())
output[i] *= CalcAzIntPolarizationCorr(experiment, static_cast<float>(x), static_cast<float>(y));
}
return corr;
}
inline std::vector<float> CalcRadIntCorrRawCoord(const DiffractionExperiment& experiment) {
std::vector<float> corr(experiment.GetModulesNum() * RAW_MODULE_SIZE, 1.0);
for (int m = 0; m < experiment.GetModulesNum(); m++) {
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
auto [x,y] = RawToConvertedCoordinate(experiment, m, i);
if (experiment.GetApplySolidAngleCorr())
corr[m * RAW_MODULE_SIZE + i] *= CalcRadIntSolidAngleCorr(experiment,
static_cast<float>(x),
static_cast<float>(y));
if (experiment.GetApplyPolarizationCorr())
corr[m * RAW_MODULE_SIZE + i] *= CalcRadIntPolarizationCorr(experiment,
static_cast<float>(x),
static_cast<float>(y));
}
inline void CalcSpotFinderResolutionMap(float *data, const DiffractionExperiment& experiment, size_t module_number) {
if (module_number >= experiment.GetModulesNum())
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Wrong module number");
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
auto [x,y] = RawToConvertedCoordinate(experiment, module_number, i);
data[i] = PxlToRes(experiment, static_cast<float>(x), static_cast<float>(y));
}
return corr;
}
inline std::vector<float> CalcSpotFinderResolutionMap(const DiffractionExperiment& experiment) {
std::vector<float> corr(experiment.GetModulesNum() * RAW_MODULE_SIZE, 1.0);
for (int m = 0; m < experiment.GetModulesNum(); m++) {
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
auto [x,y] = RawToConvertedCoordinate(experiment, m, i);
corr[m * RAW_MODULE_SIZE + i] = PxlToRes(experiment, static_cast<float>(x), static_cast<float>(y));
}
}
return corr;
}
#endif //JUNGFRAUJOCH_DIFFRACTIONGEOMETRY_H
+38
View File
@@ -78,4 +78,42 @@ void RawToConvertedGeometryAdjustMultipixels(const DiffractionExperiment &experi
}
}
inline void RawToEigerInput(uint16_t *dest, const uint16_t *source) {
// bottom left corner
for (int packet = 0; packet < 64; packet++) {
for (int i = 0; i < 2048; i++) {
size_t line = packet * 4 + (3 - i / 512);
size_t col = i % 512;
dest[(126 - (packet * 2)) * 2048 + i] = source[line * RAW_MODULE_COLS + col];
}
}
// bottom right corner
for (int packet = 0; packet < 64; packet++) {
for (int i = 0; i < 2048; i++) {
size_t line = packet * 4 + (3 - i / 512);
size_t col = 512 + i % 512;
dest[(127 - (packet * 2)) * 2048 + i] = source[line * RAW_MODULE_COLS + col];
}
}
// top left corner
for (int packet = 0; packet < 64; packet++) {
for (int i = 0; i < 2048; i++) {
size_t line = 256 + packet * 4 + i / 512;
size_t col = i % 512;
dest[(128 + (packet * 2)) * 2048 + i] = source[line * RAW_MODULE_COLS + col];
}
}
// top right corner
for (int packet = 0; packet < 64; packet++) {
for (int i = 0; i < 2048; i++) {
size_t line = 256 + packet * 4 + i / 512;
size_t col = 512 + i % 512;
dest[(129 + (packet * 2)) * 2048 + i] = source[line * RAW_MODULE_COLS + col];
}
}
}
#endif
+93 -71
View File
@@ -2,13 +2,13 @@
#include <thread>
#include "DetectorWrapper.h"
#include "../common/JFJochException.h"
#include "../common/Definitions.h"
#include "DetectorWrapper.h"
void DetectorWrapper::Configure(const DiffractionExperiment& experiment,
const std::vector<AcquisitionDeviceNetConfig>& net_config) {
logger.Info("Configure");
void DetectorWrapper::Initialize(const DiffractionExperiment& experiment,
const std::vector<AcquisitionDeviceNetConfig>& net_config) {
logger.Info("Initialize detector");
try {
if (det.size() > 0) {
// Only if the detector is already defined
@@ -21,10 +21,21 @@ void DetectorWrapper::Configure(const DiffractionExperiment& experiment,
det.setSynchronization(false);
}
auto module_hostname = experiment.GetDetectorModuleHostname();
auto det_module_hostname = det.getHostname();
if (!module_hostname.empty() > 0) {
logger.Info("Resetting detector module host names");
det.setHostname(module_hostname);
if (!module_hostname.empty()) {
bool reset = true;
if (module_hostname.size() == det_module_hostname.size()) {
reset = false;
for (int i = 0; i < module_hostname.size(); i++) {
if (module_hostname[i] != det_module_hostname[i])
reset = true;
}
}
if (reset) {
logger.Info("Resetting detector module host names");
det.setHostname(module_hostname);
}
}
if (det.size() != experiment.GetModulesNum()) {
@@ -72,6 +83,17 @@ void DetectorWrapper::Configure(const DiffractionExperiment& experiment,
det.setMaster(true, 0);
det.setSynchronization(true);
auto tx_delay = experiment.GetDetectorSetup().GetTxDelay();
if (tx_delay.size() == experiment.GetModulesNum()) {
for (int i = 0 ; i < tx_delay.size(); i++)
det.setTransmissionDelayFrame(tx_delay[i], {i});
}
if (experiment.GetUDPInterfaceCount() == 2)
det.setReadoutSpeed(slsDetectorDefs::speedLevel::FULL_SPEED);
else
det.setReadoutSpeed(slsDetectorDefs::speedLevel::HALF_SPEED);
det.setAutoComparatorDisable(true);
if (!det.getPowerChip().squash(false)) {
det.setPowerChip(true);
@@ -95,71 +117,13 @@ void DetectorWrapper::Start(const DiffractionExperiment& experiment) {
try {
InternalStop();
if (experiment.IsFixedGainG1()) {
if ((experiment.GetDetectorMode() == DetectorMode::PedestalG0) ||
(experiment.GetDetectorMode() == DetectorMode::PedestalG2))
throw JFJochException(JFJochExceptionCategory::Detector,
"Pedestal G0/G2 doesn't make sense for fixed G1 mode");
det.setGainMode(slsDetectorDefs::FIX_G1);
} else {
switch (experiment.GetDetectorMode()) {
case DetectorMode::PedestalG1:
det.setGainMode(slsDetectorDefs::gainMode::FORCE_SWITCH_G1);
break;
case DetectorMode::PedestalG2:
det.setGainMode(slsDetectorDefs::gainMode::FORCE_SWITCH_G2);
break;
default:
det.setGainMode(slsDetectorDefs::gainMode::DYNAMIC);
break;
}
}
auto tx_delay = experiment.GetDetectorSetup().GetTxDelay();
if (tx_delay.size() == experiment.GetModulesNum()) {
for (int i = 0 ; i < tx_delay.size(); i++)
det.setTransmissionDelayFrame(tx_delay[i], {i});
}
if (experiment.IsUsingGainHG0())
det.setSettings(slsDetectorDefs::HIGHGAIN0);
else
det.setSettings(slsDetectorDefs::GAIN0);
det.setDelayAfterTrigger(experiment.GetDetectorDelay());
det.setNextFrameNumber(1);
if (experiment.GetNumTriggers() == 1) {
if ((experiment.GetStorageCellNumber() == 1) && (!experiment.IsPulsedSource()))
det.setNumberOfFrames(experiment.GetFrameNumPerTrigger() + DELAY_FRAMES_STOP_AND_QUIT);
det.setNumberOfTriggers(1);
} else {
// More than 1 trigger - detector needs one trigger or few more trigger
if (experiment.GetStorageCellNumber() > 1)
det.setNumberOfFrames(1);
else
det.setNumberOfFrames(experiment.GetFrameNumPerTrigger());
if (experiment.GetFrameNumPerTrigger() < DELAY_FRAMES_STOP_AND_QUIT)
det.setNumberOfTriggers(experiment.GetNumTriggers() + DELAY_FRAMES_STOP_AND_QUIT);
else
det.setNumberOfTriggers(experiment.GetNumTriggers() + 1);
}
det.setStorageCellStart(experiment.GetStorageCellStart());
det.setNumberOfAdditionalStorageCells(experiment.GetStorageCellNumber() - 1);
det.setStorageCellDelay(experiment.GetStorageCellDelay() - std::chrono::nanoseconds(MIN_STORAGE_CELL_DELAY_IN_NS));
if ((experiment.GetStorageCellNumber() > 1) || (experiment.GetFrameTime().count() < MIN_FRAME_TIME_HALF_SPEED_IN_US))
det.setReadoutSpeed(slsDetectorDefs::speedLevel::FULL_SPEED);
else
det.setReadoutSpeed(slsDetectorDefs::speedLevel::HALF_SPEED);
if (experiment.GetStorageCellNumber() > 1) {
det.setPeriod((experiment.GetFrameTime() + std::chrono::microseconds(10)) * experiment.GetStorageCellNumber() );
} else
det.setPeriod(experiment.GetFrameTime());
det.setExptime(std::chrono::microseconds(experiment.GetFrameCountTime()));
det.setNumberOfTriggers(experiment.GetNumTriggers());
det.startDetector();
} catch (std::exception &e) {
@@ -174,14 +138,14 @@ void DetectorWrapper::InternalStop() {
// Assume it is executed in try-catch!
auto state = GetState();
if (state == DetectorState::ERROR)
throw JFJochException(JFJochExceptionCategory::Detector,
"Detector in error state");
throw JFJochException(JFJochExceptionCategory::Detector, "Detector in error state");
else if (state == DetectorState::BUSY) {
try {
det.stopDetector();
} catch (...) {
// Sometimes stop gives problem - ignore these
logger.Warning("Problem with stopping the detector - ignored.");
det.stopDetector();
} catch (...) {}
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
state = GetState();
if (state != DetectorState::IDLE)
@@ -197,6 +161,7 @@ void DetectorWrapper::Deactivate() {
det.setHighVoltage(0);
std::this_thread::sleep_for(std::chrono::seconds(5));
det.setPowerChip(false);
det.freeSharedMemory();
} catch (std::exception &e) {
logger.ErrorException(e);
throw JFJochException(JFJochExceptionCategory::Detector, e.what());
@@ -304,6 +269,19 @@ std::vector<int64_t> DetectorWrapper::GetFPGATemperatures() const {
}
}
std::vector<int64_t> DetectorWrapper::GetHighVoltage() const {
try {
auto result = det.getHighVoltage();
std::vector<int64_t> ret;
for (int i = 0; i < result.size(); i++)
ret.push_back(result[i]);
return ret;
} catch (std::exception &e) {
throw JFJochException(JFJochExceptionCategory::Detector, e.what());
}
}
DetectorStatus DetectorWrapper::GetStatus() const {
DetectorStatus status;
status.detector_server_version = GetDetectorServerVersion();
@@ -311,5 +289,49 @@ DetectorStatus DetectorWrapper::GetStatus() const {
status.power_state = GetPowerState();
status.remaining_triggers = GetNumberOfTriggersLeft();
status.temperature_fpga_degC = GetFPGATemperatures();
status.high_voltage_V = GetHighVoltage();
return status;
}
void DetectorWrapper::Configure(const DiffractionExperiment &experiment) {
if (experiment.IsFixedGainG1()) {
if ((experiment.GetDetectorMode() == DetectorMode::PedestalG0) ||
(experiment.GetDetectorMode() == DetectorMode::PedestalG2))
throw JFJochException(JFJochExceptionCategory::Detector,
"Pedestal G0/G2 doesn't make sense for fixed G1 mode");
det.setGainMode(slsDetectorDefs::FIX_G1);
} else {
switch (experiment.GetDetectorMode()) {
case DetectorMode::PedestalG1:
det.setGainMode(slsDetectorDefs::gainMode::FORCE_SWITCH_G1);
break;
case DetectorMode::PedestalG2:
det.setGainMode(slsDetectorDefs::gainMode::FORCE_SWITCH_G2);
break;
default:
det.setGainMode(slsDetectorDefs::gainMode::DYNAMIC);
break;
}
}
det.setStorageCellStart(experiment.GetStorageCellStart());
det.setNumberOfAdditionalStorageCells(experiment.GetStorageCellNumber() - 1);
det.setStorageCellDelay(experiment.GetStorageCellDelay() - std::chrono::nanoseconds(MIN_STORAGE_CELL_DELAY_IN_NS));
if ((experiment.GetStorageCellNumber() > 1) || (experiment.IsPulsedSource()))
det.setNumberOfFrames(1);
if (experiment.IsPulsedSource()) {
det.setPeriod((experiment.GetFrameCountTime() + std::chrono::microseconds(10)) * experiment.GetStorageCellNumber() );
} else
det.setPeriod(experiment.GetFrameTime());
det.setExptime(std::chrono::microseconds(experiment.GetFrameCountTime()));
if (experiment.IsUsingGainHG0())
det.setSettings(slsDetectorDefs::HIGHGAIN0);
else
det.setSettings(slsDetectorDefs::GAIN0);
det.setDelayAfterTrigger(experiment.GetDetectorDelay());
}
+6 -3
View File
@@ -9,13 +9,14 @@
#define BASE_DETECTOR_MAC 0xAABBCCDDEE10 // little-endian!
#define HIGH_VOLTAGE 120
#define THRESHOLD_TEMPERATURE_DEGC 60
#define THRESHOLD_TEMPERATURE_DEGC 55
enum class DetectorState {IDLE, ERROR, BUSY, WAITING};
enum class DetectorPowerState {ON, OFF, PARTIAL};
struct DetectorStatus {
std::vector<int64_t> temperature_fpga_degC;
std::vector<int64_t> high_voltage_V;
DetectorState detector_state;
DetectorPowerState power_state;
std::string detector_server_version;
@@ -26,14 +27,16 @@ class DetectorWrapper {
Logger logger{"DetectorWrapper"};
sls::Detector det;
void InternalStop();
[[nodiscard]] DetectorState GetState() const;
[[nodiscard]] int64_t GetNumberOfTriggersLeft() const;
[[nodiscard]] DetectorPowerState GetPowerState() const;
int64_t GetFirmwareVersion() const;
std::string GetDetectorServerVersion() const;
std::vector<int64_t> GetFPGATemperatures() const;
std::vector<int64_t> GetHighVoltage() const;
public:
void Configure(const DiffractionExperiment& experiment, const std::vector<AcquisitionDeviceNetConfig>& net_config);
[[nodiscard]] DetectorState GetState() const;
void Initialize(const DiffractionExperiment& experiment, const std::vector<AcquisitionDeviceNetConfig>& net_config);
void Configure(const DiffractionExperiment& experiment);
void Start(const DiffractionExperiment& experiment);
void Stop();
void Trigger();
+90
View File
@@ -0,0 +1,90 @@
{
"cfg": {
"source_name": "SwissFEL",
"source_name_short": "SwissFEL",
"instrument_name": "CristallinaMX",
"instrument_name_short": "CrMX",
"datastreams": 1,
"pedestal_g0_frames": 2000,
"pedestal_g1_frames": 300,
"pedestal_g2_frames": 300,
"frame_time_us": "1000 us",
"count_time_us": "10 us",
"preview_period_us": "1 s",
"detector_ipv4": "10.3.30.155",
"pulsed_source": true
},
"frontend_directory":"/home/jungfrau/nextgendcu/frontend/build",
"numa_policy": "n2g4",
"zmq_image_addr": ["tcp://0.0.0.0:5500"],
"zmq_preview_addr": "tcp://0.0.0.0:5400",
"receiver_threads": 64,
"send_buffer_count": 2048,
"devices": {
"type": "pcie",
"count": 1,
"ipv4_addr": ["10.3.30.200"]
},
"detectors": [
{
"custom_geometry": [
{"x0": 607, "y0": 0, "fast_axis":"Xp", "slow_axis":"Yp"},
{"x0": 1646, "y0": 69, "fast_axis":"Xp", "slow_axis":"Yp"},
{"x0": 607, "y0": 550, "fast_axis":"Xp", "slow_axis":"Yp"},
{"x0": 1646, "y0": 619, "fast_axis":"Xp", "slow_axis":"Yp"},
{"x0": 607, "y0": 1100, "fast_axis":"Xp", "slow_axis":"Yp"},
{"x0": 1646, "y0": 1169, "fast_axis":"Xp", "slow_axis":"Yp"},
{"x0": 538, "y0": 1650, "fast_axis":"Xp", "slow_axis":"Yp"},
{"x0": 1577, "y0": 1719, "fast_axis":"Xp", "slow_axis":"Yp"},
{"x0": 538, "y0": 2200, "fast_axis":"Xp", "slow_axis":"Yp"},
{"x0": 1577, "y0": 2269, "fast_axis":"Xp", "slow_axis":"Yp"},
{"x0": 538, "y0": 2750, "fast_axis":"Xp", "slow_axis":"Yp"},
{"x0": 1577, "y0": 2819, "fast_axis":"Xp", "slow_axis":"Yp"},
{"x0": 583, "y0": 597, "fast_axis":"Yp", "slow_axis":"Xn"},
{"x0": 3212, "y0": 667, "fast_axis":"Yp", "slow_axis":"Xn"},
{"x0": 514, "y0": 1636, "fast_axis":"Yp", "slow_axis":"Xn"},
{"x0": 3143, "y0": 1706, "fast_axis":"Yp", "slow_axis":"Xn"}
],
"custom_geometry_mirror_y": true,
"description": "PSI JUNGFRAU 8M (CrMX)",
"udp_interface_count": 1,
"tx_delay": [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1],
"module_hostname": [
"jf8MA-00",
"jf8MA-01",
"jf8MA-02",
"jf8MA-03",
"jf8MA-04",
"jf8MA-05",
"jf8MA-06",
"jf8MA-07",
"jf8MA-08",
"jf8MA-09",
"jf8MA-10",
"jf8MA-11",
"jf8MA-12",
"jf8MA-13",
"jf8MA-14",
"jf8MA-15"
],
"gain_files": [
"/opt/jfjoch/gainmaps/CrMX/gainMaps_M023_2022-04-26.bin",
"/opt/jfjoch/gainmaps/CrMX/gainMaps_M263_2019-08-15.bin",
"/opt/jfjoch/gainmaps/CrMX/gainMaps_M521_2022-04-26.bin",
"/opt/jfjoch/gainmaps/CrMX/gainMaps_M523_2022-04-26.bin",
"/opt/jfjoch/gainmaps/CrMX/gainMaps_M515_2022-04-26.bin",
"/opt/jfjoch/gainmaps/CrMX/gainMaps_M518_2022-04-26.bin",
"/opt/jfjoch/gainmaps/CrMX/gainMaps_M513_2022-04-26.bin",
"/opt/jfjoch/gainmaps/CrMX/gainMaps_M514_2022-04-26.bin",
"/opt/jfjoch/gainmaps/CrMX/gainMaps_M392_2022-04-26.bin",
"/opt/jfjoch/gainmaps/CrMX/gainMaps_M394_2022-04-26.bin",
"/opt/jfjoch/gainmaps/CrMX/gainMaps_M035_2019-07-29.bin",
"/opt/jfjoch/gainmaps/CrMX/gainMaps_M064_2022-04-26.bin",
"/opt/jfjoch/gainmaps/CrMX/gainMaps_M349_2022-04-26.bin",
"/opt/jfjoch/gainmaps/CrMX/gainMaps_M125_2019-07-29.bin",
"/opt/jfjoch/gainmaps/CrMX/gainMaps_M239_2022-04-26.bin",
"/opt/jfjoch/gainmaps/CrMX/gainMaps_M086_2019-07-29.bin"
]
}
]
}
+73
View File
@@ -0,0 +1,73 @@
{
"services": {},
"cfg": {
"source_name": "Swiss Light Source",
"source_name_short": "SLS",
"instrument_name": "X06SA VESPA",
"instrument_name_short": "VESPA",
"datastreams": 2,
"pedestal_g0_frames": 2000,
"pedestal_g1_frames": 300,
"pedestal_g2_frames": 300,
"frame_time_us": "1000 us",
"count_time_us": "980 us",
"spot_finding_period_us": "5 ms",
"preview_period_us": "1 s",
"detector_ipv4": "10.10.85.20"
},
"frontend_directory": "/home/leonarski_f/nextgendcu/frontend_ui/build/",
"detectors": [
{
"standard_geometry": {
"nmodules": 8,
"horizontal_stacking": 2,
"gap_x": 8,
"gap_y": 36,
"mirror_y": true
},
"description": "PSI JUNGFRAU 4M",
"module_hostname": [
"10.10.10.10",
"10.10.10.11",
"10.10.10.12",
"10.10.10.13",
"10.10.10.14",
"10.10.10.15",
"10.10.10.16",
"10.10.10.17"
],
"gain_files": [
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin"
]
},
{
"standard_geometry": {
"nmodules": 4,
"horizontal_stacking": 2,
"gap_x": 8,
"gap_y": 36,
"mirror_y": true
},
"description": "PSI JUNGFRAU 4M (2M ROI)",
"module_hostname": [
"10.10.10.12",
"10.10.10.13",
"10.10.10.14",
"10.10.10.15"
],
"gain_files": [
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin"
]
}
]
}
+2 -2
View File
@@ -115,8 +115,8 @@ std::vector<uint16_t> GenerateDioptasPreview(const void* input, size_t xpixel, s
for (int y = 0; y < ypixel; y++) {
for (int x = 0; x < xpixel; x++) {
T val = input_ptr[(ypixel - 1 - y) * xpixel + x];
if ((val == special_value) || (val >= UINT16_MAX))
vec[y * xpixel + x] = UINT16_MAX;
if ((val == special_value) || (val >= INT16_MAX))
vec[y * xpixel + x] = INT16_MAX;
else if (val <= 0)
vec [y * xpixel + x] = 0;
else
+1 -1
View File
@@ -17,7 +17,7 @@ void WriteTIFF(TIFF *tiff, void *buff, size_t cols, size_t lines, size_t elem_si
TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, lines); // set the height of the image
TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1); // set number of channels per pixel
TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, elem_size * 8); // set the size of the channels
TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_LZW); // setc ompression to LZW
TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_NONE); // setc ompression to LZW
TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, lines);
if (is_signed)
TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
+11 -7
View File
@@ -19,13 +19,17 @@ ADD_SUBDIRECTORY(pcie_driver)
ADD_SUBDIRECTORY(host_library)
IF(VIVADO_HLS AND VIVADO)
ADD_CUSTOM_COMMAND(OUTPUT action/hw/hdl/action_config.v
COMMAND ${CMAKE_COMMAND} -E env SRC_DIR=${CMAKE_CURRENT_SOURCE_DIR} HLS_IP_DIR=${CMAKE_CURRENT_BINARY_DIR}/action/ip/hls bash ${CMAKE_CURRENT_SOURCE_DIR}/scripts/setup_action.sh
DEPENDS hls hdl/action_config.v hdl/gen_xdma_descriptor.v hdl/eth_4x10g_leds.v scripts/bd_pcie.tcl scripts/jfjoch.tcl scripts/network_stack.tcl scripts/hbm_u55c.tcl scripts/mac_100g_pcie.tcl scripts/pcie_dma.tcl scripts/setup_action.sh
)
ADD_CUSTOM_TARGET(action_pcie DEPENDS action/hw/hdl/action_config.v hls
ADD_CUSTOM_TARGET(pcie_100g DEPENDS hls
COMMAND ${CMAKE_COMMAND} -E env VARIANT=0 SRC_DIR=${CMAKE_CURRENT_SOURCE_DIR} HLS_IP_DIR=${CMAKE_CURRENT_BINARY_DIR}/action/ip/hls bash ${CMAKE_CURRENT_SOURCE_DIR}/scripts/setup_action.sh
COMMAND ${VIVADO} -notrace -mode batch -source ${CMAKE_CURRENT_SOURCE_DIR}/scripts/build_pcie_design.tcl
COMMAND ${CMAKE_COMMAND} -E env FLOW=pcie_100gbit VIV_PROJECT_PATH=${CMAKE_CURRENT_BINARY_DIR}/vivado/jfjoch_pcie.xpr ${VIVADO} -notrace -mode batch -source ${CMAKE_CURRENT_BINARY_DIR}/action/scripts/synth_and_impl.tcl
COMMAND ${CMAKE_COMMAND} -E env FLOW=pcie_100g VIV_PROJECT_PATH=${CMAKE_CURRENT_BINARY_DIR}/vivado/jfjoch_pcie.xpr ${VIVADO} -notrace -mode batch -source ${CMAKE_CURRENT_BINARY_DIR}/action/scripts/synth_and_impl.tcl
DEPENDS hls hdl/action_config.v hdl/gen_xdma_descriptor.v hdl/eth_4x10g_leds.v scripts/bd_pcie.tcl scripts/jfjoch.tcl scripts/network_stack.tcl scripts/hbm_u55c.tcl scripts/mac_100g_pcie.tcl scripts/pcie_dma.tcl scripts/setup_action.sh
)
ADD_CUSTOM_TARGET(pcie_8x10g DEPENDS hls
COMMAND ${CMAKE_COMMAND} -E env VARIANT=1 SRC_DIR=${CMAKE_CURRENT_SOURCE_DIR} HLS_IP_DIR=${CMAKE_CURRENT_BINARY_DIR}/action/ip/hls bash ${CMAKE_CURRENT_SOURCE_DIR}/scripts/setup_action.sh
COMMAND ${VIVADO} -notrace -mode batch -source ${CMAKE_CURRENT_SOURCE_DIR}/scripts/build_pcie_design_8x10g.tcl
COMMAND ${CMAKE_COMMAND} -E env FLOW=pcie_8x10g VIV_PROJECT_PATH=${CMAKE_CURRENT_BINARY_DIR}/vivado/jfjoch_pcie.xpr ${VIVADO} -notrace -mode batch -source ${CMAKE_CURRENT_BINARY_DIR}/action/scripts/synth_and_impl.tcl
DEPENDS hls hdl/action_config.v hdl/gen_xdma_descriptor.v hdl/eth_4x10g_leds.v scripts/bd_pcie.tcl scripts/jfjoch.tcl scripts/network_stack.tcl scripts/hbm_u55c.tcl scripts/mac_100g_pcie.tcl scripts/pcie_dma.tcl scripts/setup_action.sh
)
ENDIF()
+26 -11
View File
@@ -70,15 +70,15 @@ Create PCIe bitstream with the following command:
mkdir build
cd build
cmake ..
make action_pcie
make pcie_100g
```
### When Vivado is not present
During CMake execution, the following executables: `vivado` and `vitis_hls` must be present in the path.
If not, build targets will not be generated, and such or similar error message will show up:
```
$ make action_pcie
make: *** No rule to make target 'action_pcie'. Stop.
$ make pcie_100g
make: *** No rule to make target 'pcie_100g'. Stop.
```
### Gitlab CI
@@ -96,15 +96,23 @@ It is impossible to perform the operation using Vivado running on the same machi
### Alveo card with Jungfraujoch firmware
First step is to find PCIe device ID from the operating system. Use for example the following command:
```
lspci |grep Xilinx
# lspci |grep Xilinx
e1:00.0 Processing accelerators: Xilinx Corporation Alveo U55C
```
To flash the card it is necessary to use 'xbflash2' utility from AMD/Xilinx:
In this case **e1:00.0** is device ID.
To flash the card it is necessary to use 'xbflash2' utility from AMD/Xilinx. For the first flashing of the U55C board use the following command:
```
xbflash2 program --spi -i <.mcs file path> -d <device id>
# xbflash2 program --spi -i <.mcs file path> -d <device ID> --bar-offset 0x1f06000
```
For subsequent runs:
```
# xbflash2 program --spi -i <.mcs file path> -d <device ID>
```
It is necessary to confirm the operation by pressing `Y` key.
It is safe to run multiple flashing processes in parallel for different cards, for example in separate screen sessions.
`xbflash2` is available as RPM for RHEL7 and RHEL8 from [Alveo product page](https://www.xilinx.com/products/boards-and-kits/alveo/u55c.html#xbflash2).
For RHEL9 this needs to built from source - [Xilinx/XRT github repository](https://github.com/Xilinx/XRT).
@@ -143,7 +151,7 @@ In the future a redirection will be possible to send the simulated stream throug
Frame generator is written in HLS and controlled with AXI-Lite.
### Register map
FPGA setup can be done via 32-bit registers:
FPGA setup can be done via registers:
| Address | Bits | Meaning | Mode | Notes |
|---------------------|------|---------------------------------------------------------------------------------------------|:-----|----------------------------------------------|
@@ -160,9 +168,11 @@ FPGA setup can be done via 32-bit registers:
| | | Bits 24-27 - Various errors in host memory writer | R | cleared on reset or action start |
| 0x010004 | 32 | Reserved | - | |
| 0x010008 | 32 | Reserved | - | |
| 0x01000C | 32 | Action GIT SHA1 | R | |
| 0x010010 | 32 | Action Type | R | |
| 0x010014 | 32 | Action Release Level | R | |
| 0x01000C | 32 | GIT SHA1 | R | |
| 0x010010 | 32 | Jungfraujoch FPGA magic number (always 0x52324158) | R | |
| 0x010014 | 32 | Jungfraujoch FPGA release level | R | |
| 0x010018 | 32 | Jungfraujoch FPGA variant | R | |
| 0x01001C | 32 | Reserved | R | |
| 0x010020 | 32 | Max. number supported detector modules | R | constant |
| 0x010024 | 32 | Reserved | R | constant |
| 0x010028 | 64 | Pipeline stalls before writing to host memory | R | reset on action start |
@@ -174,7 +184,12 @@ FPGA setup can be done via 32-bit registers:
| 0x010050 | 64 | Valid ICMP packets | R | cleared on reset |
| 0x010058 | 64 | Valid UDP packets | R | cleared on reset |
| 0x010060 | 64 | Valid detector packets processed by the card | R | cleared on reset |
| 0x010066 | 64 | Packets flagged as errors by CMAC | R | cleared on reset |
| 0x010068 | 64 | Packets flagged as errors by CMAC | R | cleared on reset |
| 0x010070 | 64 | Pipeline stalls before data processing | R | reset on action start |
| 0x010078 | 64 | AXI-beats before accessing HBM | R | reset on action start |
| 0x010080 | 64 | AXI-beats before data processing | R | reset on action start |
| 0x010088 | 64 | AXI-beats before host writer | R | reset on action start |
| 0x010090 | 64 | Last encountered SwissFEL pulse ID | R | cleared on reset |
| 0x010100 | 32 | Spot finder photon count threshold | R/W | |
| 0x010104 | 32 | Spot finder signal-to-noise ratio threshold (single-precision float) | R/W | |
| 0x010200 | 64 | MAC address of FPGA card | R/W | network byte order |
+36 -8
View File
@@ -3,17 +3,22 @@
`timescale 1ns/1ps
// parameters imported from source files
`define ACTION_TYPE 32'h52324158
`define RELEASE_LEVEL 32'h
`define JFJOCH_MAGIC 32'h52324158
`define JFJOCH_RELEASE 32'h0
`define JFJOCH_VARIANT 32'h0
`define JFJOCH_SYNTH_TIME 32'd0
`define GIT_SHA1 32'h
`define MAX_MODULES_FPGA 32'd16
`define HBM_SIZE_BYTES 32'h20000000
`define ADDR_AP_CTRL 16'h0000
`define ADDR_JFJOCH_SYNTH_TIME 16'h0008
`define ADDR_GIT_SHA1 16'h000C
`define ADDR_ACTION_TYPE 16'h0010
`define ADDR_RELEASE_LEVEL 16'h0014
`define ADDR_JFJOCH_MAGIC 16'h0010
`define ADDR_JFJOCH_RELEASE 16'h0014
`define ADDR_JFJOCH_VARIANT 16'h0018
`define ADDR_MAX_MODULES_FPGA 16'h0020
`define ADDR_RUN_COUNTER 16'h0024
@@ -44,11 +49,15 @@
`define ADDR_STALLS_PROC_HI 16'h0074
`define ADDR_BEATS_HBM_LO 16'h0078
`define ADDR_BEATS_HBM_HI 16'h007C
`define ADDR_BEATS_PROC_LO 16'h0080
`define ADDR_BEATS_PROC_HI 16'h0084
`define ADDR_BEATS_HOST_LO 16'h0088
`define ADDR_BEATS_HOST_HI 16'h008C
`define ADDR_PULSEID_LO 16'h0090
`define ADDR_PULSEID_HI 16'h0094
`define ADDR_SPOT_FINDER_CNT_THR 16'h0100
`define ADDR_SPOT_FINDER_SNR_THR 16'h0104
`define ADDR_SPOT_FINDER_D_MIN 16'h0108
@@ -183,6 +192,9 @@ module action_config
input [63:0] packets_sls ,
input packets_sls_valid ,
input [63:0] pulseid ,
input pulseid_valid ,
input [31:0] udp_err_eth ,
input udp_err_eth_valid ,
input [31:0] udp_err_len ,
@@ -229,6 +241,7 @@ localparam
reg [63:0] reg_packets_icmp;
reg [63:0] reg_packets_udp;
reg [63:0] reg_packets_sls;
reg [63:0] reg_pulseid;
reg [31:0] reg_udp_err_len;
reg [31:0] reg_udp_err_eth;
@@ -356,15 +369,21 @@ always @(posedge clk) begin
`ADDR_DATA_SOURCE: begin
rdata <= data_source;
end
`ADDR_ACTION_TYPE: begin
rdata <= `ACTION_TYPE;
`ADDR_JFJOCH_MAGIC: begin
rdata <= `JFJOCH_MAGIC;
end
`ADDR_RELEASE_LEVEL: begin
rdata <= `RELEASE_LEVEL;
`ADDR_JFJOCH_RELEASE: begin
rdata <= `JFJOCH_RELEASE;
end
`ADDR_JFJOCH_VARIANT: begin
rdata <= `JFJOCH_VARIANT;
end
`ADDR_GIT_SHA1: begin
rdata <= `GIT_SHA1;
end
`ADDR_JFJOCH_SYNTH_TIME: begin
rdata <= `JFJOCH_SYNTH_TIME;
end
`ADDR_MAX_MODULES_FPGA: begin
rdata <= `MAX_MODULES_FPGA;
end
@@ -422,6 +441,12 @@ always @(posedge clk) begin
`ADDR_PACKETS_SLS_LO: begin
rdata <= reg_packets_sls[31:0];
end
`ADDR_PULSEID_HI: begin
rdata <= reg_pulseid[63:32];
end
`ADDR_PULSEID_LO: begin
rdata <= reg_pulseid[31:0];
end
`ADDR_PACKETS_ICMP_HI: begin
rdata <= reg_packets_icmp[63:32];
end
@@ -672,6 +697,7 @@ always @ (posedge clk) begin
reg_packets_udp <= 0;
reg_packets_icmp <= 0;
reg_packets_sls <= 0;
reg_pulseid <= 0;
end
else
begin
@@ -701,6 +727,8 @@ always @ (posedge clk) begin
reg_udp_err_len <= udp_err_len;
if (udp_err_eth_valid)
reg_udp_err_eth <= udp_err_eth;
if (pulseid_valid)
reg_pulseid <= pulseid;
end
end
+12 -6
View File
@@ -28,26 +28,29 @@ ADD_LIBRARY( JFJochHLSSimulation STATIC
stream_24bit_conv.cpp
spot_finder_merge.cpp
spot_finder_connectivity.cpp
spot_finder_mask.cpp)
spot_finder_mask.cpp
save_to_hbm_data.cpp
eiger_reorder.cpp
roi_calc.cpp)
TARGET_INCLUDE_DIRECTORIES(JFJochHLSSimulation PUBLIC ../include)
TARGET_LINK_LIBRARIES(JFJochHLSSimulation JFJochCommon)
TARGET_COMPILE_DEFINITIONS(JFJochHLSSimulation PUBLIC -DJFJOCH_HLS_NOSYNTH)
ADD_EXECUTABLE(frame_summation_tb frame_summation_tb.cpp)
TARGET_LINK_LIBRARIES(frame_summation_tb HLSSimulation)
TARGET_LINK_LIBRARIES(frame_summation_tb JFJochHLSSimulation)
ADD_EXECUTABLE(frame_summation_tb_2 frame_summation_tb_2.cpp)
TARGET_LINK_LIBRARIES(frame_summation_tb_2 HLSSimulation)
TARGET_LINK_LIBRARIES(frame_summation_tb_2 JFJochHLSSimulation)
ADD_EXECUTABLE(integration_tb integration_tb.cpp)
TARGET_LINK_LIBRARIES(integration_tb HLSSimulation)
TARGET_LINK_LIBRARIES(integration_tb JFJochHLSSimulation)
ADD_EXECUTABLE(spot_finder_tb spot_finder_tb.cpp)
TARGET_LINK_LIBRARIES(spot_finder_tb HLSSimulation)
TARGET_LINK_LIBRARIES(spot_finder_tb JFJochHLSSimulation)
ADD_EXECUTABLE(adu_histo_tb adu_histo_tb.cpp)
TARGET_LINK_LIBRARIES(adu_histo_tb HLSSimulation)
TARGET_LINK_LIBRARIES(adu_histo_tb JFJochHLSSimulation)
IF(VIVADO_HLS)
@@ -81,6 +84,7 @@ MAKE_HLS_MODULE(frame_generator frame_generator.cpp "")
MAKE_HLS_MODULE(stream_merge stream_merge.cpp "")
MAKE_HLS_MODULE(load_from_hbm load_from_hbm.cpp "")
MAKE_HLS_MODULE(save_to_hbm save_to_hbm.cpp "")
MAKE_HLS_MODULE(save_to_hbm_data save_to_hbm_data.cpp "")
MAKE_HLS_MODULE(mask_missing mask_missing.cpp "")
MAKE_HLS_MODULE(integration integration.cpp integration_tb.cpp)
MAKE_HLS_MODULE(spot_finder spot_finder.cpp spot_finder_tb.cpp)
@@ -94,6 +98,8 @@ MAKE_HLS_MODULE(stream_24bit_conv stream_24bit_conv.cpp stream_24bit_conv_tb.cpp
MAKE_HLS_MODULE(spot_finder_mask spot_finder_mask.cpp "")
MAKE_HLS_MODULE(spot_finder_merge spot_finder_merge.cpp "")
MAKE_HLS_MODULE(spot_finder_connectivity spot_finder_connectivity.cpp "")
MAKE_HLS_MODULE(eiger_reorder eiger_reorder.cpp "")
MAKE_HLS_MODULE(roi_calc roi_calc.cpp "")
SET (HLS_IPS ${HLS_IPS} PARENT_SCOPE)
ADD_CUSTOM_TARGET(hls DEPENDS ${HLS_IPS})
+83
View File
@@ -0,0 +1,83 @@
// Copyright (2019-2023) Paul Scherrer Institute
#include "hls_jfjoch.h"
void eiger_reorder(STREAM_512 &data_in,
STREAM_512 &data_out,
hls::stream<axis_completion > &s_axis_completion,
hls::stream<axis_completion > &m_axis_completion) {
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE register both axis port=data_in
#pragma HLS INTERFACE register both axis port=data_out
#pragma HLS INTERFACE register both axis port=m_axis_completion
#pragma HLS INTERFACE register both axis port=s_axis_completion
packet_512_t packet;
{
#pragma HLS PROTOCOL fixed
data_in >> packet;
ap_wait();
data_out << packet;
ap_wait();
}
ap_uint<512> memory_0[128];
#pragma HLS BIND_STORAGE variable=memory_0 type=ram_t2p impl=bram latency=3
ap_uint<512> memory_1[128];
#pragma HLS BIND_STORAGE variable=memory_1 type=ram_t2p impl=bram latency=3
packet_512_t packet_out;
packet_out.user = 0;
packet_out.last = 0;
packet_out.id = 0;
axis_completion cmpl;
s_axis_completion >> cmpl;
while (!cmpl.last) {
m_axis_completion << cmpl;
if (cmpl.detector_type == SLS_DETECTOR_TYPE_EIGER) {
for (int i = 0; i < 16384; i++) {
#pragma HLS PIPELINE II=1
data_in >> packet;
size_t counter = i % 128;
size_t col0 = (counter >= 64) ? 16 : 0;
size_t line0 = (counter / 16) % 4;
if (i < 8192)
line0 = 3 - line0; // second half is reversed
size_t pos = line0 * 32 + col0 + counter % 16;
if ((i / 128) % 2 == 0) {
memory_0[pos] = packet.data;
packet_out.data = memory_1[counter];
} else {
memory_1[pos] = packet.data;
packet_out.data = memory_0[counter];
}
if (i >= 128)
data_out << packet_out;
}
for (int i = 0; i < 128; i++) {
#pragma HLS PIPELINE II=1
packet_out.data = memory_1[i];
if (i == 127)
packet_out.last = 1;
data_out << packet_out;
}
} else {
for (int i = 0; i < 16384; i++) {
#pragma HLS PIPELINE II=1
data_in >> packet;
data_out << packet;
}
}
s_axis_completion >> cmpl;
}
m_axis_completion << cmpl;
data_in >> packet;
data_out << packet;
}
+5 -4
View File
@@ -36,18 +36,19 @@ void ethernet(AXI_STREAM &eth_in,
if (state == INSPECT_HEADER) {
dest = DEST_IGNORE;
if ((fpga_mac_addr != 0) || (packet_in.id == AXI_STREAM_ID_SIMPLIFIED_NETWORK_STACK)) {
if (fpga_mac_addr != 0) {
ap_uint<48> dest_mac = packet_in.data(47, 0);
ap_uint<48> src_mac = packet_in.data(95, 48);
ap_uint<16> ether_type = get_header_field_16(packet_in.data, 12 * 8);
if (((dest_mac == fpga_mac_addr) || (packet_in.id == AXI_STREAM_ID_SIMPLIFIED_NETWORK_STACK)) // don't check MAC address for 4x10G
if (((dest_mac == fpga_mac_addr) || (dest_mac == MAC_BROADCAST))
&& (ether_type == ETHER_IP)) {
state = FORWARD;
dest = DEST_IP;
internal_counter++;
} else if ((dest_mac == MAC_BROADCAST) && (ether_type == ETHER_ARP) && (packet_in.last)
&& (packet_in.id == AXI_STREAM_ID_FULL_NETWORK_STACK)) {
} else if ((dest_mac == MAC_BROADCAST)
&& (ether_type == ETHER_ARP)
&& (packet_in.last)) {
state = FORWARD;
dest = DEST_ARP;
}
+162 -62
View File
@@ -3,22 +3,22 @@
#include "hls_jfjoch.h"
#include "ip_header_checksum.h"
void generate_packet(STREAM_512 &data_out,
ap_uint<256> *d_hbm_p0,
ap_uint<256> *d_hbm_p1,
ap_uint<32> hbm_size_bytes,
ap_uint<32> frame,
ap_uint<8> module,
ap_uint<7> eth_packet,
ap_uint<48> src_mac_addr,
ap_uint<48> dest_mac_addr,
ap_uint<32> src_ipv4_addr,
ap_uint<32> dest_ipv4_addr,
ap_uint<64> bunchid,
ap_uint<32> exptime,
ap_uint<64> timestamp,
ap_uint<32> debug,
ap_uint<1> user = 0) {
void generate_packet_jungfrau(STREAM_512 &data_out,
ap_uint<256> *d_hbm_p0,
ap_uint<256> *d_hbm_p1,
ap_uint<32> hbm_size_bytes,
ap_uint<32> frame,
ap_uint<8> module,
ap_uint<7> eth_packet,
ap_uint<48> src_mac_addr,
ap_uint<48> dest_mac_addr,
ap_uint<32> src_ipv4_addr,
ap_uint<32> dest_ipv4_addr,
ap_uint<64> bunchid,
ap_uint<32> exptime,
ap_uint<64> timestamp,
ap_uint<32> debug,
ap_uint<1> user = 0) {
#pragma HLS PIPELINE II=130
ap_uint<720> header = 0;
@@ -41,6 +41,7 @@ void generate_packet(STREAM_512 &data_out,
header(udp_payload_pos+3*64+63, udp_payload_pos+3*64) = timestamp;
header(udp_payload_pos+4*64+31, udp_payload_pos+4*64+16) = 2 * module;
header(udp_payload_pos+5*64+31, udp_payload_pos+5*64) = debug;
header(udp_payload_pos+5*64+55, udp_payload_pos+5*64+48) = SLS_DETECTOR_TYPE_JUNGFRAU;
packet_512_t packet;
packet.data = header(511 ,0);
@@ -74,28 +75,89 @@ void generate_packet(STREAM_512 &data_out,
data_out << packet;
}
void generate_packet_eiger(STREAM_512 &data_out,
ap_uint<256> *d_hbm_p0,
ap_uint<256> *d_hbm_p1,
ap_uint<32> hbm_size_bytes,
ap_uint<32> frame,
ap_uint<8> module,
ap_uint<8> eth_packet,
ap_uint<48> src_mac_addr,
ap_uint<48> dest_mac_addr,
ap_uint<32> src_ipv4_addr,
ap_uint<32> dest_ipv4_addr,
ap_uint<32> exptime,
ap_uint<64> timestamp,
ap_uint<32> debug,
ap_uint<1> user = 0) {
#pragma HLS PIPELINE II=66
ap_uint<720> header = 0;
header(47 , 0) = dest_mac_addr;
header(95 , 48) = src_mac_addr;
header(111, 96) = 0x0008; // ETHER_IP = IPv4
header(eth_payload_pos+3 , eth_payload_pos ) = 0x5; // header len of 5
header(eth_payload_pos+7 , eth_payload_pos+4 ) = 0x4; // IPv4
header(eth_payload_pos+31 , eth_payload_pos+16 ) = 0x4C10; // total length = 4172
header(eth_payload_pos+79 , eth_payload_pos+72 ) = PROTOCOL_UDP; // UDP
header(eth_payload_pos+127, eth_payload_pos+96 ) = src_ipv4_addr;
header(eth_payload_pos+159, eth_payload_pos+128) = dest_ipv4_addr;
header(eth_payload_pos+95 , eth_payload_pos+80 ) = computeCheckSum20B(header(eth_payload_pos + 159, eth_payload_pos));
header(ipv4_payload_pos+47, ipv4_payload_pos+32) = 0x3810; // UDP length = 4152
header(udp_payload_pos+63, udp_payload_pos) = frame + 1;
header(udp_payload_pos+95, udp_payload_pos+64) = exptime;
header(udp_payload_pos+127, udp_payload_pos+96) = (eth_packet / 2) % 64;
header(udp_payload_pos+2*64+63, udp_payload_pos+2*64) = 0;
header(udp_payload_pos+3*64+63, udp_payload_pos+3*64) = timestamp;
header(udp_payload_pos+4*64+31, udp_payload_pos+4*64+16) = 2 * module + ((eth_packet >= 128) ? 1 : 0);
header(udp_payload_pos+4*64+47, udp_payload_pos+4*64+32) = (eth_packet % 2);
header(udp_payload_pos+5*64+31, udp_payload_pos+5*64) = debug;
header(udp_payload_pos+5*64+55, udp_payload_pos+5*64+48) = SLS_DETECTOR_TYPE_EIGER;
packet_512_t packet;
packet.data = header(511 ,0);
packet.last = 0;
packet.dest = 0;
packet.id = 0;
packet.strb = UINT64_MAX;
packet.keep = UINT64_MAX;
packet.user = user;
data_out << packet;
ap_uint<32> offset_hbm_0 = 20 * hbm_size_bytes / 32;
ap_uint<32> offset_hbm_1 = 21 * hbm_size_bytes / 32;
ap_uint<208> remainder = header(719, 512);
for (int i = 0; i < 64; i++) {
ap_uint<512> tmp;
tmp(255, 0) = d_hbm_p0[offset_hbm_0 + module * 64 * 256 + eth_packet * 64 + i];
tmp(511, 256) = d_hbm_p1[offset_hbm_1 + module * 64 * 256 + eth_packet * 64 + i];
packet.data(207, 0) = remainder;
packet.data(511, 208) = tmp(303, 0);
data_out << packet;
remainder = tmp(511, 304);
}
packet.data(207, 0) = remainder;
packet.data(511, 208) = 0;
packet.keep(63, 26) = 0;
packet.last = 1;
data_out << packet;
}
int frame_generator(STREAM_512 &data_out,
ap_uint<256> *d_hbm_p0,
ap_uint<256> *d_hbm_p1,
ap_uint<32> hbm_size_bytes,
ap_uint<32> frames,
ap_uint<6> modules,
ap_uint<48> src_mac_addr,
ap_uint<48> dest_mac_addr,
ap_uint<32> src_ipv4_addr,
ap_uint<32> dest_ipv4_addr,
ap_uint<64> bunchid,
ap_uint<32> exptime,
ap_uint<32> debug,
volatile ap_uint<1> &in_cancel) {
volatile ap_uint<1> &in_cancel,
FrameGeneratorConfig &config) {
#pragma HLS INTERFACE mode=s_axilite port=return
#pragma HLS INTERFACE mode=s_axilite port=frames
#pragma HLS INTERFACE mode=s_axilite port=modules
#pragma HLS INTERFACE mode=s_axilite port=bunchid
#pragma HLS INTERFACE mode=s_axilite port=exptime
#pragma HLS INTERFACE mode=s_axilite port=debug
#pragma HLS INTERFACE mode=s_axilite port=dest_mac_addr
#pragma HLS INTERFACE mode=s_axilite port=dest_ipv4_addr
#pragma HLS INTERFACE mode=s_axilite port=config
#pragma HLS INTERFACE mode=ap_none register port=src_mac_addr
#pragma HLS INTERFACE mode=ap_none register port=src_ipv4_addr
#pragma HLS INTERFACE mode=ap_none register port=in_cancel
@@ -107,45 +169,83 @@ int frame_generator(STREAM_512 &data_out,
max_read_burst_length=16 max_write_burst_length=2 latency=120 num_write_outstanding=2 num_read_outstanding=9
#pragma HLS INTERFACE register both axis port=data_out
if (modules > MAX_MODULES_FPGA)
if ((config.modules > MAX_MODULES_FPGA) || (config.modules == 0))
return 1;
// send one packet with TUSER = 1, to reset on network cores on the way
generate_packet(data_out,
d_hbm_p0,
d_hbm_p1,
hbm_size_bytes,
0, 0, 0,
src_mac_addr,
dest_mac_addr,
src_ipv4_addr,
dest_ipv4_addr,
bunchid,
exptime,
exptime,
debug, 1);
if ((config.detector_type != SLS_DETECTOR_TYPE_EIGER)
&& (config.detector_type != SLS_DETECTOR_TYPE_JUNGFRAU))
return 2;
for (uint32_t f = 0; f < frames; f++) {
if (config.frames == 0)
return 0;
union {
uint64_t u64;
double d;
} pulse_id_conv;
pulse_id_conv.d = config.pulse_id;
// send one packet with TUSER = 1, to reset on network cores on the way
generate_packet_jungfrau(data_out,
d_hbm_p0,
d_hbm_p1,
hbm_size_bytes,
0, 0, 0,
src_mac_addr,
config.dest_mac_addr,
src_ipv4_addr,
config.dest_ipv4_addr,
pulse_id_conv.u64,
config.exptime,
config.exptime,
config.debug, 1);
for (uint32_t f = 0; f < config.frames; f++) {
ap_uint<1> local_cancel = in_cancel;
if (local_cancel == 1)
break;
for (uint32_t p = 0; p < 128; p++) {
for (uint32_t m = 0; m < modules; m++) {
generate_packet(data_out,
d_hbm_p0,
d_hbm_p1,
hbm_size_bytes,
f, m, p,
src_mac_addr,
dest_mac_addr,
src_ipv4_addr,
dest_ipv4_addr,
bunchid + f,
exptime,
exptime * f,
debug, 0);
if (config.detector_type == SLS_DETECTOR_TYPE_JUNGFRAU) {
generate_jf_frame:
for (uint32_t m = 0; m < config.modules; m++) {
generate_jf_packet:
for (uint32_t p = 0; p < 128; p++) {
generate_packet_jungfrau(data_out,
d_hbm_p0,
d_hbm_p1,
hbm_size_bytes,
f, m, p,
src_mac_addr,
config.dest_mac_addr,
src_ipv4_addr,
config.dest_ipv4_addr,
pulse_id_conv.u64,
config.exptime,
config.exptime * f,
config.debug, 0);
}
}
} else {
generate_eiger_frame:
for (uint32_t m = 0; m < config.modules; m++) {
generate_eiger_packet:
for (uint32_t p = 0; p < 256; p++) {
generate_packet_eiger(data_out,
d_hbm_p0,
d_hbm_p1,
hbm_size_bytes,
f, m, p,
src_mac_addr,
config.dest_mac_addr,
src_ipv4_addr,
config.dest_ipv4_addr,
config.exptime,
config.exptime * f,
config.debug, 0);
}
}
}
pulse_id_conv.d += 1.0;
}
return 0;
}
+31 -20
View File
@@ -32,9 +32,6 @@ namespace hls {
#define INT24_MAX 8388607
#define INT24_MIN (-8388608)
#define AXI_STREAM_ID_FULL_NETWORK_STACK 0 // For 100G provide full network stack - enforce MAC/IPv4 and provide ARP/ICMP
#define AXI_STREAM_ID_SIMPLIFIED_NETWORK_STACK 1 // For 4x10G the connection is direct detector-DCU, so no need to enforce MAC/IPv4 and to provide ARP and ICMP
typedef ap_ufixed<16,2, AP_RND_CONV> gainG0_t;
typedef ap_ufixed<16,4, AP_RND_CONV> gainG1_t;
typedef ap_ufixed<16,6, AP_RND_CONV> gainG2_t;
@@ -84,13 +81,15 @@ struct axis_addr {
ap_uint<64> timestamp;
ap_uint<64> bunchid;
ap_uint<32> debug;
ap_uint<8> packet_length; // in AXI-Stream beats = 64 byte; possible values 0..255
ap_uint<5> module;
ap_uint<7> eth_packet;
ap_uint<8> eth_packet;
ap_uint<4> detector_type;
ap_uint<1> last;
};
struct axis_completion {
ap_uint<128> packet_mask;
ap_uint<256> packet_mask;
ap_uint<64> frame_number;
ap_uint<64> exptime;
ap_uint<64> timestamp;
@@ -99,6 +98,7 @@ struct axis_completion {
ap_uint<16> handle;
ap_uint<16> packet_count;
ap_uint<5> module;
ap_uint<4> detector_type;
ap_uint<1> last;
ap_uint<1> ignore;
ap_uint<1> pedestal;
@@ -111,8 +111,7 @@ union float_uint32 {
void setup_datamover (hls::stream<axis_datamover_ctrl> &datamover_cmd_stream, uint64_t address, size_t bytes_to_write);
void stream_merge(AXI_STREAM &input_100g,
AXI_STREAM &input_4x10g,
void stream_merge(AXI_STREAM &input_network,
AXI_STREAM &input_frame_generator,
AXI_STREAM &data_out,
volatile ap_uint<2> &source);
@@ -205,6 +204,7 @@ static const uint8_t PROTOCOL_UDP = 0x11;
static const uint16_t ETHER_IP = 0x0800;
static const uint16_t ETHER_ARP = 0x0806;
static const ap_uint<48> MAC_BROADCAST = 0xFFFFFFFFFFFF;
static const ap_uint<32> IPV4_BROADCAST = 0xFFFFFFFF;
static const uint32_t eth_payload_pos = 14 * 8; // 112 bits
static const uint32_t ipv4_payload_pos = eth_payload_pos + 160; // 112 + 160 = 272 bits
@@ -253,6 +253,7 @@ void sls_detector(AXI_STREAM &udp_payload_in,
uint64_t& counter,
uint32_t& counter_eth_error,
uint32_t& counter_len_error,
uint64_t& pulse_id,
volatile ap_uint<1> &in_clear_counters,
volatile ap_uint<1> &idle);
@@ -340,6 +341,7 @@ void host_writer(STREAM_512 &data_in,
hls::stream<ap_uint<512>> &adu_histo_in,
hls::stream<ap_uint<512>> &integration_in,
hls::stream<ap_uint<512>> &spot_finder_in,
hls::stream<ap_uint<256>> &roi_count_in,
hls::stream<axis_completion > &s_axis_completion,
hls::stream<ap_axiu<512,1,1,1> > &host_memory_out,
hls::stream<axis_datamover_ctrl> &datamover_out_cmd,
@@ -363,18 +365,19 @@ void load_from_hbm(STREAM_512 &data_in,
volatile ap_uint<1> &idle,
ap_uint<32> hbm_size_bytes);
void save_to_hbm(STREAM_512 &data_in,
STREAM_512 &data_out,
hls::stream<axis_addr> &addr_in,
void save_to_hbm(hls::stream<axis_addr> &addr_in,
hls::stream<axis_completion > &m_axis_completion,
hls::stream<ap_uint<16>> &s_axis_free_handles,
hls::stream<ap_axiu<256,1,1,1> > &hbm_out_0,
hls::stream<ap_axiu<256,1,1,1> > &hbm_out_1,
hls::stream<axis_datamover_ctrl> &datamover_0_cmd,
hls::stream<axis_datamover_ctrl> &datamover_1_cmd,
volatile ap_uint<1> &idle,
ap_uint<32> hbm_size_bytes);
void save_to_hbm_data(STREAM_512 &data_in,
STREAM_512 &data_out,
hls::stream<ap_axiu<256,1,1,1> > &hbm_out_0,
hls::stream<ap_axiu<256,1,1,1> > &hbm_out_1);
void timer_host(STREAM_512 &data_in,
STREAM_512 &data_out,
volatile uint64_t &stalls,
@@ -386,16 +389,10 @@ int frame_generator(STREAM_512 &data_out,
ap_uint<256> *d_hbm_p0,
ap_uint<256> *d_hbm_p1,
ap_uint<32> hbm_size_bytes,
ap_uint<32> frames,
ap_uint<6> modules,
ap_uint<48> src_mac_addr,
ap_uint<48> dest_mac_addr,
ap_uint<32> src_ipv4_addr,
ap_uint<32> dest_ipv4_addr,
ap_uint<64> bunchid,
ap_uint<32> exptime,
ap_uint<32> debug,
volatile ap_uint<1> &in_cancel);
volatile ap_uint<1> &in_cancel,
FrameGeneratorConfig &config);
int load_calibration(ap_uint<256> *d_hbm_p0,
ap_uint<256> *d_hbm_p1,
@@ -438,4 +435,18 @@ void spot_finder_mask(STREAM_768 &data_in,
volatile ap_uint<32> &in_max_d_value,
ap_uint<32> hbm_size_bytes);
void eiger_reorder(STREAM_512 &data_in,
STREAM_512 &data_out,
hls::stream<axis_completion > &s_axis_completion,
hls::stream<axis_completion > &m_axis_completion);
void roi_calc(STREAM_768 &data_in,
STREAM_768 &data_out,
hls::stream<ap_uint<256>> &roi_out,
hls::stream<axis_completion > &s_axis_completion,
hls::stream<axis_completion > &m_axis_completion,
ap_uint<256> *d_hbm_p0,
ap_uint<256> *d_hbm_p1,
ap_uint<32> hbm_size_bytes);
#endif
+18 -1
View File
@@ -9,7 +9,8 @@ inline ap_uint<512> fill_module_info(axis_completion &cmpl, ap_uint<32> sat_pxl,
ap_uint<512> msg = 0;
sf(msg, frame_number, 64) = cmpl.frame_number;
sf(msg, timestamp, 64) = cmpl.timestamp;
sf(msg, bunchid, 64) = cmpl.bunchid;
sf(msg, pulse_id, 64) = cmpl.bunchid;
sf(msg, detector_type, 32) = cmpl.detector_type;
sf(msg, exptime, 32) = cmpl.exptime;
sf(msg, debug, 32) = cmpl.debug;
sf(msg, pedestal, 32) = cmpl.pedestal;
@@ -39,6 +40,7 @@ void host_writer(STREAM_512 &data_in,
hls::stream<ap_uint<512>> &adu_histo_in,
hls::stream<ap_uint<512>> &integration_in,
hls::stream<ap_uint<512>> &spot_finder_in,
hls::stream<ap_uint<256>> &roi_count_in,
hls::stream<axis_completion > &s_axis_completion,
hls::stream<ap_axiu<512,1,1,1> > &host_memory_out,
hls::stream<axis_datamover_ctrl> &datamover_out_cmd,
@@ -54,6 +56,7 @@ void host_writer(STREAM_512 &data_in,
#pragma HLS INTERFACE register both axis port=adu_histo_in
#pragma HLS INTERFACE register both axis port=integration_in
#pragma HLS INTERFACE register both axis port=spot_finder_in
#pragma HLS INTERFACE register both axis port=roi_count_in
#pragma HLS INTERFACE register both axis port=s_axis_completion
#pragma HLS INTERFACE register both axis port=host_memory_out
#pragma HLS INTERFACE register both axis port=datamover_out_cmd
@@ -144,6 +147,8 @@ void host_writer(STREAM_512 &data_in,
(FPGA_INTEGRATION_BIN_COUNT / 8) * 64);
setup_datamover(datamover_out_cmd, req_host_offset + offsetof(DeviceOutput, adu_histogram),
ADU_HISTO_BIN_COUNT / 16 * 64);
setup_datamover(datamover_out_cmd, req_host_offset + offsetof(DeviceOutput, roi_counts),
FPGA_ROI_COUNT * 64 / 2);
setup_datamover(datamover_out_cmd, req_host_offset + offsetof(DeviceOutput, module_statistics), 2 * 64);
}
@@ -203,6 +208,18 @@ void host_writer(STREAM_512 &data_in,
host_memory_out << packet_out;
}
// 32 transfers x 512-bit
for (int i = 0; i < FPGA_ROI_COUNT / 2; i++) {
#pragma HLS PIPELINE II=2
ap_uint<256> tmp_0, tmp_1;
roi_count_in >> tmp_0;
roi_count_in >> tmp_1;
packet_out.data = (tmp_1, tmp_0);
packet_out.last = (i == FPGA_ROI_COUNT / 2 - 1);
if (send_images)
host_memory_out << packet_out;
}
if (send_images)
state = 5;
else
+7 -5
View File
@@ -31,20 +31,22 @@ void ipv4(AXI_STREAM &eth_in,
packet_in.data(eth_payload_pos + 159, eth_payload_pos));
if ((ip_version == 4)
&& ((ipv4_dest_ip == fpga_ipv4_addr) ||
(packet_in.id == AXI_STREAM_ID_SIMPLIFIED_NETWORK_STACK)) // don't check IPv4 address for 4x10G
&& (ipv4_header_checksum_check == 0)) {
// IP is version 4 + IP address is correct + checksum is OK
// Possibly the conditions can be relaxed for broadcast ICMP
if (ipv4_protocol == PROTOCOL_UDP) {
if ((ipv4_protocol == PROTOCOL_UDP)
&& ((ipv4_dest_ip == fpga_ipv4_addr) || (ipv4_dest_ip == IPV4_BROADCAST))) {
// IPv4 address is not enforced for UDP - assume correct dest MAC + UDP packet len is enough
// This allows for broadcast timing messages to go through
state = FORWARD;
dest = DEST_UDP;
} else if ((ipv4_protocol == PROTOCOL_ICMP) && (packet_in.id == AXI_STREAM_ID_FULL_NETWORK_STACK)) {
} else if ((ipv4_protocol == PROTOCOL_ICMP) && (ipv4_dest_ip == fpga_ipv4_addr)) {
// IPv4 address is enforced (don't want broadcast pings)
// Has to be from 100G network
state = FORWARD;
dest = DEST_ICMP;
}
}
}
switch (dest) {
+20 -28
View File
@@ -183,16 +183,16 @@ void jf_conversion(STREAM_512 &data_in, STREAM_576 &data_out,
else
one_over_energy = 0;
if (conversion) {
axis_completion cmpl;
s_axis_completion >> cmpl;
convert_images:
while (!cmpl.last) {
m_axis_completion << cmpl;
axis_completion cmpl;
s_axis_completion >> cmpl;
convert_images:
while (!cmpl.last) {
m_axis_completion << cmpl;
if (conversion && (cmpl.detector_type == SLS_DETECTOR_TYPE_JUNGFRAU)) {
for (ap_uint<15> i = 0; i < RAW_MODULE_SIZE * sizeof(uint16_t) / 64; i++) {
#pragma HLS PIPELINE II=1
if (i % 16 == 0) {
ap_uint<19> gain_offset = (cmpl.module, i(13,0));
ap_uint<19> gain_offset = (cmpl.module, i(13, 0));
ap_uint<12> pedestal_location = cmpl.module;
if (storage_cells > 1) {
@@ -200,7 +200,7 @@ void jf_conversion(STREAM_512 &data_in, STREAM_576 &data_out,
pedestal_location += modules * storage_cell_id;
}
ap_uint<26> pedestal_offset = (pedestal_location, i(13,0));
ap_uint<26> pedestal_offset = (pedestal_location, i(13, 0));
d_hbm_p0.read_request(offset_hbm_0 + gain_offset, 16);
d_hbm_p1.read_request(offset_hbm_1 + gain_offset, 16);
@@ -230,29 +230,21 @@ void jf_conversion(STREAM_512 &data_in, STREAM_576 &data_out,
data_in >> packet_in;
packet_out.data = convert(packet_in.data,
packed_gainG0_1, packed_gainG0_2,
packed_gainG1_1, packed_gainG1_2,
packed_gainG2_1, packed_gainG2_2,
packed_pedeG0_1, packed_pedeG0_2,
packed_pedeG1_1, packed_pedeG1_2,
packed_pedeG2_1, packed_pedeG2_2,
packet_in.id[0],
fixed_g1,
one_over_energy);
packed_gainG0_1, packed_gainG0_2,
packed_gainG1_1, packed_gainG1_2,
packed_gainG2_1, packed_gainG2_2,
packed_pedeG0_1, packed_pedeG0_2,
packed_pedeG1_1, packed_pedeG1_2,
packed_pedeG2_1, packed_pedeG2_2,
packet_in.id[0],
fixed_g1,
one_over_energy);
packet_out.last = packet_in.last;
packet_out.user = packet_in.user;
data_out << packet_out;
}
s_axis_completion >> cmpl;
}
m_axis_completion << cmpl;
} else {
axis_completion cmpl;
s_axis_completion >> cmpl;
forward_packets:
while (!cmpl.last) {
m_axis_completion << cmpl;
} else {
for (int i = 0; i < RAW_MODULE_SIZE * sizeof(uint16_t) / 64; i++) {
#pragma HLS PIPELINE II=1
data_in >> packet_in;
@@ -266,10 +258,10 @@ void jf_conversion(STREAM_512 &data_in, STREAM_576 &data_out,
packet_out.user = packet_in.user;
data_out << packet_out;
}
s_axis_completion >> cmpl;
}
m_axis_completion << cmpl;
s_axis_completion >> cmpl;
}
m_axis_completion << cmpl;
data_in >> packet_in;
packet_out.data = packet_in.data;
+7 -1
View File
@@ -162,12 +162,18 @@ int load_calibration(ap_uint<256> *d_hbm_p0,
offset_hbm_1 = 21 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1);
break;
case LOAD_CALIBRATION_DEST_SPOT_FINDER_RESOLUTION_MAP:
case LOAD_CALIBRATION_DEST_SPOT_FINDER_RES_MAP:
setup_datamover(datamover_in_cmd, mem_addr, RAW_MODULE_SIZE * sizeof(float));
offset_hbm_0 = 22 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
offset_hbm_1 = 23 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
read_module_float<xray_d_t>(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1);
break;
case LOAD_CALIBRATION_DEST_ROI_CALC:
setup_datamover(datamover_in_cmd, mem_addr, RAW_MODULE_SIZE * sizeof(uint16_t));
offset_hbm_0 = 30 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
offset_hbm_1 = 31 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1);
break;
default:
return LOAD_CALIBRATION_ERR_DEST;
}
+1 -1
View File
@@ -27,7 +27,7 @@ void mask_missing(STREAM_512 &data_in,
for (int i = 0; i < RAW_MODULE_SIZE * sizeof(uint16_t) / 64; i++) {
#pragma HLS PIPELINE II=1
data_in >> packet;
if (!cmpl.packet_mask[i / 128]) {
if (!cmpl.packet_mask[i / 64]) {
for (int j = 0; j < 512; j++)
packet.data[j] = 1;
}
+3 -1
View File
@@ -165,7 +165,7 @@ void pedestal(STREAM_512 &data_in, STREAM_512 &data_out,
s_axis_completion >> cmpl;
while (!cmpl.last) {
m_axis_completion << cmpl;
if ((cmpl.packet_count == 128) && pedestal_mode) {
if ((cmpl.packet_count == 256) && pedestal_mode) {
ap_int<5> storage_cell = ((nstoragecells > 1) ? ap_int<5>((cmpl.frame_number % nstoragecells)) : ap_int<5>(0));
ap_uint<1> accumulate = (frame_count[nmodules * storage_cell + cmpl.module] < PEDESTAL_WINDOW_SIZE);
@@ -223,6 +223,8 @@ void pedestal(STREAM_512 &data_in, STREAM_512 &data_out,
cmpl_pedestal.module = m;
cmpl_pedestal.packet_mask(63, 0) = UINT64_MAX;
cmpl_pedestal.packet_mask(127, 64) = UINT64_MAX;
cmpl_pedestal.packet_mask(191, 128) = UINT64_MAX;
cmpl_pedestal.packet_mask(255, 192) = UINT64_MAX;
cmpl_pedestal.packet_count = frame_count[s * nmodules + m];
cmpl_pedestal.pedestal = 1;
+154
View File
@@ -0,0 +1,154 @@
// Copyright (2019-2024) Paul Scherrer Institute
#include "hls_jfjoch.h"
template <class T>
inline ap_uint<32> float2int(T &input) {
float_uint32 conv;
conv.f = input.to_float();
return conv.u;
}
void roi_calc(STREAM_768 &data_in,
STREAM_768 &data_out,
hls::stream<ap_uint<256>> &roi_out,
hls::stream<axis_completion > &s_axis_completion,
hls::stream<axis_completion > &m_axis_completion,
ap_uint<256> *d_hbm_p0,
ap_uint<256> *d_hbm_p1,
ap_uint<32> hbm_size_bytes) {
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE register both axis port=data_in
#pragma HLS INTERFACE register both axis port=data_out
#pragma HLS INTERFACE register both axis port=roi_out
#pragma HLS INTERFACE register both axis port=m_axis_completion
#pragma HLS INTERFACE register both axis port=s_axis_completion
#pragma HLS INTERFACE m_axi port=d_hbm_p0 bundle=d_hbm_p0 depth=16384 offset=off \
max_read_burst_length=16 max_write_burst_length=2 latency=120 num_write_outstanding=2 num_read_outstanding=8
#pragma HLS INTERFACE m_axi port=d_hbm_p1 bundle=d_hbm_p1 depth=16384 offset=off \
max_read_burst_length=16 max_write_burst_length=2 latency=120 num_write_outstanding=2 num_read_outstanding=8
#pragma HLS INTERFACE register ap_none port=hbm_size_bytes
ap_int<24+14> roi_sum[32*2][FPGA_ROI_COUNT];
#pragma HLS ARRAY_PARTITION variable=roi_sum type=complete dim=1
ap_uint<24+24+14> roi_sum2[32*2][FPGA_ROI_COUNT];
#pragma HLS ARRAY_PARTITION variable=roi_sum2 type=complete dim=1
ap_int<24+14+11> roi_x_weighted_sum[32*2][FPGA_ROI_COUNT];
#pragma HLS ARRAY_PARTITION variable=roi_x_weighted_sum type=complete dim=1
ap_int<24+14+11> roi_y_weighted_sum[32*2][FPGA_ROI_COUNT];
#pragma HLS ARRAY_PARTITION variable=roi_y_weighted_sum type=complete dim=1
ap_uint<14> roi_good_pixels[32*2][FPGA_ROI_COUNT];
#pragma HLS ARRAY_PARTITION variable=roi_good_pixels type=complete dim=1
ap_int<24> roi_max_value[32*2][FPGA_ROI_COUNT];
#pragma HLS ARRAY_PARTITION variable=roi_max_value type=complete dim=1
packet_768_t packet;
{
#pragma HLS PROTOCOL fixed
data_in >> packet;
ap_wait();
data_out << packet;
ap_wait();
}
ap_uint<32> offset_hbm_0 = 30 * hbm_size_bytes / 32;
ap_uint<32> offset_hbm_1 = 31 * hbm_size_bytes / 32;
axis_completion cmpl;
s_axis_completion >> cmpl;
while (!cmpl.last) {
m_axis_completion << cmpl;
for (int i = 0; i < FPGA_ROI_COUNT; i++) {
#pragma HLS PIPELINE II=1
for (int j = 0; j < 64; j++) {
roi_sum[j][i] = 0;
roi_sum2[j][i] = 0;
roi_x_weighted_sum[j][i] = 0;
roi_y_weighted_sum[j][i] = 0;
roi_good_pixels[j][i] = 0;
roi_max_value[j][i] = INT24_MIN;
}
}
for (int i = 0; i < RAW_MODULE_SIZE / 32 / 2; i++) {
#pragma HLS PIPELINE II=2
for (int k = 0; k < 2; k++) {
data_in >> packet;
ap_uint<9> line = (2 * i + k) / 32;
ap_uint<10> col = (2 * i + k) % 32 * 32;
// account for multipixel
line += (line / 256) * 2;
col += (col / 256) * 2;
ap_uint<16> roi[32];
ap_uint<256> roi_0 = d_hbm_p0[offset_hbm_0 + cmpl.module * RAW_MODULE_SIZE * sizeof(int16_t) / 64 + 2 * i + k];
ap_uint<256> roi_1 = d_hbm_p1[offset_hbm_1 + cmpl.module * RAW_MODULE_SIZE * sizeof(int16_t) / 64 + 2 * i + k];
unpack_2xhbm_to_32x16bit(roi_0, roi_1, roi);
ap_int<24> in_val[32];
unpack32(packet.data, in_val);
for (int pxl = 0; pxl < 32; pxl++) {
if ((roi[pxl] < FPGA_ROI_COUNT) && (in_val[pxl] != INT24_MIN)) {
if (in_val[pxl] != INT24_MAX) {
roi_sum[32 * k + pxl][roi[pxl]] += in_val[pxl];
roi_sum2[32 * k + pxl][roi[pxl]] += in_val[pxl] * in_val[pxl];
roi_x_weighted_sum[32 * k + pxl][roi[pxl]] += in_val[pxl] * (col + pxl);
roi_y_weighted_sum[32 * k + pxl][roi[pxl]] += in_val[pxl] * line;
roi_good_pixels[32 * k + pxl][roi[pxl]] += 1;
}
if (roi_max_value[32 * k + pxl][roi[pxl]] < in_val[pxl])
roi_max_value[32 * k + pxl][roi[pxl]] = in_val[pxl];
}
}
data_out << packet;
}
}
for (int i = 0; i < FPGA_ROI_COUNT; i++) {
#pragma HLS PIPELINE II=1
ap_uint<256> packet_out = 0;
ap_int<64> sum_tmp = 0;
ap_uint<64> sum2_tmp = 0;
ap_int<64> sum_x_tmp = 0;
ap_int<64> sum_y_tmp = 0;
ap_int<32> good_pixels_tmp = 0;
ap_int<32> max_value = INT32_MIN;
for (int j = 0; j < 64; j++) {
sum_tmp += roi_sum[j][i];
sum2_tmp += roi_sum2[j][i];
sum_x_tmp += roi_x_weighted_sum[j][i];
sum_y_tmp += roi_y_weighted_sum[j][i];
good_pixels_tmp += roi_good_pixels[j][i];
if (max_value < roi_max_value[j][i])
max_value = roi_max_value[j][i];
}
if (max_value == INT24_MIN)
max_value = INT32_MIN;
else if (max_value == INT24_MAX)
max_value = INT32_MAX;
packet_out( 63, 0) = sum_tmp;
packet_out(127, 64) = sum2_tmp;
packet_out(159, 128) = float2int(sum_x_tmp);
packet_out(191, 160) = float2int(sum_y_tmp);
packet_out(223, 192) = good_pixels_tmp;
packet_out(255, 224) = max_value;
roi_out << packet_out;
}
s_axis_completion >> cmpl;
}
m_axis_completion << cmpl;
data_in >> packet;
data_out << packet;
}
+34 -56
View File
@@ -2,25 +2,17 @@
#include "hls_jfjoch.h"
void save_to_hbm(STREAM_512 &data_in,
STREAM_512 &data_out,
hls::stream<axis_addr> &addr_in,
void save_to_hbm(hls::stream<axis_addr> &addr_in,
hls::stream<axis_completion > &m_axis_completion,
hls::stream<ap_uint<16>> &s_axis_free_handles,
hls::stream<ap_axiu<256,1,1,1> > &hbm_out_0,
hls::stream<ap_axiu<256,1,1,1> > &hbm_out_1,
hls::stream<axis_datamover_ctrl> &datamover_0_cmd,
hls::stream<axis_datamover_ctrl> &datamover_1_cmd,
volatile ap_uint<1> &idle,
ap_uint<32> hbm_size_bytes) {
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE register both axis port=data_in
#pragma HLS INTERFACE register both axis port=data_out
#pragma HLS INTERFACE register both axis port=addr_in
#pragma HLS INTERFACE register both axis port=m_axis_completion
#pragma HLS INTERFACE register both axis port=s_axis_free_handles
#pragma HLS INTERFACE register both axis port=hbm_out_0
#pragma HLS INTERFACE register both axis port=hbm_out_1
#pragma HLS INTERFACE register both axis port=datamover_0_cmd
#pragma HLS INTERFACE register both axis port=datamover_1_cmd
#pragma HLS INTERFACE mode=ap_none port=hbm_size_bytes
@@ -37,32 +29,21 @@ void save_to_hbm(STREAM_512 &data_in,
cmpl[i].last = 0;
}
packet_512_t packet_in;
{
#pragma HLS PROTOCOL fixed
data_in >> packet_in;
ap_wait();
data_out << packet_in;
ap_wait();
idle = 0;
ap_wait();
}
ap_uint<32> offset_hbm_0 = 12 * hbm_size_bytes / 32;
ap_uint<32> offset_hbm_1 = 14 * hbm_size_bytes / 32;
data_in >> packet_in;
axis_addr addr;
addr_in >> addr;
Loop_good_packet:
idle = 0;
size_t offset_hbm_0 = 12 * hbm_size_bytes;
size_t offset_hbm_1 = 14 * hbm_size_bytes;
Loop_good_packet:
while (!addr.last) {
// Process one UDP packet per iteration
#pragma HLS PIPELINE II=128
#pragma HLS PIPELINE II=4
ap_uint<64> frame_number = addr.frame_number;
ap_uint<5> module_number = addr.module;
ap_uint<7> eth_packet = addr.eth_packet;
ap_uint<8> eth_packet = addr.eth_packet;
ap_uint<6> id = module_number * 2 + (frame_number % 2);
ap_uint<16> curr_handle = 0;
@@ -75,42 +56,41 @@ void save_to_hbm(STREAM_512 &data_in,
cmpl[id].exptime = addr.exptime;
cmpl[id].debug = addr.debug;
cmpl[id].bunchid = addr.bunchid;
cmpl[id].detector_type = addr.detector_type;
cmpl[id].last = 0;
cmpl[id].ignore = 0;
cmpl[id].packet_mask = ap_uint<128>(1) << eth_packet;
cmpl[id].packet_count = 1;
if (addr.packet_length == 128) {
cmpl[id].packet_mask = (ap_uint<256>(1) << (2 * eth_packet))
| (ap_uint<256>(1) << (2 * eth_packet + 1));
cmpl[id].packet_count = 2;
} else {
cmpl[id].packet_mask = ap_uint<256>(1) << eth_packet;
cmpl[id].packet_count = 1;
}
cmpl[id].pedestal = 0;
curr_handle = s_axis_free_handles.read();
cmpl[id].handle = curr_handle;
} else {
cmpl[id].packet_mask |= ap_uint<128>(1) << eth_packet;
cmpl[id].packet_count++;
if (addr.packet_length == 128) {
cmpl[id].packet_mask |= (ap_uint<256>(1) << (2 * eth_packet))
| (ap_uint<256>(1) << (2 * eth_packet + 1));
cmpl[id].packet_count += 2;
} else {
cmpl[id].packet_mask |= ap_uint<256>(1) << eth_packet;
cmpl[id].packet_count++;
}
}
size_t offset = ((cmpl[id].handle / 2) * RAW_MODULE_SIZE * sizeof(uint16_t) + eth_packet * 8192) / 64;
size_t offset = (cmpl[id].handle / 2) * (RAW_MODULE_SIZE * sizeof(uint16_t) / 2);
if (cmpl[id].handle % 2 == 1)
offset += hbm_size_bytes / 32;
offset += hbm_size_bytes;
setup_datamover(datamover_0_cmd, (offset_hbm_0 + offset) * 32, 4096);
setup_datamover(datamover_1_cmd, (offset_hbm_1 + offset) * 32, 4096);
for (int i = 0; i < 128; i++) {
ap_axiu<256,1,1,1> packet_out;
packet_out.keep = UINT32_MAX;
packet_out.strb = UINT32_MAX;
packet_out.user = 0;
packet_out.dest = 0;
packet_out.id = 0;
packet_out.last = (i == 127);
packet_out.data = packet_in.data(255, 0);
hbm_out_0 << packet_out;
packet_out.data = packet_in.data(511, 256);
hbm_out_1 << packet_out;
data_in >> packet_in;
}
// JUNGFRAU
setup_datamover(datamover_0_cmd, offset_hbm_0 + offset + eth_packet * addr.packet_length * 32,
addr.packet_length * 32);
setup_datamover(datamover_1_cmd, offset_hbm_1 + offset + eth_packet * addr.packet_length * 32,
addr.packet_length * 32);
addr_in >> addr;
}
@@ -130,8 +110,6 @@ void save_to_hbm(STREAM_512 &data_in,
}
}
data_out << packet_in;
m_axis_completion << axis_completion{.last = 1};
ap_uint<16> tmp = s_axis_free_handles.read();
+49
View File
@@ -0,0 +1,49 @@
// Copyright (2019-2024) Paul Scherrer Institute
#include "hls_jfjoch.h"
void save_to_hbm_data(STREAM_512 &data_in,
STREAM_512 &data_out,
hls::stream<ap_axiu<256,1,1,1> > &hbm_out_0,
hls::stream<ap_axiu<256,1,1,1> > &hbm_out_1) {
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE register both axis port=data_in
#pragma HLS INTERFACE register both axis port=data_out
#pragma HLS INTERFACE register both axis port=hbm_out_0
#pragma HLS INTERFACE register both axis port=hbm_out_1
packet_512_t packet_in;
{
#pragma HLS PROTOCOL fixed
data_in >> packet_in;
ap_wait();
data_out << packet_in;
ap_wait();
}
data_in >> packet_in;
Loop_good_packet:
while (! packet_in.user) {
// Process one UDP packet per iteration
#pragma HLS PIPELINE II=1
ap_axiu<256,1,1,1> packet_out;
packet_out.keep = UINT32_MAX;
packet_out.strb = UINT32_MAX;
packet_out.user = 0;
packet_out.dest = 0;
packet_out.id = 0;
packet_out.last = packet_in.last;
packet_out.data = packet_in.data(255, 0);
hbm_out_0 << packet_out;
packet_out.data = packet_in.data(511, 256);
hbm_out_1 << packet_out;
data_in >> packet_in;
}
data_out << packet_in;
}
+58 -20
View File
@@ -1,16 +1,17 @@
// Copyright (2019-2023) Paul Scherrer Institute
#include "hls_jfjoch.h"
#include "../../jungfrau/sls_packet.h"
void sls_detector(AXI_STREAM &udp_payload_in,
hls::stream<ap_uint<UDP_METADATA_STREAM_WIDTH> > &udp_metadata_in,
AXI_STREAM &data_out,
hls::stream<axis_addr> &addr_out,
uint64_t& counter,
uint32_t& counter_eth_error,
uint32_t& counter_len_error,
volatile ap_uint<1> &in_clear_counters,
hls::stream<ap_uint<UDP_METADATA_STREAM_WIDTH> > &udp_metadata_in,
AXI_STREAM &data_out,
hls::stream<axis_addr> &addr_out,
uint64_t& counter,
uint32_t& counter_eth_error,
uint32_t& counter_len_error,
uint64_t& pulse_id,
volatile ap_uint<1> &in_clear_counters,
volatile ap_uint<1> &idle) {
#pragma HLS INTERFACE ap_ctrl_none port=return
@@ -18,6 +19,7 @@ void sls_detector(AXI_STREAM &udp_payload_in,
#pragma HLS INTERFACE axis register both port=data_out
#pragma HLS INTERFACE axis register both port=udp_metadata_in
#pragma HLS INTERFACE axis register both port=addr_out
#pragma HLS INTERFACE ap_vld register port=pulse_id
#pragma HLS INTERFACE ap_vld register port=counter
#pragma HLS INTERFACE ap_vld register port=counter_eth_error
#pragma HLS INTERFACE ap_vld register port=counter_len_error
@@ -39,13 +41,13 @@ void sls_detector(AXI_STREAM &udp_payload_in,
ap_uint<UDP_METADATA_STREAM_WIDTH> udp_metadata;
static ap_uint<8> beat_counter;
static ap_uint<8> packet_length = 0;
static uint64_t internal_counter = 0;
static uint32_t internal_counter_eth_error = 0;
static uint32_t internal_counter_len_error = 0;
static uint64_t internal_pulseid = UINT64_MAX;
ap_uint<1> tmp = in_clear_counters;
if (tmp) {
if ( in_clear_counters.read()) {
internal_counter = 0;
internal_counter_len_error = 0;
internal_counter_eth_error = 0;
@@ -54,6 +56,7 @@ void sls_detector(AXI_STREAM &udp_payload_in,
#pragma HLS RESET variable=internal_counter
#pragma HLS RESET variable=internal_counter_eth_error
#pragma HLS RESET variable=internal_counter_len_error
#pragma HLS RESET variable=internal_pulseid
#pragma HLS RESET variable=state
if (state == INSPECT_HEADER && udp_metadata_in.empty())
@@ -65,25 +68,58 @@ void sls_detector(AXI_STREAM &udp_payload_in,
case INSPECT_HEADER:
udp_metadata_in >> udp_metadata;
if ((udp_metadata_payload_size(udp_metadata) == 8240)
if ((udp_metadata_payload_size(udp_metadata) == sizeof(bunchid_payload))
&& (udp_metadata_eth_err(udp_metadata) == 0)
&& (udp_metadata_len_err(udp_metadata) == 0)
&& (packet_in.data(63, 0) != 0)) {
&& (packet_in.last)
&& (packet_in.data(6*8 + 31, 6*8) == BUNCHID_MAGICN)
&& (packet_in.data(6*8 + 2 * 32 + 31, 6*8 + 2 * 32) == BUNCHID_MAGICN)) {
internal_pulseid = (packet_in.data(6 * 8 + 5 * 32 + 31, 6 * 8 + 5 * 32),
packet_in.data(6*8 + 3 * 32 + 31, 6 * 8 + 3 * 32));
} else if ((udp_metadata_eth_err(udp_metadata) == 0)
&& (udp_metadata_len_err(udp_metadata) == 0)
&& (packet_in.data(63, 0) != 0)) {
ap_uint<16> column = packet_in.data(4 * 64 + 31, 4 * 64 + 16);
ap_uint<1> module_part = column[0];
ap_uint<16> row = packet_in.data(4 * 64 + 31, 4 * 64 + 16);
ap_uint<16> column = packet_in.data(4 * 64 + 47, 4 * 64 + 32);
ap_uint<1> top_half_module = row[0];
ap_uint<1> right_column = column[0];
ap_uint<8> detector_type = packet_in.data(5*64+48+7, 5*64+48);
axis_addr addr;
if ((detector_type == SLS_DETECTOR_TYPE_JUNGFRAU)
&& (udp_metadata_payload_size(udp_metadata) == sizeof(jf_udp_payload))) {
packet_length = 128;
addr.eth_packet = (packet_in.data(127, 96) % 128) | (top_half_module * 64);
} else if ((detector_type == SLS_DETECTOR_TYPE_EIGER)
&& (udp_metadata_payload_size(udp_metadata) == sizeof(eiger_udp_payload))) {
packet_length = 64;
if (!top_half_module)
addr.eth_packet = (126 - (packet_in.data(127, 96) % 64) * 2) | (right_column);
else
addr.eth_packet = (128 + (packet_in.data(127, 96) % 64) * 2) | (right_column);
} else {
state = DISCARD;
break;
}
beat_counter = 0;
reminder = packet_in.data(511, 384);
axis_addr addr;
addr.frame_number = packet_in.data(63, 0) - 1; // Calculate frame_number from zero
addr.debug = packet_in.data(5 * 64 + 31, 5 * 64);
addr.timestamp = packet_in.data(3 * 64 + 63, 3 * 64);
addr.bunchid = packet_in.data(2 * 64 + 63, 2 * 64);
addr.module = (column / 2) % MAX_MODULES_FPGA;
addr.eth_packet = (packet_in.data(127, 96) % 128) | (module_part * 64);
addr.module = (row / 2) % MAX_MODULES_FPGA;
addr.detector_type = detector_type;
addr.exptime = packet_in.data(95, 64);
addr.packet_length = packet_length;
addr.last = 0;
addr_out << addr;
@@ -98,7 +134,7 @@ void sls_detector(AXI_STREAM &udp_payload_in,
}
break;
case FORWARD:
packet_out.last = (beat_counter == 127);
packet_out.last = (beat_counter == packet_length - 1);
packet_out.data = (packet_in.data(383, 0), reminder);
data_out << packet_out;
reminder = packet_in.data(511, 384);
@@ -115,9 +151,11 @@ void sls_detector(AXI_STREAM &udp_payload_in,
counter = internal_counter;
counter_eth_error = internal_counter_eth_error;
counter_len_error = internal_counter_len_error;
pulse_id = internal_pulseid;
if (state == INSPECT_HEADER)
idle = 1;
else
idle = 0;
}
}
+7 -16
View File
@@ -2,14 +2,12 @@
#include "hls_jfjoch.h"
void stream_merge(AXI_STREAM &input_100g,
AXI_STREAM &input_4x10g,
void stream_merge(AXI_STREAM &input_network,
AXI_STREAM &input_frame_generator,
AXI_STREAM &data_out,
volatile ap_uint<2> &source) {
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE axis register both port=input_100g
#pragma HLS INTERFACE axis register both port=input_4x10g
#pragma HLS INTERFACE axis register both port=input_network
#pragma HLS INTERFACE axis register both port=input_frame_generator
#pragma HLS INTERFACE axis register both port=data_out
#pragma HLS INTERFACE ap_none register port=source
@@ -21,22 +19,15 @@ void stream_merge(AXI_STREAM &input_100g,
data_source_local = data_source_local_read;
data_out.write(packet_512_t{.user = 1, .last = 1});
} else {
packet_512_t packet_in_frame_gen, packet_in_eth_100g, packet_in_eth_4x10g;
packet_512_t packet_in_frame_gen, packet_in_network;
bool rcv_frame_gen = input_frame_generator.read_nb(packet_in_frame_gen);
bool rcv_eth_100g = input_100g.read_nb(packet_in_eth_100g);
bool rcv_eth_4x10g = input_4x10g.read_nb(packet_in_eth_4x10g);
bool rcv_network = input_network.read_nb(packet_in_network);
if (data_source_local == STREAM_MERGE_SRC_100G) {
packet_in_eth_100g.id = AXI_STREAM_ID_FULL_NETWORK_STACK;
if (rcv_eth_100g)
data_out.write(packet_in_eth_100g);
} else if (data_source_local == STREAM_MERGE_SRC_4x10G) {
packet_in_eth_4x10g.id = AXI_STREAM_ID_SIMPLIFIED_NETWORK_STACK;
if (rcv_eth_4x10g)
data_out.write(packet_in_eth_4x10g);
if (data_source_local == STREAM_MERGE_SRC_NETWORK) {
if (rcv_network)
data_out.write(packet_in_network);
} else if (data_source_local == STREAM_MERGE_SRC_FRAME_GEN) {
packet_in_frame_gen.id = AXI_STREAM_ID_FULL_NETWORK_STACK;
if (rcv_frame_gen)
data_out.write(packet_in_frame_gen);
}
+8 -4
View File
@@ -3,17 +3,21 @@ ADD_LIBRARY(JFJochDevice STATIC JungfraujochDevice.cpp JungfraujochDevice.h ../i
TARGET_LINK_LIBRARIES(JFJochDevice JFJochCommon)
ADD_EXECUTABLE(jfjoch_pcie_status jfjoch_pcie_status.cpp)
TARGET_LINK_LIBRARIES(jfjoch_pcie_status JungfraujochDevice )
TARGET_LINK_LIBRARIES(jfjoch_pcie_status JFJochDevice )
INSTALL(TARGETS jfjoch_pcie_status RUNTIME)
ADD_EXECUTABLE(jfjoch_pcie_set_network jfjoch_pcie_set_network.cpp)
TARGET_LINK_LIBRARIES(jfjoch_pcie_set_network JungfraujochDevice )
TARGET_LINK_LIBRARIES(jfjoch_pcie_set_network JFJochDevice )
INSTALL(TARGETS jfjoch_pcie_set_network RUNTIME)
ADD_EXECUTABLE(jfjoch_pcie_cancel_data_collection jfjoch_pcie_cancel_data_collection.cpp)
TARGET_LINK_LIBRARIES(jfjoch_pcie_cancel_data_collection JungfraujochDevice )
TARGET_LINK_LIBRARIES(jfjoch_pcie_cancel_data_collection JFJochDevice )
INSTALL(TARGETS jfjoch_pcie_cancel_data_collection RUNTIME)
ADD_EXECUTABLE(jfjoch_pcie_clear_net_counters jfjoch_pcie_clear_net_counters.cpp)
TARGET_LINK_LIBRARIES(jfjoch_pcie_clear_net_counters JungfraujochDevice )
TARGET_LINK_LIBRARIES(jfjoch_pcie_clear_net_counters JFJochDevice )
INSTALL(TARGETS jfjoch_pcie_clear_net_counters RUNTIME)
ADD_EXECUTABLE(jfjoch_pcie_clock_cfg_test jfjoch_pcie_clock_cfg_test.cpp)
TARGET_LINK_LIBRARIES(jfjoch_pcie_clock_cfg_test JFJochDevice )
INSTALL(TARGETS jfjoch_pcie_clock_cfg_test RUNTIME)
+28 -5
View File
@@ -20,12 +20,12 @@ JungfraujochDevice::JungfraujochDevice(const std::string &device_name, bool writ
else
throw JFJochException(JFJochExceptionCategory::PCIeError, "Cannot open device");
}
auto action_type = GetDataCollectionStatus().action_type;
if (action_type != ACTION_TYPE)
auto action_type = GetDataCollectionStatus().jfjoch_fpga_magic;
if (action_type != JFJOCH_FPGA_MAGIC)
throw JFJochException(JFJochExceptionCategory::PCIeError, "Wrong device type");
auto action_release = GetDataCollectionStatus().release_level;
if (action_release != RELEASE_LEVEL)
auto action_release = GetDataCollectionStatus().jfjoch_fpga_release;
if (action_release != JFJOCH_FPGA_RELEASE)
throw JFJochException(JFJochExceptionCategory::PCIeError, "Mismatch of FPGA release between driver and library");
}
@@ -220,5 +220,28 @@ bool JungfraujochDevice::ReadWorkCompletion(JungfraujochDeviceCompletion &comple
bool ret = ReadWorkCompletion(&tmp);
completion.buffer_id = tmp & 0xFFFF;
completion.data_collection_id = (tmp >> 16) & 0xFFFF;
return false;
return ret;
}
uint8_t JungfraujochDevice::ReadClockConfig(uint8_t addr) {
I2COperation operation{
.dev_addr = 0xD0,
.reg_addr = addr
};
if (ioctl(fd, IOCTL_JFJOCH_I2C_CLK_READ, &operation) != 0)
throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed reading I2C config");
return operation.content;
}
void JungfraujochDevice::WriteClockConfig(uint8_t addr, uint8_t val) {
I2COperation operation{
.dev_addr = 0xD0,
.reg_addr = addr,
.content = val
};
if (ioctl(fd, IOCTL_JFJOCH_I2C_CLK_WRITE, &operation) != 0)
throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed writing I2C config");
}
+3
View File
@@ -108,6 +108,9 @@ public:
// 3 - frame generator within the FPGA
void SetDataSource(uint32_t id);
uint32_t GetDataSource();
uint8_t ReadClockConfig(uint8_t addr);
void WriteClockConfig(uint8_t addr, uint8_t val);
};
#endif //JUNGFRAUJOCH_JUNGFRAUJOCHDEVICE_H
@@ -0,0 +1,41 @@
// Copyright (2019-2024) Paul Scherrer Institute
#include "../common/Logger.h"
#include "../common/JFJochException.h"
#include "JungfraujochDevice.h"
int main(int argc, char **argv) {
Logger logger("jfjoch_pcie_clock_cfg_test");
if (argc != 2) {
logger.Error("Usage: ./jfjoch_pcie_clock_cfg_test <device name>");
exit(EXIT_FAILURE);
}
try {
JungfraujochDevice device(argv[1], true);
logger.Info("Current page {}", device.ReadClockConfig(0x1));
logger.Info("Device Ready {:x}", device.ReadClockConfig(0xFE));
device.WriteClockConfig(0x1, 0x0);
logger.Info("Current page {}", device.ReadClockConfig(0x1));
logger.Info("Base part 0x{:x}{:x}", device.ReadClockConfig(0x3), device.ReadClockConfig(0x2));
logger.Info("Base part 0x{:x}{:x}", device.ReadClockConfig(0x3), device.ReadClockConfig(0x2));
device.WriteClockConfig(0x1, 0x2);
logger.Info("Current page {}", device.ReadClockConfig(0x1));
logger.Info("OPN {:c}{:c}{:c}{:c}{:c}",
device.ReadClockConfig(0x78),
device.ReadClockConfig(0x79),
device.ReadClockConfig(0x7A),
device.ReadClockConfig(0x7B),
device.ReadClockConfig(0x7C));
device.WriteClockConfig(0x1, 0x0);
logger.Info("Current page {}", device.ReadClockConfig(0x1));
logger.Info("Done");
} catch (const JFJochException &e) {
logger.ErrorException(e);
}
}
@@ -23,4 +23,4 @@ int main(int argc, char **argv) {
} catch (const JFJochException &e) {
logger.ErrorException(e);
}
}
}
+22 -16
View File
@@ -65,11 +65,8 @@ int main(int argc, char **argv) {
case STREAM_MERGE_SRC_NONE:
std::cout << "none";
break;
case STREAM_MERGE_SRC_100G:
std::cout << "100G";
break;
case STREAM_MERGE_SRC_4x10G:
std::cout << "4x10G";
case STREAM_MERGE_SRC_NETWORK:
std::cout << "Network";
break;
case STREAM_MERGE_SRC_FRAME_GEN:
std::cout << "frame generator";
@@ -79,13 +76,21 @@ int main(int argc, char **argv) {
break;
}
std::cout << std::endl;
std::cout << "Ethernet 100G link " << (fpga_env_data.eth_100G_link ? "Yes" : "No") << std::endl;
std::cout << "Ethernet 10G link (*=link) "
<< (fpga_env_data.eth_10G_link[0] ? "*" : "-")
<< (fpga_env_data.eth_10G_link[1] ? "*" : "-")
<< (fpga_env_data.eth_10G_link[2] ? "*" : "-")
<< (fpga_env_data.eth_10G_link[3] ? "*" : "-")
<< std::endl;
if (fpga_status.jfjoch_fpga_variant == JFJOCH_FPGA_VARIANT_100G) {
std::cout << "FPGA variant " << "100G" << std::endl;
std::cout << "Ethernet 100G link " << (fpga_env_data.eth_100G_link ? "Yes" : "No") << std::endl;
} else {
std::cout << "Ethernet 10G link (*=link) "
<< (fpga_env_data.eth_10G_link[0] ? "*" : "-")
<< (fpga_env_data.eth_10G_link[1] ? "*" : "-")
<< (fpga_env_data.eth_10G_link[2] ? "*" : "-")
<< (fpga_env_data.eth_10G_link[3] ? "*" : "-")
<< (fpga_env_data.eth_10G_link[4] ? "*" : "-")
<< (fpga_env_data.eth_10G_link[5] ? "*" : "-")
<< (fpga_env_data.eth_10G_link[6] ? "*" : "-")
<< (fpga_env_data.eth_10G_link[7] ? "*" : "-")
<< std::endl;
}
std::cout << "FPGA 12V rail current [A] " << fpga_env_data.fpga_pcie_12V_I_mA / 1000.0 << std::endl;
std::cout << "FPGA 12V rail voltage [V] " << fpga_env_data.fpga_pcie_12V_V_mV / 1000.0 << std::endl;
@@ -127,6 +132,7 @@ int main(int argc, char **argv) {
std::cout << "Data collection ID (hex) " << std::hex << ((cfg.mode & 0xFFFF0000) >> 16) << std::dec << std::endl;
std::cout << "Modules " << std::dec << cfg.nmodules << std::endl;
std::cout << "Frames int. pkt. gen. " << std::dec << cfg.nframes << std::endl;
std::cout << "Pulse ID " << fpga_status.current_pulseid << std::endl;
std::cout << std::endl;
std::cout << "Spot finder settings " << std::endl;
std::cout << "Count threshold " << spot_finder_settings.count_threshold << std::endl;
@@ -147,17 +153,17 @@ int main(int argc, char **argv) {
std::cout << std::endl;
std::cout << "User interrupts mask: " << std::bitset<32>(fpga_env_data.pcie_user_interrupt_mask)
<< " pending: " << std::bitset<32>(fpga_env_data.pcie_user_interrupt_pending)
<< " request: " << std::bitset<32>(fpga_env_data.pcie_user_interrupt_request) << std::endl;
<< " pending: " << std::bitset<32>(fpga_env_data.pcie_user_interrupt_pending)
<< " request: " << std::bitset<32>(fpga_env_data.pcie_user_interrupt_request) << std::endl;
std::cout << "DMA interrupts mask: " << std::bitset<32>(fpga_env_data.pcie_dma_interrupt_mask)
<< " pending: " << std::bitset<32>(fpga_env_data.pcie_dma_interrupt_pending)
<< " request: " << std::bitset<32>(fpga_env_data.pcie_dma_interrupt_request) << std::endl;
std::cout << "H2C descriptors:" << fpga_env_data.pcie_h2c_descriptors << " beats: " << fpga_env_data.pcie_h2c_beats
<< " status:" << fpga_env_data.pcie_h2c_status << std::endl;
<< " status:" << fpga_env_data.pcie_h2c_status << std::endl;
std::cout << "C2H descriptors:" << fpga_env_data.pcie_c2h_descriptors << " beats: " << fpga_env_data.pcie_c2h_beats
<< " status:" << fpga_env_data.pcie_c2h_status << std::endl;
<< " status:" << fpga_env_data.pcie_c2h_status << std::endl;
std::cout << std::endl;
} catch (const JFJochException &e) {
+51 -23
View File
@@ -4,6 +4,7 @@
#define JUNGFRAUJOCH_JFJOCH_FPGA_H
#ifdef __KERNEL__
typedef __u8 uint8_t;
typedef __u32 uint32_t;
typedef __u64 uint64_t;
#else
@@ -25,8 +26,11 @@ typedef __u64 uint64_t;
#define GAIN_G1_MULTIPLIER (-1)
#define GAIN_G2_MULTIPLIER (-1)
#define ACTION_TYPE 0x52324158
#define RELEASE_LEVEL 0x004F
#define JFJOCH_FPGA_MAGIC 0x52324158
#define JFJOCH_FPGA_RELEASE 0x0054
#define JFJOCH_FPGA_VARIANT_100G 0
#define JFJOCH_FPGA_VARIANT_8x10G 1
#define MODE_CONV 0x0001L
#define MODE_32BIT 0x0002L
@@ -37,8 +41,7 @@ typedef __u64 uint64_t;
#define MODE_FIXG1 0x0080L
#define STREAM_MERGE_SRC_NONE 0
#define STREAM_MERGE_SRC_100G 1
#define STREAM_MERGE_SRC_4x10G 2
#define STREAM_MERGE_SRC_NETWORK 1
#define STREAM_MERGE_SRC_FRAME_GEN 3
#define LOAD_CALIBRATION_OK (0)
@@ -62,26 +65,32 @@ typedef __u64 uint64_t;
#define ADU_HISTO_BIN_WIDTH 32
#define ADU_HISTO_BIN_COUNT (65536/ ADU_HISTO_BIN_WIDTH)
#define DMA_DESCRIPTORS_PER_MODULE 5
#define DMA_DESCRIPTORS_PER_MODULE 6
#define SPOT_FINDER_MAX_STRONG_PIXEL (16384)
#define FPGA_ROI_COUNT 64
// INT32_MAX is written explicitly, as the constant is not present in kernel
#define MAX_FRAMES (2147483647/(MAX_MODULES_FPGA*DMA_DESCRIPTORS_PER_MODULE))
#pragma pack(push)
#pragma pack(4)
#define LOAD_CALIBRATION_DEST_GAIN_G0 0
#define LOAD_CALIBRATION_DEST_GAIN_G1 1
#define LOAD_CALIBRATION_DEST_GAIN_G2 2
#define LOAD_CALIBRATION_DEST_PEDESTAL_G0 3
#define LOAD_CALIBRATION_DEST_PEDESTAL_G1 4
#define LOAD_CALIBRATION_DEST_PEDESTAL_G2 5
#define LOAD_CALIBRATION_DEST_INTEGRATION_MAP 6
#define LOAD_CALIBRATION_DEST_INTEGRATION_WEIGHTS 7
#define LOAD_CALIBRATION_DEST_FRAME_GEN 8
#define LOAD_CALIBRATION_DEST_SPOT_FINDER_RESOLUTION_MAP 9
#define LOAD_CALIBRATION_DEST_GAIN_G0 0
#define LOAD_CALIBRATION_DEST_GAIN_G1 1
#define LOAD_CALIBRATION_DEST_GAIN_G2 2
#define LOAD_CALIBRATION_DEST_PEDESTAL_G0 3
#define LOAD_CALIBRATION_DEST_PEDESTAL_G1 4
#define LOAD_CALIBRATION_DEST_PEDESTAL_G2 5
#define LOAD_CALIBRATION_DEST_INTEGRATION_MAP 6
#define LOAD_CALIBRATION_DEST_INTEGRATION_WEIGHTS 7
#define LOAD_CALIBRATION_DEST_FRAME_GEN 8
#define LOAD_CALIBRATION_DEST_SPOT_FINDER_RES_MAP 9
#define LOAD_CALIBRATION_DEST_ROI_CALC 10
#define SLS_DETECTOR_TYPE_JUNGFRAU (0x3)
#define SLS_DETECTOR_TYPE_EIGER (0x1)
struct LoadCalibrationConfig {
uint32_t handle;
@@ -99,11 +108,11 @@ struct DataCollectionConfig {
struct DataCollectionStatus {
uint32_t ctrl_reg;
uint32_t reserved_0;
uint32_t reserved_1;
int32_t jfjoch_synth_time; // unit time is signed
uint32_t git_sha1;
uint32_t action_type;
uint32_t release_level;
uint32_t reserved_2;
uint32_t jfjoch_fpga_magic;
uint32_t jfjoch_fpga_release;
uint32_t jfjoch_fpga_variant;
uint32_t reserved_3;
uint32_t max_modules;
uint32_t run_counter;
@@ -123,6 +132,7 @@ struct DataCollectionStatus {
uint64_t pipeline_beats_hbm;
uint64_t pipeline_beats_proc;
uint64_t pipeline_beats_host;
double current_pulseid;
};
struct DeviceStatus {
@@ -160,7 +170,7 @@ struct DeviceStatus {
uint32_t work_compl_fifo_avail;
bool eth_100G_link;
bool eth_10G_link[4];
bool eth_10G_link[8];
int32_t active_handles;
};
@@ -169,9 +179,10 @@ struct FrameGeneratorConfig {
uint32_t modules; // Number of modules (1-32)
uint64_t dest_mac_addr; // Use the same as source address
uint32_t dest_ipv4_addr; // Use the same as source address
uint64_t bunchid;
double pulse_id;
uint32_t exptime;
uint32_t debug;
uint32_t detector_type; // EIGER = 1, JUNGFRAU = 3
};
struct RegisterConfig {
@@ -179,6 +190,12 @@ struct RegisterConfig {
uint32_t val;
};
struct I2COperation {
uint8_t dev_addr;
uint8_t reg_addr;
uint8_t content;
};
struct SpotFinderParameters {
int32_t count_threshold;
float snr_threshold;
@@ -208,8 +225,9 @@ struct SpotFindingResult {
struct ModuleStatistics {
uint64_t frame_number;
uint64_t timestamp;
uint64_t bunchid;
uint64_t reserved_1;
double pulse_id;
uint32_t detector_type;
uint32_t reserved_1;
uint32_t load_calibration_destination;
uint32_t err_pixels; // number of pixels with 0xffff value
uint32_t exptime;
@@ -221,11 +239,21 @@ struct ModuleStatistics {
uint64_t packet_mask[4]; // This is reserved for 256 packets/module
};
struct ROICount {
uint64_t sum;
int64_t sum2;
float sum_x_weighted;
float sum_y_weighted;
uint32_t good_pixels;
int32_t max_value;
};
struct DeviceOutput {
int16_t pixels[RAW_MODULE_SIZE * 2]; // accommodate 32-bit output
struct SpotFindingResult spot_finding_result;
struct IntegrationResult integration_result[FPGA_INTEGRATION_BIN_COUNT];
uint32_t adu_histogram[ADU_HISTO_BIN_COUNT];
struct ROICount roi_counts[FPGA_ROI_COUNT];
struct ModuleStatistics module_statistics;
};
+2 -1
View File
@@ -4,7 +4,8 @@
ADD_LIBRARY(jfjoch_kernel_module STATIC
jfjoch_ioctl.h jfjoch_drv.c jfjoch_drv.h jfjoch_ioctl.h jfjoch_pcie_setup.c jfjoch_memory.c jfjoch_ioctl.c jfjoch_function.c jfjoch_miscdev.c
jfjoch_sysfs.c
jfjoch_int.c)
jfjoch_int.c
jfjoch_i2c.c)
EXECUTE_PROCESS(COMMAND uname -r
OUTPUT_VARIABLE KERNEL_RELEASE
+1 -1
View File
@@ -1,7 +1,7 @@
obj-m += jfjoch.o
cflags-m=-std=c99
jfjoch-y := jfjoch_drv.o jfjoch_ioctl.o jfjoch_memory.o jfjoch_pcie_setup.o jfjoch_function.o jfjoch_miscdev.o jfjoch_sysfs.o jfjoch_int.o
jfjoch-y := jfjoch_drv.o jfjoch_ioctl.o jfjoch_memory.o jfjoch_pcie_setup.o jfjoch_function.o jfjoch_miscdev.o jfjoch_sysfs.o jfjoch_int.o jfjoch_i2c.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(CURDIR) modules
+2 -1
View File
@@ -88,11 +88,12 @@ static int jfjoch_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
jfjoch_get_status(drvdata, &status);
drvdata->git_sha1 = status.git_sha1;
drvdata->max_modules = status.max_modules;
drvdata->fpga_variant = status.jfjoch_fpga_variant;
jfjoch_setup_cms(drvdata);
jfjoch_setup_network(drvdata);
jfjoch_read_mac_addr(drvdata);
jfjoch_i2c_si5394_init(drvdata);
err = jfjoch_register_sysfs(drvdata);
if (err)
goto free_phys_continous_buf;
+13 -11
View File
@@ -46,7 +46,7 @@
#define MAILBOX_OFFSET (0x030000)
#define LOAD_CALIBRATION_OFFSET (0x060000)
#define CMS_OFFSET (0x0C0000)
#define CMAC_OFFSET (0x020000)
#define MAC_100G_OFFSET (0x020000)
#define PCIE_OFFSET (0x090000)
#define FRAME_GEN_OFFSET (0x080000)
#define ADDRESS_TABLE_OFFSET (0x200000)
@@ -54,6 +54,11 @@
#define MAC_10G_1_OFFSET (0x110000)
#define MAC_10G_2_OFFSET (0x120000)
#define MAC_10G_3_OFFSET (0x130000)
#define MAC_10G_4_OFFSET (0x140000)
#define MAC_10G_5_OFFSET (0x150000)
#define MAC_10G_6_OFFSET (0x160000)
#define MAC_10G_7_OFFSET (0x170000)
#define I2C_SI5394_OFFSET (0x0A0000)
// Action config
#define ADDR_CTRL_REGISTER 0x0000
@@ -119,15 +124,7 @@
#define ADDR_FRAME_GEN_CTRL (FRAME_GEN_OFFSET | 0x000000)
#define ADDR_FRAME_GEN_RETURN (FRAME_GEN_OFFSET | 0x000010)
#define ADDR_FRAME_GEN_FRAMES (FRAME_GEN_OFFSET | 0x000018)
#define ADDR_FRAME_GEN_MODULES (FRAME_GEN_OFFSET | 0x000020)
#define ADDR_FRAME_GEN_DEST_MAC_LO (FRAME_GEN_OFFSET | 0x000028)
#define ADDR_FRAME_GEN_DEST_MAC_HI (FRAME_GEN_OFFSET | 0x00002C)
#define ADDR_FRAME_GEN_DEST_IPV4_ADDR (FRAME_GEN_OFFSET | 0x000034)
#define ADDR_FRAME_GEN_BUNCHID_LO (FRAME_GEN_OFFSET | 0x00003C)
#define ADDR_FRAME_GEN_BUNCHID_HI (FRAME_GEN_OFFSET | 0x000040)
#define ADDR_FRAME_GEN_EXPTIME (FRAME_GEN_OFFSET | 0x000048)
#define ADDR_FRAME_GEN_DEBUG (FRAME_GEN_OFFSET | 0x000050)
#define ADDR_FRAME_GEN_CONFIG (FRAME_GEN_OFFSET | 0x000018)
#define JFJOCH_DMA_SETTINGS (XDMA_CTRL_RUN_STOP | XDMA_CTRL_IE_DESC_ALIGN_MISMATCH | XDMA_CTRL_IE_DESC_ERROR | XDMA_CTRL_IE_READ_ERROR \
| XDMA_CTRL_IE_WRITE_ERROR | XDMA_CTRL_IE_DESC_COMPLETED | XDMA_CTRL_STM_MODE_WB)
@@ -145,7 +142,7 @@
#define ADDR_CMS_CAGE_TEMP1_INS_REG 0x028184 // in C
#define ADDR_CMS_HOST_STATUS2_REG 0x02830C
#define MAX_FPGA_BUFFER 2048
#define MAX_FPGA_BUFFER 8192
extern int nbuffer;
@@ -163,6 +160,7 @@ struct jfjoch_drvdata {
char name[256];
u32 max_modules;
u32 git_sha1;
u32 fpga_variant;
spinlock_t file_write_open_count_spinlock;
int file_write_open_count; // ensure
@@ -244,6 +242,10 @@ uint32_t jfjoch_read_register(struct jfjoch_drvdata *drvdata, uint32_t addr);
int jfjoch_register_sysfs(struct jfjoch_drvdata *drvdata);
void jfjoch_unregister_sysfs(struct jfjoch_drvdata *drvdata);
int jfjoch_i2c_si5394_init(struct jfjoch_drvdata *drvdata);
int jfjoch_i2c_si5394_read(struct jfjoch_drvdata *drvdata, struct I2COperation *operation);
int jfjoch_i2c_si5394_write(struct jfjoch_drvdata *drvdata, const struct I2COperation *operation);
static const struct file_operations jfjoch_cdev_fileops = {
.mmap = jfjoch_cdev_mmap,
.unlocked_ioctl = jfjoch_cdev_ioctl,
+33 -37
View File
@@ -170,7 +170,6 @@ u64 jfjoch_read_mac_addr(struct jfjoch_drvdata *drvdata) {
}
host_msg_offset = ioread32(drvdata->bar0 + CMS_OFFSET + 0x28300);
dev_info(dev, "Host msg offset %x", host_msg_offset);
iowrite32(0x04 << 24, drvdata->bar0 + CMS_OFFSET + 0x28000 + host_msg_offset);
iowrite32(1<<5, drvdata->bar0 + CMS_OFFSET + ADDR_CMS_CONTROL_REG);
@@ -199,8 +198,6 @@ u64 jfjoch_read_mac_addr(struct jfjoch_drvdata *drvdata) {
opcode = (tmp >> 24) & 0xFF;
msg_len = tmp & 0xFFF;
dev_info(dev, "Mailbox response %x opcode %x len %x", tmp, opcode, msg_len);
if (opcode != 0x04) {
dev_err(dev, "Opcode in return message 0x%x doesn't match 0x%x", opcode, 0x04);
return 0;
@@ -262,34 +259,33 @@ void jfjoch_setup_cms(struct jfjoch_drvdata *drvdata) {
if (i == 10000)
dev_err(dev, "CMS not ready after 10s");
else
dev_info(dev, "CMS ready after restart in %d ms", i);
}
void jfjoch_setup_network(struct jfjoch_drvdata *drvdata) {
// Enable RS_FEC
iowrite32(0x03, drvdata->bar0 + CMAC_OFFSET + 0x107C);
if (drvdata->fpga_variant == JFJOCH_FPGA_VARIANT_100G) {
// Enable RS_FEC
iowrite32(0x03, drvdata->bar0 + MAC_100G_OFFSET + 0x107C);
// Restart TX and RX cores + deassert resets
iowrite32((1 << 31) + (1 << 30), drvdata->bar0 + CMAC_OFFSET + 0x0004);
iowrite32(0x0, drvdata->bar0 + CMAC_OFFSET + 0x0004);
// Restart TX and RX cores + deassert resets
iowrite32((1 << 31) + (1 << 30), drvdata->bar0 + MAC_100G_OFFSET + 0x0004);
iowrite32(0x0, drvdata->bar0 + MAC_100G_OFFSET + 0x0004);
// TX Send RFI
iowrite32(0x10, drvdata->bar0 + CMAC_OFFSET + 0x000C);
// TX Send RFI
iowrite32(0x10, drvdata->bar0 + MAC_100G_OFFSET + 0x000C);
// Enable RX
iowrite32(0x1, drvdata->bar0 + CMAC_OFFSET + 0x0014);
// Enable RX
iowrite32(0x1, drvdata->bar0 + MAC_100G_OFFSET + 0x0014);
// start communication
iowrite32(0x1, drvdata->bar0 + CMAC_OFFSET + 0x000C);
// start communication
iowrite32(0x1, drvdata->bar0 + MAC_100G_OFFSET + 0x000C);
// enable counters
iowrite32(0, drvdata->bar0 + ACTION_CONFIG_OFFSET);
// enable counters
iowrite32(0, drvdata->bar0 + ACTION_CONFIG_OFFSET);
}
}
void jfjoch_get_env_data(struct jfjoch_drvdata *drvdata, struct DeviceStatus *env_params) {
int i;
int i,j;
env_params->mailbox_status_reg = ioread32(drvdata->bar0 + MAILBOX_OFFSET + ADDR_MAILBOX_STATUS);
env_params->mailbox_err_reg = ioread32(drvdata->bar0 + MAILBOX_OFFSET + ADDR_MAILBOX_ERR);
@@ -325,12 +321,21 @@ void jfjoch_get_env_data(struct jfjoch_drvdata *drvdata, struct DeviceStatus *en
// These are latched low register, so need to ask twice, to get current value
for (i = 0; i < 2; i++) {
env_params->eth_100G_link = ioread32(drvdata->bar0 + CMAC_OFFSET + 0x0204) & 0x1; // stat_rx_status
env_params->eth_10G_link[0] = ioread32(drvdata->bar0 + MAC_10G_0_OFFSET + 0x0404) & 0x1; // stat_rx_status
env_params->eth_10G_link[1] = ioread32(drvdata->bar0 + MAC_10G_1_OFFSET + 0x0404) & 0x1; // stat_rx_status
env_params->eth_10G_link[2] = ioread32(drvdata->bar0 + MAC_10G_2_OFFSET + 0x0404) & 0x1; // stat_rx_status
env_params->eth_10G_link[3] = ioread32(drvdata->bar0 + MAC_10G_3_OFFSET + 0x0404) & 0x1; // stat_rx_status
if (drvdata->fpga_variant == JFJOCH_FPGA_VARIANT_100G) {
env_params->eth_100G_link = ioread32(drvdata->bar0 + MAC_100G_OFFSET + 0x0204) & 0x1; // stat_rx_status
for (j = 0; j < 8; j++)
env_params->eth_10G_link[j] = false;
} else {
env_params->eth_100G_link = false;
env_params->eth_10G_link[0] = ioread32(drvdata->bar0 + MAC_10G_0_OFFSET + 0x0404) & 0x1; // stat_rx_status
env_params->eth_10G_link[1] = ioread32(drvdata->bar0 + MAC_10G_1_OFFSET + 0x0404) & 0x1; // stat_rx_status
env_params->eth_10G_link[2] = ioread32(drvdata->bar0 + MAC_10G_2_OFFSET + 0x0404) & 0x1; // stat_rx_status
env_params->eth_10G_link[3] = ioread32(drvdata->bar0 + MAC_10G_3_OFFSET + 0x0404) & 0x1; // stat_rx_status
env_params->eth_10G_link[4] = ioread32(drvdata->bar0 + MAC_10G_4_OFFSET + 0x0404) & 0x1; // stat_rx_status
env_params->eth_10G_link[5] = ioread32(drvdata->bar0 + MAC_10G_5_OFFSET + 0x0404) & 0x1; // stat_rx_status
env_params->eth_10G_link[6] = ioread32(drvdata->bar0 + MAC_10G_6_OFFSET + 0x0404) & 0x1; // stat_rx_status
env_params->eth_10G_link[7] = ioread32(drvdata->bar0 + MAC_10G_7_OFFSET + 0x0404) & 0x1; // stat_rx_status
}
}
env_params->work_compl_fifo_avail = kfifo_avail(&drvdata->work_compl);
env_params->active_handles = atomic_read(&drvdata->active_handles);
@@ -399,17 +404,8 @@ int jfjoch_run_frame_gen(struct jfjoch_drvdata *drvdata, struct FrameGeneratorCo
dev_err(dev, "Frame generator busy\n");
return -EBUSY;
}
iowrite32(config->frames, drvdata->bar0 + ADDR_FRAME_GEN_FRAMES);
iowrite32(config->modules, drvdata->bar0 + ADDR_FRAME_GEN_MODULES);
iowrite32(config->dest_ipv4_addr, drvdata->bar0 + ADDR_FRAME_GEN_DEST_IPV4_ADDR);
iowrite32(config->dest_mac_addr & 0xFFFFFFFF, drvdata->bar0 + ADDR_FRAME_GEN_DEST_MAC_LO);
iowrite32(config->dest_mac_addr >> 32, drvdata->bar0 + ADDR_FRAME_GEN_DEST_MAC_HI);
iowrite32(config->bunchid & 0xFFFFFFFF, drvdata->bar0 + ADDR_FRAME_GEN_BUNCHID_LO);
iowrite32(config->bunchid >> 32, drvdata->bar0 + ADDR_FRAME_GEN_BUNCHID_HI);
iowrite32(config->exptime, drvdata->bar0 + ADDR_FRAME_GEN_EXPTIME);
iowrite32(config->debug, drvdata->bar0 + ADDR_FRAME_GEN_DEBUG);
iowrite32(0x1, drvdata->bar0 + ADDR_FRAME_GEN_CTRL);
memcpy_toio(drvdata->bar0 + ADDR_FRAME_GEN_CONFIG, config, sizeof(struct FrameGeneratorConfig));
iowrite32(0x1, drvdata->bar0 + ADDR_FRAME_GEN_CTRL);
return 0;
}
+178
View File
@@ -0,0 +1,178 @@
// Copyright (2019-2024) Paul Scherrer Institute
#include <linux/delay.h>
#include "jfjoch_drv.h"
#define AMD_I2C_CTRL_REG (0x100)
#define AMD_I2C_STATUS_REG (0x104)
#define AMD_I2C_TX_FIFO (0x108)
#define AMD_I2C_RX_FIFO (0x10C)
#define AMD_I2C_RX_FIFO_PIRQ (0x120)
#define AMD_I2C_TX_FIFO_START (0x100)
#define AMD_I2C_TX_FIFO_STOP (0x200)
#define AMD_I2C_CTRL_REG_I2C_ENABLE (0x01)
#define AMD_I2C_CTRL_REG_TX_FIFO_RST (0x02)
#define AMD_I2C_STATUS_REG_BUS_BUSY (1<<2)
#define AMD_I2C_STATUS_REG_TX_FIFO_EMPTY (1<<7)
#define AMD_I2C_STATUS_REG_RX_FIFO_EMPTY (1<<6)
static int i2c_init(struct jfjoch_drvdata *drvdata, size_t i2c_offset) {
struct device *const dev = &drvdata->pdev->dev;
u32 status_reg;
// Set the RX_FIFO depth to one byte
iowrite32(0xF, drvdata->bar0 + i2c_offset + AMD_I2C_RX_FIFO_PIRQ);
// Reset TX FIFO
iowrite32(AMD_I2C_CTRL_REG_TX_FIFO_RST, drvdata->bar0 + i2c_offset + AMD_I2C_CTRL_REG);
// Enable I2C
iowrite32(AMD_I2C_CTRL_REG_I2C_ENABLE, drvdata->bar0 + i2c_offset + AMD_I2C_CTRL_REG);
status_reg = ioread32(drvdata->bar0 + i2c_offset + AMD_I2C_STATUS_REG);
if (status_reg != (AMD_I2C_STATUS_REG_RX_FIFO_EMPTY | AMD_I2C_STATUS_REG_TX_FIFO_EMPTY))
dev_err(dev, "I2C init result: %x", status_reg);
return 0;
}
static int i2c_wait_while_rx_fifo_empty(struct jfjoch_drvdata *drvdata, size_t i2c_offset) {
struct device *const dev = &drvdata->pdev->dev;
int i = 0;
u32 status_reg = ioread32(drvdata->bar0 + i2c_offset + AMD_I2C_STATUS_REG);
while (i < 1000) {
if ((status_reg & AMD_I2C_STATUS_REG_RX_FIFO_EMPTY) == 0 )
return 0;
udelay(10);
status_reg = ioread32(drvdata->bar0 + i2c_offset + AMD_I2C_STATUS_REG);
i++;
}
dev_err(dev, "I2C read: RX FIFO empty after 10 ms");
return -EIO;
}
static int i2c_wait_while_busy(struct jfjoch_drvdata *drvdata, size_t i2c_offset) {
struct device *const dev = &drvdata->pdev->dev;
int i = 0;
u32 status_reg = ioread32(drvdata->bar0 + i2c_offset + AMD_I2C_STATUS_REG);
while (i < 1000) {
if ((status_reg & AMD_I2C_STATUS_REG_BUS_BUSY) == 0)
return 0;
udelay(10);
i++;
status_reg = ioread32(drvdata->bar0 + i2c_offset + AMD_I2C_STATUS_REG);
}
dev_err(dev, "I2C op: bus busy after 10 ms");
return -EIO;
}
static int i2c_write(struct jfjoch_drvdata *drvdata, size_t i2c_offset, const struct I2COperation *operation) {
struct device *const dev = &drvdata->pdev->dev;
u32 status_reg;
int err;
// Disable I2C
iowrite32(0, drvdata->bar0 + i2c_offset + AMD_I2C_CTRL_REG);
// Enable I2C
iowrite32(AMD_I2C_CTRL_REG_I2C_ENABLE, drvdata->bar0 + i2c_offset + AMD_I2C_CTRL_REG);
status_reg = ioread32(drvdata->bar0 + i2c_offset + AMD_I2C_STATUS_REG);
if (((status_reg & AMD_I2C_STATUS_REG_BUS_BUSY) != 0 )
|| ((status_reg & AMD_I2C_STATUS_REG_RX_FIFO_EMPTY) == 0 )
|| ((status_reg & AMD_I2C_STATUS_REG_TX_FIFO_EMPTY) == 0 )) {
dev_err(dev, "I2C not ready to write SR: %x", status_reg);
return -EIO;
}
iowrite32(AMD_I2C_TX_FIFO_START | operation->dev_addr, drvdata->bar0 + i2c_offset + AMD_I2C_TX_FIFO);
iowrite32(operation->reg_addr , drvdata->bar0 + i2c_offset + AMD_I2C_TX_FIFO);
iowrite32(AMD_I2C_TX_FIFO_STOP | operation->content, drvdata->bar0 + i2c_offset + AMD_I2C_TX_FIFO);
err = i2c_wait_while_busy(drvdata, i2c_offset);
if (err != 0)
return err;
return 0;
}
static int i2c_write_reg_addr(struct jfjoch_drvdata *drvdata, size_t i2c_offset, const struct I2COperation *operation) {
struct device *const dev = &drvdata->pdev->dev;
u32 status_reg;
int err;
// Disable I2C
iowrite32(0, drvdata->bar0 + i2c_offset + AMD_I2C_CTRL_REG);
// Enable I2C
iowrite32(AMD_I2C_CTRL_REG_I2C_ENABLE, drvdata->bar0 + i2c_offset + AMD_I2C_CTRL_REG);
status_reg = ioread32(drvdata->bar0 + i2c_offset + AMD_I2C_STATUS_REG);
if (((status_reg & AMD_I2C_STATUS_REG_BUS_BUSY) != 0 )
|| ((status_reg & AMD_I2C_STATUS_REG_RX_FIFO_EMPTY) == 0 )
|| ((status_reg & AMD_I2C_STATUS_REG_TX_FIFO_EMPTY) == 0 )) {
dev_err(dev, "I2C not ready to write SR: %x", status_reg);
return -EIO;
}
iowrite32(operation->dev_addr | AMD_I2C_TX_FIFO_START, drvdata->bar0 + i2c_offset + AMD_I2C_TX_FIFO);
iowrite32(operation->reg_addr | AMD_I2C_TX_FIFO_STOP, drvdata->bar0 + i2c_offset + AMD_I2C_TX_FIFO);
err = i2c_wait_while_busy(drvdata, i2c_offset);
if (err != 0)
return err;
return 0;
}
static int i2c_read(struct jfjoch_drvdata *drvdata, size_t i2c_offset, struct I2COperation *operation) {
struct device *const dev = &drvdata->pdev->dev;
int err;
u32 status_reg;
// Disable I2C
iowrite32(0, drvdata->bar0 + i2c_offset + AMD_I2C_CTRL_REG);
// Enable I2C
iowrite32(AMD_I2C_CTRL_REG_I2C_ENABLE, drvdata->bar0 + i2c_offset + AMD_I2C_CTRL_REG);
status_reg = ioread32(drvdata->bar0 + i2c_offset + AMD_I2C_STATUS_REG);
if (((status_reg & AMD_I2C_STATUS_REG_BUS_BUSY) != 0 )
|| ((status_reg & AMD_I2C_STATUS_REG_RX_FIFO_EMPTY) == 0 )
|| ((status_reg & AMD_I2C_STATUS_REG_TX_FIFO_EMPTY) == 0 )) {
dev_err(dev, "I2C not ready to read SR: %x", status_reg);
return -EIO;
}
iowrite32(operation->dev_addr | 0x1 | AMD_I2C_TX_FIFO_START, drvdata->bar0 + i2c_offset + AMD_I2C_TX_FIFO);
iowrite32(0x1 | AMD_I2C_TX_FIFO_STOP, drvdata->bar0 + i2c_offset + AMD_I2C_TX_FIFO);
err = i2c_wait_while_rx_fifo_empty(drvdata, i2c_offset);
if (err != 0)
return err;
operation->content = ioread32(drvdata->bar0 + i2c_offset + AMD_I2C_RX_FIFO);
err = i2c_wait_while_busy(drvdata, i2c_offset);
if (err != 0)
return err;
return 0;
}
int jfjoch_i2c_si5394_init(struct jfjoch_drvdata *drvdata) {
return i2c_init(drvdata, I2C_SI5394_OFFSET);
}
int jfjoch_i2c_si5394_read(struct jfjoch_drvdata *drvdata, struct I2COperation *operation) {
int tmp = i2c_write_reg_addr(drvdata, I2C_SI5394_OFFSET, operation);
if (tmp != 0)
return tmp;
return i2c_read(drvdata, I2C_SI5394_OFFSET, operation);
}
int jfjoch_i2c_si5394_write(struct jfjoch_drvdata *drvdata, const struct I2COperation *operation) {
return i2c_write(drvdata, I2C_SI5394_OFFSET, operation);
}
+16
View File
@@ -12,6 +12,7 @@ long jfjoch_cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {
struct RegisterConfig reg_config;
struct SpotFinderParameters spot_finder_parameters;
struct LoadCalibrationConfig load_calibration_config;
struct I2COperation i2c_operation;
u32 exchange[16];
int err;
@@ -168,6 +169,21 @@ long jfjoch_cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {
if (copy_to_user((char *) arg, &reg_config, sizeof(struct RegisterConfig)) != 0)
return -EFAULT;
return 0;
case IOCTL_JFJOCH_I2C_CLK_READ:
if (copy_from_user(&i2c_operation, (char *) arg, sizeof(struct I2COperation)) != 0)
return -EFAULT;
err = jfjoch_i2c_si5394_read(drvdata, &i2c_operation) != 0;
if (err)
return err;
if (copy_to_user((char *) arg, &i2c_operation, sizeof(struct I2COperation)) != 0)
return -EFAULT;
return 0;
case IOCTL_JFJOCH_I2C_CLK_WRITE:
if (!(file->f_mode & FMODE_WRITE))
return -EACCES;
if (copy_from_user(&i2c_operation, (char *) arg, sizeof(struct I2COperation)) != 0)
return -EFAULT;
return jfjoch_i2c_si5394_write(drvdata, &i2c_operation);
default:
return -ENOTTY;
}
+2
View File
@@ -42,5 +42,7 @@
#define IOCTL_JFJOCH_GET_DATA_SOURCE _IOR(IOCTL_JFJOCH_MAGIC, 29, uint32_t)
#define IOCTL_JFJOCH_GET_SPOTFIN_PAR _IOR(IOCTL_JFJOCH_MAGIC, 30, struct SpotFinderParameters)
#define IOCTL_JFJOCH_LOAD_CALIB _IOW(IOCTL_JFJOCH_MAGIC, 31, struct LoadCalibrationConfig)
#define IOCTL_JFJOCH_I2C_CLK_READ _IOR(IOCTL_JFJOCH_MAGIC, 32, struct I2COperation)
#define IOCTL_JFJOCH_I2C_CLK_WRITE _IOW(IOCTL_JFJOCH_MAGIC, 33, struct I2COperation)
#endif //JUNGFRAUJOCH_JFJOCH_IOCTL_H
+2 -2
View File
@@ -53,12 +53,12 @@ int jfjoch_check_version(struct pci_dev *pdev) {
action_type = ioread32(drvdata->bar0 + ACTION_CONFIG_OFFSET + ADDR_ACTION_TYPE);
release_level = ioread32(drvdata->bar0 + ACTION_CONFIG_OFFSET + ADDR_RELEASE_LEVEL);
if (action_type != ACTION_TYPE) {
if (action_type != JFJOCH_FPGA_MAGIC) {
dev_err(dev, "Mismatch in JFJoch action type (%x)\n", action_type);
return -EINVAL;
}
if (release_level != RELEASE_LEVEL) {
if (release_level != JFJOCH_FPGA_RELEASE) {
dev_err(dev, "Mismatch in JFJoch release level (%x)\n", release_level);
return -EINVAL;
}
+7 -5
View File
@@ -86,10 +86,12 @@ static ssize_t eth_aligned_show(struct device *dev,
struct miscdevice* miscdev = dev_get_drvdata(dev);
struct jfjoch_drvdata* drvdata = container_of(miscdev, struct jfjoch_drvdata, miscdev);
unsigned int val;
// Need to ask twice to get recent answer
ioread32(drvdata->bar0 + CMAC_OFFSET + 0x0204);
val = ioread32(drvdata->bar0 + CMAC_OFFSET + 0x0204) & 0x2;
if (drvdata->fpga_variant == JFJOCH_FPGA_VARIANT_100G) {
// Need to ask twice to get recent answer
ioread32(drvdata->bar0 + MAC_100G_OFFSET + 0x0204);
val = ioread32(drvdata->bar0 + MAC_100G_OFFSET + 0x0204) & 0x2;
} else
val = 0;
return scnprintf(buf, PAGE_SIZE, "%d", val);
}
@@ -160,7 +162,7 @@ static ssize_t active_handles_show(struct device *dev,
static ssize_t release_show(struct device *dev,
struct device_attribute *attr,
char *buf) {
return scnprintf(buf, 25, "%d", RELEASE_LEVEL);
return scnprintf(buf, 25, "%d", JFJOCH_FPGA_RELEASE);
}
static struct device_attribute device_attrs[] = {
+41 -35
View File
@@ -1,4 +1,4 @@
## Copyright (2019-2023) Paul Scherrer Institute
## Copyright (2019-2024) Paul Scherrer Institute
################################################################
# This is a generated script based on design: jfjoch_pcie
@@ -131,6 +131,7 @@ set bCheckIPsPassed 1
set bCheckIPs 1
if { $bCheckIPs == 1 } {
set list_check_ips "\
xilinx.com:ip:axi_iic:2.1\
xilinx.com:ip:axi_intc:4.1\
xilinx.com:ip:axi_quad_spi:3.2\
xilinx.com:ip:clk_wiz:6.0\
@@ -138,6 +139,7 @@ xilinx.com:ip:cms_subsystem:4.0\
xilinx.com:ip:xlconstant:1.1\
xilinx.com:ip:proc_sys_reset:5.0\
xilinx.com:ip:smartconnect:1.0\
xilinx.com:ip:util_ds_buf:2.2\
xilinx.com:ip:xlconcat:2.1\
xilinx.com:ip:axi_protocol_converter:2.1\
xilinx.com:ip:axi_register_slice:2.1\
@@ -159,21 +161,24 @@ xilinx.com:ip:axis_dwidth_converter:1.1\
xilinx.com:ip:xxv_ethernet:4.1\
xilinx.com:ip:axi_firewall:1.2\
xilinx.com:ip:axis_clock_converter:1.1\
xilinx.com:ip:util_ds_buf:2.2\
xilinx.com:ip:xdma:4.1\
xilinx.com:ip:axi_datamover:5.1\
psi.ch:hls:frame_summation_reorder_compl:1.0\
psi.ch:hls:load_from_hbm:1.0\
psi.ch:hls:save_to_hbm:1.0\
psi.ch:hls:save_to_hbm_data:1.0\
psi.ch:hls:adu_histo:1.0\
psi.ch:hls:axis_64_to_512:1.0\
psi.ch:hls:eiger_reorder:1.0\
psi.ch:hls:frame_summation:1.0\
psi.ch:hls:integration:1.0\
psi.ch:hls:jf_conversion:1.0\
psi.ch:hls:mask_missing:1.0\
psi.ch:hls:pedestal:1.0\
psi.ch:hls:roi_calc:1.0\
psi.ch:hls:spot_finder:1.0\
psi.ch:hls:spot_finder_connectivity:1.0\
psi.ch:hls:spot_finder_mask:1.0\
psi.ch:hls:spot_finder_merge:1.0\
psi.ch:hls:stream_24bit_conv:1.0\
psi.ch:hls:arp:1.0\
@@ -210,7 +215,6 @@ if { $bCheckModules == 1 } {
set list_check_mods "\
action_config\
gen_xdma_descriptor\
eth_4x10g_leds\
"
set list_mods_missing ""
@@ -271,6 +275,8 @@ proc create_root_design { parentCell } {
# Create interface ports
set i2c_si5394 [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:iic_rtl:1.0 i2c_si5394 ]
set pcie0_mgt [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:pcie_7x_mgt_rtl:1.0 pcie0_mgt ]
set pcie0_ref [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:diff_clock_rtl:1.0 pcie0_ref ]
@@ -278,6 +284,7 @@ proc create_root_design { parentCell } {
set qsfp0 [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:gt_rtl:1.0 qsfp0 ]
set qsfp0_ref [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:diff_clock_rtl:1.0 qsfp0_ref ]
set_property -dict [ list \
CONFIG.FREQ_HZ {161132812} \
] $qsfp0_ref
@@ -298,20 +305,23 @@ proc create_root_design { parentCell } {
# Create ports
set hbm_cattrip [ create_bd_port -dir O hbm_cattrip ]
set hbm_cattrip [ create_bd_port -dir O -from 0 -to 0 hbm_cattrip ]
set pcie_perstn [ create_bd_port -dir I -type rst pcie_perstn ]
set qsfp0_led_busy [ create_bd_port -dir O -from 0 -to 0 qsfp0_led_busy ]
set qsfp0_led_conn_green [ create_bd_port -dir O qsfp0_led_conn_green ]
set qsfp0_led_conn_yellow [ create_bd_port -dir O qsfp0_led_conn_yellow ]
set qsfp0_led_busy [ create_bd_port -dir O qsfp0_led_busy ]
set qsfp0_led_conn_yellow [ create_bd_port -dir O -from 0 -to 0 qsfp0_led_conn_yellow ]
set qsfp1_led_busy [ create_bd_port -dir O -from 0 -to 0 qsfp1_led_busy ]
set qsfp1_led_conn_green [ create_bd_port -dir O qsfp1_led_conn_green ]
set qsfp1_led_conn_yellow [ create_bd_port -dir O qsfp1_led_conn_yellow ]
set qsfp1_led_busy [ create_bd_port -dir O qsfp1_led_busy ]
set satellite_gpio_0 [ create_bd_port -dir I -from 3 -to 0 -type intr satellite_gpio_0 ]
set_property -dict [ list \
CONFIG.PortWidth {4} \
CONFIG.SENSITIVITY {EDGE_RISING} \
] $satellite_gpio_0
# Create instance: axi_iic_0, and set properties
set axi_iic_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_iic:2.1 axi_iic_0 ]
# Create instance: axi_intc_0, and set properties
set axi_intc_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_intc:4.1 axi_intc_0 ]
set_property -dict [ list \
@@ -333,20 +343,20 @@ proc create_root_design { parentCell } {
# Create instance: clk_wiz_0, and set properties
set clk_wiz_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz:6.0 clk_wiz_0 ]
set_property -dict [ list \
CONFIG.CLKOUT1_JITTER {132.683} \
CONFIG.CLKOUT1_JITTER {153.164} \
CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {50.000} \
CONFIG.CLKOUT2_JITTER {115.831} \
CONFIG.CLKOUT2_PHASE_ERROR {87.180} \
CONFIG.CLKOUT2_JITTER {134.506} \
CONFIG.CLKOUT2_PHASE_ERROR {154.678} \
CONFIG.CLKOUT2_USED {true} \
CONFIG.CLKOUT3_JITTER {102.086} \
CONFIG.CLKOUT3_PHASE_ERROR {87.180} \
CONFIG.CLKOUT3_JITTER {119.392} \
CONFIG.CLKOUT3_PHASE_ERROR {154.678} \
CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {200.000} \
CONFIG.CLKOUT3_USED {true} \
CONFIG.MMCM_CLKOUT0_DIVIDE_F {24.000} \
CONFIG.MMCM_CLKOUT1_DIVIDE {12} \
CONFIG.MMCM_CLKOUT2_DIVIDE {6} \
CONFIG.NUM_OUT_CLKS {3} \
CONFIG.PRIM_SOURCE {Differential_clock_capable_pin} \
CONFIG.PRIM_SOURCE {Single_ended_clock_capable_pin} \
CONFIG.RESET_PORT {reset} \
CONFIG.RESET_TYPE {ACTIVE_HIGH} \
CONFIG.USE_LOCKED {false} \
@@ -365,9 +375,6 @@ proc create_root_design { parentCell } {
# Create instance: mac_100g
create_hier_cell_mac_100g [current_bd_instance .] mac_100g
# Create instance: mac_4x10g
create_hier_cell_mac_4x10g [current_bd_instance .] mac_4x10g
# Create instance: one, and set properties
set one [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 one ]
@@ -390,10 +397,13 @@ proc create_root_design { parentCell } {
set smartconnect_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 smartconnect_0 ]
set_property -dict [ list \
CONFIG.NUM_CLKS {4} \
CONFIG.NUM_MI {7} \
CONFIG.NUM_MI {8} \
CONFIG.NUM_SI {1} \
] $smartconnect_0
# Create instance: util_ds_buf_0, and set properties
set util_ds_buf_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:util_ds_buf:2.2 util_ds_buf_0 ]
# Create instance: xlconcat_intc, and set properties
set xlconcat_intc [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconcat:2.1 xlconcat_intc ]
set_property -dict [ list \
@@ -414,8 +424,8 @@ proc create_root_design { parentCell } {
# Create interface connections
connect_bd_intf_net -intf_net S_AXIS_100G_1 [get_bd_intf_pins jungfraujoch/eth_out] [get_bd_intf_pins mac_100g/s_axis_eth_out]
connect_bd_intf_net -intf_net axi_iic_0_IIC [get_bd_intf_ports i2c_si5394] [get_bd_intf_pins axi_iic_0/IIC]
connect_bd_intf_net -intf_net cms_subsystem_0_satellite_uart [get_bd_intf_ports satellite_uart_0] [get_bd_intf_pins cms_subsystem_0/satellite_uart]
connect_bd_intf_net -intf_net eth_4x10g_in_1 [get_bd_intf_pins jungfraujoch/eth_4x10g_in] [get_bd_intf_pins mac_4x10g/m_axis]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p0 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_0] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p0]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p1 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_1] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p1]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p2 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_2] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p2]
@@ -446,18 +456,18 @@ proc create_root_design { parentCell } {
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p27 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_27] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p27]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p28 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_28] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p28]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p29 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_29] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p29]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p30 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_30] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p30]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p31 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_31] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p31]
connect_bd_intf_net -intf_net jungfraujoch_m_axis_c2h_data [get_bd_intf_pins jungfraujoch/m_axis_c2h_data] [get_bd_intf_pins pcie_dma_0/s_axis_c2h_data]
connect_bd_intf_net -intf_net jungfraujoch_m_axis_c2h_datamover_cmd [get_bd_intf_pins jungfraujoch/m_axis_c2h_datamover_cmd] [get_bd_intf_pins pcie_dma_0/s_axis_c2h_cmd]
connect_bd_intf_net -intf_net jungfraujoch_m_axis_h2c_datamover_cmd [get_bd_intf_pins jungfraujoch/m_axis_h2c_datamover_cmd] [get_bd_intf_pins pcie_dma_0/s_axis_h2c_cmd]
connect_bd_intf_net -intf_net mac_100g_1_qsfp0 [get_bd_intf_ports qsfp0] [get_bd_intf_pins mac_100g/qsfp]
connect_bd_intf_net -intf_net mac_100g_m_axis_eth_in [get_bd_intf_pins jungfraujoch/eth_100g_in] [get_bd_intf_pins mac_100g/m_axis_eth_in]
connect_bd_intf_net -intf_net mac_4x10g_qsfp1 [get_bd_intf_ports qsfp1] [get_bd_intf_pins mac_4x10g/qsfp1]
connect_bd_intf_net -intf_net mac_100g_m_axis_eth_in [get_bd_intf_pins jungfraujoch/eth_in] [get_bd_intf_pins mac_100g/m_axis_eth_in]
connect_bd_intf_net -intf_net pcie0_ref_1 [get_bd_intf_ports pcie0_ref] [get_bd_intf_pins pcie_dma_0/pcie_refclk]
connect_bd_intf_net -intf_net pcie_dma_0_M_AXI [get_bd_intf_pins pcie_dma_0/m_axi_ctrl] [get_bd_intf_pins smartconnect_0/S00_AXI]
connect_bd_intf_net -intf_net pcie_dma_0_pcie0_mgt [get_bd_intf_ports pcie0_mgt] [get_bd_intf_pins pcie_dma_0/pcie_mgt]
connect_bd_intf_net -intf_net qsfp0_ref_1 [get_bd_intf_ports qsfp0_ref] [get_bd_intf_pins mac_100g/qsfp_ref]
connect_bd_intf_net -intf_net qsfp1_ref_1 [get_bd_intf_ports qsfp1_ref] [get_bd_intf_pins mac_4x10g/qsfp_ref]
connect_bd_intf_net -intf_net ref100_1 [get_bd_intf_ports ref100] [get_bd_intf_pins clk_wiz_0/CLK_IN1_D]
connect_bd_intf_net -intf_net ref100_1 [get_bd_intf_ports ref100] [get_bd_intf_pins util_ds_buf_0/CLK_IN_D]
connect_bd_intf_net -intf_net s_axi_1 [get_bd_intf_pins jungfraujoch/s_axi] [get_bd_intf_pins smartconnect_0/M00_AXI]
connect_bd_intf_net -intf_net s_axi_2 [get_bd_intf_pins mac_100g/s_axi] [get_bd_intf_pins smartconnect_0/M02_AXI]
connect_bd_intf_net -intf_net s_axis_h2c_data_1 [get_bd_intf_pins jungfraujoch/s_axis_h2c_data] [get_bd_intf_pins pcie_dma_0/m_axis_h2c_data]
@@ -465,10 +475,10 @@ proc create_root_design { parentCell } {
connect_bd_intf_net -intf_net smartconnect_0_M03_AXI [get_bd_intf_pins axi_quad_spi_0/AXI_LITE] [get_bd_intf_pins smartconnect_0/M03_AXI]
connect_bd_intf_net -intf_net smartconnect_0_M04_AXI [get_bd_intf_pins axi_intc_0/s_axi] [get_bd_intf_pins smartconnect_0/M04_AXI]
connect_bd_intf_net -intf_net smartconnect_0_M05_AXI [get_bd_intf_pins pcie_dma_0/s_axi_dma_ctrl] [get_bd_intf_pins smartconnect_0/M05_AXI]
connect_bd_intf_net -intf_net smartconnect_0_M06_AXI [get_bd_intf_pins mac_4x10g/s_axi] [get_bd_intf_pins smartconnect_0/M06_AXI]
connect_bd_intf_net -intf_net smartconnect_0_M07_AXI [get_bd_intf_pins axi_iic_0/S_AXI] [get_bd_intf_pins smartconnect_0/M06_AXI]
# Create port connections
connect_bd_net -net axi_clk_1 [get_bd_pins pcie_dma_0/axi_aclk] [get_bd_pins proc_sys_reset_pcie_0/slowest_sync_clk] [get_bd_pins smartconnect_0/aclk3]
connect_bd_net -net axi_clk_1 [get_bd_pins clk_wiz_0/clk_in1] [get_bd_pins pcie_dma_0/axi_aclk] [get_bd_pins proc_sys_reset_pcie_0/slowest_sync_clk] [get_bd_pins smartconnect_0/aclk3]
connect_bd_net -net axi_intc_0_irq [get_bd_pins axi_intc_0/irq] [get_bd_pins xlconcat_irq/In0]
connect_bd_net -net axi_quad_spi_0_ip2intc_irpt [get_bd_pins axi_quad_spi_0/ip2intc_irpt] [get_bd_pins xlconcat_intc/In0]
connect_bd_net -net cms_subsystem_0_interrupt_host [get_bd_pins cms_subsystem_0/interrupt_host] [get_bd_pins xlconcat_intc/In1]
@@ -478,21 +488,20 @@ proc create_root_design { parentCell } {
connect_bd_net -net jungfraujoch_Interrupt_0 [get_bd_pins jungfraujoch/Interrupt_0] [get_bd_pins xlconcat_irq/In1]
connect_bd_net -net mac_100g_led_green [get_bd_ports qsfp0_led_conn_green] [get_bd_pins mac_100g/led_green]
connect_bd_net -net mac_100g_led_yellow [get_bd_ports qsfp0_led_conn_yellow] [get_bd_pins mac_100g/led_yellow]
connect_bd_net -net mac_4x10g_led_green [get_bd_ports qsfp1_led_conn_green] [get_bd_pins mac_4x10g/led_green]
connect_bd_net -net mac_4x10g_led_yellow [get_bd_ports qsfp1_led_conn_yellow] [get_bd_pins mac_4x10g/led_yellow]
connect_bd_net -net net_refclk50 [get_bd_pins axi_intc_0/s_axi_aclk] [get_bd_pins axi_quad_spi_0/s_axi_aclk] [get_bd_pins clk_wiz_0/clk_out1] [get_bd_pins cms_subsystem_0/aclk_ctrl] [get_bd_pins mac_4x10g/refclk50] [get_bd_pins proc_sys_reset_refclk/slowest_sync_clk] [get_bd_pins smartconnect_0/aclk2]
connect_bd_net -net net_refclk100 [get_bd_pins axi_quad_spi_0/ext_spi_clk] [get_bd_pins clk_wiz_0/clk_out2] [get_bd_pins hbm_infrastructure/refclk100] [get_bd_pins mac_100g/refclk100] [get_bd_pins smartconnect_0/aclk1]
connect_bd_net -net net_refclk200 [get_bd_pins clk_wiz_0/clk_out3] [get_bd_pins hbm_infrastructure/axi_clk] [get_bd_pins jungfraujoch/axi_clk] [get_bd_pins mac_100g/axiclk] [get_bd_pins mac_4x10g/m_axis_aclk] [get_bd_pins pcie_dma_0/refclk200] [get_bd_pins smartconnect_0/aclk]
connect_bd_net -net net_refclk50 [get_bd_pins clk_wiz_0/clk_out1] [get_bd_pins axi_intc_0/s_axi_aclk] [get_bd_pins axi_iic_0/s_axi_aclk] [get_bd_pins axi_quad_spi_0/s_axi_aclk] [get_bd_pins cms_subsystem_0/aclk_ctrl] [get_bd_pins proc_sys_reset_refclk/slowest_sync_clk] [get_bd_pins smartconnect_0/aclk2]
connect_bd_net -net net_refclk100 [get_bd_pins clk_wiz_0/clk_out2] [get_bd_pins hbm_infrastructure/refclk100] [get_bd_pins axi_quad_spi_0/ext_spi_clk] [get_bd_pins mac_100g/refclk100] [get_bd_pins smartconnect_0/aclk1]
connect_bd_net -net net_refclk200 [get_bd_pins clk_wiz_0/clk_out3] [get_bd_pins hbm_infrastructure/axi_clk] [get_bd_pins jungfraujoch/axi_clk] [get_bd_pins mac_100g/axiclk] [get_bd_pins pcie_dma_0/refclk200] [get_bd_pins smartconnect_0/aclk]
connect_bd_net -net one_dout [get_bd_pins cms_subsystem_0/aresetn_ctrl] [get_bd_pins one/dout] [get_bd_pins proc_sys_reset_pcie_0/dcm_locked] [get_bd_pins proc_sys_reset_refclk/dcm_locked]
connect_bd_net -net pcie_dma_0_axi_aresetn [get_bd_pins pcie_dma_0/axi_aresetn] [get_bd_pins proc_sys_reset_pcie_0/ext_reset_in] [get_bd_pins proc_sys_reset_refclk/ext_reset_in] [get_bd_pins smartconnect_0/aresetn]
connect_bd_net -net pcie_perstn_1 [get_bd_ports pcie_perstn] [get_bd_pins pcie_dma_0/pcie_perstn]
connect_bd_net -net proc_sys_reset_pcie_0_interconnect_aresetn [get_bd_pins pcie_dma_0/axi_clk_resetn] [get_bd_pins proc_sys_reset_pcie_0/interconnect_aresetn]
connect_bd_net -net proc_sys_reset_refclk_peripheral_aresetn [get_bd_pins axi_intc_0/s_axi_aresetn] [get_bd_pins axi_quad_spi_0/s_axi_aresetn] [get_bd_pins hbm_infrastructure/axi_resetn] [get_bd_pins jungfraujoch/ap_rst_n] [get_bd_pins mac_100g/ap_rst_n] [get_bd_pins mac_4x10g/axi_aresetn] [get_bd_pins proc_sys_reset_refclk/peripheral_aresetn]
connect_bd_net -net proc_sys_reset_refclk_peripheral_aresetn [get_bd_pins axi_iic_0/s_axi_aresetn] [get_bd_pins axi_intc_0/s_axi_aresetn] [get_bd_pins axi_quad_spi_0/s_axi_aresetn] [get_bd_pins hbm_infrastructure/axi_resetn] [get_bd_pins jungfraujoch/ap_rst_n] [get_bd_pins mac_100g/ap_rst_n] [get_bd_pins proc_sys_reset_refclk/peripheral_aresetn]
connect_bd_net -net refclk100_1 [get_bd_pins hbm_infrastructure/hbmclk100] [get_bd_pins util_ds_buf_0/IBUF_OUT]
connect_bd_net -net resetn_1 [get_bd_pins jungfraujoch/axi_rst_n] [get_bd_pins mac_100g/resetn] [get_bd_pins pcie_dma_0/refclk200_resetn] [get_bd_pins proc_sys_reset_refclk/interconnect_aresetn]
connect_bd_net -net satellite_gpio_0_1 [get_bd_ports satellite_gpio_0] [get_bd_pins cms_subsystem_0/satellite_gpio]
connect_bd_net -net xlconcat_0_dout [get_bd_pins pcie_dma_0/usr_irq_req] [get_bd_pins xlconcat_irq/dout]
connect_bd_net -net xlconcat_irq_dout [get_bd_pins axi_intc_0/intr] [get_bd_pins xlconcat_intc/dout]
connect_bd_net -net zero_dout [get_bd_pins axi_quad_spi_0/usrcclkts] [get_bd_pins zero/dout] [get_bd_ports qsfp0_led_busy] [get_bd_ports qsfp1_led_busy]
connect_bd_net -net zero_dout [get_bd_ports qsfp0_led_busy] [get_bd_ports qsfp1_led_busy] [get_bd_pins axi_quad_spi_0/usrcclkts] [get_bd_pins zero/dout] [get_bd_ports qsfp1_led_conn_green] [get_bd_ports qsfp1_led_conn_yellow]
# Create address segments
assign_bd_address -offset 0x00010000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs jungfraujoch/action_config_0/s_axi/reg0] -force
@@ -505,10 +514,7 @@ proc create_root_design { parentCell } {
assign_bd_address -offset 0x00080000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs jungfraujoch/frame_generator_0/s_axi_control/Reg] -force
assign_bd_address -offset 0x00090000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs pcie_dma_0/xdma_0/S_AXI_LITE/CTL0] -force
assign_bd_address -offset 0x000C0000 -range 0x00040000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs cms_subsystem_0/s_axi_ctrl/Mem] -force
assign_bd_address -offset 0x00100000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs mac_4x10g/xxv_ethernet_0/s_axi_0/Reg] -force
assign_bd_address -offset 0x00110000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs mac_4x10g/xxv_ethernet_0/s_axi_1/Reg] -force
assign_bd_address -offset 0x00120000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs mac_4x10g/xxv_ethernet_0/s_axi_2/Reg] -force
assign_bd_address -offset 0x00130000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs mac_4x10g/xxv_ethernet_0/s_axi_3/Reg] -force
assign_bd_address -offset 0x000A0000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs axi_iic_0/S_AXI/Reg] -force
assign_bd_address -offset 0x00200000 -range 0x00080000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs jungfraujoch/axi_bram_ctrl_calibration_addr_0/S_AXI/Mem0] -force
assign_bd_address -offset 0x00000000 -range 0x00080000 -target_address_space [get_bd_addr_spaces jungfraujoch/load_calibration_0/Data_m_axi_handle_to_dma_address] [get_bd_addr_segs jungfraujoch/axi_bram_ctrl_calibration_addr_1/S_AXI/Mem0] -force
assign_bd_address
+561
View File
@@ -0,0 +1,561 @@
## Copyright (2019-2024) Paul Scherrer Institute
################################################################
# This is a generated script based on design: jfjoch_pcie
#
# Though there are limitations about the generated script,
# the main purpose of this utility is to make learning
# IP Integrator Tcl commands easier.
################################################################
namespace eval _tcl {
proc get_script_folder {} {
set script_path [file normalize [info script]]
set script_folder [file dirname $script_path]
return $script_folder
}
}
variable script_folder
set script_folder [_tcl::get_script_folder]
################################################################
# Check if script is running in correct Vivado version.
################################################################
set scripts_vivado_version 2022.1
set current_vivado_version [version -short]
if { [string first $scripts_vivado_version $current_vivado_version] == -1 } {
puts ""
catch {common::send_gid_msg -ssname BD::TCL -id 2041 -severity "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."}
return 1
}
################################################################
# START
################################################################
# To test this script, run the following commands from Vivado Tcl console:
# source jfjoch_pcie_script.tcl
# The design that will be created by this Tcl script contains the following
# module references:
# gen_xdma_descriptor, action_config
# Please add the sources of those modules before sourcing this Tcl script.
# If there is no project opened, this script will create a
# project, but make sure you do not have an existing project
# <./myproj/project_1.xpr> in the current working folder.
set list_projs [get_projects -quiet]
if { $list_projs eq "" } {
create_project project_1 myproj -part xcvu35p-fsvh2104-2-e
}
# CHANGE DESIGN NAME HERE
variable design_name
set design_name jfjoch_pcie
# If you do not already have an existing IP Integrator design open,
# you can create a design using the following command:
# create_bd_design $design_name
# Creating design if needed
set errMsg ""
set nRet 0
set cur_design [current_bd_design -quiet]
set list_cells [get_bd_cells -quiet]
if { ${design_name} eq "" } {
# USE CASES:
# 1) Design_name not set
set errMsg "Please set the variable <design_name> to a non-empty value."
set nRet 1
} elseif { ${cur_design} ne "" && ${list_cells} eq "" } {
# USE CASES:
# 2): Current design opened AND is empty AND names same.
# 3): Current design opened AND is empty AND names diff; design_name NOT in project.
# 4): Current design opened AND is empty AND names diff; design_name exists in project.
if { $cur_design ne $design_name } {
common::send_gid_msg -ssname BD::TCL -id 2001 -severity "INFO" "Changing value of <design_name> from <$design_name> to <$cur_design> since current design is empty."
set design_name [get_property NAME $cur_design]
}
common::send_gid_msg -ssname BD::TCL -id 2002 -severity "INFO" "Constructing design in IPI design <$cur_design>..."
} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } {
# USE CASES:
# 5) Current design opened AND has components AND same names.
set errMsg "Design <$design_name> already exists in your project, please set the variable <design_name> to another value."
set nRet 1
} elseif { [get_files -quiet ${design_name}.bd] ne "" } {
# USE CASES:
# 6) Current opened design, has components, but diff names, design_name exists in project.
# 7) No opened design, design_name exists in project.
set errMsg "Design <$design_name> already exists in your project, please set the variable <design_name> to another value."
set nRet 2
} else {
# USE CASES:
# 8) No opened design, design_name not in project.
# 9) Current opened design, has components, but diff names, design_name not in project.
common::send_gid_msg -ssname BD::TCL -id 2003 -severity "INFO" "Currently there is no design <$design_name> in project, so creating one..."
create_bd_design $design_name
common::send_gid_msg -ssname BD::TCL -id 2004 -severity "INFO" "Making design <$design_name> as current_bd_design."
current_bd_design $design_name
}
common::send_gid_msg -ssname BD::TCL -id 2005 -severity "INFO" "Currently the variable <design_name> is equal to \"$design_name\"."
if { $nRet != 0 } {
catch {common::send_gid_msg -ssname BD::TCL -id 2006 -severity "ERROR" $errMsg}
return $nRet
}
set bCheckIPsPassed 1
##################################################################
# CHECK IPs
##################################################################
set bCheckIPs 1
if { $bCheckIPs == 1 } {
set list_check_ips "\
xilinx.com:ip:axi_iic:2.1\
xilinx.com:ip:axi_intc:4.1\
xilinx.com:ip:axi_quad_spi:3.2\
xilinx.com:ip:clk_wiz:6.0\
xilinx.com:ip:cms_subsystem:4.0\
xilinx.com:ip:xlconstant:1.1\
xilinx.com:ip:proc_sys_reset:5.0\
xilinx.com:ip:smartconnect:1.0\
xilinx.com:ip:util_ds_buf:2.2\
xilinx.com:ip:xlconcat:2.1\
xilinx.com:ip:axi_protocol_converter:2.1\
xilinx.com:ip:axi_register_slice:2.1\
xilinx.com:ip:hbm:1.0\
xilinx.com:ip:util_vector_logic:2.0\
xilinx.com:ip:axi_bram_ctrl:4.1\
xilinx.com:ip:axis_data_fifo:2.0\
xilinx.com:ip:axis_register_slice:1.1\
psi.ch:hls:data_collection_fsm:1.0\
xilinx.com:ip:blk_mem_gen:8.4\
psi.ch:hls:frame_generator:1.0\
psi.ch:hls:host_writer:1.0\
psi.ch:hls:load_calibration:1.0\
xilinx.com:ip:mailbox:2.1\
psi.ch:hls:stream_merge:1.0\
psi.ch:hls:timer_host:1.0\
xilinx.com:ip:cmac_usplus:3.1\
xilinx.com:ip:axis_dwidth_converter:1.1\
xilinx.com:ip:xxv_ethernet:4.1\
xilinx.com:ip:axi_firewall:1.2\
xilinx.com:ip:axis_clock_converter:1.1\
xilinx.com:ip:xdma:4.1\
xilinx.com:ip:axi_datamover:5.1\
psi.ch:hls:frame_summation_reorder_compl:1.0\
psi.ch:hls:load_from_hbm:1.0\
psi.ch:hls:save_to_hbm:1.0\
psi.ch:hls:save_to_hbm_data:1.0\
psi.ch:hls:adu_histo:1.0\
psi.ch:hls:axis_64_to_512:1.0\
psi.ch:hls:eiger_reorder:1.0\
psi.ch:hls:frame_summation:1.0\
psi.ch:hls:integration:1.0\
psi.ch:hls:jf_conversion:1.0\
psi.ch:hls:mask_missing:1.0\
psi.ch:hls:pedestal:1.0\
psi.ch:hls:roi_calc:1.0\
psi.ch:hls:spot_finder:1.0\
psi.ch:hls:spot_finder_connectivity:1.0\
psi.ch:hls:spot_finder_mask:1.0\
psi.ch:hls:spot_finder_merge:1.0\
psi.ch:hls:stream_24bit_conv:1.0\
psi.ch:hls:arp:1.0\
xilinx.com:ip:axis_switch:1.1\
psi.ch:hls:ethernet:1.0\
psi.ch:hls:icmp:1.0\
psi.ch:hls:ipv4:1.0\
psi.ch:hls:sls_detector:1.0\
psi.ch:hls:udp:1.0\
"
set list_ips_missing ""
common::send_msg_id "BD_TCL-006" "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ."
foreach ip_vlnv $list_check_ips {
set ip_obj [get_ipdefs -all $ip_vlnv]
if { $ip_obj eq "" } {
lappend list_ips_missing $ip_vlnv
}
}
if { $list_ips_missing ne "" } {
catch {common::send_msg_id "BD_TCL-115" "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." }
set bCheckIPsPassed 0
}
}
##################################################################
# CHECK Modules
##################################################################
set bCheckModules 1
if { $bCheckModules == 1 } {
set list_check_mods "\
action_config\
gen_xdma_descriptor\
eth_4x10g_leds\
"
set list_mods_missing ""
common::send_msg_id "BD_TCL-006" "INFO" "Checking if the following modules exist in the project's sources: $list_check_mods ."
foreach mod_vlnv $list_check_mods {
if { [can_resolve_reference $mod_vlnv] == 0 } {
lappend list_mods_missing $mod_vlnv
}
}
if { $list_mods_missing ne "" } {
catch {common::send_msg_id "BD_TCL-115" "ERROR" "The following module(s) are not found in the project: $list_mods_missing" }
common::send_msg_id "BD_TCL-008" "INFO" "Please add source files for the missing module(s) above."
set bCheckIPsPassed 0
}
}
if { $bCheckIPsPassed != 1 } {
common::send_msg_id "BD_TCL-1003" "WARNING" "Will not continue with creation of design due to the error(s) above."
return 3
}
##################################################################
# DESIGN PROCs
##################################################################
# Procedure to create entire design; Provide argument to make
# procedure reusable. If parentCell is "", will use root.
proc create_root_design { parentCell } {
variable script_folder
variable design_name
if { $parentCell eq "" } {
set parentCell [get_bd_cells /]
}
# Get object for parentCell
set parentObj [get_bd_cells $parentCell]
if { $parentObj == "" } {
catch {common::send_gid_msg -ssname BD::TCL -id 2090 -severity "ERROR" "Unable to find parent cell <$parentCell>!"}
return
}
# Make sure parentObj is hier blk
set parentType [get_property TYPE $parentObj]
if { $parentType ne "hier" } {
catch {common::send_gid_msg -ssname BD::TCL -id 2091 -severity "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be <hier>."}
return
}
# Save current instance; Restore later
set oldCurInst [current_bd_instance .]
# Set parent object as current
current_bd_instance $parentObj
# Create interface ports
set i2c_si5394 [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:iic_rtl:1.0 i2c_si5394 ]
set pcie0_mgt [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:pcie_7x_mgt_rtl:1.0 pcie0_mgt ]
set pcie0_ref [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:diff_clock_rtl:1.0 pcie0_ref ]
set qsfp0 [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:gt_rtl:1.0 qsfp0 ]
set qsfp0_ref [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:diff_clock_rtl:1.0 qsfp0_ref ]
set_property -dict [ list \
CONFIG.FREQ_HZ {161132812} \
] $qsfp0_ref
set qsfp1 [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:gt_rtl:1.0 qsfp1 ]
set qsfp1_ref [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:diff_clock_rtl:1.0 qsfp1_ref ]
set_property -dict [ list \
CONFIG.FREQ_HZ {161132812} \
] $qsfp1_ref
set ref100 [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:diff_clock_rtl:1.0 ref100 ]
set_property -dict [ list \
CONFIG.FREQ_HZ {100000000} \
] $ref100
set satellite_uart_0 [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:uart_rtl:1.0 satellite_uart_0 ]
# Create ports
set hbm_cattrip [ create_bd_port -dir O -from 0 -to 0 hbm_cattrip ]
set pcie_perstn [ create_bd_port -dir I -type rst pcie_perstn ]
set qsfp0_led_busy [ create_bd_port -dir O -from 0 -to 0 qsfp0_led_busy ]
set qsfp0_led_conn_green [ create_bd_port -dir O qsfp0_led_conn_green ]
set qsfp0_led_conn_yellow [ create_bd_port -dir O -from 0 -to 0 qsfp0_led_conn_yellow ]
set qsfp1_led_busy [ create_bd_port -dir O -from 0 -to 0 qsfp1_led_busy ]
set qsfp1_led_conn_green [ create_bd_port -dir O qsfp1_led_conn_green ]
set qsfp1_led_conn_yellow [ create_bd_port -dir O qsfp1_led_conn_yellow ]
set satellite_gpio_0 [ create_bd_port -dir I -from 3 -to 0 -type intr satellite_gpio_0 ]
set_property -dict [ list \
CONFIG.PortWidth {4} \
CONFIG.SENSITIVITY {EDGE_RISING} \
] $satellite_gpio_0
# Create instance: axi_iic_0, and set properties
set axi_iic_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_iic:2.1 axi_iic_0 ]
# Create instance: axi_intc_0, and set properties
set axi_intc_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_intc:4.1 axi_intc_0 ]
set_property -dict [ list \
CONFIG.C_IRQ_CONNECTION {1} \
CONFIG.C_NUM_SW_INTR {2} \
] $axi_intc_0
# Create instance: axi_quad_spi_0, and set properties
set axi_quad_spi_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_quad_spi:3.2 axi_quad_spi_0 ]
set_property -dict [ list \
CONFIG.C_FIFO_DEPTH {256} \
CONFIG.C_SCK_RATIO {2} \
CONFIG.C_SPI_MEMORY {2} \
CONFIG.C_SPI_MODE {2} \
CONFIG.C_USE_STARTUP {1} \
CONFIG.C_USE_STARTUP_INT {1} \
] $axi_quad_spi_0
# Create instance: axis_interconnect_0, and set properties
set axis_interconnect_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_interconnect:2.1 axis_interconnect_0 ]
set_property -dict [ list \
CONFIG.ARB_ON_TLAST {1} \
CONFIG.NUM_MI {1} \
CONFIG.NUM_SI {2} \
] $axis_interconnect_0
# Create instance: clk_wiz_0, and set properties
set clk_wiz_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz:6.0 clk_wiz_0 ]
set_property -dict [ list \
CONFIG.CLKOUT1_JITTER {153.164} \
CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {50.000} \
CONFIG.CLKOUT2_JITTER {134.506} \
CONFIG.CLKOUT2_PHASE_ERROR {154.678} \
CONFIG.CLKOUT2_USED {true} \
CONFIG.CLKOUT3_JITTER {119.392} \
CONFIG.CLKOUT3_PHASE_ERROR {154.678} \
CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {200.000} \
CONFIG.CLKOUT3_USED {true} \
CONFIG.MMCM_CLKOUT0_DIVIDE_F {24.000} \
CONFIG.MMCM_CLKOUT1_DIVIDE {12} \
CONFIG.MMCM_CLKOUT2_DIVIDE {6} \
CONFIG.NUM_OUT_CLKS {3} \
CONFIG.PRIM_SOURCE {Single_ended_clock_capable_pin} \
CONFIG.RESET_PORT {reset} \
CONFIG.RESET_TYPE {ACTIVE_HIGH} \
CONFIG.USE_LOCKED {false} \
CONFIG.USE_RESET {false} \
] $clk_wiz_0
# Create instance: cms_subsystem_0, and set properties
set cms_subsystem_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:cms_subsystem:4.0 cms_subsystem_0 ]
# Create instance: hbm_infrastructure
create_hier_cell_hbm_infrastructure [current_bd_instance .] hbm_infrastructure
# Create instance: jungfraujoch
create_hier_cell_jungfraujoch [current_bd_instance .] jungfraujoch
# Create instance: mac_4x10g
create_hier_cell_mac_4x10g [current_bd_instance .] mac_4x10g
# Create instance: mac_4x10g_1
create_hier_cell_mac_4x10g [current_bd_instance .] mac_4x10g_1
# Create instance: one, and set properties
set one [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 one ]
# Create instance: pcie_dma_0
create_hier_cell_pcie_dma_0 [current_bd_instance .] pcie_dma_0
# Create instance: proc_sys_reset_pcie_0, and set properties
set proc_sys_reset_pcie_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 proc_sys_reset_pcie_0 ]
set_property -dict [ list \
CONFIG.C_EXT_RST_WIDTH {1} \
] $proc_sys_reset_pcie_0
# Create instance: proc_sys_reset_refclk, and set properties
set proc_sys_reset_refclk [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 proc_sys_reset_refclk ]
set_property -dict [ list \
CONFIG.C_EXT_RST_WIDTH {1} \
] $proc_sys_reset_refclk
# Create instance: smartconnect_0, and set properties
set smartconnect_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 smartconnect_0 ]
set_property -dict [ list \
CONFIG.NUM_CLKS {4} \
CONFIG.NUM_MI {8} \
CONFIG.NUM_SI {1} \
] $smartconnect_0
# Create instance: util_ds_buf_0, and set properties
set util_ds_buf_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:util_ds_buf:2.2 util_ds_buf_0 ]
# Create instance: xlconcat_intc, and set properties
set xlconcat_intc [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconcat:2.1 xlconcat_intc ]
set_property -dict [ list \
CONFIG.NUM_PORTS {2} \
] $xlconcat_intc
# Create instance: xlconcat_irq, and set properties
set xlconcat_irq [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconcat:2.1 xlconcat_irq ]
set_property -dict [ list \
CONFIG.NUM_PORTS {2} \
] $xlconcat_irq
# Create instance: zero, and set properties
set zero [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 zero ]
set_property -dict [ list \
CONFIG.CONST_VAL {0} \
] $zero
# Create interface connections
connect_bd_intf_net -intf_net S01_AXIS_1 [get_bd_intf_pins axis_interconnect_0/S01_AXIS] [get_bd_intf_pins mac_4x10g/m_axis]
connect_bd_intf_net -intf_net axi_iic_0_IIC [get_bd_intf_ports i2c_si5394] [get_bd_intf_pins axi_iic_0/IIC]
connect_bd_intf_net -intf_net axis_interconnect_0_M00_AXIS [get_bd_intf_pins axis_interconnect_0/M00_AXIS] [get_bd_intf_pins jungfraujoch/eth_in]
connect_bd_intf_net -intf_net cms_subsystem_0_satellite_uart [get_bd_intf_ports satellite_uart_0] [get_bd_intf_pins cms_subsystem_0/satellite_uart]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p0 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_0] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p0]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p1 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_1] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p1]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p2 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_2] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p2]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p3 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_3] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p3]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p4 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_4] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p4]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p5 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_5] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p5]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p6 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_6] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p6]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p7 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_7] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p7]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p8 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_8] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p8]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p9 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_9] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p9]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p10 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_10] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p10]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p11 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_11] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p11]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p12 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_12] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p12]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p13 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_13] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p13]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p14 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_14] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p14]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p15 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_15] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p15]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p16 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_16] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p16]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p17 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_17] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p17]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p18 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_18] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p18]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p19 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_19] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p19]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p20 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_20] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p20]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p21 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_21] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p21]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p22 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_22] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p22]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p23 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_23] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p23]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p24 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_24] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p24]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p25 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_25] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p25]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p26 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_26] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p26]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p27 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_27] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p27]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p28 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_28] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p28]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p29 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_29] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p29]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p30 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_30] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p30]
connect_bd_intf_net -intf_net jungfraujoch_m_axi_d_hbm_p31 [get_bd_intf_pins hbm_infrastructure/s_axi_hbm_31] [get_bd_intf_pins jungfraujoch/m_axi_d_hbm_p31]
connect_bd_intf_net -intf_net jungfraujoch_m_axis_c2h_data [get_bd_intf_pins jungfraujoch/m_axis_c2h_data] [get_bd_intf_pins pcie_dma_0/s_axis_c2h_data]
connect_bd_intf_net -intf_net jungfraujoch_m_axis_c2h_datamover_cmd [get_bd_intf_pins jungfraujoch/m_axis_c2h_datamover_cmd] [get_bd_intf_pins pcie_dma_0/s_axis_c2h_cmd]
connect_bd_intf_net -intf_net jungfraujoch_m_axis_h2c_datamover_cmd [get_bd_intf_pins jungfraujoch/m_axis_h2c_datamover_cmd] [get_bd_intf_pins pcie_dma_0/s_axis_h2c_cmd]
connect_bd_intf_net -intf_net mac_4x10g1_m_axis [get_bd_intf_pins axis_interconnect_0/S00_AXIS] [get_bd_intf_pins mac_4x10g_1/m_axis]
connect_bd_intf_net -intf_net mac_4x10g1_qsfp1 [get_bd_intf_ports qsfp0] [get_bd_intf_pins mac_4x10g_1/qsfp1]
connect_bd_intf_net -intf_net mac_4x10g_qsfp1 [get_bd_intf_ports qsfp1] [get_bd_intf_pins mac_4x10g/qsfp1]
connect_bd_intf_net -intf_net pcie0_ref_1 [get_bd_intf_ports pcie0_ref] [get_bd_intf_pins pcie_dma_0/pcie_refclk]
connect_bd_intf_net -intf_net pcie_dma_0_M_AXI [get_bd_intf_pins pcie_dma_0/m_axi_ctrl] [get_bd_intf_pins smartconnect_0/S00_AXI]
connect_bd_intf_net -intf_net pcie_dma_0_pcie0_mgt [get_bd_intf_ports pcie0_mgt] [get_bd_intf_pins pcie_dma_0/pcie_mgt]
connect_bd_intf_net -intf_net qsfp0_ref_1 [get_bd_intf_ports qsfp0_ref] [get_bd_intf_pins mac_4x10g_1/qsfp_ref]
connect_bd_intf_net -intf_net qsfp1_ref_1 [get_bd_intf_ports qsfp1_ref] [get_bd_intf_pins mac_4x10g/qsfp_ref]
connect_bd_intf_net -intf_net ref100_1 [get_bd_intf_ports ref100] [get_bd_intf_pins util_ds_buf_0/CLK_IN_D]
connect_bd_intf_net -intf_net s_axi_1 [get_bd_intf_pins jungfraujoch/s_axi] [get_bd_intf_pins smartconnect_0/M00_AXI]
connect_bd_intf_net -intf_net s_axis_h2c_data_1 [get_bd_intf_pins jungfraujoch/s_axis_h2c_data] [get_bd_intf_pins pcie_dma_0/m_axis_h2c_data]
connect_bd_intf_net -intf_net smartconnect_0_M01_AXI [get_bd_intf_pins cms_subsystem_0/s_axi_ctrl] [get_bd_intf_pins smartconnect_0/M01_AXI]
connect_bd_intf_net -intf_net smartconnect_0_M02_AXI [get_bd_intf_pins mac_4x10g_1/s_axi] [get_bd_intf_pins smartconnect_0/M02_AXI]
connect_bd_intf_net -intf_net smartconnect_0_M03_AXI [get_bd_intf_pins axi_quad_spi_0/AXI_LITE] [get_bd_intf_pins smartconnect_0/M03_AXI]
connect_bd_intf_net -intf_net smartconnect_0_M04_AXI [get_bd_intf_pins axi_intc_0/s_axi] [get_bd_intf_pins smartconnect_0/M04_AXI]
connect_bd_intf_net -intf_net smartconnect_0_M05_AXI [get_bd_intf_pins pcie_dma_0/s_axi_dma_ctrl] [get_bd_intf_pins smartconnect_0/M05_AXI]
connect_bd_intf_net -intf_net smartconnect_0_M06_AXI [get_bd_intf_pins mac_4x10g/s_axi] [get_bd_intf_pins smartconnect_0/M06_AXI]
connect_bd_intf_net -intf_net smartconnect_0_M07_AXI [get_bd_intf_pins axi_iic_0/S_AXI] [get_bd_intf_pins smartconnect_0/M07_AXI]
# Create port connections
connect_bd_net -net axi_clk_1 [get_bd_pins clk_wiz_0/clk_in1] [get_bd_pins pcie_dma_0/axi_aclk] [get_bd_pins proc_sys_reset_pcie_0/slowest_sync_clk] [get_bd_pins smartconnect_0/aclk3]
connect_bd_net -net axi_intc_0_irq [get_bd_pins axi_intc_0/irq] [get_bd_pins xlconcat_irq/In0]
connect_bd_net -net axi_quad_spi_0_ip2intc_irpt [get_bd_pins axi_quad_spi_0/ip2intc_irpt] [get_bd_pins xlconcat_intc/In0]
connect_bd_net -net cms_subsystem_0_interrupt_host [get_bd_pins cms_subsystem_0/interrupt_host] [get_bd_pins xlconcat_intc/In1]
connect_bd_net -net hbm_infrastructure_hbm_temp_trip_1 [get_bd_ports hbm_cattrip] [get_bd_pins cms_subsystem_0/interrupt_hbm_cattrip] [get_bd_pins hbm_infrastructure/hbm_cattrip]
connect_bd_net -net hbm_infrastructure_hbm_temperature_0 [get_bd_pins cms_subsystem_0/hbm_temp_1] [get_bd_pins hbm_infrastructure/hbm_temperature_0]
connect_bd_net -net hbm_infrastructure_hbm_temperature_1 [get_bd_pins cms_subsystem_0/hbm_temp_2] [get_bd_pins hbm_infrastructure/hbm_temperature_1]
connect_bd_net -net jungfraujoch_Interrupt_0 [get_bd_pins jungfraujoch/Interrupt_0] [get_bd_pins xlconcat_irq/In1]
connect_bd_net -net mac_4x10g1_led_green [get_bd_ports qsfp0_led_conn_green] [get_bd_pins mac_4x10g_1/led_green]
connect_bd_net -net mac_4x10g1_led_yellow [get_bd_ports qsfp0_led_conn_yellow] [get_bd_pins mac_4x10g_1/led_yellow]
connect_bd_net -net mac_4x10g_led_green [get_bd_ports qsfp1_led_conn_green] [get_bd_pins mac_4x10g/led_green]
connect_bd_net -net mac_4x10g_led_yellow [get_bd_ports qsfp1_led_conn_yellow] [get_bd_pins mac_4x10g/led_yellow]
connect_bd_net -net net_refclk50 [get_bd_pins axi_iic_0/s_axi_aclk] [get_bd_pins axi_intc_0/s_axi_aclk] [get_bd_pins axi_quad_spi_0/s_axi_aclk] [get_bd_pins clk_wiz_0/clk_out1] [get_bd_pins cms_subsystem_0/aclk_ctrl] [get_bd_pins mac_4x10g/refclk50] [get_bd_pins mac_4x10g_1/refclk50] [get_bd_pins proc_sys_reset_refclk/slowest_sync_clk] [get_bd_pins smartconnect_0/aclk2]
connect_bd_net -net net_refclk100 [get_bd_pins axi_quad_spi_0/ext_spi_clk] [get_bd_pins clk_wiz_0/clk_out2] [get_bd_pins hbm_infrastructure/refclk100] [get_bd_pins smartconnect_0/aclk1]
connect_bd_net -net net_refclk200 [get_bd_pins axis_interconnect_0/ACLK] [get_bd_pins axis_interconnect_0/M00_AXIS_ACLK] [get_bd_pins axis_interconnect_0/S00_AXIS_ACLK] [get_bd_pins axis_interconnect_0/S01_AXIS_ACLK] [get_bd_pins clk_wiz_0/clk_out3] [get_bd_pins hbm_infrastructure/axi_clk] [get_bd_pins jungfraujoch/axi_clk] [get_bd_pins mac_4x10g/m_axis_aclk] [get_bd_pins mac_4x10g_1/m_axis_aclk] [get_bd_pins pcie_dma_0/refclk200] [get_bd_pins smartconnect_0/aclk]
connect_bd_net -net one_dout [get_bd_pins cms_subsystem_0/aresetn_ctrl] [get_bd_pins one/dout] [get_bd_pins proc_sys_reset_pcie_0/dcm_locked] [get_bd_pins proc_sys_reset_refclk/dcm_locked] [get_bd_pins jungfraujoch/eth_out_tready]
connect_bd_net -net pcie_dma_0_axi_aresetn [get_bd_pins pcie_dma_0/axi_aresetn] [get_bd_pins proc_sys_reset_pcie_0/ext_reset_in] [get_bd_pins proc_sys_reset_refclk/ext_reset_in] [get_bd_pins smartconnect_0/aresetn]
connect_bd_net -net pcie_perstn_1 [get_bd_ports pcie_perstn] [get_bd_pins pcie_dma_0/pcie_perstn]
connect_bd_net -net proc_sys_reset_pcie_0_interconnect_aresetn [get_bd_pins pcie_dma_0/axi_clk_resetn] [get_bd_pins proc_sys_reset_pcie_0/interconnect_aresetn]
connect_bd_net -net proc_sys_reset_refclk_peripheral_aresetn [get_bd_pins axi_iic_0/s_axi_aresetn] [get_bd_pins axi_intc_0/s_axi_aresetn] [get_bd_pins axi_quad_spi_0/s_axi_aresetn] [get_bd_pins axis_interconnect_0/ARESETN] [get_bd_pins axis_interconnect_0/M00_AXIS_ARESETN] [get_bd_pins axis_interconnect_0/S00_AXIS_ARESETN] [get_bd_pins axis_interconnect_0/S01_AXIS_ARESETN] [get_bd_pins hbm_infrastructure/axi_resetn] [get_bd_pins jungfraujoch/ap_rst_n] [get_bd_pins mac_4x10g/axi_aresetn] [get_bd_pins mac_4x10g_1/axi_aresetn] [get_bd_pins proc_sys_reset_refclk/peripheral_aresetn]
connect_bd_net -net refclk100_1 [get_bd_pins hbm_infrastructure/hbmclk100] [get_bd_pins util_ds_buf_0/IBUF_OUT]
connect_bd_net -net resetn_1 [get_bd_pins jungfraujoch/axi_rst_n] [get_bd_pins pcie_dma_0/refclk200_resetn] [get_bd_pins proc_sys_reset_refclk/interconnect_aresetn]
connect_bd_net -net satellite_gpio_0_1 [get_bd_ports satellite_gpio_0] [get_bd_pins cms_subsystem_0/satellite_gpio]
connect_bd_net -net xlconcat_0_dout [get_bd_pins pcie_dma_0/usr_irq_req] [get_bd_pins xlconcat_irq/dout]
connect_bd_net -net xlconcat_irq_dout [get_bd_pins axi_intc_0/intr] [get_bd_pins xlconcat_intc/dout]
connect_bd_net -net zero_dout [get_bd_ports qsfp0_led_busy] [get_bd_ports qsfp1_led_busy] [get_bd_pins axi_quad_spi_0/usrcclkts] [get_bd_pins zero/dout]
# Create address segments
assign_bd_address -offset 0x00010000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs jungfraujoch/action_config_0/s_axi/reg0] -force
assign_bd_address -offset 0x00030000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs jungfraujoch/mailbox_0/S0_AXI/Reg] -force
assign_bd_address -offset 0x00040000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs axi_quad_spi_0/AXI_LITE/Reg] -force
assign_bd_address -offset 0x00050000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs axi_intc_0/S_AXI/Reg] -force
assign_bd_address -offset 0x00060000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs jungfraujoch/load_calibration_0/s_axi_control/Reg] -force
assign_bd_address -offset 0x00070000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs pcie_dma_0/axi_firewall_0/S_AXI_CTL/Control] -force
assign_bd_address -offset 0x00080000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs jungfraujoch/frame_generator_0/s_axi_control/Reg] -force
assign_bd_address -offset 0x00090000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs pcie_dma_0/xdma_0/S_AXI_LITE/CTL0] -force
assign_bd_address -offset 0x000C0000 -range 0x00040000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs cms_subsystem_0/s_axi_ctrl/Mem] -force
assign_bd_address -offset 0x000A0000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs axi_iic_0/S_AXI/Reg] -force
assign_bd_address -offset 0x00100000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs mac_4x10g/xxv_ethernet_0/s_axi_0/Reg] -force
assign_bd_address -offset 0x00110000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs mac_4x10g/xxv_ethernet_0/s_axi_1/Reg] -force
assign_bd_address -offset 0x00120000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs mac_4x10g/xxv_ethernet_0/s_axi_2/Reg] -force
assign_bd_address -offset 0x00130000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs mac_4x10g/xxv_ethernet_0/s_axi_3/Reg] -force
assign_bd_address -offset 0x00140000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs mac_4x10g_1/xxv_ethernet_0/s_axi_0/Reg] -force
assign_bd_address -offset 0x00150000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs mac_4x10g_1/xxv_ethernet_0/s_axi_1/Reg] -force
assign_bd_address -offset 0x00160000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs mac_4x10g_1/xxv_ethernet_0/s_axi_2/Reg] -force
assign_bd_address -offset 0x00170000 -range 0x00010000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs mac_4x10g_1/xxv_ethernet_0/s_axi_3/Reg] -force
assign_bd_address -offset 0x00200000 -range 0x00080000 -target_address_space [get_bd_addr_spaces pcie_dma_0/xdma_0/M_AXI_LITE] [get_bd_addr_segs jungfraujoch/axi_bram_ctrl_calibration_addr_0/S_AXI/Mem0] -force
assign_bd_address -offset 0x00000000 -range 0x00080000 -target_address_space [get_bd_addr_spaces jungfraujoch/load_calibration_0/Data_m_axi_handle_to_dma_address] [get_bd_addr_segs jungfraujoch/axi_bram_ctrl_calibration_addr_1/S_AXI/Mem0] -force
assign_bd_address
set_property -dict [list CONFIG.GT_GROUP_SELECT {Quad_X0Y6} CONFIG.LANE1_GT_LOC {X0Y24} CONFIG.LANE2_GT_LOC {X0Y25} CONFIG.LANE3_GT_LOC {X0Y26} CONFIG.LANE4_GT_LOC {X0Y27}] [get_bd_cells mac_4x10g_1/xxv_ethernet_0]
# Restore current instance
current_bd_instance $oldCurInst
save_bd_design
validate_bd_design
save_bd_design
}
# End of create_root_design()
##################################################################
# MAIN FLOW
##################################################################
create_root_design ""
+66
View File
@@ -0,0 +1,66 @@
## Copyright (2019-2023) Paul Scherrer Institute
set origin_dir [file dirname [file normalize [info script]]]
set project [create_project -force -part "xcu55c-fsvh2892-2L-e" "jfjoch_pcie" "vivado"]
current_project $project
# Get the directory path for the new project
set proj_dir [get_property directory $project]
set_property ip_repo_paths [concat [get_property ip_repo_paths [current_project]] "action/ip"] [current_project]
update_ip_catalog
# Create 'sources_1' fileset (if not found)
if {[string equal [get_filesets -quiet sources_1] ""]} {
create_fileset -srcset sources_1
}
set source_set [get_filesets sources_1]
set hdl_files [list \
[file normalize "action/hw/hdl/action_config.v"] \
[file normalize "action/hw/hdl/gen_xdma_descriptor.v"] \
[file normalize "action/hw/hdl/eth_4x10g_leds.v"] \
]
if { [llength $hdl_files] > 0 } {
add_files -norecurse -fileset $source_set $hdl_files
}
if {[string equal [get_filesets -quiet constrs_1] ""]} {
create_fileset -constrset constrs_1
}
set constraint_set [get_filesets constrs_1]
# Add constraints files
# Put target .xdc as LAST in list
set constraint_files [list \
[file normalize "$origin_dir/../xdc/pcie_u55c.xdc"] \
[file normalize "$origin_dir/../xdc/pcie_timing.xdc"] \
]
add_files -norecurse -fileset $constraint_set $constraint_files
set_property "target_constrs_file" [lindex $constraint_files 0] $constraint_set
source $origin_dir/network_stack.tcl
source $origin_dir/hbm_u55c.tcl
source $origin_dir/jfjoch.tcl
source $origin_dir/hbm_cache.tcl
source $origin_dir/image_processing.tcl
source $origin_dir/pcie_dma.tcl
source $origin_dir/mac_100g_pcie.tcl
source $origin_dir/mac_4x10g.tcl
source $origin_dir/bd_pcie_8x10g.tcl >> build_pcie.log
make_wrapper -files [get_files "vivado/jfjoch_pcie.srcs/sources_1/bd/jfjoch_pcie/jfjoch_pcie.bd"] -top >> make_wrapper.log
add_files -norecurse "vivado/jfjoch_pcie.gen/sources_1/bd/jfjoch_pcie/hdl/jfjoch_pcie_wrapper.v"
set_property top jfjoch_pcie_wrapper [current_fileset]
update_compile_order -fileset sources_1
set_property synth_checkpoint_mode None [get_files vivado/jfjoch_pcie.srcs/sources_1/bd/jfjoch_pcie/jfjoch_pcie.bd]
generate_target all [get_files vivado/jfjoch_pcie.srcs/sources_1/bd/jfjoch_pcie/jfjoch_pcie.bd] >> generate_target.log
set_property flow {Vivado Synthesis 2022} [get_runs synth_1]
set_property strategy Flow_PerfOptimized_high [get_runs synth_1]
set_property strategy Performance_ExploreWithRemap [get_runs impl_1]
+9 -6
View File
@@ -206,6 +206,9 @@ proc create_hier_cell_hbm_cache { parentCell nameHier } {
# Create instance: save_to_hbm_0, and set properties
set save_to_hbm_0 [ create_bd_cell -type ip -vlnv psi.ch:hls:save_to_hbm:1.0 save_to_hbm_0 ]
# Create instance: save_to_hbm_data_0, and set properties
set save_to_hbm_data_0 [ create_bd_cell -type ip -vlnv psi.ch:hls:save_to_hbm_data:1.0 save_to_hbm_data_0 ]
# Create interface connections
connect_bd_intf_net -intf_net Conn4 [get_bd_intf_pins m_axi_d_hbm_p12] [get_bd_intf_pins axi_datamover_0/M_AXI_MM2S]
connect_bd_intf_net -intf_net Conn5 [get_bd_intf_pins m_axi_d_hbm_p13] [get_bd_intf_pins axi_datamover_0/M_AXI_S2MM]
@@ -213,7 +216,7 @@ proc create_hier_cell_hbm_cache { parentCell nameHier } {
connect_bd_intf_net -intf_net Conn7 [get_bd_intf_pins m_axi_d_hbm_p15] [get_bd_intf_pins axi_datamover_1/M_AXI_S2MM]
connect_bd_intf_net -intf_net Conn8 [get_bd_intf_pins m_axis_completion] [get_bd_intf_pins load_from_hbm_0/m_axis_completion]
connect_bd_intf_net -intf_net Conn17 [get_bd_intf_pins addr_in] [get_bd_intf_pins save_to_hbm_0/addr_in]
connect_bd_intf_net -intf_net Conn18 [get_bd_intf_pins data_in] [get_bd_intf_pins save_to_hbm_0/data_in]
connect_bd_intf_net -intf_net Conn18 [get_bd_intf_pins data_in] [get_bd_intf_pins save_to_hbm_data_0/data_in]
connect_bd_intf_net -intf_net axi_datamover_0_M_AXIS_MM2S [get_bd_intf_pins axi_datamover_0/M_AXIS_MM2S] [get_bd_intf_pins axis_datamover_fifo_2/S_AXIS]
connect_bd_intf_net -intf_net axi_datamover_1_M_AXIS_MM2S [get_bd_intf_pins axi_datamover_1/M_AXIS_MM2S] [get_bd_intf_pins axis_datamover_fifo_3/S_AXIS]
connect_bd_intf_net -intf_net axis_compl_fifo_0_M_AXIS [get_bd_intf_pins axis_compl_fifo_0/M_AXIS] [get_bd_intf_pins frame_summation_reor_0/s_axis_completion]
@@ -236,16 +239,16 @@ proc create_hier_cell_hbm_cache { parentCell nameHier } {
connect_bd_intf_net -intf_net load_from_hbm_0_datamover_0_cmd [get_bd_intf_pins axis_datamover_cmd_fifo_2/S_AXIS] [get_bd_intf_pins load_from_hbm_0/datamover_0_cmd]
connect_bd_intf_net -intf_net load_from_hbm_0_datamover_1_cmd [get_bd_intf_pins axis_datamover_cmd_fifo_3/S_AXIS] [get_bd_intf_pins load_from_hbm_0/datamover_1_cmd]
connect_bd_intf_net -intf_net load_from_hbm_0_m_axis_free_handles [get_bd_intf_pins axis_hbm_handles_fifo/S_AXIS] [get_bd_intf_pins load_from_hbm_0/m_axis_free_handles]
connect_bd_intf_net -intf_net save_to_hbm_0_data_out [get_bd_intf_pins axis_data_fifo_2/S_AXIS] [get_bd_intf_pins save_to_hbm_0/data_out]
connect_bd_intf_net -intf_net save_to_hbm_0_data_out [get_bd_intf_pins axis_data_fifo_2/S_AXIS] [get_bd_intf_pins save_to_hbm_data_0/data_out]
connect_bd_intf_net -intf_net save_to_hbm_0_datamover_0_cmd [get_bd_intf_pins axis_datamover_cmd_fifo_0/S_AXIS] [get_bd_intf_pins save_to_hbm_0/datamover_0_cmd]
connect_bd_intf_net -intf_net save_to_hbm_0_datamover_1_cmd [get_bd_intf_pins axis_datamover_cmd_fifo_1/S_AXIS] [get_bd_intf_pins save_to_hbm_0/datamover_1_cmd]
connect_bd_intf_net -intf_net save_to_hbm_0_hbm_out_0 [get_bd_intf_pins axis_datamover_fifo_0/S_AXIS] [get_bd_intf_pins save_to_hbm_0/hbm_out_0]
connect_bd_intf_net -intf_net save_to_hbm_0_hbm_out_1 [get_bd_intf_pins axis_datamover_fifo_1/S_AXIS] [get_bd_intf_pins save_to_hbm_0/hbm_out_1]
connect_bd_intf_net -intf_net save_to_hbm_0_hbm_out_0 [get_bd_intf_pins axis_datamover_fifo_0/S_AXIS] [get_bd_intf_pins save_to_hbm_data_0/hbm_out_0]
connect_bd_intf_net -intf_net save_to_hbm_0_hbm_out_1 [get_bd_intf_pins axis_datamover_fifo_1/S_AXIS] [get_bd_intf_pins save_to_hbm_data_0/hbm_out_1]
connect_bd_intf_net -intf_net save_to_hbm_0_m_axis_completion [get_bd_intf_pins axis_compl_fifo_0/S_AXIS] [get_bd_intf_pins save_to_hbm_0/m_axis_completion]
# Create port connections
connect_bd_net -net ap_rst_n_1 [get_bd_pins ap_rst_n] [get_bd_pins axi_datamover_0/m_axi_mm2s_aresetn] [get_bd_pins axi_datamover_0/m_axi_s2mm_aresetn] [get_bd_pins axi_datamover_0/m_axis_mm2s_cmdsts_aresetn] [get_bd_pins axi_datamover_0/m_axis_s2mm_cmdsts_aresetn] [get_bd_pins axi_datamover_1/m_axi_mm2s_aresetn] [get_bd_pins axi_datamover_1/m_axi_s2mm_aresetn] [get_bd_pins axi_datamover_1/m_axis_mm2s_cmdsts_aresetn] [get_bd_pins axi_datamover_1/m_axis_s2mm_cmdsts_aresetn] [get_bd_pins frame_summation_reor_0/ap_rst_n] [get_bd_pins load_from_hbm_0/ap_rst_n] [get_bd_pins save_to_hbm_0/ap_rst_n]
connect_bd_net -net axi_clk_1 [get_bd_pins axi_clk] [get_bd_pins axi_datamover_0/m_axi_mm2s_aclk] [get_bd_pins axi_datamover_0/m_axi_s2mm_aclk] [get_bd_pins axi_datamover_0/m_axis_mm2s_cmdsts_aclk] [get_bd_pins axi_datamover_0/m_axis_s2mm_cmdsts_awclk] [get_bd_pins axi_datamover_1/m_axi_mm2s_aclk] [get_bd_pins axi_datamover_1/m_axi_s2mm_aclk] [get_bd_pins axi_datamover_1/m_axis_mm2s_cmdsts_aclk] [get_bd_pins axi_datamover_1/m_axis_s2mm_cmdsts_awclk] [get_bd_pins axis_compl_fifo_0/s_axis_aclk] [get_bd_pins axis_compl_fifo_1/s_axis_aclk] [get_bd_pins axis_data_fifo_2/s_axis_aclk] [get_bd_pins axis_data_fifo_3/s_axis_aclk] [get_bd_pins axis_data_fifo_4/s_axis_aclk] [get_bd_pins axis_datamover_cmd_fifo_0/s_axis_aclk] [get_bd_pins axis_datamover_cmd_fifo_1/s_axis_aclk] [get_bd_pins axis_datamover_cmd_fifo_2/s_axis_aclk] [get_bd_pins axis_datamover_cmd_fifo_3/s_axis_aclk] [get_bd_pins axis_datamover_fifo_0/s_axis_aclk] [get_bd_pins axis_datamover_fifo_1/s_axis_aclk] [get_bd_pins axis_datamover_fifo_2/s_axis_aclk] [get_bd_pins axis_datamover_fifo_3/s_axis_aclk] [get_bd_pins axis_hbm_handles_fifo/s_axis_aclk] [get_bd_pins frame_summation_reor_0/ap_clk] [get_bd_pins load_from_hbm_0/ap_clk] [get_bd_pins save_to_hbm_0/ap_clk]
connect_bd_net -net ap_rst_n_1 [get_bd_pins ap_rst_n] [get_bd_pins axi_datamover_0/m_axi_mm2s_aresetn] [get_bd_pins axi_datamover_0/m_axi_s2mm_aresetn] [get_bd_pins axi_datamover_0/m_axis_mm2s_cmdsts_aresetn] [get_bd_pins axi_datamover_0/m_axis_s2mm_cmdsts_aresetn] [get_bd_pins axi_datamover_1/m_axi_mm2s_aresetn] [get_bd_pins axi_datamover_1/m_axi_s2mm_aresetn] [get_bd_pins axi_datamover_1/m_axis_mm2s_cmdsts_aresetn] [get_bd_pins axi_datamover_1/m_axis_s2mm_cmdsts_aresetn] [get_bd_pins frame_summation_reor_0/ap_rst_n] [get_bd_pins load_from_hbm_0/ap_rst_n] [get_bd_pins save_to_hbm_0/ap_rst_n] [get_bd_pins save_to_hbm_data_0/ap_rst_n]
connect_bd_net -net axi_clk_1 [get_bd_pins axi_clk] [get_bd_pins axi_datamover_0/m_axi_mm2s_aclk] [get_bd_pins axi_datamover_0/m_axi_s2mm_aclk] [get_bd_pins axi_datamover_0/m_axis_mm2s_cmdsts_aclk] [get_bd_pins axi_datamover_0/m_axis_s2mm_cmdsts_awclk] [get_bd_pins axi_datamover_1/m_axi_mm2s_aclk] [get_bd_pins axi_datamover_1/m_axi_s2mm_aclk] [get_bd_pins axi_datamover_1/m_axis_mm2s_cmdsts_aclk] [get_bd_pins axi_datamover_1/m_axis_s2mm_cmdsts_awclk] [get_bd_pins axis_compl_fifo_0/s_axis_aclk] [get_bd_pins axis_compl_fifo_1/s_axis_aclk] [get_bd_pins axis_data_fifo_2/s_axis_aclk] [get_bd_pins axis_data_fifo_3/s_axis_aclk] [get_bd_pins axis_data_fifo_4/s_axis_aclk] [get_bd_pins axis_datamover_cmd_fifo_0/s_axis_aclk] [get_bd_pins axis_datamover_cmd_fifo_1/s_axis_aclk] [get_bd_pins axis_datamover_cmd_fifo_2/s_axis_aclk] [get_bd_pins axis_datamover_cmd_fifo_3/s_axis_aclk] [get_bd_pins axis_datamover_fifo_0/s_axis_aclk] [get_bd_pins axis_datamover_fifo_1/s_axis_aclk] [get_bd_pins axis_datamover_fifo_2/s_axis_aclk] [get_bd_pins axis_datamover_fifo_3/s_axis_aclk] [get_bd_pins axis_hbm_handles_fifo/s_axis_aclk] [get_bd_pins frame_summation_reor_0/ap_clk] [get_bd_pins load_from_hbm_0/ap_clk] [get_bd_pins save_to_hbm_0/ap_clk] [get_bd_pins save_to_hbm_data_0/ap_clk]
connect_bd_net -net axi_rst_n_1 [get_bd_pins axi_rst_n] [get_bd_pins axis_compl_fifo_0/s_axis_aresetn] [get_bd_pins axis_compl_fifo_1/s_axis_aresetn] [get_bd_pins axis_data_fifo_2/s_axis_aresetn] [get_bd_pins axis_data_fifo_3/s_axis_aresetn] [get_bd_pins axis_data_fifo_4/s_axis_aresetn] [get_bd_pins axis_datamover_cmd_fifo_0/s_axis_aresetn] [get_bd_pins axis_datamover_cmd_fifo_1/s_axis_aresetn] [get_bd_pins axis_datamover_cmd_fifo_2/s_axis_aresetn] [get_bd_pins axis_datamover_cmd_fifo_3/s_axis_aresetn] [get_bd_pins axis_datamover_fifo_0/s_axis_aresetn] [get_bd_pins axis_datamover_fifo_1/s_axis_aresetn] [get_bd_pins axis_datamover_fifo_2/s_axis_aresetn] [get_bd_pins axis_datamover_fifo_3/s_axis_aresetn] [get_bd_pins axis_hbm_handles_fifo/s_axis_aresetn]
connect_bd_net -net axis_compl_fifo_1_almost_empty [get_bd_pins compl_fifo_empty] [get_bd_pins axis_compl_fifo_1/almost_empty]
connect_bd_net -net axis_compl_fifo_1_almost_full [get_bd_pins compl_fifo_full] [get_bd_pins axis_compl_fifo_1/almost_full]
+6 -6
View File
@@ -1,4 +1,4 @@
## Copyright (2019-2023) Paul Scherrer Institute
## Copyright (2019-2024) Paul Scherrer Institute
# Inspired on Apache License based SNAP/OC-Accel design from IBM
@@ -38,6 +38,7 @@ proc create_hier_cell_hbm_infrastructure { parentCell nameHier } {
create_bd_pin -dir I -type clk axi_clk
create_bd_pin -dir I -type rst axi_resetn
create_bd_pin -dir I -type clk hbmclk100
create_bd_pin -dir I -type clk refclk100
create_bd_pin -dir O hbm_cattrip
@@ -217,7 +218,6 @@ proc create_hier_cell_hbm_infrastructure { parentCell nameHier } {
CONFIG.USER_MC9_LOOKAHEAD_SBRF {true} \
CONFIG.USER_MC9_REF_TEMP_COMP {false} \
CONFIG.USER_MC9_TRAFFIC_OPTION {Linear} \
CONFIG.USER_MC_ENABLE_15 {FALSE} \
CONFIG.USER_MC_ENABLE_APB_01 {FALSE} \
CONFIG.USER_MEMORY_DISPLAY {16384} \
CONFIG.USER_PHY_ENABLE_08 {TRUE} \
@@ -228,8 +228,6 @@ proc create_hier_cell_hbm_infrastructure { parentCell nameHier } {
CONFIG.USER_PHY_ENABLE_13 {TRUE} \
CONFIG.USER_PHY_ENABLE_14 {TRUE} \
CONFIG.USER_PHY_ENABLE_15 {TRUE} \
CONFIG.USER_SAXI_30 {false} \
CONFIG.USER_SAXI_31 {false} \
CONFIG.USER_SWITCH_ENABLE_00 {TRUE} \
CONFIG.USER_SWITCH_ENABLE_01 {TRUE} \
CONFIG.USER_TEMP_POLL_CNT_0 {100000} \
@@ -249,6 +247,7 @@ proc create_hier_cell_hbm_infrastructure { parentCell nameHier } {
CONFIG.USER_tXP_0 {0x07} \
] $hbm
# Create instance: util_vector_logic_0, and set properties
set util_vector_logic_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:util_vector_logic:2.0 util_vector_logic_0 ]
set_property -dict [ list \
@@ -264,9 +263,10 @@ proc create_hier_cell_hbm_infrastructure { parentCell nameHier } {
connect_bd_net -net util_vector_logic_0_Res [get_bd_pins hbm_cattrip] [get_bd_pins util_vector_logic_0/Res]
connect_bd_net [get_bd_pins axi_resetn] [get_bd_pins hbm/APB_0_PRESET_N] [get_bd_pins hbm/APB_1_PRESET_N]
connect_bd_net [get_bd_pins refclk100] [get_bd_pins hbm/APB_0_PCLK] [get_bd_pins hbm/APB_1_PCLK] [get_bd_pins hbm/HBM_REF_CLK_0] [get_bd_pins hbm/HBM_REF_CLK_1]
connect_bd_net [get_bd_pins refclk100] [get_bd_pins hbm/APB_0_PCLK] [get_bd_pins hbm/APB_1_PCLK]
connect_bd_net [get_bd_pins hbmclk100] [get_bd_pins hbm/HBM_REF_CLK_0] [get_bd_pins hbm/HBM_REF_CLK_1]
for {set i 0} {$i < 30} {incr i} {
for {set i 0} {$i < 32} {incr i} {
create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 s_axi_hbm_$i
set cell [create_bd_cell -type ip -vlnv {xilinx.com:ip:axi_register_slice:*} axi_register_slice_$i ]
+89 -35
View File
@@ -1,4 +1,4 @@
## Copyright (2019-2023) Paul Scherrer Institute
## Copyright (2019-2024) Paul Scherrer Institute
# Hierarchical cell: image_processing
proc create_hier_cell_image_processing { parentCell nameHier } {
@@ -89,10 +89,16 @@ proc create_hier_cell_image_processing { parentCell nameHier } {
create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 m_axi_d_hbm_p29
create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 m_axi_d_hbm_p30
create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 m_axi_d_hbm_p31
create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 m_axis_completion
create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 result_out
create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 roi_calc_out
create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 s_axis_completion
create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 spot_finder_out
@@ -106,8 +112,8 @@ proc create_hier_cell_image_processing { parentCell nameHier } {
create_bd_pin -dir I -from 31 -to 0 -type data hbm_size_bytes
create_bd_pin -dir I -from 31 -to 0 -type data in_count_threshold
create_bd_pin -dir I -from 31 -to 0 -type data in_max_d_value
create_bd_pin -dir I -from 31 -to 0 -type data in_min_pix_per_spot
create_bd_pin -dir I -from 31 -to 0 -type data in_min_d_value
create_bd_pin -dir I -from 31 -to 0 -type data in_min_pix_per_spot
create_bd_pin -dir I -from 31 -to 0 -type data in_snr_threshold
create_bd_pin -dir O -from 0 -to 0 integration_idle
create_bd_pin -dir O proc_fifo_empty
@@ -160,6 +166,18 @@ proc create_hier_cell_image_processing { parentCell nameHier } {
CONFIG.FIFO_DEPTH {16} \
] $axis_compl_fifo_5
# Create instance: axis_compl_fifo_6, and set properties
set axis_compl_fifo_6 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_compl_fifo_6 ]
set_property -dict [ list \
CONFIG.FIFO_DEPTH {16} \
] $axis_compl_fifo_6
# Create instance: axis_compl_fifo_7, and set properties
set axis_compl_fifo_7 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_compl_fifo_7 ]
set_property -dict [ list \
CONFIG.FIFO_DEPTH {16} \
] $axis_compl_fifo_7
# Create instance: axis_data_fifo_0, and set properties
set axis_data_fifo_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_fifo_0 ]
set_property -dict [ list \
@@ -200,22 +218,34 @@ proc create_hier_cell_image_processing { parentCell nameHier } {
set axis_data_fifo_6 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_fifo_6 ]
set_property -dict [ list \
CONFIG.FIFO_DEPTH {256} \
CONFIG.HAS_AEMPTY {1} \
CONFIG.HAS_AFULL {1} \
] $axis_data_fifo_6
# Create instance: axis_data_fifo_7, and set properties
set axis_data_fifo_7 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_fifo_7 ]
set_property -dict [ list \
CONFIG.FIFO_DEPTH {256} \
CONFIG.HAS_AEMPTY {1} \
CONFIG.HAS_AFULL {1} \
] $axis_data_fifo_7
# Create instance: axis_data_fifo_8, and set properties
set axis_data_fifo_8 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_fifo_8 ]
set_property -dict [ list \
CONFIG.FIFO_DEPTH {512} \
CONFIG.FIFO_DEPTH {256} \
] $axis_data_fifo_8
# Create instance: axis_data_fifo_9, and set properties
set axis_data_fifo_9 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_fifo_9 ]
set_property -dict [ list \
CONFIG.FIFO_DEPTH {512} \
] $axis_data_fifo_9
# Create instance: axis_data_fifo_10, and set properties
set axis_data_fifo_10 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_fifo_10 ]
set_property -dict [ list \
CONFIG.FIFO_DEPTH {512} \
] $axis_data_fifo_10
# Create instance: axis_data_spot_finder_mask_0, and set properties
set axis_data_spot_finder_mask_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_spot_finder_mask_0 ]
set_property -dict [ list \
@@ -252,6 +282,12 @@ proc create_hier_cell_image_processing { parentCell nameHier } {
CONFIG.REG_CONFIG {16} \
] $axis_register_slice_data_3
# Create instance: axis_roi_calc_result_fifo_0, and set properties
set axis_roi_calc_result_fifo_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_roi_calc_result_fifo_0 ]
set_property -dict [ list \
CONFIG.FIFO_DEPTH {256} \
] $axis_roi_calc_result_fifo_0
# Create instance: axis_spot_finder_conn_fifo_0, and set properties
set axis_spot_finder_conn_fifo_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_spot_finder_conn_fifo_0 ]
set_property -dict [ list \
@@ -277,6 +313,9 @@ proc create_hier_cell_image_processing { parentCell nameHier } {
CONFIG.FIFO_MEMORY_TYPE {ultra} \
] $axis_spot_finder_fifo_2
# Create instance: eiger_reorder_0, and set properties
set eiger_reorder_0 [ create_bd_cell -type ip -vlnv psi.ch:hls:eiger_reorder:1.0 eiger_reorder_0 ]
# Create instance: frame_summation_0, and set properties
set frame_summation_0 [ create_bd_cell -type ip -vlnv psi.ch:hls:frame_summation:1.0 frame_summation_0 ]
@@ -295,6 +334,9 @@ proc create_hier_cell_image_processing { parentCell nameHier } {
# Create instance: pedestal_0, and set properties
set pedestal_0 [ create_bd_cell -type ip -vlnv psi.ch:hls:pedestal:1.0 pedestal_0 ]
# Create instance: roi_calc_0, and set properties
set roi_calc_0 [ create_bd_cell -type ip -vlnv psi.ch:hls:roi_calc:1.0 roi_calc_0 ]
# Create instance: smartconnect_0, and set properties
set smartconnect_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 smartconnect_0 ]
@@ -339,7 +381,6 @@ proc create_hier_cell_image_processing { parentCell nameHier } {
connect_bd_intf_net -intf_net Conn12 [get_bd_intf_pins m_axi_d_hbm_p3] [get_bd_intf_pins jf_conversion_0/m_axi_d_hbm_p3]
connect_bd_intf_net -intf_net Conn13 [get_bd_intf_pins m_axi_d_hbm_p4] [get_bd_intf_pins jf_conversion_0/m_axi_d_hbm_p4]
connect_bd_intf_net -intf_net Conn15 [get_bd_intf_pins m_axi_d_hbm_p5] [get_bd_intf_pins jf_conversion_0/m_axi_d_hbm_p5]
connect_bd_intf_net -intf_net Conn19 [get_bd_intf_pins result_out] [get_bd_intf_pins adu_histo_0/result_out]
connect_bd_intf_net -intf_net Conn21 [get_bd_intf_pins m_axi_d_hbm_p6] [get_bd_intf_pins jf_conversion_0/m_axi_d_hbm_p6]
connect_bd_intf_net -intf_net Conn23 [get_bd_intf_pins m_axi_d_hbm_p7] [get_bd_intf_pins jf_conversion_0/m_axi_d_hbm_p7]
connect_bd_intf_net -intf_net Conn26 [get_bd_intf_pins m_axi_d_hbm_p8] [get_bd_intf_pins jf_conversion_0/m_axi_d_hbm_p8]
@@ -348,40 +389,50 @@ proc create_hier_cell_image_processing { parentCell nameHier } {
connect_bd_intf_net -intf_net Conn29 [get_bd_intf_pins m_axi_d_hbm_p11] [get_bd_intf_pins jf_conversion_0/m_axi_d_hbm_p11]
connect_bd_intf_net -intf_net Conn30 [get_bd_intf_pins m_axi_d_hbm_p2] [get_bd_intf_pins jf_conversion_0/m_axi_d_hbm_p2]
connect_bd_intf_net -intf_net Conn31 [get_bd_intf_pins m_axi_d_hbm_p1] [get_bd_intf_pins jf_conversion_0/m_axi_d_hbm_p1]
connect_bd_intf_net -intf_net Conn32 [get_bd_intf_pins m_axi_d_hbm_p30] [get_bd_intf_pins roi_calc_0/m_axi_d_hbm_p0]
connect_bd_intf_net -intf_net Conn33 [get_bd_intf_pins m_axi_d_hbm_p31] [get_bd_intf_pins roi_calc_0/m_axi_d_hbm_p1]
connect_bd_intf_net -intf_net adu_histo_0_data_out [get_bd_intf_pins adu_histo_0/data_out] [get_bd_intf_pins axis_data_fifo_2/S_AXIS]
connect_bd_intf_net -intf_net adu_histo_0_m_axis_completion [get_bd_intf_pins adu_histo_0/m_axis_completion] [get_bd_intf_pins axis_compl_fifo_1/S_AXIS]
connect_bd_intf_net -intf_net adu_histo_0_result_out [get_bd_intf_pins result_out] [get_bd_intf_pins adu_histo_0/result_out]
connect_bd_intf_net -intf_net axis_64_to_512_0_data_out [get_bd_intf_pins axis_64_to_512_0/data_out] [get_bd_intf_pins axis_integration_result_fifo_1/S_AXIS]
connect_bd_intf_net -intf_net axis_compl_fifo_0_M_AXIS [get_bd_intf_pins adu_histo_0/s_axis_completion] [get_bd_intf_pins axis_compl_fifo_0/M_AXIS]
connect_bd_intf_net -intf_net axis_compl_fifo_1_M_AXIS [get_bd_intf_pins axis_compl_fifo_2/M_AXIS] [get_bd_intf_pins jf_conversion_0/s_axis_completion]
connect_bd_intf_net -intf_net axis_compl_fifo_2_M_AXIS [get_bd_intf_pins axis_compl_fifo_1/M_AXIS] [get_bd_intf_pins mask_missing_0/s_axis_completion]
connect_bd_intf_net -intf_net axis_compl_fifo_4_M_AXIS [get_bd_intf_pins axis_compl_fifo_3/M_AXIS] [get_bd_intf_pins frame_summation_0/s_axis_completion]
connect_bd_intf_net -intf_net axis_compl_fifo_5_M_AXIS [get_bd_intf_pins axis_compl_fifo_4/M_AXIS] [get_bd_intf_pins integration_0/s_axis_completion]
connect_bd_intf_net -intf_net axis_compl_fifo_5_M_AXIS1 [get_bd_intf_pins axis_compl_fifo_5/M_AXIS] [get_bd_intf_pins spot_finder_mask_0/s_axis_completion]
connect_bd_intf_net -intf_net axis_compl_fifo_1_M_AXIS [get_bd_intf_pins axis_compl_fifo_1/M_AXIS] [get_bd_intf_pins mask_missing_0/s_axis_completion]
connect_bd_intf_net -intf_net axis_compl_fifo_2_M_AXIS [get_bd_intf_pins axis_compl_fifo_2/M_AXIS] [get_bd_intf_pins eiger_reorder_0/s_axis_completion]
connect_bd_intf_net -intf_net axis_compl_fifo_3_M_AXIS [get_bd_intf_pins axis_compl_fifo_3/M_AXIS] [get_bd_intf_pins jf_conversion_0/s_axis_completion]
connect_bd_intf_net -intf_net axis_compl_fifo_4_M_AXIS [get_bd_intf_pins axis_compl_fifo_4/M_AXIS] [get_bd_intf_pins frame_summation_0/s_axis_completion]
connect_bd_intf_net -intf_net axis_compl_fifo_5_M_AXIS [get_bd_intf_pins axis_compl_fifo_5/M_AXIS] [get_bd_intf_pins integration_0/s_axis_completion]
connect_bd_intf_net -intf_net axis_compl_fifo_6_M_AXIS [get_bd_intf_pins axis_compl_fifo_6/M_AXIS] [get_bd_intf_pins spot_finder_mask_0/s_axis_completion]
connect_bd_intf_net -intf_net axis_compl_fifo_7_M_AXIS [get_bd_intf_pins axis_compl_fifo_7/M_AXIS] [get_bd_intf_pins roi_calc_0/s_axis_completion]
connect_bd_intf_net -intf_net axis_data_fifo_0_M_AXIS [get_bd_intf_pins axis_data_fifo_0/M_AXIS] [get_bd_intf_pins pedestal_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_3_M_AXIS [get_bd_intf_pins adu_histo_0/data_in] [get_bd_intf_pins axis_data_fifo_1/M_AXIS]
connect_bd_intf_net -intf_net axis_data_fifo_3_M_AXIS1 [get_bd_intf_pins axis_data_fifo_3/M_AXIS] [get_bd_intf_pins jf_conversion_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_4_M_AXIS [get_bd_intf_pins axis_data_fifo_2/M_AXIS] [get_bd_intf_pins mask_missing_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_6_M_AXIS [get_bd_intf_pins axis_data_fifo_4/M_AXIS] [get_bd_intf_pins axis_register_slice_data_1/S_AXIS]
connect_bd_intf_net -intf_net axis_data_fifo_6_M_AXIS1 [get_bd_intf_pins axis_data_fifo_8/M_AXIS] [get_bd_intf_pins stream_24bit_conv_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_6_M_AXIS2 [get_bd_intf_pins axis_data_fifo_6/M_AXIS] [get_bd_intf_pins spot_finder_mask_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_7_M_AXIS [get_bd_intf_pins axis_data_fifo_5/M_AXIS] [get_bd_intf_pins integration_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_7_M_AXIS1 [get_bd_intf_pins axis_data_fifo_7/M_AXIS] [get_bd_intf_pins spot_finder_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_10_M_AXIS [get_bd_intf_pins axis_data_fifo_10/M_AXIS] [get_bd_intf_pins stream_24bit_conv_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_1_M_AXIS [get_bd_intf_pins adu_histo_0/data_in] [get_bd_intf_pins axis_data_fifo_1/M_AXIS]
connect_bd_intf_net -intf_net axis_data_fifo_2_M_AXIS [get_bd_intf_pins axis_data_fifo_2/M_AXIS] [get_bd_intf_pins mask_missing_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_3_M_AXIS [get_bd_intf_pins axis_data_fifo_3/M_AXIS] [get_bd_intf_pins eiger_reorder_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_4_M_AXIS [get_bd_intf_pins axis_data_fifo_4/M_AXIS] [get_bd_intf_pins jf_conversion_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_5_M_AXIS [get_bd_intf_pins axis_data_fifo_5/M_AXIS] [get_bd_intf_pins axis_register_slice_data_1/S_AXIS]
connect_bd_intf_net -intf_net axis_data_fifo_6_M_AXIS [get_bd_intf_pins axis_data_fifo_6/M_AXIS] [get_bd_intf_pins integration_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_7_M_AXIS [get_bd_intf_pins axis_data_fifo_7/M_AXIS] [get_bd_intf_pins spot_finder_mask_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_8_M_AXIS [get_bd_intf_pins axis_data_fifo_8/M_AXIS] [get_bd_intf_pins spot_finder_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_9_M_AXIS [get_bd_intf_pins axis_data_fifo_9/M_AXIS] [get_bd_intf_pins roi_calc_0/data_in]
connect_bd_intf_net -intf_net axis_data_spot_finder_mask_0_M_AXIS [get_bd_intf_pins axis_data_spot_finder_mask_0/M_AXIS] [get_bd_intf_pins spot_finder_0/mask_in]
connect_bd_intf_net -intf_net axis_integration_result_fifo_0_M_AXIS [get_bd_intf_pins axis_64_to_512_0/data_in] [get_bd_intf_pins axis_integration_result_fifo_0/M_AXIS]
connect_bd_intf_net -intf_net axis_register_slice_data_1_M_AXIS [get_bd_intf_pins axis_register_slice_data_1/M_AXIS] [get_bd_intf_pins frame_summation_0/data_in]
connect_bd_intf_net -intf_net axis_register_slice_data_2_M_AXIS [get_bd_intf_pins axis_data_fifo_5/S_AXIS] [get_bd_intf_pins axis_register_slice_data_2/M_AXIS]
connect_bd_intf_net -intf_net axis_register_slice_data_2_M_AXIS [get_bd_intf_pins axis_data_fifo_6/S_AXIS] [get_bd_intf_pins axis_register_slice_data_2/M_AXIS]
connect_bd_intf_net -intf_net axis_register_slice_data_3_M_AXIS [get_bd_intf_pins data_out] [get_bd_intf_pins axis_register_slice_data_3/M_AXIS]
connect_bd_intf_net -intf_net axis_roi_calc_result_fifo_0_M_AXIS [get_bd_intf_pins roi_calc_out] [get_bd_intf_pins axis_roi_calc_result_fifo_0/M_AXIS]
connect_bd_intf_net -intf_net axis_spot_finder_conn_fifo_0_M_AXIS [get_bd_intf_pins axis_spot_finder_conn_fifo_0/M_AXIS] [get_bd_intf_pins spot_finder_merge_0/connectivity_in]
connect_bd_intf_net -intf_net axis_spot_finder_fifo_0_M_AXIS [get_bd_intf_pins axis_spot_finder_fifo_0/M_AXIS] [get_bd_intf_pins spot_finder_connecti_0/data_in]
connect_bd_intf_net -intf_net axis_spot_finder_fifo_1_M_AXIS [get_bd_intf_pins axis_spot_finder_fifo_1/M_AXIS] [get_bd_intf_pins spot_finder_merge_0/data_in]
connect_bd_intf_net -intf_net data_in_1 [get_bd_intf_pins data_in] [get_bd_intf_pins axis_data_fifo_0/S_AXIS]
connect_bd_intf_net -intf_net eiger_reorder_0_data_out [get_bd_intf_pins axis_data_fifo_4/S_AXIS] [get_bd_intf_pins eiger_reorder_0/data_out]
connect_bd_intf_net -intf_net eiger_reorder_0_m_axis_completion [get_bd_intf_pins axis_compl_fifo_3/S_AXIS] [get_bd_intf_pins eiger_reorder_0/m_axis_completion]
connect_bd_intf_net -intf_net frame_summation_0_data_out [get_bd_intf_pins axis_register_slice_data_2/S_AXIS] [get_bd_intf_pins frame_summation_0/data_out]
connect_bd_intf_net -intf_net frame_summation_0_m_axis_completion [get_bd_intf_pins axis_compl_fifo_4/S_AXIS] [get_bd_intf_pins frame_summation_0/m_axis_completion]
connect_bd_intf_net -intf_net integration_0_data_out [get_bd_intf_pins axis_data_fifo_6/S_AXIS] [get_bd_intf_pins integration_0/data_out]
connect_bd_intf_net -intf_net integration_0_m_axis_completion [get_bd_intf_pins axis_compl_fifo_5/S_AXIS] [get_bd_intf_pins integration_0/m_axis_completion]
connect_bd_intf_net -intf_net frame_summation_0_m_axis_completion [get_bd_intf_pins axis_compl_fifo_5/S_AXIS] [get_bd_intf_pins frame_summation_0/m_axis_completion]
connect_bd_intf_net -intf_net integration_0_data_out [get_bd_intf_pins axis_data_fifo_7/S_AXIS] [get_bd_intf_pins integration_0/data_out]
connect_bd_intf_net -intf_net integration_0_m_axis_completion [get_bd_intf_pins axis_compl_fifo_6/S_AXIS] [get_bd_intf_pins integration_0/m_axis_completion]
connect_bd_intf_net -intf_net integration_0_result_out [get_bd_intf_pins axis_integration_result_fifo_0/S_AXIS] [get_bd_intf_pins integration_0/result_out]
connect_bd_intf_net -intf_net jf_conversion_0_data_out [get_bd_intf_pins axis_data_fifo_4/S_AXIS] [get_bd_intf_pins jf_conversion_0/data_out]
connect_bd_intf_net -intf_net jf_conversion_0_m_axis_completion [get_bd_intf_pins axis_compl_fifo_3/S_AXIS] [get_bd_intf_pins jf_conversion_0/m_axis_completion]
connect_bd_intf_net -intf_net jf_conversion_0_data_out [get_bd_intf_pins axis_data_fifo_5/S_AXIS] [get_bd_intf_pins jf_conversion_0/data_out]
connect_bd_intf_net -intf_net jf_conversion_0_m_axis_completion [get_bd_intf_pins axis_compl_fifo_4/S_AXIS] [get_bd_intf_pins jf_conversion_0/m_axis_completion]
connect_bd_intf_net -intf_net mask_missing_0_data_out [get_bd_intf_pins axis_data_fifo_3/S_AXIS] [get_bd_intf_pins mask_missing_0/data_out]
connect_bd_intf_net -intf_net mask_missing_0_m_axis_completion [get_bd_intf_pins axis_compl_fifo_2/S_AXIS] [get_bd_intf_pins mask_missing_0/m_axis_completion]
connect_bd_intf_net -intf_net pedestal_0_data_out [get_bd_intf_pins axis_data_fifo_1/S_AXIS] [get_bd_intf_pins pedestal_0/data_out]
@@ -398,6 +449,9 @@ proc create_hier_cell_image_processing { parentCell nameHier } {
connect_bd_intf_net -intf_net pedestal_0_m_axi_d_hbm_p5 [get_bd_intf_pins pedestal_0/m_axi_d_hbm_p5] [get_bd_intf_pins smartconnect_5/S00_AXI]
connect_bd_intf_net -intf_net pedestal_0_m_axi_d_hbm_p5_w [get_bd_intf_pins pedestal_0/m_axi_d_hbm_p5_w] [get_bd_intf_pins smartconnect_5/S01_AXI]
connect_bd_intf_net -intf_net pedestal_0_m_axis_completion [get_bd_intf_pins axis_compl_fifo_0/S_AXIS] [get_bd_intf_pins pedestal_0/m_axis_completion]
connect_bd_intf_net -intf_net roi_calc_0_data_out [get_bd_intf_pins axis_data_fifo_10/S_AXIS] [get_bd_intf_pins roi_calc_0/data_out]
connect_bd_intf_net -intf_net roi_calc_0_m_axis_completion [get_bd_intf_pins m_axis_completion] [get_bd_intf_pins roi_calc_0/m_axis_completion]
connect_bd_intf_net -intf_net roi_calc_0_roi_out [get_bd_intf_pins axis_roi_calc_result_fifo_0/S_AXIS] [get_bd_intf_pins roi_calc_0/roi_out]
connect_bd_intf_net -intf_net s_axis_completion_1 [get_bd_intf_pins s_axis_completion] [get_bd_intf_pins pedestal_0/s_axis_completion]
connect_bd_intf_net -intf_net smartconnect_0_M00_AXI [get_bd_intf_pins m_axi_d_hbm_p24] [get_bd_intf_pins smartconnect_0/M00_AXI]
connect_bd_intf_net -intf_net smartconnect_1_M00_AXI [get_bd_intf_pins m_axi_d_hbm_p25] [get_bd_intf_pins smartconnect_1/M00_AXI]
@@ -405,31 +459,31 @@ proc create_hier_cell_image_processing { parentCell nameHier } {
connect_bd_intf_net -intf_net smartconnect_3_M00_AXI [get_bd_intf_pins m_axi_d_hbm_p27] [get_bd_intf_pins smartconnect_3/M00_AXI]
connect_bd_intf_net -intf_net smartconnect_4_M00_AXI [get_bd_intf_pins m_axi_d_hbm_p28] [get_bd_intf_pins smartconnect_4/M00_AXI]
connect_bd_intf_net -intf_net smartconnect_5_M00_AXI [get_bd_intf_pins m_axi_d_hbm_p29] [get_bd_intf_pins smartconnect_5/M00_AXI]
connect_bd_intf_net -intf_net spot_finder_0_data_out [get_bd_intf_pins axis_data_fifo_8/S_AXIS] [get_bd_intf_pins spot_finder_0/data_out]
connect_bd_intf_net -intf_net spot_finder_0_data_out [get_bd_intf_pins axis_data_fifo_9/S_AXIS] [get_bd_intf_pins spot_finder_0/data_out]
connect_bd_intf_net -intf_net spot_finder_0_strong_pixel_out [get_bd_intf_pins axis_spot_finder_fifo_0/S_AXIS] [get_bd_intf_pins spot_finder_0/strong_pixel_out]
connect_bd_intf_net -intf_net spot_finder_connecti_0_connectivity_out [get_bd_intf_pins axis_spot_finder_conn_fifo_0/S_AXIS] [get_bd_intf_pins spot_finder_connecti_0/connectivity_out]
connect_bd_intf_net -intf_net spot_finder_connecti_0_data_out [get_bd_intf_pins axis_spot_finder_fifo_1/S_AXIS] [get_bd_intf_pins spot_finder_connecti_0/data_out]
connect_bd_intf_net -intf_net spot_finder_mask_0_data_out [get_bd_intf_pins axis_data_fifo_7/S_AXIS] [get_bd_intf_pins spot_finder_mask_0/data_out]
connect_bd_intf_net -intf_net spot_finder_mask_0_data_out [get_bd_intf_pins axis_data_fifo_8/S_AXIS] [get_bd_intf_pins spot_finder_mask_0/data_out]
connect_bd_intf_net -intf_net spot_finder_mask_0_m_axi_d_hbm_p0 [get_bd_intf_pins m_axi_d_hbm_p22] [get_bd_intf_pins spot_finder_mask_0/m_axi_d_hbm_p0]
connect_bd_intf_net -intf_net spot_finder_mask_0_m_axi_d_hbm_p1 [get_bd_intf_pins m_axi_d_hbm_p23] [get_bd_intf_pins spot_finder_mask_0/m_axi_d_hbm_p1]
connect_bd_intf_net -intf_net spot_finder_mask_0_m_axis_completion [get_bd_intf_pins m_axis_completion] [get_bd_intf_pins spot_finder_mask_0/m_axis_completion]
connect_bd_intf_net -intf_net spot_finder_mask_0_m_axis_completion [get_bd_intf_pins axis_compl_fifo_7/S_AXIS] [get_bd_intf_pins spot_finder_mask_0/m_axis_completion]
connect_bd_intf_net -intf_net spot_finder_mask_0_mask_out [get_bd_intf_pins axis_data_spot_finder_mask_0/S_AXIS] [get_bd_intf_pins spot_finder_mask_0/mask_out]
connect_bd_intf_net -intf_net spot_finder_merge_0_data_out [get_bd_intf_pins axis_spot_finder_fifo_2/S_AXIS] [get_bd_intf_pins spot_finder_merge_0/data_out]
connect_bd_intf_net -intf_net stream_24bit_conv_0_data_out [get_bd_intf_pins axis_register_slice_data_3/S_AXIS] [get_bd_intf_pins stream_24bit_conv_0/data_out]
# Create port connections
connect_bd_net -net ap_rst_n_1 [get_bd_pins ap_rst_n] [get_bd_pins adu_histo_0/ap_rst_n] [get_bd_pins axis_64_to_512_0/ap_rst_n] [get_bd_pins frame_summation_0/ap_rst_n] [get_bd_pins integration_0/ap_rst_n] [get_bd_pins jf_conversion_0/ap_rst_n] [get_bd_pins mask_missing_0/ap_rst_n] [get_bd_pins pedestal_0/ap_rst_n] [get_bd_pins spot_finder_0/ap_rst_n] [get_bd_pins spot_finder_connecti_0/ap_rst_n] [get_bd_pins spot_finder_mask_0/ap_rst_n] [get_bd_pins spot_finder_merge_0/ap_rst_n] [get_bd_pins stream_24bit_conv_0/ap_rst_n]
connect_bd_net -net ap_rst_n_1 [get_bd_pins ap_rst_n] [get_bd_pins adu_histo_0/ap_rst_n] [get_bd_pins axis_64_to_512_0/ap_rst_n] [get_bd_pins eiger_reorder_0/ap_rst_n] [get_bd_pins frame_summation_0/ap_rst_n] [get_bd_pins integration_0/ap_rst_n] [get_bd_pins jf_conversion_0/ap_rst_n] [get_bd_pins mask_missing_0/ap_rst_n] [get_bd_pins pedestal_0/ap_rst_n] [get_bd_pins roi_calc_0/ap_rst_n] [get_bd_pins spot_finder_0/ap_rst_n] [get_bd_pins spot_finder_connecti_0/ap_rst_n] [get_bd_pins spot_finder_mask_0/ap_rst_n] [get_bd_pins spot_finder_merge_0/ap_rst_n] [get_bd_pins stream_24bit_conv_0/ap_rst_n]
connect_bd_net -net ap_start_1 [get_bd_pins frame_summation_0/ap_start] [get_bd_pins integration_0/ap_start] [get_bd_pins one/dout] [get_bd_pins spot_finder_0/ap_start] [get_bd_pins stream_24bit_conv_0/ap_start]
connect_bd_net -net axi_clk_1 [get_bd_pins axi_clk] [get_bd_pins adu_histo_0/ap_clk] [get_bd_pins axis_64_to_512_0/ap_clk] [get_bd_pins axis_compl_fifo_0/s_axis_aclk] [get_bd_pins axis_compl_fifo_1/s_axis_aclk] [get_bd_pins axis_compl_fifo_2/s_axis_aclk] [get_bd_pins axis_compl_fifo_3/s_axis_aclk] [get_bd_pins axis_compl_fifo_4/s_axis_aclk] [get_bd_pins axis_compl_fifo_5/s_axis_aclk] [get_bd_pins axis_data_fifo_0/s_axis_aclk] [get_bd_pins axis_data_fifo_1/s_axis_aclk] [get_bd_pins axis_data_fifo_2/s_axis_aclk] [get_bd_pins axis_data_fifo_3/s_axis_aclk] [get_bd_pins axis_data_fifo_4/s_axis_aclk] [get_bd_pins axis_data_fifo_5/s_axis_aclk] [get_bd_pins axis_data_fifo_6/s_axis_aclk] [get_bd_pins axis_data_fifo_7/s_axis_aclk] [get_bd_pins axis_data_fifo_8/s_axis_aclk] [get_bd_pins axis_data_spot_finder_mask_0/s_axis_aclk] [get_bd_pins axis_integration_result_fifo_0/s_axis_aclk] [get_bd_pins axis_integration_result_fifo_1/s_axis_aclk] [get_bd_pins axis_register_slice_data_1/aclk] [get_bd_pins axis_register_slice_data_2/aclk] [get_bd_pins axis_register_slice_data_3/aclk] [get_bd_pins axis_spot_finder_conn_fifo_0/s_axis_aclk] [get_bd_pins axis_spot_finder_fifo_0/s_axis_aclk] [get_bd_pins axis_spot_finder_fifo_1/s_axis_aclk] [get_bd_pins axis_spot_finder_fifo_2/s_axis_aclk] [get_bd_pins frame_summation_0/ap_clk] [get_bd_pins integration_0/ap_clk] [get_bd_pins jf_conversion_0/ap_clk] [get_bd_pins mask_missing_0/ap_clk] [get_bd_pins pedestal_0/ap_clk] [get_bd_pins smartconnect_0/aclk] [get_bd_pins smartconnect_1/aclk] [get_bd_pins smartconnect_2/aclk] [get_bd_pins smartconnect_3/aclk] [get_bd_pins smartconnect_4/aclk] [get_bd_pins smartconnect_5/aclk] [get_bd_pins spot_finder_0/ap_clk] [get_bd_pins spot_finder_connecti_0/ap_clk] [get_bd_pins spot_finder_mask_0/ap_clk] [get_bd_pins spot_finder_merge_0/ap_clk] [get_bd_pins stream_24bit_conv_0/ap_clk]
connect_bd_net -net axi_rst_n_1 [get_bd_pins axi_rst_n] [get_bd_pins axis_compl_fifo_0/s_axis_aresetn] [get_bd_pins axis_compl_fifo_1/s_axis_aresetn] [get_bd_pins axis_compl_fifo_2/s_axis_aresetn] [get_bd_pins axis_compl_fifo_3/s_axis_aresetn] [get_bd_pins axis_compl_fifo_4/s_axis_aresetn] [get_bd_pins axis_compl_fifo_5/s_axis_aresetn] [get_bd_pins axis_data_fifo_0/s_axis_aresetn] [get_bd_pins axis_data_fifo_1/s_axis_aresetn] [get_bd_pins axis_data_fifo_2/s_axis_aresetn] [get_bd_pins axis_data_fifo_3/s_axis_aresetn] [get_bd_pins axis_data_fifo_4/s_axis_aresetn] [get_bd_pins axis_data_fifo_5/s_axis_aresetn] [get_bd_pins axis_data_fifo_6/s_axis_aresetn] [get_bd_pins axis_data_fifo_7/s_axis_aresetn] [get_bd_pins axis_data_fifo_8/s_axis_aresetn] [get_bd_pins axis_data_spot_finder_mask_0/s_axis_aresetn] [get_bd_pins axis_integration_result_fifo_0/s_axis_aresetn] [get_bd_pins axis_integration_result_fifo_1/s_axis_aresetn] [get_bd_pins axis_register_slice_data_1/aresetn] [get_bd_pins axis_register_slice_data_2/aresetn] [get_bd_pins axis_register_slice_data_3/aresetn] [get_bd_pins axis_spot_finder_conn_fifo_0/s_axis_aresetn] [get_bd_pins axis_spot_finder_fifo_0/s_axis_aresetn] [get_bd_pins axis_spot_finder_fifo_1/s_axis_aresetn] [get_bd_pins axis_spot_finder_fifo_2/s_axis_aresetn] [get_bd_pins smartconnect_0/aresetn] [get_bd_pins smartconnect_1/aresetn] [get_bd_pins smartconnect_2/aresetn] [get_bd_pins smartconnect_3/aresetn] [get_bd_pins smartconnect_4/aresetn] [get_bd_pins smartconnect_5/aresetn]
connect_bd_net -net axis_data_fifo_6_almost_empty [get_bd_pins proc_fifo_empty] [get_bd_pins axis_data_fifo_6/almost_empty]
connect_bd_net -net axis_data_fifo_6_almost_full [get_bd_pins proc_fifo_full] [get_bd_pins axis_data_fifo_6/almost_full]
connect_bd_net -net axi_clk_1 [get_bd_pins axi_clk] [get_bd_pins adu_histo_0/ap_clk] [get_bd_pins axis_64_to_512_0/ap_clk] [get_bd_pins axis_compl_fifo_0/s_axis_aclk] [get_bd_pins axis_compl_fifo_1/s_axis_aclk] [get_bd_pins axis_compl_fifo_2/s_axis_aclk] [get_bd_pins axis_compl_fifo_3/s_axis_aclk] [get_bd_pins axis_compl_fifo_4/s_axis_aclk] [get_bd_pins axis_compl_fifo_5/s_axis_aclk] [get_bd_pins axis_compl_fifo_6/s_axis_aclk] [get_bd_pins axis_compl_fifo_7/s_axis_aclk] [get_bd_pins axis_data_fifo_0/s_axis_aclk] [get_bd_pins axis_data_fifo_1/s_axis_aclk] [get_bd_pins axis_data_fifo_10/s_axis_aclk] [get_bd_pins axis_data_fifo_2/s_axis_aclk] [get_bd_pins axis_data_fifo_3/s_axis_aclk] [get_bd_pins axis_data_fifo_4/s_axis_aclk] [get_bd_pins axis_data_fifo_5/s_axis_aclk] [get_bd_pins axis_data_fifo_6/s_axis_aclk] [get_bd_pins axis_data_fifo_7/s_axis_aclk] [get_bd_pins axis_data_fifo_8/s_axis_aclk] [get_bd_pins axis_data_fifo_9/s_axis_aclk] [get_bd_pins axis_data_spot_finder_mask_0/s_axis_aclk] [get_bd_pins axis_integration_result_fifo_0/s_axis_aclk] [get_bd_pins axis_integration_result_fifo_1/s_axis_aclk] [get_bd_pins axis_register_slice_data_1/aclk] [get_bd_pins axis_register_slice_data_2/aclk] [get_bd_pins axis_register_slice_data_3/aclk] [get_bd_pins axis_roi_calc_result_fifo_0/s_axis_aclk] [get_bd_pins axis_spot_finder_conn_fifo_0/s_axis_aclk] [get_bd_pins axis_spot_finder_fifo_0/s_axis_aclk] [get_bd_pins axis_spot_finder_fifo_1/s_axis_aclk] [get_bd_pins axis_spot_finder_fifo_2/s_axis_aclk] [get_bd_pins eiger_reorder_0/ap_clk] [get_bd_pins frame_summation_0/ap_clk] [get_bd_pins integration_0/ap_clk] [get_bd_pins jf_conversion_0/ap_clk] [get_bd_pins mask_missing_0/ap_clk] [get_bd_pins pedestal_0/ap_clk] [get_bd_pins roi_calc_0/ap_clk] [get_bd_pins smartconnect_0/aclk] [get_bd_pins smartconnect_1/aclk] [get_bd_pins smartconnect_2/aclk] [get_bd_pins smartconnect_3/aclk] [get_bd_pins smartconnect_4/aclk] [get_bd_pins smartconnect_5/aclk] [get_bd_pins spot_finder_0/ap_clk] [get_bd_pins spot_finder_connecti_0/ap_clk] [get_bd_pins spot_finder_mask_0/ap_clk] [get_bd_pins spot_finder_merge_0/ap_clk] [get_bd_pins stream_24bit_conv_0/ap_clk]
connect_bd_net -net axi_rst_n_1 [get_bd_pins axi_rst_n] [get_bd_pins axis_compl_fifo_0/s_axis_aresetn] [get_bd_pins axis_compl_fifo_1/s_axis_aresetn] [get_bd_pins axis_compl_fifo_2/s_axis_aresetn] [get_bd_pins axis_compl_fifo_3/s_axis_aresetn] [get_bd_pins axis_compl_fifo_4/s_axis_aresetn] [get_bd_pins axis_compl_fifo_5/s_axis_aresetn] [get_bd_pins axis_compl_fifo_6/s_axis_aresetn] [get_bd_pins axis_compl_fifo_7/s_axis_aresetn] [get_bd_pins axis_data_fifo_0/s_axis_aresetn] [get_bd_pins axis_data_fifo_1/s_axis_aresetn] [get_bd_pins axis_data_fifo_10/s_axis_aresetn] [get_bd_pins axis_data_fifo_2/s_axis_aresetn] [get_bd_pins axis_data_fifo_3/s_axis_aresetn] [get_bd_pins axis_data_fifo_4/s_axis_aresetn] [get_bd_pins axis_data_fifo_5/s_axis_aresetn] [get_bd_pins axis_data_fifo_6/s_axis_aresetn] [get_bd_pins axis_data_fifo_7/s_axis_aresetn] [get_bd_pins axis_data_fifo_8/s_axis_aresetn] [get_bd_pins axis_data_fifo_9/s_axis_aresetn] [get_bd_pins axis_data_spot_finder_mask_0/s_axis_aresetn] [get_bd_pins axis_integration_result_fifo_0/s_axis_aresetn] [get_bd_pins axis_integration_result_fifo_1/s_axis_aresetn] [get_bd_pins axis_register_slice_data_1/aresetn] [get_bd_pins axis_register_slice_data_2/aresetn] [get_bd_pins axis_register_slice_data_3/aresetn] [get_bd_pins axis_roi_calc_result_fifo_0/s_axis_aresetn] [get_bd_pins axis_spot_finder_conn_fifo_0/s_axis_aresetn] [get_bd_pins axis_spot_finder_fifo_0/s_axis_aresetn] [get_bd_pins axis_spot_finder_fifo_1/s_axis_aresetn] [get_bd_pins axis_spot_finder_fifo_2/s_axis_aresetn] [get_bd_pins smartconnect_0/aresetn] [get_bd_pins smartconnect_1/aresetn] [get_bd_pins smartconnect_2/aresetn] [get_bd_pins smartconnect_3/aresetn] [get_bd_pins smartconnect_4/aresetn] [get_bd_pins smartconnect_5/aresetn]
connect_bd_net -net axis_data_fifo_6_almost_empty [get_bd_pins proc_fifo_empty] [get_bd_pins axis_data_fifo_7/almost_empty]
connect_bd_net -net axis_data_fifo_6_almost_full [get_bd_pins proc_fifo_full] [get_bd_pins axis_data_fifo_7/almost_full]
connect_bd_net -net frame_summation_0_idle [get_bd_pins frame_summation_idle] [get_bd_pins frame_summation_0/idle]
connect_bd_net -net hbm_size_bytes_1 [get_bd_pins hbm_size_bytes] [get_bd_pins integration_0/hbm_size_bytes] [get_bd_pins jf_conversion_0/hbm_size_bytes] [get_bd_pins pedestal_0/hbm_size_bytes] [get_bd_pins spot_finder_mask_0/hbm_size_bytes]
connect_bd_net -net hbm_size_bytes_1 [get_bd_pins hbm_size_bytes] [get_bd_pins integration_0/hbm_size_bytes] [get_bd_pins jf_conversion_0/hbm_size_bytes] [get_bd_pins pedestal_0/hbm_size_bytes] [get_bd_pins roi_calc_0/hbm_size_bytes] [get_bd_pins spot_finder_mask_0/hbm_size_bytes]
connect_bd_net -net in_count_threshold_1 [get_bd_pins in_count_threshold] [get_bd_pins spot_finder_0/in_count_threshold]
connect_bd_net -net in_min_pix_per_spot_1 [get_bd_pins in_min_pix_per_spot] [get_bd_pins spot_finder_mask_0/in_min_pix_per_spot]
connect_bd_net -net in_max_d_value_1 [get_bd_pins in_max_d_value] [get_bd_pins spot_finder_mask_0/in_max_d_value]
connect_bd_net -net in_min_d_value_1 [get_bd_pins in_min_d_value] [get_bd_pins spot_finder_mask_0/in_min_d_value]
connect_bd_net -net in_min_pix_per_spot_1 [get_bd_pins in_min_pix_per_spot] [get_bd_pins spot_finder_merge_0/in_min_pix_per_spot]
connect_bd_net -net in_snr_threshold_1 [get_bd_pins in_snr_threshold] [get_bd_pins spot_finder_0/in_snr_threshold]
connect_bd_net -net integration_0_idle [get_bd_pins integration_idle] [get_bd_pins integration_0/idle]
connect_bd_net -net stream_conv_0_idle [get_bd_pins stream_conv_idle] [get_bd_pins stream_24bit_conv_0/idle]
+14 -10
View File
@@ -1,6 +1,5 @@
## Copyright (2019-2023) Paul Scherrer Institute
## Copyright (2019-2024) Paul Scherrer Institute
# Hierarchical cell: jungfraujoch
# Hierarchical cell: jungfraujoch
proc create_hier_cell_jungfraujoch { parentCell nameHier } {
@@ -36,9 +35,7 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } {
current_bd_instance $hier_obj
# Create interface pins
create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 eth_100g_in
create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 eth_4x10g_in
create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 eth_in
create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 eth_out
@@ -102,6 +99,10 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } {
create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 m_axi_d_hbm_p29
create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 m_axi_d_hbm_p30
create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 m_axi_d_hbm_p31
create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 m_axis_c2h_data
create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 m_axis_c2h_datamover_cmd
@@ -180,8 +181,7 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } {
# Create instance: axis_data_fifo_0, and set properties
set axis_data_fifo_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_fifo_0 ]
set_property -dict [ list \
CONFIG.FIFO_DEPTH {2048} \
CONFIG.FIFO_MEMORY_TYPE {ultra} \
CONFIG.FIFO_DEPTH {512} \
] $axis_data_fifo_0
# Create instance: axis_data_fifo_1, and set properties
@@ -202,7 +202,7 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } {
# Create instance: axis_data_fifo_3, and set properties
set axis_data_fifo_3 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_fifo_3 ]
set_property -dict [ list \
CONFIG.FIFO_DEPTH {8192} \
CONFIG.FIFO_DEPTH {2048} \
CONFIG.FIFO_MEMORY_TYPE {ultra} \
CONFIG.HAS_AEMPTY {1} \
CONFIG.HAS_AFULL {1} \
@@ -413,8 +413,7 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } {
connect_bd_intf_net -intf_net axis_udp_fifo_0_M_AXIS [get_bd_intf_pins axis_register_slice_udp/S_AXIS] [get_bd_intf_pins axis_udp_fifo_0/M_AXIS]
connect_bd_intf_net -intf_net data_collection_fsm_0_addr_out [get_bd_intf_pins axis_addr_fifo_0/S_AXIS] [get_bd_intf_pins data_collection_fsm_0/addr_out]
connect_bd_intf_net -intf_net data_collection_fsm_0_data_out [get_bd_intf_pins axis_data_fifo_0/S_AXIS] [get_bd_intf_pins data_collection_fsm_0/data_out]
connect_bd_intf_net -intf_net eth_100g_in_1 [get_bd_intf_pins eth_100g_in] [get_bd_intf_pins stream_merge_0/input_100g]
connect_bd_intf_net -intf_net eth_4x10g_in_1 [get_bd_intf_pins eth_4x10g_in] [get_bd_intf_pins stream_merge_0/input_4x10g]
connect_bd_intf_net -intf_net eth_in_1 [get_bd_intf_pins eth_in] [get_bd_intf_pins stream_merge_0/input_network]
connect_bd_intf_net -intf_net eth_out_M00_AXIS [get_bd_intf_pins eth_out] [get_bd_intf_pins network_stack/M00_AXIS]
connect_bd_intf_net -intf_net frame_generator_0_data_out [get_bd_intf_pins axis_frame_generator_fifo_0/S_AXIS] [get_bd_intf_pins frame_generator_0/data_out]
connect_bd_intf_net -intf_net frame_generator_0_m_axi_d_hbm_p0 [get_bd_intf_pins m_axi_d_hbm_p20] [get_bd_intf_pins frame_generator_0/m_axi_d_hbm_p0]
@@ -456,8 +455,11 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } {
connect_bd_intf_net -intf_net image_processing_m_axi_d_hbm_p27 [get_bd_intf_pins m_axi_d_hbm_p27] [get_bd_intf_pins image_processing/m_axi_d_hbm_p27]
connect_bd_intf_net -intf_net image_processing_m_axi_d_hbm_p28 [get_bd_intf_pins m_axi_d_hbm_p28] [get_bd_intf_pins image_processing/m_axi_d_hbm_p28]
connect_bd_intf_net -intf_net image_processing_m_axi_d_hbm_p29 [get_bd_intf_pins m_axi_d_hbm_p29] [get_bd_intf_pins image_processing/m_axi_d_hbm_p29]
connect_bd_intf_net -intf_net image_processing_m_axi_d_hbm_p30 [get_bd_intf_pins m_axi_d_hbm_p30] [get_bd_intf_pins image_processing/m_axi_d_hbm_p30]
connect_bd_intf_net -intf_net image_processing_m_axi_d_hbm_p31 [get_bd_intf_pins m_axi_d_hbm_p31] [get_bd_intf_pins image_processing/m_axi_d_hbm_p31]
connect_bd_intf_net -intf_net image_processing_m_axis_completion3 [get_bd_intf_pins axis_compl_fifo_1/S_AXIS] [get_bd_intf_pins image_processing/m_axis_completion]
connect_bd_intf_net -intf_net image_processing_result_out [get_bd_intf_pins axis_adu_histo_result_fifo/S_AXIS] [get_bd_intf_pins image_processing/result_out]
connect_bd_intf_net -intf_net image_processing_roi_calc_out [get_bd_intf_pins host_writer_0/roi_count_in] [get_bd_intf_pins image_processing/roi_calc_out]
connect_bd_intf_net -intf_net load_calibration_0_datamover_in_cmd [get_bd_intf_pins axis_data_fifo_h2c_cmd/S_AXIS] [get_bd_intf_pins load_calibration_0/datamover_in_cmd]
connect_bd_intf_net -intf_net load_calibration_0_m_axi_d_hbm_p0 [get_bd_intf_pins load_calibration_0/m_axi_d_hbm_p0] [get_bd_intf_pins smartconnect_1/S01_AXI]
connect_bd_intf_net -intf_net load_calibration_0_m_axi_d_hbm_p1 [get_bd_intf_pins load_calibration_0/m_axi_d_hbm_p1] [get_bd_intf_pins smartconnect_2/S01_AXI]
@@ -550,6 +552,8 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } {
connect_bd_net -net network_stack_packets_sls_ap_vld [get_bd_pins action_config_0/packets_sls_valid] [get_bd_pins network_stack/packets_sls_ap_vld]
connect_bd_net -net network_stack_packets_udp [get_bd_pins action_config_0/packets_udp] [get_bd_pins network_stack/packets_udp]
connect_bd_net -net network_stack_packets_udp_ap_vld [get_bd_pins action_config_0/packets_udp_valid] [get_bd_pins network_stack/packets_udp_ap_vld]
connect_bd_net -net network_stack_pulse_id [get_bd_pins action_config_0/pulseid] [get_bd_pins network_stack/pulse_id]
connect_bd_net -net network_stack_pulse_id_ap_vld [get_bd_pins action_config_0/pulseid_valid] [get_bd_pins network_stack/pulse_id_ap_vld]
connect_bd_net -net reset_axi [get_bd_pins axi_rst_n] [get_bd_pins action_config_0/resetn] [get_bd_pins axis_addr_fifo_0/s_axis_aresetn] [get_bd_pins axis_adu_histo_result_fifo/s_axis_aresetn] [get_bd_pins axis_compl_fifo_0/s_axis_aresetn] [get_bd_pins axis_compl_fifo_1/s_axis_aresetn] [get_bd_pins axis_data_fifo_0/s_axis_aresetn] [get_bd_pins axis_data_fifo_1/s_axis_aresetn] [get_bd_pins axis_data_fifo_2/s_axis_aresetn] [get_bd_pins axis_data_fifo_3/s_axis_aresetn] [get_bd_pins axis_data_fifo_c2h_cmd/s_axis_aresetn] [get_bd_pins axis_data_fifo_c2h_data/s_axis_aresetn] [get_bd_pins axis_data_fifo_h2c_cmd/s_axis_aresetn] [get_bd_pins axis_data_fifo_h2c_data/s_axis_aresetn] [get_bd_pins axis_eth_in_fifo/s_axis_aresetn] [get_bd_pins axis_frame_generator_fifo_0/s_axis_aresetn] [get_bd_pins axis_register_slice_addr_0/aresetn] [get_bd_pins axis_register_slice_data_0/aresetn] [get_bd_pins axis_register_slice_data_in_0/aresetn] [get_bd_pins axis_register_slice_host_mem/aresetn] [get_bd_pins axis_register_slice_udp/aresetn] [get_bd_pins axis_udp_addr_fifo_0/s_axis_aresetn] [get_bd_pins axis_udp_fifo_0/s_axis_aresetn] [get_bd_pins hbm_cache/axi_rst_n] [get_bd_pins image_processing/axi_rst_n] [get_bd_pins network_stack/resetn] [get_bd_pins smartconnect_0/aresetn] [get_bd_pins smartconnect_1/aresetn] [get_bd_pins smartconnect_2/aresetn] [get_bd_pins smartconnect_3/aresetn]
connect_bd_net -net reset_hls [get_bd_pins ap_rst_n] [get_bd_pins axi_bram_ctrl_calibration_addr_0/s_axi_aresetn] [get_bd_pins axi_bram_ctrl_calibration_addr_1/s_axi_aresetn] [get_bd_pins data_collection_fsm_0/ap_rst_n] [get_bd_pins frame_generator_0/ap_rst_n] [get_bd_pins hbm_cache/ap_rst_n] [get_bd_pins host_writer_0/ap_rst_n] [get_bd_pins image_processing/ap_rst_n] [get_bd_pins load_calibration_0/ap_rst_n] [get_bd_pins mailbox_0/S0_AXI_ARESETN] [get_bd_pins network_stack/ap_rst_n] [get_bd_pins stream_merge_0/ap_rst_n] [get_bd_pins timer_hbm/ap_rst_n] [get_bd_pins timer_host/ap_rst_n] [get_bd_pins timer_proc/ap_rst_n]
connect_bd_net -net save_to_hbm_0_idle [get_bd_pins action_config_0/save_to_hbm_idle] [get_bd_pins hbm_cache/save_to_hbm_idle]
+4 -4
View File
@@ -57,8 +57,8 @@ proc create_hier_cell_mac_100g { parentCell nameHier } {
# Create instance: axis_data_fifo_rx_0, and set properties
set axis_data_fifo_rx_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_fifo_rx_0 ]
set_property -dict [ list \
CONFIG.FIFO_DEPTH {2048} \
CONFIG.FIFO_MEMORY_TYPE {ultra} \
CONFIG.FIFO_DEPTH {256} \
CONFIG.FIFO_MEMORY_TYPE {block} \
] $axis_data_fifo_rx_0
# Create instance: axis_data_fifo_rx_1, and set properties
@@ -73,14 +73,14 @@ proc create_hier_cell_mac_100g { parentCell nameHier } {
# Create instance: axis_data_fifo_rx_2, and set properties
set axis_data_fifo_rx_2 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_fifo_rx_2 ]
set_property -dict [ list \
CONFIG.FIFO_DEPTH {512} \
CONFIG.FIFO_DEPTH {256} \
CONFIG.FIFO_MEMORY_TYPE {block} \
] $axis_data_fifo_rx_2
# Create instance: axis_data_fifo_tx, and set properties
set axis_data_fifo_tx [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_fifo_tx ]
set_property -dict [ list \
CONFIG.FIFO_DEPTH {128} \
CONFIG.FIFO_DEPTH {256} \
CONFIG.FIFO_MODE {2} \
CONFIG.IS_ACLK_ASYNC {1} \
] $axis_data_fifo_tx
+4
View File
@@ -63,6 +63,8 @@ proc create_hier_cell_network_stack { parentCell nameHier } {
create_bd_pin -dir O packets_sls_ap_vld
create_bd_pin -dir O -from 63 -to 0 -type data packets_udp
create_bd_pin -dir O packets_udp_ap_vld
create_bd_pin -dir O -from 63 -to 0 -type data pulse_id
create_bd_pin -dir O pulse_id_ap_vld
create_bd_pin -dir I -type rst resetn
create_bd_pin -dir O -from 0 -to 0 -type data sls_detector_idle
create_bd_pin -dir O -from 0 -to 0 -type data udp_idle
@@ -193,6 +195,8 @@ proc create_hier_cell_network_stack { parentCell nameHier } {
connect_bd_net -net sls_detector_0_counter_len_error [get_bd_pins counter_len_error] [get_bd_pins sls_detector_0/counter_len_error]
connect_bd_net -net sls_detector_0_counter_len_error_ap_vld [get_bd_pins counter_len_error_ap_vld] [get_bd_pins sls_detector_0/counter_len_error_ap_vld]
connect_bd_net -net sls_detector_0_idle [get_bd_pins sls_detector_idle] [get_bd_pins sls_detector_0/idle]
connect_bd_net -net sls_detector_0_pulse_id [get_bd_pins pulse_id] [get_bd_pins sls_detector_0/pulse_id]
connect_bd_net -net sls_detector_0_pulse_id_ap_vld [get_bd_pins pulse_id_ap_vld] [get_bd_pins sls_detector_0/pulse_id_ap_vld]
connect_bd_net -net udp_0_counter [get_bd_pins packets_udp] [get_bd_pins udp_0/counter]
connect_bd_net -net udp_0_counter_ap_vld [get_bd_pins packets_udp_ap_vld] [get_bd_pins udp_0/counter_ap_vld]
connect_bd_net -net udp_0_idle [get_bd_pins udp_idle] [get_bd_pins udp_0/idle]
+18 -7
View File
@@ -14,7 +14,7 @@ for i in hls/psi_ch*.zip
do
x=${i##hls/psi_ch_}
y=${x%%.zip}
unzip $i -d action/ip/$y
unzip -qq -d action/ip/$y $i
done
@@ -29,23 +29,34 @@ EOF
cp ${SRC_DIR}/hdl/*.v action/hw/hdl
# Update action type and release level based on jfjoch_fpga.h
ACTION_TYPE=`grep "#define ACTION_TYPE" ${SRC_DIR}/include/jfjoch_fpga.h | awk -F"0x" '{print $2}'`
RELEASE_LEVEL=`grep "#define RELEASE_LEVEL" ${SRC_DIR}/include/jfjoch_fpga.h | awk -F"0x" '{print $2}'`
ACTION_TYPE=`grep "#define JFJOCH_FPGA_MAGIC" ${SRC_DIR}/include/jfjoch_fpga.h | awk -F"0x" '{print $2}'`
RELEASE_LEVEL=`grep "#define JFJOCH_FPGA_RELEASE" ${SRC_DIR}/include/jfjoch_fpga.h | awk -F"0x" '{print $2}'`
MAX_MODULES_FPGA=`grep "#define MAX_MODULES_FPGA" ${SRC_DIR}/include/jfjoch_fpga.h |tr -s " " |cut -f3 -d" "`
GIT_SHA1=`git describe --match=NeVeRmAtCh --always --abbrev=8`
SRC="define ACTION_TYPE 32'h.*"
DST="define ACTION_TYPE 32'h${ACTION_TYPE}"
SRC="define JFJOCH_MAGIC 32'h.*"
DST="define JFJOCH_MAGIC 32'h${ACTION_TYPE}"
sed -i "s/$SRC/$DST/" action/hw/hdl/action_config.v
SRC="define RELEASE_LEVEL 32'h.*"
DST="define RELEASE_LEVEL 32'h${RELEASE_LEVEL}"
SRC="define JFJOCH_RELEASE 32'h.*"
DST="define JFJOCH_RELEASE 32'h${RELEASE_LEVEL}"
sed -i "s/$SRC/$DST/" action/hw/hdl/action_config.v
SRC="define JFJOCH_VARIANT 32'h.*"
DST="define JFJOCH_VARIANT 32'h${VARIANT}"
sed -i "s/$SRC/$DST/" action/hw/hdl/action_config.v
SRC="define GIT_SHA1 32'h.*"
DST="define GIT_SHA1 32'h${GIT_SHA1}"
sed -i "s/$SRC/$DST/" action/hw/hdl/action_config.v
TIME_EPOCH=`date +%s`
SRC="define JFJOCH_SYNTH_TIME 32'd*"
DST="define JFJOCH_SYNTH_TIME 32'd${TIME_EPOCH}"
sed -i "s/$SRC/$DST/" action/hw/hdl/action_config.v
SRC="define MAX_MODULES_FPGA 32'd.*"
DST="define MAX_MODULES_FPGA 32'd${MAX_MODULES_FPGA}"
sed -i "s/$SRC/$DST/" action/hw/hdl/action_config.v
+1 -1
View File
@@ -67,7 +67,7 @@ if {$WNSPLACE > -0.3000} {
write_checkpoint -force jungfraujoch_route.dcp
report_utilization -no_primitives
report_power
report_power -file jungfraujoch_power_report.txt
puts ""
puts "Route WNS (before optimization): $WNSROUTE ps"
+1 -1
View File
@@ -25,4 +25,4 @@ config_export -vendor {psi.ch} -version 1.0 -ipname $env(HLS_TOP_FUNCTION) -form
export_design
close_project
exit
exit
+8 -1
View File
@@ -93,8 +93,15 @@ set_property IOSTANDARD LVCMOS18 [get_ports {satellite_gpio_0[2]}]
set_property PACKAGE_PIN BF46 [get_ports {satellite_gpio_0[3]}]
set_property IOSTANDARD LVCMOS18 [get_ports {satellite_gpio_0[3]}]
## HBM debug clock
## I2C for clock generator
set_property PACKAGE_PIN BM14 [get_ports {i2c_si5394_scl_io}]
set_property IOSTANDARD LVCMOS18 [get_ports {i2c_si5394_scl_io}]
set_property PACKAGE_PIN BN14 [get_ports {i2c_si5394_sda_io}]
set_property IOSTANDARD LVCMOS18 [get_ports {i2c_si5394_sda_io}]
set_property PACKAGE_PIN BM8 [get_ports {si5394_rstn}] #active low
set_property IOSTANDARD LVCMOS18 [get_ports {si5394_rstn}] #active low
## HBM debug clock
set_property C_CLK_INPUT_FREQ_HZ 100000000 [get_debug_cores dbg_hub]
set_property C_ENABLE_CLK_DIVIDER false [get_debug_cores dbg_hub]
set_property C_USER_SCAN_CHAIN 1 [get_debug_cores dbg_hub]
+279 -222
View File
@@ -4,17 +4,18 @@
#include "tinycbor/src/cbor.h"
#include "CborErr.h"
#include "CborUtil.h"
#include <nlohmann/json.hpp>
inline std::string GetCBORString(CborValue &value) {
if (!cbor_value_is_text_string(&value))
throw JFJochException(JFJochExceptionCategory::CBORError, "String expected");
char buf[256];
size_t len = 255;
cborErr(cbor_value_copy_text_string(&value, buf, &len, nullptr));
buf[len+1] = 0;
std::vector<char> s(16384);
size_t len = s.size() - 1;
cborErr(cbor_value_copy_text_string(&value, s.data(), &len, nullptr));
s[len+1] = 0;
cborErr(cbor_value_advance(&value));
return {buf};
return {s.data()};
}
inline int64_t GetCBORInt(CborValue &value) {
@@ -37,12 +38,23 @@ inline uint64_t GetCBORUInt(CborValue &value) {
}
inline float GetCBORFloat(CborValue &value) {
if (!cbor_value_is_float(&value) )
throw JFJochException(JFJochExceptionCategory::CBORError, "Float expected");
float tmp;
cborErr(cbor_value_get_float(&value, &tmp));
cborErr(cbor_value_advance(&value));
return tmp;
if (cbor_value_is_double(&value)) {
double tmp;
cborErr(cbor_value_get_double(&value, &tmp));
cborErr(cbor_value_advance(&value));
return static_cast<float>(tmp);
} else if (cbor_value_is_float(&value)) {
float tmp;
cborErr(cbor_value_get_float(&value, &tmp));
cborErr(cbor_value_advance(&value));
return tmp;
} else if (cbor_value_is_half_float(&value)) {
float tmp;
cborErr(cbor_value_get_half_float_as_float(&value, &tmp));
cborErr(cbor_value_advance(&value));
return tmp;
}
throw JFJochException(JFJochExceptionCategory::CBORError, "Float expected");
}
inline bool GetCBORBool(CborValue &value) {
@@ -198,6 +210,17 @@ inline void GetCBORFloatArray(CborValue &value, std::vector<float> &v) {
memcpy(v.data(), ptr, len);
}
inline void GetCBORStringArray(CborValue &value, std::vector<std::string> &v) {
if (!cbor_value_is_array(&value))
throw JFJochException(JFJochExceptionCategory::CBORError, "Array expected");
CborValue array_value;
cborErr(cbor_value_enter_container(&value, &array_value));
while (! cbor_value_at_end(&array_value)) {
v.emplace_back(GetCBORString(array_value));
}
cborErr(cbor_value_leave_container(&value, &array_value));
}
inline void GetCBORUInt64Array(CborValue &value, std::vector<uint64_t> &v) {
if (GetCBORTag(value) != TagUnsignedInt64BitLE)
throw JFJochException(JFJochExceptionCategory::CBORError, "Incorrect array type tag");
@@ -382,7 +405,8 @@ void CBORStream2Deserializer::ProcessGoniometerMap(CborValue &value) {
cborErr(cbor_value_enter_container(&value, &map_value));
while (! cbor_value_at_end(&map_value)) {
auto key = GetCBORString(map_value);
start_message.goniometer[key] = ProcessGoniometer(map_value);
if (key == "omega")
ProcessGoniometerOmega(map_value);
}
cborErr(cbor_value_leave_container(&value, &map_value));
}
@@ -398,7 +422,7 @@ void CBORStream2Deserializer::ProcessAxis(CborValue &value, float v[3]) {
cborErr(cbor_value_leave_container(&value, &array_value));
}
GoniometerAxis CBORStream2Deserializer::ProcessGoniometer(CborValue &value) {
void CBORStream2Deserializer::ProcessGoniometerOmega(CborValue &value) {
CborValue map_value;
GoniometerAxis ret{};
@@ -406,16 +430,13 @@ GoniometerAxis CBORStream2Deserializer::ProcessGoniometer(CborValue &value) {
while (! cbor_value_at_end(&map_value)) {
auto key = GetCBORString(map_value);
if (key == "increment")
ret.increment = GetCBORFloat(map_value);
start_message.omega.increment = GetCBORFloat(map_value);
else if (key == "start")
ret.start = GetCBORFloat(map_value);
else if (key == "axis")
ProcessAxis(map_value, ret.axis);
start_message.omega.start = GetCBORFloat(map_value);
else
cbor_value_advance(&value);
}
cborErr(cbor_value_leave_container(&value, &map_value));
return ret;
}
bool CBORStream2Deserializer::ProcessImageMessageElement(CborValue &value) {
@@ -423,68 +444,66 @@ bool CBORStream2Deserializer::ProcessImageMessageElement(CborValue &value) {
return false;
else {
auto key = GetCBORString(value);
if (key == "image_id")
data_message.number = GetCBORInt(value);
else if (key == "data")
ProcessImageData(value);
else if (key == "series_unique_id")
data_message.series_unique_id = GetCBORString(value);
else if (key == "series_id")
data_message.series_id = GetCBORUInt(value);
else if (key == "real_time") {
auto r = GetRational(value);
data_message.exptime = r.first;
data_message.exptime_base = r.second;
} else if (key == "start_time") {
auto r = GetRational(value);
data_message.timestamp = r.first;
data_message.timestamp_base = r.second;
} else if (key == "user_data")
data_message.user_data = GetCBORString(value);
else if (key == "spots")
GetCBORSpots(value);
else if (key == "az_int_profile")
GetCBORFloatArray(value, data_message.az_int_profile);
else if (key == "indexing_result")
data_message.indexing_result = GetCBORUInt(value);
else if (key == "indexing_lattice")
GetCBORFloatArray(value, data_message.indexing_lattice);
else if (key == "jf_info")
data_message.jf_info = GetCBORUInt(value) & UINT32_MAX;
else if (key == "receiver_aq_dev_delay")
data_message.receiver_aq_dev_delay = GetCBORInt(value);
else if (key == "storage_cell")
data_message.storage_cell = GetCBORUInt(value) & UINT32_MAX;
else if (key == "xfel_bunch_id")
data_message.xfel_bunch_id = GetCBORUInt(value);
else if (key == "xfel_event_code")
data_message.xfel_event_code = GetCBORUInt(value);
else if (key == "saturated_pixel_count")
data_message.saturated_pixel_count = GetCBORUInt(value);
else if (key == "error_pixel_count")
data_message.error_pixel_count = GetCBORUInt(value);
else if (key == "strong_pixel_count")
data_message.strong_pixel_count = GetCBORUInt(value);
else if (key == "data_collection_efficiency")
data_message.image_collection_efficiency = GetCBORFloat(value);
else if (key == "bkg_estimate")
data_message.bkg_estimate = GetCBORFloat(value);
else if (key == "adu_histogram")
GetCBORUInt64Array(value, data_message.adu_histogram);
else if (key == "beam_center_x")
data_message.beam_center_x = GetCBORFloat(value);
else if (key == "beam_center_y")
data_message.beam_center_y = GetCBORFloat(value);
else if (key == "detector_distance")
data_message.detector_distance = GetCBORFloat(value);
else if (key == "incident_energy")
data_message.incident_energy = GetCBORFloat(value);
else if (key == "roi_sum")
data_message.roi_sum = GetCBORInt(value);
else
cbor_value_advance(&value);
return true;
try {
if (key == "image_id")
data_message.number = GetCBORInt(value);
else if (key == "data")
ProcessImageData(value);
else if (key == "series_unique_id")
data_message.series_unique_id = GetCBORString(value);
else if (key == "series_id")
data_message.series_id = GetCBORUInt(value);
else if (key == "real_time") {
auto r = GetRational(value);
data_message.exptime = r.first;
data_message.exptime_base = r.second;
} else if (key == "start_time") {
auto r = GetRational(value);
data_message.timestamp = r.first;
data_message.timestamp_base = r.second;
} else if (key == "user_data")
data_message.user_data = GetCBORString(value);
else if (key == "spots")
GetCBORSpots(value);
else if (key == "az_int_profile")
GetCBORFloatArray(value, data_message.az_int_profile);
else if (key == "indexing_result")
data_message.indexing_result = GetCBORUInt(value);
else if (key == "indexing_lattice")
GetCBORFloatArray(value, data_message.indexing_lattice);
else if (key == "jf_info")
data_message.jf_info = GetCBORUInt(value) & UINT32_MAX;
else if (key == "receiver_aq_dev_delay")
data_message.receiver_aq_dev_delay = GetCBORInt(value);
else if (key == "storage_cell")
data_message.storage_cell = GetCBORUInt(value) & UINT32_MAX;
else if (key == "xfel_pulse_id")
data_message.xfel_pulse_id = GetCBORUInt(value);
else if (key == "xfel_event_code")
data_message.xfel_event_code = GetCBORUInt(value);
else if (key == "saturated_pixel_count")
data_message.saturated_pixel_count = GetCBORUInt(value);
else if (key == "error_pixel_count")
data_message.error_pixel_count = GetCBORUInt(value);
else if (key == "strong_pixel_count")
data_message.strong_pixel_count = GetCBORUInt(value);
else if (key == "data_collection_efficiency")
data_message.image_collection_efficiency = GetCBORFloat(value);
else if (key == "bkg_estimate")
data_message.bkg_estimate = GetCBORFloat(value);
else if (key == "adu_histogram")
GetCBORUInt64Array(value, data_message.adu_histogram);
else if (key == "roi_sum")
data_message.roi_sum = GetCBORInt(value);
else {
if (cbor_value_is_tag(&value))
cbor_value_advance(&value);
cbor_value_advance(&value);
}
return true;
} catch (const JFJochException &e) {
throw JFJochException(JFJochExceptionCategory::CBORError, "Error processing image message, key " + key + ":" + e.what());
}
}
}
@@ -585,123 +604,159 @@ void CBORStream2Deserializer::ProcessUnitCellElement(CborValue &value) {
start_message.unit_cell = unit_cell;
}
void CBORStream2Deserializer::ProcessStartUserData(CborValue &value) {
try {
const std::string s = GetCBORString(value);
auto j = nlohmann::json::parse(s);
if (!j.is_object())
return;
if (j.contains("file_prefix"))
start_message.file_prefix = j["file_prefix"];
if (j.contains("data_file_count"))
start_message.data_file_count = j["data_file_count"];
if (j.contains("user"))
start_message.user_data = j["user"];
if (j.contains("sample_name"))
start_message.sample_name = j["sample_name"];
if (j.contains("source_name"))
start_message.source_name = j["source_name"];
if (j.contains("source_name_short"))
start_message.source_name_short = j["source_name_short"];
if (j.contains("instrument_name"))
start_message.instrument_name = j["instrument_name"];
if (j.contains("instrument_name_short"))
start_message.instrument_name_short = j["instrument_name_short"];
if (j.contains("total_flux"))
start_message.total_flux = j["total_flux"];
if (j.contains("attenuator_transmission"))
start_message.attenuator_transmission = j["attenuator_transmission"];
if (j.contains("omega_rotation_axis") && j["omega_rotation_axis"].is_array() &&
(j["omega_rotation_axis"].size() == 3)) {
for (int i = 0; i < 3; i++)
start_message.omega.axis[i] = j["omega_rotation_axis"][i];
}
if (j.contains("space_group_number"))
start_message.space_group_number = j["space_group_number"];
} catch (const std::exception &e) {
throw JFJochException(JFJochExceptionCategory::CBORError, "Cannot parse user_data as valid JSON " + std::string(e.what()));
}
}
bool CBORStream2Deserializer::ProcessStartMessageElement(CborValue &value) {
if (cbor_value_at_end(&value))
return false;
else {
auto key = GetCBORString(value);
if (key == "beam_center_x")
start_message.beam_center_x = GetCBORFloat(value);
else if (key == "beam_center_y")
start_message.beam_center_y = GetCBORFloat(value);
else if (key == "detector_distance")
start_message.detector_distance = GetCBORFloat(value);
else if (key == "number_of_images")
start_message.number_of_images = GetCBORUInt(value);
else if (key == "image_size_x")
start_message.image_size_x = GetCBORUInt(value);
else if (key == "image_size_y")
start_message.image_size_y = GetCBORUInt(value);
else if (key == "incident_energy")
start_message.incident_energy = GetCBORFloat(value);
else if (key == "incident_wavelength")
start_message.incident_wavelength = GetCBORFloat(value);
else if (key == "frame_time")
start_message.frame_time = GetCBORFloat(value);
else if (key == "count_time")
start_message.count_time = GetCBORFloat(value);
else if (key == "saturation_value")
start_message.saturation_value = GetCBORInt(value);
else if (key == "error_value")
start_message.error_value = GetCBORInt(value);
else if (key == "pixel_size_x")
start_message.pixel_size_x = GetCBORFloat(value);
else if (key == "pixel_size_y")
start_message.pixel_size_y = GetCBORFloat(value);
else if (key == "sensor_thickness")
start_message.sensor_thickness = GetCBORFloat(value);
else if (key == "sensor_material")
start_message.sensor_material = GetCBORString(value);
else if (key == "detector_description")
start_message.detector_description = GetCBORString(value);
else if (key == "detector_serial_number")
start_message.detector_serial_number = GetCBORString(value);
else if (key == "series_unique_id")
start_message.series_unique_id = GetCBORString(value);
else if (key == "series_id")
start_message.series_id = GetCBORUInt(value);
else if (key == "pixel_mask")
ProcessPixelMaskElement(value);
else if (key == "channels")
ProcessChannels(value);
else if (key == "detector_translation")
ProcessAxis(value, start_message.detector_translation);
else if (key == "goniometer")
ProcessGoniometerMap(value);
else if (key == "pixel_mask_enabled")
start_message.pixel_mask_enabled = GetCBORBool(value);
else if (key == "arm_date")
start_message.arm_date = GetCBORDateTime(value);
else if (key == "user_data")
start_message.user_data = GetCBORString(value);
else if (key == "space_group_number")
start_message.space_group_number = GetCBORUInt(value);
else if (key == "unit_cell")
ProcessUnitCellElement(value);
else if (key == "sample_name")
start_message.sample_name = GetCBORString(value);
else if (key == "source_name")
start_message.source_name = GetCBORString(value);
else if (key == "source_name_short")
start_message.source_name_short = GetCBORString(value);
else if (key == "instrument_name")
start_message.instrument_name = GetCBORString(value);
else if (key == "instrument_name_short")
start_message.instrument_name_short = GetCBORString(value);
else if (key == "file_prefix")
start_message.file_prefix = GetCBORString(value);
else if (key == "max_spot_count")
start_message.max_spot_count = GetCBORUInt(value);
else if (key == "data_file_count")
start_message.data_file_count = GetCBORUInt(value);
else if (key == "pixel_bit_depth")
start_message.pixel_bit_depth = GetCBORUInt(value);
else if (key == "pixel_signed")
start_message.pixel_signed = GetCBORBool(value);
else if (key == "az_int_bin_number")
start_message.az_int_bin_number = GetCBORInt(value);
else if (key == "az_int_bin_to_q")
GetCBORFloatArray(value, start_message.az_int_bin_to_q);
else if (key == "summation")
start_message.summation = GetCBORUInt(value);
else if (key == "storage_cell_number")
start_message.storage_cell_number = GetCBORUInt(value);
else if (key == "storage_cell_delay")
start_message.storage_cell_delay_ns = GetRational(value).first;
else if (key == "total_flux")
start_message.total_flux = GetCBORFloat(value);
else if (key == "attenuator_transmission")
start_message.attenuator_transmission = GetCBORFloat(value);
else if (key == "roi_sum_area")
start_message.roi_summation_area = GetROIRectangle(value);
else if (key == "compression_algorithm") {
auto tmp = GetCBORString(value);
if (tmp == "bslz4")
start_message.compression_algorithm = CompressionAlgorithm::BSHUF_LZ4;
else if (tmp == "bszstd")
start_message.compression_algorithm = CompressionAlgorithm::BSHUF_ZSTD;
else if (tmp == "none")
start_message.compression_algorithm = CompressionAlgorithm::NO_COMPRESSION;
else
throw JFJochException(JFJochExceptionCategory::CBORError, "Unsupported compression");
} else if (key == "compression_block_size")
start_message.compression_block_size = GetCBORUInt(value);
else if (key == "calibration")
ProcessCalibration(value);
else
cbor_value_advance(&value);
return true;
try {
if (key == "beam_center_x")
start_message.beam_center_x = GetCBORFloat(value);
else if (key == "beam_center_y")
start_message.beam_center_y = GetCBORFloat(value);
else if (key == "detector_distance")
start_message.detector_distance = GetCBORFloat(value);
else if (key == "number_of_images")
start_message.number_of_images = GetCBORUInt(value);
else if (key == "countrate_correction_enabled")
start_message.countrate_correction_enabled = GetCBORBool(value);
else if (key == "flatfield_enabled")
start_message.flatfield_enabled = GetCBORBool(value);
else if (key == "image_size_x")
start_message.image_size_x = GetCBORUInt(value);
else if (key == "image_size_y")
start_message.image_size_y = GetCBORUInt(value);
else if (key == "incident_energy")
start_message.incident_energy = GetCBORFloat(value);
else if (key == "incident_wavelength")
start_message.incident_wavelength = GetCBORFloat(value);
else if (key == "frame_time")
start_message.frame_time = GetCBORFloat(value);
else if (key == "count_time")
start_message.count_time = GetCBORFloat(value);
else if (key == "saturation_value")
start_message.saturation_value = GetCBORInt(value);
else if (key == "error_value")
start_message.error_value = GetCBORInt(value);
else if (key == "pixel_size_x")
start_message.pixel_size_x = GetCBORFloat(value);
else if (key == "pixel_size_y")
start_message.pixel_size_y = GetCBORFloat(value);
else if (key == "sensor_thickness")
start_message.sensor_thickness = GetCBORFloat(value);
else if (key == "sensor_material")
start_message.sensor_material = GetCBORString(value);
else if (key == "detector_description")
start_message.detector_description = GetCBORString(value);
else if (key == "detector_serial_number")
start_message.detector_serial_number = GetCBORString(value);
else if (key == "series_unique_id")
start_message.series_unique_id = GetCBORString(value);
else if (key == "series_id")
start_message.series_id = GetCBORUInt(value);
else if (key == "pixel_mask")
ProcessPixelMaskElement(value);
else if (key == "channels")
GetCBORStringArray(value, start_message.channels);
else if (key == "detector_translation")
ProcessAxis(value, start_message.detector_translation);
else if (key == "goniometer")
ProcessGoniometerMap(value);
else if (key == "pixel_mask_enabled")
start_message.pixel_mask_enabled = GetCBORBool(value);
else if (key == "arm_date")
start_message.arm_date = GetCBORDateTime(value);
else if (key == "user_data")
ProcessStartUserData(value);
else if (key == "unit_cell")
ProcessUnitCellElement(value);
else if (key == "max_spot_count")
start_message.max_spot_count = GetCBORUInt(value);
else if (key == "image_dtype") {
auto val = GetCBORString(value);
if (val == "uint8") {
start_message.pixel_signed = false;
start_message.pixel_bit_depth = 8;
} else if (val == "int8") {
start_message.pixel_signed = true;
start_message.pixel_bit_depth = 8;
} else if (val == "uint16") {
start_message.pixel_signed = false;
start_message.pixel_bit_depth = 16;
} else if (val == "int16") {
start_message.pixel_signed = true;
start_message.pixel_bit_depth = 16;
} else if (val == "uint32") {
start_message.pixel_signed = false;
start_message.pixel_bit_depth = 32;
} else if (val == "int32") {
start_message.pixel_signed = true;
start_message.pixel_bit_depth = 32;
}
} else if (key == "az_int_bin_number")
start_message.az_int_bin_number = GetCBORInt(value);
else if (key == "az_int_bin_to_q")
GetCBORFloatArray(value, start_message.az_int_bin_to_q);
else if (key == "summation")
start_message.summation = GetCBORUInt(value);
else if (key == "storage_cell_number")
start_message.storage_cell_number = GetCBORUInt(value);
else if (key == "storage_cell_delay")
start_message.storage_cell_delay_ns = GetRational(value).first;
else if (key == "roi_sum_area")
start_message.roi_summation_area = GetROIRectangle(value);
else if (key == "gain_file_names")
GetCBORStringArray(value, start_message.gain_file_names);
else if (key == "calibration")
ProcessCalibration(value);
else {
if (cbor_value_is_tag(&value))
cbor_value_advance(&value);
cbor_value_advance(&value);
}
return true;
} catch (const JFJochException &e) {
throw JFJochException(JFJochExceptionCategory::CBORError, "Error processing start message, key " + key + ":" + e.what());
}
}
}
@@ -710,33 +765,37 @@ bool CBORStream2Deserializer::ProcessEndMessageElement(CborValue &value) {
return false;
else {
auto key = GetCBORString(value);
if (key == "end_date")
end_message.end_date = GetCBORString(value);
else if (key == "series_unique_id")
end_message.series_unique_id = GetCBORString(value);
else if (key == "series_id")
end_message.series_id = GetCBORUInt(value);
else if (key == "max_image_number")
end_message.max_image_number = GetCBORUInt(value);
else if (key == "images_collected")
end_message.images_collected_count = GetCBORUInt(value);
else if (key == "images_sent_to_write")
end_message.images_sent_to_write_count = GetCBORUInt(value);
else if (key == "max_receiver_delay")
end_message.max_receiver_delay = GetCBORUInt(value);
else if (key == "data_collection_efficiency")
end_message.efficiency = GetCBORFloat(value);
else if (key == "write_master_file")
end_message.write_master_file = GetCBORBool(value);
else if (key == "az_int_result")
ProcessRadIntResultElement(value);
else if (key == "adu_histogram")
ProcessADUHistogramElement(value);
else if (key == "adu_histogram_bin_width")
end_message.adu_histogram_bin_width = GetCBORUInt(value);
else
cbor_value_advance(&value);
return true;
try {
if (key == "end_date")
end_message.end_date = GetCBORString(value);
else if (key == "series_unique_id")
end_message.series_unique_id = GetCBORString(value);
else if (key == "series_id")
end_message.series_id = GetCBORUInt(value);
else if (key == "max_image_number")
end_message.max_image_number = GetCBORUInt(value);
else if (key == "images_collected")
end_message.images_collected_count = GetCBORUInt(value);
else if (key == "images_sent_to_write")
end_message.images_sent_to_write_count = GetCBORUInt(value);
else if (key == "max_receiver_delay")
end_message.max_receiver_delay = GetCBORUInt(value);
else if (key == "data_collection_efficiency")
end_message.efficiency = GetCBORFloat(value);
else if (key == "write_master_file")
end_message.write_master_file = GetCBORBool(value);
else if (key == "az_int_result")
ProcessRadIntResultElement(value);
else if (key == "adu_histogram")
ProcessADUHistogramElement(value);
else if (key == "adu_histogram_bin_width")
end_message.adu_histogram_bin_width = GetCBORUInt(value);
else
cbor_value_advance(&value);
return true;
} catch (const JFJochException &e) {
throw JFJochException(JFJochExceptionCategory::CBORError, "Error processing end message, key " + key + ":" + e.what());
}
}
}
@@ -785,9 +844,7 @@ std::unique_lock<std::mutex> ul(m);
break;
case Type::START:
start_message = StartMessage{
.data_file_count = 1,
.compression_algorithm = CompressionAlgorithm::NO_COMPRESSION,
.compression_block_size = 0
.data_file_count = 1
};
while (ProcessStartMessageElement(map_value));
break;
+2 -1
View File
@@ -30,7 +30,7 @@ private:
void GetCBORSpots(CborValue &value);
void ProcessGoniometerMap(CborValue &value);
GoniometerAxis ProcessGoniometer(CborValue &value);
void ProcessGoniometerOmega(CborValue &value);
void ProcessAxis(CborValue &value, float v[3]);
void ProcessCalibration(CborValue &value);
@@ -40,6 +40,7 @@ private:
void ProcessRadIntResultElement(CborValue &value);
void ProcessADUHistogramElement(CborValue &value);
void ProcessUnitCellElement(CborValue &value);
void ProcessStartUserData(CborValue &value);
bool ProcessImageMessageElement(CborValue &value);
bool ProcessStartMessageElement(CborValue &value);
bool ProcessEndMessageElement(CborValue &value);
+55 -46
View File
@@ -4,6 +4,7 @@
#include "tinycbor/src/cbor.h"
#include "CborErr.h"
#include "CborUtil.h"
#include <nlohmann/json.hpp>
inline void CBOR_ENC(CborEncoder &encoder, const char* key, const char* value) {
cborErr(cbor_encode_text_stringz(&encoder, key));
@@ -47,6 +48,12 @@ inline void CBOR_ENC(CborEncoder &encoder, const char* key, int64_t value) {
cborErr(cbor_encode_int(&encoder, value));
}
template <class T>
inline void CBOR_ENC(CborEncoder &encoder, const char* key, const std::optional<T> &value) {
if (value)
CBOR_ENC(encoder, key, value.value());
}
void CBOR_ENC_COMPRESSED(CborEncoder &encoder,
const void *image, size_t image_size,
CompressionAlgorithm algorithm,
@@ -223,27 +230,23 @@ inline void CBOR_ENC_GONIOMETER(CborEncoder &encoder, const char* key, const Gon
CborEncoder mapEncoder;
cborErr(cbor_encode_text_stringz(&encoder, key));
cborErr(cbor_encoder_create_map(&encoder, &mapEncoder, 3));
cborErr(cbor_encoder_create_map(&encoder, &mapEncoder, 2));
CBOR_ENC(mapEncoder, "increment", g.increment);
CBOR_ENC(mapEncoder, "start", g.start);
CBOR_ENC_AXIS(mapEncoder, "axis", g.axis);
cborErr(cbor_encoder_close_container(&encoder, &mapEncoder));
}
inline void CBOR_ENC_GONIOMETER_MAP(CborEncoder &encoder, const char* key,
const std::map<std::string, GoniometerAxis> &g) {
inline void CBOR_ENC_GONIOMETER_MAP(CborEncoder &encoder, const char* key, const StartMessage &msg) {
CborEncoder mapEncoder;
cborErr(cbor_encode_text_stringz(&encoder, key));
cborErr(cbor_encoder_create_map(&encoder, &mapEncoder, g.size()));
for (const auto& [x, y]: g)
CBOR_ENC_GONIOMETER(mapEncoder, x.c_str(), y);
cborErr(cbor_encoder_create_map(&encoder, &mapEncoder, 1));
CBOR_ENC_GONIOMETER(mapEncoder, "omega", msg.omega);
cborErr(cbor_encoder_close_container(&encoder, &mapEncoder));
}
inline void CBOR_ENC_CHANNELS(CborEncoder &encoder, const char* key, const std::vector<std::string> &v) {
inline void CBOR_ENC(CborEncoder &encoder, const char* key, const std::vector<std::string> &v) {
CborEncoder arrayEncoder;
cborErr(cbor_encode_text_stringz(&encoder, key));
@@ -277,6 +280,28 @@ inline void CBOR_ENC(CborEncoder &encoder, const char* key, const std::vector<Co
cborErr(cbor_encoder_close_container(&encoder, &mapEncoder));
}
inline void CBOR_ENC_START_USER_DATA(CborEncoder& encoder, const char* key,
const StartMessage& message) {
nlohmann::json j;
j["file_prefix"] = message.file_prefix;
j["data_file_count"] = message.data_file_count;
j["source_name"] = message.source_name;
j["source_name_short"] = message.source_name_short;
j["instrument_name"] = message.instrument_name;
j["instrument_name_short"] = message.instrument_name_short;
j["sample_name"] = message.sample_name;
j["user"] = message.user_data;
if (message.attenuator_transmission)
j["attenuator_transmission"] = message.attenuator_transmission.value();
if (message.total_flux)
j["total_flux"] = message.total_flux.value();
j["omega_rotation_axis"] = {message.omega.axis[0], message.omega.axis[1], message.omega.axis[2]};
j["space_group_number"] = message.space_group_number;
auto str = j.dump();
CBOR_ENC(encoder, key, str);
}
CBORStream2Serializer::CBORStream2Serializer(uint8_t *in_buffer, size_t buffer_size) :
buffer(in_buffer), max_buffer_size(buffer_size), curr_size(0) {}
@@ -298,7 +323,8 @@ void CBORStream2Serializer::SerializeSequenceStart(const StartMessage& message)
CBOR_ENC(mapEncoder, "detector_distance", message.detector_distance);
CBOR_ENC(mapEncoder, "beam_center_x", message.beam_center_x);
CBOR_ENC(mapEncoder, "beam_center_y", message.beam_center_y);
CBOR_ENC(mapEncoder, "countrate_correction_enabled", message.countrate_correction_enabled);
CBOR_ENC(mapEncoder, "flatfield_enabled", message.flatfield_enabled);
CBOR_ENC(mapEncoder, "number_of_images", message.number_of_images);
CBOR_ENC(mapEncoder, "image_size_x", message.image_size_x);
CBOR_ENC(mapEncoder, "image_size_y", message.image_size_y);
@@ -323,53 +349,40 @@ void CBORStream2Serializer::SerializeSequenceStart(const StartMessage& message)
CBOR_ENC(mapEncoder, "series_id", message.series_id);
CBOR_ENC_AXIS(mapEncoder, "detector_translation", message.detector_translation);
CBOR_ENC_GONIOMETER_MAP(mapEncoder, "goniometer", message.goniometer);
CBOR_ENC_GONIOMETER_MAP(mapEncoder, "goniometer", message);
CBOR_ENC(mapEncoder, "pixel_mask", message.pixel_mask);
CBOR_ENC_CHANNELS(mapEncoder, "channels", message.channels);
CBOR_ENC(mapEncoder, "file_prefix", message.file_prefix);
CBOR_ENC(mapEncoder, "sample_name", message.sample_name);
CBOR_ENC(mapEncoder, "space_group_number", message.space_group_number);
CBOR_ENC(mapEncoder, "channels", message.channels);
CBOR_ENC(mapEncoder, "max_spot_count", message.max_spot_count);
CBOR_ENC(mapEncoder, "data_file_count", message.data_file_count);
CBOR_ENC(mapEncoder, "storage_cell_number", message.storage_cell_number);
CBOR_ENC_RATIONAL(mapEncoder, "storage_cell_delay", message.storage_cell_delay_ns, 1000*1000*1000UL);
if (message.roi_summation_area)
CBOR_ENC(mapEncoder, "roi_sum_area", message.roi_summation_area.value());
CBOR_ENC(mapEncoder, "pixel_bit_depth", message.pixel_bit_depth);
CBOR_ENC(mapEncoder, "pixel_signed", message.pixel_signed);
switch (message.compression_algorithm) {
case CompressionAlgorithm::BSHUF_LZ4:
CBOR_ENC(mapEncoder, "compression_algorithm", "bslz4");
CBOR_ENC(mapEncoder, "roi_sum_area", message.roi_summation_area);
switch (message.pixel_bit_depth) {
case 8:
CBOR_ENC(mapEncoder, "image_dtype", message.pixel_signed ? "int8" : "uint8");
break;
case CompressionAlgorithm::BSHUF_ZSTD:
case CompressionAlgorithm::BSHUF_ZSTD_RLE:
CBOR_ENC(mapEncoder, "compression_algorithm", "bszstd");
case 16:
CBOR_ENC(mapEncoder, "image_dtype", message.pixel_signed ? "int16" : "uint16");
break;
default:
CBOR_ENC(mapEncoder, "compression_algorithm", "none");
case 32:
CBOR_ENC(mapEncoder, "image_dtype", message.pixel_signed ? "int32" : "uint32");
break;
}
CBOR_ENC(mapEncoder, "compression_block_size", message.compression_block_size);
if (message.unit_cell)
CBOR_ENC_UNIT_CELL(mapEncoder, "unit_cell", message.unit_cell.value());
if (message.attenuator_transmission)
CBOR_ENC(mapEncoder, "attenuator_transmission", message.attenuator_transmission.value());
if (message.total_flux)
CBOR_ENC(mapEncoder, "total_flux", message.total_flux.value());
CBOR_ENC(mapEncoder, "source_name", message.source_name);
CBOR_ENC(mapEncoder, "source_name_short", message.source_name_short);
CBOR_ENC(mapEncoder, "instrument_name", message.instrument_name);
CBOR_ENC(mapEncoder, "instrument_name_short", message.instrument_name_short);
CBOR_ENC(mapEncoder, "az_int_bin_number", message.az_int_bin_number);
CBOR_ENC(mapEncoder, "az_int_bin_to_q", message.az_int_bin_to_q);
CBOR_ENC(mapEncoder, "summation", message.summation);
CBOR_ENC(mapEncoder, "gain_file_names", message.gain_file_names);
if (!message.calibration.empty())
CBOR_ENC(mapEncoder, "calibration", message.calibration);
CBOR_ENC(mapEncoder, "user_data", message.user_data);
CBOR_ENC_START_USER_DATA(mapEncoder, "user_data", message);
cborErr(cbor_encoder_close_container(&encoder, &mapEncoder));
curr_size = cbor_encoder_get_buffer_size(&encoder, buffer);
}
@@ -423,11 +436,11 @@ void CBORStream2Serializer::SerializeImage(const DataMessage& message) {
CBOR_ENC(mapEncoder, "indexing_result", message.indexing_result);
if (!message.indexing_lattice.empty())
CBOR_ENC(mapEncoder, "indexing_lattice", message.indexing_lattice);
CBOR_ENC(mapEncoder, "xfel_bunch_id", message.xfel_bunch_id);
CBOR_ENC(mapEncoder, "xfel_pulse_id", message.xfel_pulse_id);
CBOR_ENC(mapEncoder, "xfel_event_code", message.xfel_event_code);
CBOR_ENC(mapEncoder, "jf_info", (uint64_t) message.jf_info);
CBOR_ENC(mapEncoder, "jf_info", message.jf_info);
CBOR_ENC(mapEncoder, "receiver_aq_dev_delay", message.receiver_aq_dev_delay);
CBOR_ENC(mapEncoder, "storage_cell", (uint64_t) message.storage_cell);
CBOR_ENC(mapEncoder, "storage_cell", message.storage_cell);
CBOR_ENC(mapEncoder, "saturated_pixel_count", message.saturated_pixel_count);
CBOR_ENC(mapEncoder, "error_pixel_count", message.error_pixel_count);
CBOR_ENC(mapEncoder, "strong_pixel_count", message.strong_pixel_count);
@@ -435,10 +448,6 @@ void CBORStream2Serializer::SerializeImage(const DataMessage& message) {
CBOR_ENC(mapEncoder, "bkg_estimate", message.bkg_estimate);
CBOR_ENC(mapEncoder, "adu_histogram", message.adu_histogram);
CBOR_ENC(mapEncoder, "user_data", message.user_data);
CBOR_ENC(mapEncoder, "detector_distance", message.detector_distance);
CBOR_ENC(mapEncoder, "beam_center_x", message.beam_center_x);
CBOR_ENC(mapEncoder, "beam_center_y", message.beam_center_y);
CBOR_ENC(mapEncoder, "incident_energy", message.incident_energy);
if (message.roi_sum)
CBOR_ENC(mapEncoder, "roi_sum", message.roi_sum.value());
+1 -5
View File
@@ -17,11 +17,7 @@ ADD_LIBRARY(ImagePusher STATIC
TestImagePusher.cpp TestImagePusher.h
ZMQStream2PusherGroup.cpp ZMQStream2PusherGroup.h
ZMQStream2PreviewPublisher.cpp ZMQStream2PreviewPublisher.h
ZMQBsreadImagePusher.cpp
ZMQBsreadImagePusher.h
ZMQStream2Pusher.cpp
ZMQStream2Pusher.h)
FIND_PACKAGE(OpenSSL REQUIRED)
TARGET_LINK_LIBRARIES(ImagePusher CBORStream2FrameSerialize JFJochCommon Compression OpenSSL::Crypto)
TARGET_LINK_LIBRARIES(ImagePusher CBORStream2FrameSerialize JFJochCommon Compression)
+18 -24
View File
@@ -61,17 +61,9 @@ struct DataMessage {
std::vector<uint64_t> adu_histogram;
uint64_t xfel_bunch_id;
uint64_t xfel_event_code;
uint32_t jf_info;
int64_t receiver_aq_dev_delay;
uint64_t timestamp;
uint32_t timestamp_base;
uint32_t storage_cell;
uint32_t exptime;
uint32_t exptime_base;
@@ -84,14 +76,15 @@ struct DataMessage {
std::string user_data;
float detector_distance;
float beam_center_x;
float beam_center_y;
float incident_energy;
std::optional<uint64_t> jf_info;
std::optional<uint64_t> receiver_aq_dev_delay;
std::optional<uint64_t> storage_cell;
std::optional<float> resolution_estimation;
std::optional<int64_t> roi_sum;
std::optional<uint64_t> xfel_pulse_id;
std::optional<uint64_t> xfel_event_code;
};
struct GoniometerAxis {
@@ -114,6 +107,8 @@ struct StartMessage {
uint64_t pixel_bit_depth; // user data
bool pixel_signed; // user data
bool countrate_correction_enabled;
float incident_energy;
float incident_wavelength;
@@ -121,23 +116,21 @@ struct StartMessage {
float count_time;
int64_t saturation_value;
int64_t error_value;
std::optional<int64_t> error_value;
float pixel_size_x;
float pixel_size_y;
float sensor_thickness;
std::string sensor_material;
CompressionAlgorithm compression_algorithm; // user data
uint64_t compression_block_size; // user data
std::optional<UnitCell> unit_cell; // user data
uint64_t space_group_number; // user data
uint64_t max_spot_count; // user data
uint64_t storage_cell_number; // user data
std::optional<uint64_t> storage_cell_number; // user data
uint64_t storage_cell_delay_ns;
bool flatfield_enabled;
bool pixel_mask_enabled;
std::string arm_date;
@@ -151,8 +144,9 @@ struct StartMessage {
std::string detector_serial_number;
std::string series_unique_id;
uint64_t series_id;
std::vector<std::string> gain_file_names;
std::map<std::string, GoniometerAxis> goniometer;
GoniometerAxis omega;
float detector_translation[3];
std::string source_name;
@@ -191,14 +185,14 @@ struct StartMessage {
struct EndMessage {
uint64_t max_image_number; // Counting from 1, i.e. 0 = no images collected
uint64_t images_collected_count;
uint64_t images_sent_to_write_count;
uint64_t max_receiver_delay;
float efficiency;
std::optional<uint64_t> images_collected_count;
std::optional<uint64_t> images_sent_to_write_count;
std::optional<uint64_t> max_receiver_delay;
std::optional<float> efficiency;
bool write_master_file;
std::optional<bool> write_master_file;
std::string end_date;
std::optional<std::string> end_date;
std::string series_unique_id;
uint64_t series_id;
+81 -91
View File
@@ -12,98 +12,92 @@ There are minor differences at the moment:
## Start message
| Field name | Type | Description | Present in DECTRIS format |
|-------------------------|---------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|:-------------------------:|
| type | String | value "start" | X |
| magic_number | uint64 | Number used to describe version of the Jungfraujoch data interface - to allow to detect inconsistency between sender and receiver | |
| detector_distance | float | Detector distance \[m\] | |
| detector_translation | float | Detector translation vector \[m\] | X |
| beam_center_x | float | Beam center in X direction \[pixels\] | X |
| beam_center_y | float | Beam center in Y direction \[pixels\] | X |
| number_of_images | uint64 | Number of images in the series | X |
| image_size_x | uint64 | Image width \[pixels\] | X |
| image_size_y | uint64 | Image height \[pixels\] | X |
| incident_energy | float | X-ray energy \[eV\] | X |
| incident_wavelength | float | X-ray wavelength \[Angstrom\] | X |
| frame_time | float | Frame time, if multiple frames per trigger \[s\] | X |
| count_time | float | Exposure time \[s\] | X |
| saturation_value | int64 | Maximum valid sample value | X |
| error_value | int64 | Value used in images to describe pixels that are in error state or missing | |
| pixel_size_x | float | Pixel width \[m\] | X |
| pixel_size_y | float | Pixel height \[m\] | X |
| sensor_thickness | float | Sensor thickness \[m\] | X |
| sensor_material | string | Sensor material | X |
| arm_data | data | Approximate date of arming | X |
| pixel_mask_enabled | bool | Pixel mask applied on images | X |
| detector_description | string | Name of the detector | X |
| series_unique_id | string | Unique text ID of the series | X |
| series_id | uint64 | Unique numeric ID of the series | X |
| goniometer | Map | See [DECTRIS documentation](https://github.com/dectris/documentation/tree/main/stream_v2) | X |
| pixel_mask | Map(string -> Image) | Pixel mask - multiple in case of storage cells | X |
| channels | Array(string) | List of image channels | X |
| file_prefix | string | File prefix | |
| sample_name | string | Name of the sample | |
| space_group_number | uint64 | Space group number | |
| max_spot_count | uint64 | Maximum number of spots identified in spot finding | |
| data_file_count | uint64 | Number of used data files | |
| storage_cell_number | uint64 | Number of storage cells used by JUNGFRAU | |
| pixel_bit_depth | uint64 | Pixel bit depth \[bytes\] | |
| pixel_signed | bool | Pixel described with signed representation | |
| compression_algorithm | string | Compression algorithm (bslz4 \| bszstd \| none) | |
| compression_block_size | uint64 | Compression block size \[pixel representation size\] | |
| unit_cell | Array(6 * float) (optional) | Unit cell of the system: a, b, c \[angstrom\] and alpha, beta, gamma \[degree\] | |
| attenuator_transmission | float (optional) | Attenuator transmission \[\] | |
| total_flux | float (optional) | Total flux \[ph/s\] | |
| source_name | string | Facility name | |
| source_name_short | string | Facility name (short) | |
| instrument_name | string | Instrument name | |
| instrument_name_short | string | Instrument name (short | |
| az_int_bin_number | uint64 | Number of azimuthal integration bins | |
| az_int_bin_to_q | Array(float) | Q value for each azimuthal integration bin \[angstrom^-1\] | |
| summation | uint64 | Factor of frame summation | |
| calibration | Map(string -> Image) (optional) | Pedestal values | |
| user_data | string | Optional user defined text information | |
| Field name | Type | Description | Present in DECTRIS format |
|---------------------------|---------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|:-------------------------:|
| type | String | value "start" | X |
| magic_number | uint64 | Number used to describe version of the Jungfraujoch data interface - to allow to detect inconsistency between sender and receiver | |
| detector_distance | float | Detector distance \[m\] | |
| detector_translation | float | Detector translation vector \[m\] | X |
| beam_center_x | float | Beam center in X direction \[pixels\] | X |
| beam_center_y | float | Beam center in Y direction \[pixels\] | X |
| number_of_images | uint64 | Number of images in the series | X |
| image_size_x | uint64 | Image width \[pixels\] | X |
| image_size_y | uint64 | Image height \[pixels\] | X |
| incident_energy | float | X-ray energy \[eV\] | X |
| incident_wavelength | float | X-ray wavelength \[Angstrom\] | X |
| frame_time | float | Frame time, if multiple frames per trigger \[s\] | X |
| count_time | float | Exposure time \[s\] | X |
| saturation_value | int64 | Maximum valid sample value | X |
| error_value | int64 | Value used in images to describe pixels that are in error state or missing | |
| pixel_size_x | float | Pixel width \[m\] | X |
| pixel_size_y | float | Pixel height \[m\] | X |
| sensor_thickness | float | Sensor thickness \[m\] | X |
| sensor_material | string | Sensor material | X |
| arm_data | data | Approximate date of arming | X |
| pixel_mask_enabled | bool | Pixel mask applied on images | X |
| detector_description | string | Name of the detector | X |
| series_unique_id | string | Unique text ID of the series | X |
| series_id | uint64 | Unique numeric ID of the series | X |
| goniometer | Map | See [DECTRIS documentation](https://github.com/dectris/documentation/tree/main/stream_v2) - only "omega" axis is supported | X |
| pixel_mask | Map(string -> Image) | Pixel mask - multiple in case of storage cells | X |
| channels | Array(string) | List of image channels | X |
| max_spot_count | uint64 | Maximum number of spots identified in spot finding | |
| storage_cell_number | uint64 | Number of storage cells used by JUNGFRAU | |
| image_dtype | string | Pixel bit type (e.g. uint16) | X |
| unit_cell | Array(6 * float) (optional) | Unit cell of the system: a, b, c \[angstrom\] and alpha, beta, gamma \[degree\] | |
| az_int_bin_number | uint64 | Number of azimuthal integration bins | |
| az_int_bin_to_q | Array(float) | Q value for each azimuthal integration bin \[angstrom^-1\] | |
| summation | uint64 | Factor of frame summation | |
| calibration | Map(string -> Image) (optional) | Pedestal values | |
| user_data | string | JSON string that can contain the following fields (among others): | X |
| - source_name | string | Facility name | |
| - source_name_short | string | Facility name (short) | |
| - instrument_name | string | Instrument name | |
| - instrument_name_short | string | Instrument name (short | |
| - attenuator_transmission | float (optional) | Attenuator transmission \[\] | |
| - total_flux | float (optional) | Total flux \[ph/s\] | |
| - data_file_count | uint64 | Number of used data files | |
| - file_prefix | string | File prefix | |
| - sample_name | string | Name of the sample | |
| - omega_rotation_axis | Array(float) | Omega rotation axis (array of size 3) | |
| - space_group_number | uint64 | Space group number | |
See [DECTRIS documentation](https://github.com/dectris/documentation/tree/main/stream_v2) for definition of Image as MultiDimArray with optional compression.
## Image message
| Field name | Type | Description | Present in DECTRIS format |
|----------------------------|-----------------------------|-----------------------------------------------------------------------------------------------------------------------------------|:-------------------------:|
| type | String | value "image" | X |
| magic_number | uint64 | Number used to describe version of the Jungfraujoch data interface - to allow to detect inconsistency between sender and receiver | |
| series_unique_id | string | Unique text ID of the series | X |
| series_id | uint64 | Unique numeric ID of the series | X |
| image_id | uint64 | Number of image within the series | X |
| real_time | Rational | Exposure time | X |
| start_time | Rational | Exposure start time (highly approximate) | X |
| end_time | Rational | Exposure end time (highly approximate) | X |
| spots | Array(object) | Spots: | |
| - x | float | position in x (pixels) | |
| - y | float | position in y (pixels) | |
| - I | float | intensity (photons) | |
| - indexed | bool | indexed solution | |
| az_int_profile | Array(float) | Azimuthal integration results, use az_int_bin_to_q from start message for legend | |
| indexing_result | uint64 | Indexing result: 0 - failed, 1 - success | |
| indexing_lattice | Array(float * 9) (optional) | Indexing result real lattice; present only if indexed | |
| xfel_bunch_id | uint64 | Bunch ID (for SwissFEL) | |
| xfel_event_code | uint64 | Event code (for SwissFEL) | |
| jf_info | uint64 | Detector info field | |
| receiver_aq_dev_delay | uint64 | Receiver internal delay | |
| storage_cell | uint64 | Storage cell number | |
| saturated_pixel_count | uint64 | Saturated pixel count | |
| error_pixel_count | uint64 | Error pixel count | |
| strong_pixel_count | uint64 | Strong pixel count (first stage of spot finding) | |
| data_collection_efficiency | float | Image collection efficiency \[\] | |
| bkg_estimate | float | Mean value for pixels in resolution range from 3.0 to 5.0 A [\photons\] | |
| adu_histogram | Array(uint64) | ADU histogram | |
| user_data | string | Optional user defined text information | |
| detector_distance | float | Detector distance \[m\] (duplicate information from start message, for data processing) | |
| beam_center_x | float | Beam center in X direction \[pixels\] (duplicate information from start message, for data processing) | |
| beam_center_y | float | Beam center in Y direction \[pixels\] (duplicate information from start message, for data processing) | |
| incident_energy | float | X-ray energy \[eV\] (duplicate information from start message, for data processing) | |
| roi_sum | int64 | Sum of ROI rectangle \[photons\] | |
| image | Map(string -> Image) | Image | |
| Field name | Type | Description | Present in DECTRIS format | Optional |
|----------------------------|-----------------------------|-----------------------------------------------------------------------------------------------------------------------------------|:-------------------------:|:--------:|
| type | String | value "image" | X | |
| magic_number | uint64 | Number used to describe version of the Jungfraujoch data interface - to allow to detect inconsistency between sender and receiver | | |
| series_unique_id | string | Unique text ID of the series | X | |
| series_id | uint64 | Unique numeric ID of the series | X | |
| image_id | uint64 | Number of image within the series | X | |
| real_time | Rational | Exposure time | X | |
| start_time | Rational | Exposure start time (highly approximate) | X | |
| end_time | Rational | Exposure end time (highly approximate) | X | |
| spots | Array(object) | Spots: | | |
| - x | float | position in x (pixels) | | |
| - y | float | position in y (pixels) | | |
| - I | float | intensity (photons) | | |
| - indexed | bool | indexed solution | | |
| az_int_profile | Array(float) | Azimuthal integration results, use az_int_bin_to_q from start message for legend | | |
| indexing_result | uint64 | Indexing result: 0 - failed, 1 - success | | |
| indexing_lattice | Array(float * 9) (optional) | Indexing result real lattice; present only if indexed | | |
| xfel_pulse_id | uint64 | Bunch ID (for SwissFEL) | | X |
| xfel_event_code | uint64 | Event code (for SwissFEL) | | X |
| jf_info | uint64 | Detector info field | | |
| receiver_aq_dev_delay | uint64 | Receiver internal delay | | |
| storage_cell | uint64 | Storage cell number | | |
| saturated_pixel_count | uint64 | Saturated pixel count | | |
| error_pixel_count | uint64 | Error pixel count | | |
| strong_pixel_count | uint64 | Strong pixel count (first stage of spot finding) | | |
| data_collection_efficiency | float | Image collection efficiency \[\] | | |
| bkg_estimate | float | Mean value for pixels in resolution range from 3.0 to 5.0 A [\photons\] | | |
| adu_histogram | Array(uint64) | ADU histogram | | |
| user_data | string | Optional user defined text information | | |
| roi_sum | int64 | Sum of ROI rectangle \[photons\] | | X |
| image | Map(string -> Image) | Image | | |
## End message
@@ -147,9 +141,5 @@ Similar to sockets above, though with minor differences:
* No start and end messages are sent
* Communication is fully nonblocking - no exceptions are raised in case of communication issues and `true` is set always returned.
## ZMQBSreadImagePusher
This interface is using BSREAD encoding for SwissFEL. Experimental.
This is fully blocking behavior - with multipart messages it could be detrimental to send only part of the message.
## TestImagePusher
This interface is used for automated tests. It reads incoming images and compares one image with the reference data provided.
-82
View File
@@ -1,82 +0,0 @@
// Copyright (2019-2023) Paul Scherrer Institute
#include "ZMQBsreadImagePusher.h"
#include <nlohmann/json.hpp>
#include <openssl/md5.h>
ZMQBsreadImagePusher::ZMQBsreadImagePusher(const std::string &addr, int32_t send_buffer_high_watermark,
int32_t send_buffer_size) : socket(context, ZMQSocketType::Push) {
if (send_buffer_size > 0)
socket.SendBufferSize(send_buffer_size);
if (send_buffer_high_watermark > 0)
socket.SendWaterMark(send_buffer_high_watermark);
socket.Bind(addr);
}
void ZMQBsreadImagePusher::StartDataCollection(const StartMessage &message) {
// Do nothing
}
bool ZMQBsreadImagePusher::SendImage(const DataMessage &message) {
std::unique_lock<std::mutex> ul(m);
timespec ts{};
clock_gettime(CLOCK_REALTIME, &ts);
auto data_header = DataHeader(message);
auto main_header = MainHeader(message, data_header, ts);
socket.Send(main_header, true, true);
socket.Send(data_header, true, true);
socket.Send(message.image.data, message.image.size, true, true);
socket.Send(&ts, sizeof(ts), true, false);
return true; // Blocking! - it would be unsafe to use non-blocking send with multipart
}
bool ZMQBsreadImagePusher::EndDataCollection(const EndMessage &message) {
return true;
}
std::string ZMQBsreadImagePusher::MainHeader(const DataMessage &message, const std::string &data_header, timespec &ts) {
nlohmann::json j;
j["htype"] = "bsr_m-1.1";
j["pulse_id"] = message.xfel_bunch_id;
j["hash"] = MD5Hash(data_header);
j["global_timestamp"]["sec"] = ts.tv_sec;
j["global_timestamp"]["ns"] = ts.tv_nsec;
return j.dump();
}
std::string ZMQBsreadImagePusher::MD5Hash(const std::string &s) {
std::string ret;
uint8_t hash[MD5_DIGEST_LENGTH];
MD5(reinterpret_cast<const unsigned char *>(s.data()), s.length(), hash);
for (unsigned char i : hash) {
char buf[4];
sprintf(buf, "%02x", i);
ret.append(buf);
}
return ret;
}
std::string ZMQBsreadImagePusher::DataHeader(const DataMessage &message) {
nlohmann::json data;
data["htype"] = "bsr_d-1.1";
nlohmann::json image_channel;
image_channel["name"] = "JFJOCH:IMAGE";
if (message.image.pixel_depth_bytes == 2)
image_channel["type"] = (message.image.pixel_is_signed ? "int16" : "uint16");
else
image_channel["type"] = (message.image.pixel_is_signed ? "int32" : "uint32");
image_channel["shape"] = {message.image.ypixel, message.image.xpixel};
image_channel["encoding"] = "little";
if (message.image.algorithm == CompressionAlgorithm::BSHUF_LZ4)
image_channel["compression"] = "bitshuffle_lz4";
else if (message.image.algorithm == CompressionAlgorithm::NO_COMPRESSION)
image_channel["compression"] = "none";
else
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Compression not allowed for BSRead data");
image_channel["modulo"] = 1;
image_channel["offset"] = 0;
data["channels"].push_back(image_channel);
return data.dump();
}
-24
View File
@@ -1,24 +0,0 @@
// Copyright (2019-2023) Paul Scherrer Institute
#ifndef JUNGFRAUJOCH_ZMQBSREADIMAGEPUSHER_H
#define JUNGFRAUJOCH_ZMQBSREADIMAGEPUSHER_H
#include "ImagePusher.h"
#include "../common/ZMQWrappers.h"
class ZMQBsreadImagePusher : public ImagePusher {
std::mutex m;
ZMQContext context;
ZMQSocket socket;
static std::string MainHeader(const DataMessage &message, const std::string &data_header, timespec &ts);
static std::string MD5Hash(const std::string& s);
static std::string DataHeader(const DataMessage &message);
public:
ZMQBsreadImagePusher(const std::string& addr, int32_t send_buffer_high_watermark = -1, int32_t send_buffer_size = -1);
void StartDataCollection(const StartMessage &message) override;
bool SendImage(const DataMessage &message) override;
bool EndDataCollection(const EndMessage &message) override;
};
#endif //JUNGFRAUJOCH_ZMQBSREADIMAGEPUSHER_H

Some files were not shown because too many files have changed in this diff Show More