modified memory model

This commit is contained in:
2026-05-29 15:55:09 +02:00
parent 008c09cf04
commit 8f18eaca92
13 changed files with 408 additions and 73 deletions
+11
View File
@@ -78,6 +78,17 @@ constexpr RegisterField ModuleIndex{
"""
postpend = r"""
constexpr RegisterField ModuleRow{
Frame_HDR_ModCoord_LSB_Reg, 0, 0xffff};
constexpr RegisterField ModuleCol{
Frame_HDR_ModCoord_LSB_Reg, 16, 0xffff};
constexpr RegisterField ModuleCoordz{
Frame_HDR_ModCoord_MSB_Reg, 0, 0xffff};
constexpr RegisterField ModuleIndex{
Frame_HDR_ModCoord_MSB_Reg, 16, 0xffff};
} // namespace Reg
} // namespace sls
// clang-format on
@@ -53,9 +53,15 @@ class BaseMatterhornServer
ReturnCode get_receiver_parameters(ServerInterface &socket) const;
ReturnCode get_num_frames(ServerInterface &socket) const;
ReturnCode set_module_position(ServerInterface &socket);
uint64_t get_frames() const;
uint64_t getNumFrames() const;
void setNumFrames(const uint64_t num_frames);
uint32_t getNumTriggers() const;
void setNumTriggers(const uint32_t num_triggers);
/**
* @brief call function corresponding to the function ID received from the
@@ -71,13 +77,18 @@ class BaseMatterhornServer
std::is_same_v<DerivedServer, VirtualMatterhornServer>,
VirtualMemoryModel, HardwareMemoryModel>;
// TODO: for now in MatterhornServer and not generic Server but can be
// templated on different IPCore types for each detector
BusCommunication<IPCore, MemoryModel> busCommunication{};
// TODO: probably virtaul server specific details, can be moved to derived
// class
/// @brief initial setup of detector
void setupDetector();
private:
static std::string getMatterhornServerVersion();
int64_t getNumFrames() const;
static constexpr uint8_t numUDPInterfaces =
1; // only one udp per module for now
};
@@ -95,6 +106,14 @@ BaseMatterhornServer<DerivedServer>::processFunction(const detFuncs function_id,
}
}
template <typename DerivedServer>
void BaseMatterhornServer<DerivedServer>::setupDetector() {
// TODO: extend
setNumFrames(1); // maybe have a file with constexpr default values
setNumTriggers(1);
}
template <typename DerivedServer>
ReturnCode BaseMatterhornServer<DerivedServer>::get_num_udp_interfaces(
ServerInterface &socket) const {
@@ -154,9 +173,11 @@ ReturnCode BaseMatterhornServer<DerivedServer>::get_receiver_parameters(
rx_params.udp_dstmac = this->udpDetails[0].dstmac;
rx_params.frames = get_frames();
rx_params.frames = getNumFrames();
// rx_params.triggers = 0;
rx_params.triggers = getNumTriggers();
// TODO: extend
// rx_params.expTimeNs = 0;
@@ -172,17 +193,125 @@ ReturnCode BaseMatterhornServer<DerivedServer>::get_receiver_parameters(
}
template <typename DerivedServer>
ReturnCode BaseMatterhornServer<DerivedServer>::get_num_frames(
ServerInterface &socket) const {
uint64_t BaseMatterhornServer<DerivedServer>::getNumFrames() const {
uint64_t num_frames = get_frames();
return static_cast<ReturnCode>(socket.sendResult(num_frames));
try {
uint32_t num_frames =
busCommunication.readRegister(Reg::MH_SM_Frames_Reg);
return static_cast<uint64_t>(num_frames);
} catch (const std::exception &e) {
LOG(logERROR) << "Failed to read number of frames from register: "
<< e.what();
throw;
}
}
template <typename DerivedServer>
uint64_t BaseMatterhornServer<DerivedServer>::get_frames() const {
return static_cast<uint64_t>(
busCommunication.readRegister(Reg::MH_SM_Frames_Reg));
void BaseMatterhornServer<DerivedServer>::setNumFrames(
const uint64_t num_frames) {
try {
busCommunication.writeRegister(Reg::MH_SM_Frames_Reg,
static_cast<uint32_t>(num_frames));
} catch (const std::exception &e) {
LOG(logERROR) << "Failed to set number of frames: " << e.what();
throw;
}
// TODO: maybe always check that the value is correctly set by reading back
// the register and comparing
}
template <typename DerivedServer>
void BaseMatterhornServer<DerivedServer>::setNumTriggers(
const uint32_t num_triggers) {
try {
busCommunication.writeRegister(Reg::MH_SM_Triggers_Reg, num_triggers);
} catch (const std::exception &e) {
LOG(logERROR) << "Failed to set number of triggers: " << e.what();
throw;
}
}
template <typename DerivedServer>
uint32_t BaseMatterhornServer<DerivedServer>::getNumTriggers() const {
try {
uint32_t num_triggers =
busCommunication.readRegister(Reg::MH_SM_Triggers_Reg);
return num_triggers;
} catch (const std::exception &e) {
LOG(logERROR) << "Failed to read number of triggers from register: "
<< e.what();
throw;
}
}
template <typename DerivedServer>
ReturnCode BaseMatterhornServer<DerivedServer>::set_module_position(
ServerInterface &socket) {
std::array<int, 2> position_info{}; // [num_modules_in_y, module_index]
try {
int ret = socket.Receive(position_info.data(),
position_info.size() * sizeof(int));
} catch (const SocketError &e) {
LOG(logERROR)
<< "Failed to receive num modules in y dimension and module index: "
<< e.what();
return ReturnCode::FAIL;
}
const size_t module_row = position_info[1] % position_info[0];
const size_t module_col = position_info[1] / position_info[0];
// write to register
uint32_t register_value_LSB{};
uint32_t register_value_MSB{};
try {
register_value_LSB =
busCommunication.readRegister(Reg::Frame_HDR_ModCoord_LSB_Reg);
register_value_MSB =
busCommunication.readRegister(Reg::Frame_HDR_ModCoord_MSB_Reg);
} catch (const std::exception &e) {
LOG(logERROR) << "Failed to read module position register: "
<< e.what();
return ReturnCode::FAIL;
}
setRegisterField(register_value_LSB, Reg::ModuleRow, module_row);
setRegisterField(register_value_LSB, Reg::ModuleCol, module_col);
setRegisterField(register_value_MSB, Reg::ModuleCoordz, 0);
setRegisterField(register_value_MSB, Reg::ModuleIndex, position_info[1]);
try {
busCommunication.writeRegister(Reg::Frame_HDR_ModCoord_LSB_Reg,
register_value_LSB);
busCommunication.writeRegister(Reg::Frame_HDR_ModCoord_MSB_Reg,
register_value_MSB);
} catch (const std::exception &e) {
LOG(logERROR) << "Failed to write module position register: "
<< e.what();
return ReturnCode::FAIL;
}
// configure mac address based on module position
if (this->udpDetails[0].srcmac ==
0) { // only configure if source mac address is not set already
this->udpDetails[0].srcmac = generaterandomMacAddress();
uint64_t newSrcMac = (this->udpDetails[0].srcmac & 0xffffffffffff0000) |
(module_row << 16) | module_col;
try {
this->updateSrcMacAddress(newSrcMac);
} catch (const std::invalid_argument &e) {
LOG(logERROR) << "Failed to update source MAC address: "
<< e.what();
return ReturnCode::FAIL;
}
}
return static_cast<ReturnCode>(socket.Send(ReturnCode::OK));
}
} // namespace sls
@@ -1,3 +1,5 @@
// clang-format off
#pragma once
#include "RegisterHelperStructs.hpp"
@@ -20,6 +22,7 @@ constexpr size_t IPCORE_REGISTER_BLOCK_SIZE =
// clang-format off
namespace Reg {
// Register definitions
constexpr Register CTRL_Reg{IPCore::UNKNOWN, 0x0};
@@ -27,7 +30,7 @@ constexpr Register Status_Reg{IPCore::UNKNOWN, 0x4};
constexpr Register FPGAVersionReg{IPCore::UNKNOWN, 0x8};
constexpr Register FPGA_GIT_HEAD_Reg{IPCore::UNKNOWN, 0xc};
constexpr Register FPGA_GIT_HEADReg{IPCore::UNKNOWN, 0xc};
constexpr Register FixedPatternReg{IPCore::UNKNOWN, 0x10};
@@ -47,6 +50,8 @@ constexpr Register MH_SM_StoreLength_Reg{IPCore::MH_RO_SM_AXI, 0x10};
constexpr Register MH_SM_ResetMHLength_Reg{IPCore::MH_RO_SM_AXI, 0x14};
constexpr Register MH_SM_Triggers_Reg{IPCore::MH_RO_SM_AXI, 0x18};
constexpr Register Frame_HDR_Set_Reg{IPCore::FHDR_AXI, 0x0};
constexpr Register Frame_HDR_FrameNumLSB_Reg{IPCore::FHDR_AXI, 0x4};
@@ -121,7 +126,7 @@ constexpr RegisterField FPGADetType{
FPGAVersionReg, 24, 0xff};
constexpr RegisterField FPGA_GIT_HEAD{
FPGA_GIT_HEAD_Reg, 0, 0xffffffff};
FPGA_GIT_HEADReg, 0, 0xffffffff};
constexpr RegisterField FixedPattern{
FixedPatternReg, 0, 0xffffffff};
@@ -141,6 +146,24 @@ constexpr RegisterField Start_Acquistion{
constexpr RegisterField Stop_Acquistion{
MH_SM_Ctrl_Reg, 1, 0x1};
constexpr RegisterField External_Counter_Enable{
MH_SM_Ctrl_Reg, 2, 0x1};
constexpr RegisterField Parallel_RO{
MH_SM_Ctrl_Reg, 3, 0x1};
constexpr RegisterField Trigger_Mode{
MH_SM_Ctrl_Reg, 4, 0x3};
constexpr RegisterField HW_Trigger_Polarity{
MH_SM_Ctrl_Reg, 6, 0x1};
constexpr RegisterField SW_Trigger{
MH_SM_Ctrl_Reg, 7, 0x1};
constexpr RegisterField Reset_Readout_SM{
MH_SM_Ctrl_Reg, 8, 0x1};
constexpr RegisterField MH_Readout_Exposure_Time{
MH_SM_Exposure_Reg, 0, 0xffffffff};
@@ -156,6 +179,9 @@ constexpr RegisterField MH_SM_StoreLength{
constexpr RegisterField MH_SM_ResetMHLength{
MH_SM_ResetMHLength_Reg, 0, 0xffffffff};
constexpr RegisterField MH_SM_Triggers{
MH_SM_Triggers_Reg, 0, 0xffffffff};
constexpr RegisterField Frame_Hdr_Set_Framenumber{
Frame_HDR_Set_Reg, 0, 0x1};
@@ -240,7 +266,18 @@ constexpr RegisterField Coordy{
constexpr RegisterField Coordz{
PktCoordReg2, 0, 0xffff};
} // namespace Reg
constexpr RegisterField ModuleRow{
Frame_HDR_ModCoord_LSB_Reg, 0, 0xffff};
constexpr RegisterField ModuleCol{
Frame_HDR_ModCoord_LSB_Reg, 16, 0xffff};
constexpr RegisterField ModuleCoordz{
Frame_HDR_ModCoord_MSB_Reg, 0, 0xffff};
constexpr RegisterField ModuleIndex{
Frame_HDR_ModCoord_MSB_Reg, 16, 0xffff};
} // namespace Reg
} // namespace sls
// clang-format on
@@ -13,40 +13,30 @@ namespace sls {
template <typename MemoryModel>
struct IpCoreRegisterBlock<IPCore, MemoryModel> {
std::map<IPCore, MemoryModel> &operator()() {
memoryblocks_.try_emplace(
IPCore::MH_RO_SM_AXI,
MemoryModel{static_cast<uint32_t>(IPCore::MH_RO_SM_AXI),
IPCORE_REGISTER_BLOCK_SIZE});
memoryblocks_.try_emplace(
IPCore::FHDR_AXI,
MemoryModel{static_cast<uint32_t>(IPCore::FHDR_AXI),
IPCORE_REGISTER_BLOCK_SIZE});
memoryblocks_.try_emplace(
IPCore::AURORA_STATUS,
MemoryModel{static_cast<uint32_t>(IPCore::AURORA_STATUS),
IPCORE_REGISTER_BLOCK_SIZE});
memoryblocks_.try_emplace(
IPCore::AURORA_STATUS2,
MemoryModel{static_cast<uint32_t>(IPCore::AURORA_STATUS2),
IPCORE_REGISTER_BLOCK_SIZE});
memoryblocks_.try_emplace(
IPCore::PACKETIZERREG,
MemoryModel{static_cast<uint32_t>(IPCore::PACKETIZERREG),
IPCORE_REGISTER_BLOCK_SIZE});
memoryblocks_.try_emplace(
IPCore::UNKNOWN, MemoryModel{static_cast<uint32_t>(IPCore::UNKNOWN),
IPCORE_REGISTER_BLOCK_SIZE});
return memoryblocks_;
}
std::map<IPCore, MemoryModel> &operator()() { return memoryblocks_; }
const std::map<IPCore, MemoryModel> &operator()() const {
return memoryblocks_;
}
private:
std::map<IPCore, MemoryModel> memoryblocks_;
std::map<IPCore, MemoryModel> memoryblocks_{
{IPCore::MH_RO_SM_AXI,
MemoryModel{static_cast<uint32_t>(IPCore::MH_RO_SM_AXI),
IPCORE_REGISTER_BLOCK_SIZE}},
{IPCore::FHDR_AXI, MemoryModel{static_cast<uint32_t>(IPCore::FHDR_AXI),
IPCORE_REGISTER_BLOCK_SIZE}},
{IPCore::AURORA_STATUS,
MemoryModel{static_cast<uint32_t>(IPCore::AURORA_STATUS),
IPCORE_REGISTER_BLOCK_SIZE}},
{IPCore::AURORA_STATUS2,
MemoryModel{static_cast<uint32_t>(IPCore::AURORA_STATUS2),
IPCORE_REGISTER_BLOCK_SIZE}},
{IPCore::PACKETIZERREG,
MemoryModel{static_cast<uint32_t>(IPCore::PACKETIZERREG),
IPCORE_REGISTER_BLOCK_SIZE}},
{IPCore::UNKNOWN, MemoryModel{static_cast<uint32_t>(IPCore::UNKNOWN),
IPCORE_REGISTER_BLOCK_SIZE}}};
};
} // namespace sls
@@ -4,14 +4,15 @@ namespace sls {
MatterhornServer::MatterhornServer(uint16_t port)
: BaseMatterhornServer<MatterhornServer>(port) {
// map the IP core base addresses to memory
busCommunication.mapToMemory(); // TODO: should this happen in constructor?
// should maybe be part of the constructor?
tcpInterface->startTCPServer();
// need a function to setup detector - e.g. set all registers etc.
// TODO: no init_server function for now is it neccessary to set the init
// flag
this->setupDetector();
}
ReturnCode MatterhornServer::initial_checks(ServerInterface &socket) {
@@ -14,7 +14,9 @@ VirtualMatterhornServer::VirtualMatterhornServer(uint16_t port)
// should maybe be part of the constructor?
tcpInterface->startTCPServer();
// need a function to setup detector - e.g. set all registers etc.
// TODO: no init_server function for now is it neccessary to set the init
// flag
this->setupDetector();
}
ReturnCode VirtualMatterhornServer::initial_checks(ServerInterface &socket) {
@@ -9,8 +9,8 @@
#include <sys/mman.h>
#include <vector>
// TODO: maybe should be templated on address type (e.g. uint32_t or uint64_t)
// for more flexibility?
// TODO: maybe should be templated on address type (e.g. uint32_t register or
// uint64_t register) for more flexibility?
namespace sls {
@@ -38,14 +38,14 @@ class BusCommunication {
void mapToMemory();
uint32_t readRegister(const Register &register_) const;
void writeRegister(const Register &register_, const uint32_t data) const;
void writeRegister(const Register &register_, const uint32_t data);
private:
/// @brief stores register blocks for each IP core
IpCoreRegisterBlock<IPCoreEnumType, MemoryModel> ipcoreregisterblocks;
void bus_w(const uint32_t offset, IPCoreEnumType baseadress,
const uint32_t data) const;
const uint32_t data);
uint32_t bus_r(const uint32_t offset, IPCoreEnumType baseadress) const;
};
@@ -66,7 +66,7 @@ uint32_t BusCommunication<IPCoreEnumType, MemoryModel>::readRegister(
template <typename IPCoreEnumType, typename MemoryModel>
void BusCommunication<IPCoreEnumType, MemoryModel>::writeRegister(
const Register &register_, const uint32_t data) const {
const Register &register_, const uint32_t data) {
bus_w(register_.offset_in_bytes, register_.ip_core, data);
}
@@ -81,7 +81,7 @@ uint32_t BusCommunication<IPCoreEnumType, MemoryModel>::bus_r(
template <typename IPCoreEnumType, typename MemoryModel>
void BusCommunication<IPCoreEnumType, MemoryModel>::bus_w(
const uint32_t offset, const IPCoreEnumType baseadress,
const uint32_t data) const {
const uint32_t data) {
auto ptr1 = ipcoreregisterblocks().at(baseadress).getMappedMemoryPtr() +
offset / (sizeof(uint32_t));
*ptr1 = data;
@@ -26,6 +26,19 @@ struct UDPInfo {
};
using ReturnCode = slsDetectorDefs::ReturnCode;
/// @brief generates a random locally administered unicast MAC address for the
/// source UDP
/// @return generated MAC address
inline uint64_t generaterandomMacAddress() {
uint64_t mac =
0xAA0000000000; // locally administered unicast address (0xA: 0b1010) //
// TODO maybe 0x02000000000 better?
for (int i = 2; i < 5; ++i) {
mac |= (static_cast<uint64_t>(rand() % 256) << (i * 8));
}
return mac;
}
/// @brief Shared memory structure for stop server to store run status
struct acquisitionStatus {
@@ -65,12 +78,17 @@ template <typename DerivedDetectorServer> class DetectorServer {
udpDetails{}; // TODO: for now only one receiver per module
/// @brief TODO what is this?
bool updateMode{true};
bool updateMode{
false}; // what should the default be - can update module size etc.
/// @brief shared mempory with aquisition status
mutable SharedMemory<acquisitionStatus> shm{
0, 0}; // TODO: is mutable really neccessary?
/// @brief sets source UDP MAC address in udpDetails and updates udp header
/// @param srcmac
void updateSrcMacAddress(const uint64_t srcmac);
private:
/// @brief creates and maps shared memory
void createSharedMemory();
@@ -102,6 +120,14 @@ template <typename DerivedDetectorServer> class DetectorServer {
ReturnCode set_destination_udp_port(ServerInterface &socket);
ReturnCode get_destination_udp_port(ServerInterface &socket) const;
ReturnCode get_num_frames(ServerInterface &socket) const;
ReturnCode set_num_frames(ServerInterface &socket);
ReturnCode get_num_triggers(ServerInterface &socket) const;
ReturnCode set_num_triggers(ServerInterface &socket);
};
template <typename DerivedDetectorServer>
@@ -162,9 +188,20 @@ ReturnCode DetectorServer<DerivedDetectorServer>::processFunction(
case detFuncs::F_GET_RUN_STATUS:
return static_cast<DerivedDetectorServer *>(this)->get_run_status(
socket);
case detFuncs::F_GET_NUM_FRAMES:
return get_num_frames(socket);
case detFuncs::F_SET_NUM_FRAMES:
return set_num_frames(socket);
case detFuncs::F_GET_NUM_TRIGGERS:
return get_num_triggers(socket);
case detFuncs::F_SET_NUM_TRIGGERS:
return set_num_triggers(socket);
case detFuncs::F_GET_RECEIVER_PARAMETERS:
return static_cast<DerivedDetectorServer *>(this)
->get_receiver_parameters(socket);
case detFuncs::F_SET_POSITION:
return static_cast<DerivedDetectorServer *>(this)->set_module_position(
socket);
default:
LOG(logDEBUG) << "Checking specific server functions for function ID: "
<< function_id;
@@ -189,6 +226,30 @@ void DetectorServer<DerivedDetectorServer>::createSharedMemory() {
}
}
template <typename DerivedDetectorServer>
void DetectorServer<DerivedDetectorServer>::updateSrcMacAddress(
const uint64_t srcmac) {
LOG(logINFO) << "Updating source MAC address to: "
<< fmt::format("{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
(srcmac >> 40) & 0xff, (srcmac >> 32) & 0xff,
(srcmac >> 24) & 0xff, (srcmac >> 16) & 0xff,
(srcmac >> 8) & 0xff, srcmac & 0xff);
if ((srcmac & 0x020000000000) == 0) {
LOG(logERROR) << "Invalid source MAC address: unicast bit or local "
"administration bit is not set";
throw std::invalid_argument("Invalid source MAC address: unicast bit "
"or local administration bit is not set");
}
udpDetails[0].srcmac = srcmac;
// TODO: update UDP header with new source MAC address
// TODO: do i need to keep track of the configured member ?
}
template <typename DerivedDetectorServer>
ReturnCode DetectorServer<DerivedDetectorServer>::get_update_mode(
ServerInterface &socket) const {
@@ -210,8 +271,13 @@ ReturnCode DetectorServer<DerivedDetectorServer>::set_source_udp_mac(
return ReturnCode::FAIL;
}
udpDetails[0].srcmac = newsrcudpMac;
// TODO: configuremac, check unicast address
try {
updateSrcMacAddress(newsrcudpMac);
} catch (const std::invalid_argument &e) {
LOG(logERROR) << "Failed to update source MAC address: " << e.what();
return ReturnCode::FAIL;
}
return static_cast<ReturnCode>(socket.Send(ReturnCode::OK));
}
@@ -315,4 +381,71 @@ ReturnCode DetectorServer<DerivedDetectorServer>::get_destination_udp_port(
return static_cast<ReturnCode>(socket.sendResult(udpDetails[0].dstport));
};
template <typename DerivedDetectorServer>
ReturnCode DetectorServer<DerivedDetectorServer>::get_num_frames(
ServerInterface &socket) const {
uint64_t num_frames{};
try {
num_frames =
static_cast<const DerivedDetectorServer *>(this)->getNumFrames();
} catch (const std::exception &e) {
LOG(logERROR) << "Failed to get number of frames: " << e.what();
return ReturnCode::FAIL;
}
return static_cast<ReturnCode>(socket.sendResult(num_frames));
}
template <typename DerivedDetectorServer>
ReturnCode
DetectorServer<DerivedDetectorServer>::set_num_frames(ServerInterface &socket) {
int64_t num_frames{};
try {
int ret = socket.Receive(num_frames);
} catch (const SocketError &e) {
LOG(logERROR) << "Failed to receive number of frames: " << e.what();
return ReturnCode::FAIL;
}
try {
static_cast<DerivedDetectorServer *>(this)->setNumFrames(num_frames);
} catch (const std::exception &e) {
LOG(logERROR) << "Failed to set number of frames: " << e.what();
return ReturnCode::FAIL;
}
return static_cast<ReturnCode>(socket.Send(ReturnCode::OK));
}
template <typename DerivedDetectorServer>
ReturnCode DetectorServer<DerivedDetectorServer>::get_num_triggers(
ServerInterface &socket) const {
uint32_t num_triggers{};
try {
num_triggers =
static_cast<const DerivedDetectorServer *>(this)->getNumTriggers();
} catch (const std::exception &e) {
LOG(logERROR) << "Failed to get number of triggers: " << e.what();
return ReturnCode::FAIL;
}
return static_cast<ReturnCode>(socket.sendResult(num_triggers));
}
template <typename DerivedDetectorServer>
ReturnCode DetectorServer<DerivedDetectorServer>::set_num_triggers(
ServerInterface &socket) {
uint32_t num_triggers{};
try {
int ret = socket.Receive(num_triggers);
} catch (const SocketError &e) {
LOG(logERROR) << "Failed to receive number of triggers: " << e.what();
return ReturnCode::FAIL;
}
try {
static_cast<DerivedDetectorServer *>(this)->setNumTriggers(
num_triggers);
} catch (const std::exception &e) {
LOG(logERROR) << "Failed to set number of triggers: " << e.what();
return ReturnCode::FAIL;
}
return static_cast<ReturnCode>(socket.Send(ReturnCode::OK));
}
} // namespace sls
@@ -1,6 +1,6 @@
#include "fmt/format.h"
#include <cstdint>
#include <memory>
#include <vector>
/// @brief class to handle memory mapping and access for hardware IP cores
class HardwareMemoryModel {
@@ -38,19 +38,14 @@ class VirtualMemoryModel {
~VirtualMemoryModel() = default;
VirtualMemoryModel(const VirtualMemoryModel &) = delete;
VirtualMemoryModel &operator=(const VirtualMemoryModel &) = delete;
VirtualMemoryModel(VirtualMemoryModel &&) noexcept = default;
VirtualMemoryModel &
operator=(VirtualMemoryModel &&) = delete; // const members
void mapToMemory();
uint32_t *getMappedMemoryPtr() const;
uint32_t *getMappedMemoryPtr();
const uint32_t *getMappedMemoryPtr() const;
private:
std::unique_ptr<uint32_t[]> mapped_memory_ptr;
std::vector<uint32_t> mapped_memory{};
/// @brief offset of the IP core base address in the memory space, used for
/// mapping
@@ -6,6 +6,7 @@ namespace sls {
enum class IPCore : uint32_t; // forward declaration of IPCore enum class
/// @brief struct representing 32 bit register
struct Register {
/// @brief IP core address space
const IPCore ip_core{}; // TODO replace by enum type
@@ -27,4 +28,27 @@ struct RegisterField {
const uint32_t bitmask{};
};
// TODO: maybe static member function of RegisterField?
template <typename T>
void setRegisterField(uint32_t &registervalue, const RegisterField &reg_field,
T field_value) {
// Clear the bits corresponding to the field
registervalue &= ~(reg_field.bitmask << reg_field.bit_position);
// Set the new value for the field
registervalue |= (static_cast<uint32_t>(field_value) & reg_field.bitmask)
<< reg_field.bit_position;
}
template <typename T>
T getRegisterField(const uint32_t &registervalue,
const RegisterField &reg_field) {
// Extract the bits corresponding to the field and shift them to get the
// value
auto field_value =
(registervalue >> reg_field.bit_position) & reg_field.bitmask;
return static_cast<T>(field_value);
}
} // namespace sls
@@ -59,10 +59,15 @@ VirtualMemoryModel::VirtualMemoryModel(const uint32_t IPcore_base_address,
void VirtualMemoryModel::mapToMemory() {
mapped_memory_ptr =
std::make_unique<uint32_t[]>(size_memory_space / sizeof(uint32_t));
mapped_memory.resize(
size_memory_space /
sizeof(uint32_t)); // TODO: should it be zero initialized?
}
uint32_t *VirtualMemoryModel::getMappedMemoryPtr() const {
return mapped_memory_ptr.get();
uint32_t *VirtualMemoryModel::getMappedMemoryPtr() {
return mapped_memory.data();
}
const uint32_t *VirtualMemoryModel::getMappedMemoryPtr() const {
return mapped_memory.data();
}
+8 -3
View File
@@ -474,14 +474,15 @@ class MatterhornData : public GeneralData {
MatterhornData() {
detType = slsDetectorDefs::MATTERHORN;
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
framesPerFile = 10000; // TODO: dummy value
fifoDepth = 50000; // TODO: dummy value
framesPerFile = MATTERHORN_MAX_FRAMES_PER_FILE; // TODO: dummy value
fifoDepth = 50000; // TODO: dummy value
standardheader = true;
// udpSocketBufferSize = 0; // TODO: dummy value
dynamicRange = 16; // default
tengigaEnable = true; // TODO: not sure
tengigaEnable = true; // TODO: not sure should also be 100g
SetCounterMask(0xf); // default all 4 counters enabled
UpdateImageSize();
calculatefifoDepth();
};
void SetDynamicRange(int dr) {
@@ -500,6 +501,8 @@ class MatterhornData : public GeneralData {
UpdateImageSize();
};
void calculatefifoDepth() { fifoDepth = max_fifo_depth / imageSize; }
private:
void UpdateImageSize() {
nPixelsX = (nChannelsX * ncounters);
@@ -528,6 +531,8 @@ class MatterhornData : public GeneralData {
int ncounters{0};
int nChannelsX{1024};
int nChannelsY{512};
constexpr static int max_fifo_depth = 100000; // TODO: dummy value for now
};
class Gotthard2Data : public GeneralData {
+3
View File
@@ -31,6 +31,9 @@ namespace sls {
#define XILINX_CTB_MAX_FRAMES_PER_FILE 20000
#define MYTHEN3_MAX_FRAMES_PER_FILE 10000
#define GOTTHARD2_MAX_FRAMES_PER_FILE 20000
#define MATTERHORN_MAX_FRAMES_PER_FILE \
20000 // dummy value for now - maybe even specialized receiver for
// matterhorn?
#define STATISTIC_FRAMENUMBER_INFINITE (20000)