From 5367df5f20e47c26610d0e2fa552cd7f83a80471 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Thu, 30 Oct 2025 17:17:21 +0100 Subject: [PATCH] moved everythign to bit_utils class --- slsDetectorSoftware/generator/Caller.in.h | 8 +- slsDetectorSoftware/include/sls/Detector.h | 1 + slsDetectorSoftware/src/Caller.h | 6 +- slsDetectorSoftware/src/CallerSpecial.cpp | 134 +++++++++--------- slsSupportLib/include/sls/ToString.h | 3 - slsSupportLib/include/sls/bit_utils.h | 72 ++++++++++ slsSupportLib/include/sls/sls_detector_defs.h | 30 ---- slsSupportLib/include/sls/string_utils.h | 2 +- slsSupportLib/src/ToString.cpp | 11 -- slsSupportLib/src/bit_utils.cpp | 48 +++++++ slsSupportLib/src/string_utils.cpp | 2 +- 11 files changed, 200 insertions(+), 117 deletions(-) create mode 100644 slsSupportLib/src/bit_utils.cpp diff --git a/slsDetectorSoftware/generator/Caller.in.h b/slsDetectorSoftware/generator/Caller.in.h index a9e9af466..c135c1bbd 100644 --- a/slsDetectorSoftware/generator/Caller.in.h +++ b/slsDetectorSoftware/generator/Caller.in.h @@ -73,11 +73,11 @@ class Caller { static void EmptyDataCallBack(detectorData *data, uint64_t frameIndex, uint32_t subFrameIndex, void *this_pointer); - defs::RegisterAddress parseAddress(int argPos) const; - defs::BitPosition parseBitNumberAndAddress() const; - bool parseandRemoveValidate() const; - std::pair parseRegAddressAndValue() const; + RegisterAddress parseAddress(const int argPos) const; + BitPosition parseBitPosition(); + bool parseandRemoveValidate(); + std::pair parseRegAddressAndValue(); std::string bitoperations(int action); FunctionMap functions{ diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index 49f59cfb0..e41c4d38f 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -3,6 +3,7 @@ #pragma once #include "sls/Pattern.h" #include "sls/Result.h" +#include "sls/bit_utils.h" #include "sls/network_utils.h" #include "sls/sls_detector_defs.h" #include diff --git a/slsDetectorSoftware/src/Caller.h b/slsDetectorSoftware/src/Caller.h index 09e5e79a4..197006949 100644 --- a/slsDetectorSoftware/src/Caller.h +++ b/slsDetectorSoftware/src/Caller.h @@ -400,10 +400,10 @@ class Caller { static void EmptyDataCallBack(detectorData *data, uint64_t frameIndex, uint32_t subFrameIndex, void *this_pointer); defs::RegisterAddress parseAddress(int argPos) const; - defs::BitPosition parseBitNumberAndAddress() const; - bool parseandRemoveValidate() const; + defs::BitPosition parseBitPosition(); + bool parseandRemoveValidate(); std::pair - parseRegAddressAndValue() const; + parseRegAddressAndValue(); std::string bitoperations(int action); diff --git a/slsDetectorSoftware/src/CallerSpecial.cpp b/slsDetectorSoftware/src/CallerSpecial.cpp index c1a98a4c1..ad70529ab 100644 --- a/slsDetectorSoftware/src/CallerSpecial.cpp +++ b/slsDetectorSoftware/src/CallerSpecial.cpp @@ -1440,28 +1440,38 @@ std::string Caller::define(int action) { std::ostringstream os; if (action == defs::HELP_ACTION) { os << "[Ctb][Xilinx Ctb]" - "\n\t[addr] [addr name] [address]" - "\n\t[bit] [bit name] [bit position] [addr name/ address]" - "\n\n\tSets a user defined register or bit name in shared memory. The name can be upto 32 characters long." - "\n\teg." - "\n\tsls_detector_put define addr test_reg 0x200" - "\n\tsls_detector_put define bit test_bit 2 test_reg" - "\n\tsls_detector_put define bit test_bit 2 0x200" - "\n\n\tOne can retrieve the address or bit position using the name.And vice versa, but bit name retrieval requires both bit and register name/address." - "\n\teg." - "\n\tsls_detector_get define addr test_reg" - "\n\tsls_detector_get define addr 0x200" - "\n\tsls_detector_get define bit test_bit" - "\n\tsls_detector_get define bit 2 test_reg" - "\n\tsls_detector_get define bit 2 0x200" - "\n\n\tOne can then use this user-defined name in other commands instead of hard coding the address or bit position such as for reg, setbit, clearbit and getbit commands. When using bit names, register name or address is not expected as the bit name is tied to a specific register already. For reg command, using bit names or concatenation of them is the value that will be set, provided both bit names are tied to the same register address." - "\n\teg." - "\n\tsls_detector_put reg test_reg 0x1" - "\n\tsls_detector_put reg test_bit" - "\n\tsls_detector_put reg test_bit|test_bit2" - "\n\tsls_detector_put setbit test_bit" - "\n\tsls_detector_put clearbit test_bit" - "\n\tsls_detector_get getbit test_bit" + "\n\t[addr] [addr name] [address]" + "\n\t[bit] [bit name] [bit position] [addr name/ address]" + "\n\n\tSets a user defined register or bit name in shared " + "memory. The name can be upto 32 characters long." + "\n\teg." + "\n\tsls_detector_put define addr test_reg 0x200" + "\n\tsls_detector_put define bit test_bit test_reg 2" + "\n\tsls_detector_put define bit test_bit 0x200 2" + "\n\n\tOne can retrieve the address or bit position using the " + "name.And vice versa, but bit name retrieval requires both bit " + "and register name/address." + "\n\teg." + "\n\tsls_detector_get define addr test_reg" + "\n\tsls_detector_get define addr 0x200" + "\n\tsls_detector_get define bit test_bit" + "\n\tsls_detector_get define bit test_reg 2" + "\n\tsls_detector_get define bit 0x200 2" + "\n\n\tOne can then use this user-defined name in other commands " + "instead of hard coding the address or bit position such as for " + "reg, setbit, clearbit and getbit commands. When using bit " + "names, register name or address is not expected as the bit name " + "is tied to a specific register already. For reg command, using " + "bit names or concatenation of them is the value that will be " + "set, provided both bit names are tied to the same register " + "address." + "\n\teg." + "\n\tsls_detector_put reg test_reg 0x1" + "\n\tsls_detector_put reg test_bit" + "\n\tsls_detector_put reg test_bit|test_bit2" + "\n\tsls_detector_put setbit test_bit" + "\n\tsls_detector_put clearbit test_bit" + "\n\tsls_detector_get getbit test_bit" << '\n'; return os.str(); } @@ -1488,16 +1498,17 @@ std::string Caller::define(int action) { std::string mode = args[0]; if (mode == "addr") { if (action == defs::GET_ACTION) { + // get name from address - if (is_extended_int(args[1])) { - auto addr = defs::RegisterAddress(StringTo(args[1])); + if (is_hex_or_dec_int(args[1])) { + auto addr = parseAddress(1); auto t = det->getRegisterDefinitionByValue(addr); os << t << '\n'; } // get address from name else { auto t = det->getRegisterDefinitionByName(args[1]); - os << ToStringHex(t.value) << '\n'; + os << t.str() << '\n'; } } // put action @@ -1505,29 +1516,28 @@ std::string Caller::define(int action) { if (args.size() != 3) { WrongNumberOfParameters(3); } - if (!is_extended_int(args[2])) { + if (!is_hex_or_dec_int(args[2])) { throw RuntimeError("Address must be an integer value."); } - auto addr = defs::RegisterAddress(StringTo(args[2])); + auto addr = RegisterAddress(args[2]); det->setRegisterDefinition(args[1], addr); - os << "addr " << args[1] << ' ' << ToStringHex(addr.value) << '\n'; + os << "addr " << args[1] << ' ' << addr.str() << '\n'; } } else if (mode == "bit") { if (action == defs::GET_ACTION) { // get name from position and address - if (is_extended_int(args[1])) { + if (is_hex_or_dec_int(args[1])) { if (args.size() != 3) { WrongNumberOfParameters(3); } - auto pos = defs::BitPosition(parseAddress(2), - StringTo(args[1])); + auto pos = BitPosition(parseAddress(1), StringTo(args[2])); auto t = det->getBitDefinitionByValue(pos); os << t << '\n'; } // get position from name else { auto t = det->getBitDefinitionByName(args[1]); - os << t << '\n'; + os << t.str() << '\n'; } } // put action @@ -1538,8 +1548,7 @@ std::string Caller::define(int action) { if (!is_int(args[2])) { throw RuntimeError("Bit position must be an integer value."); } - auto pos = defs::BitPosition(parseAddress(3), - StringTo(args[2])); + auto pos = BitPosition(parseAddress(2), StringTo(args[3])); det->setBitDefinition(args[1], pos); os << ToString(args) << '\n'; } @@ -1624,9 +1633,9 @@ std::string Caller::setbit(int action) { return bitoperations(action); } std::string Caller::clearbit(int action) { return bitoperations(action); } -defs::RegisterAddress Caller::parseAddress(int argPos) const { - if (is_extended_int(args[argPos])) { - return defs::RegisterAddress(StringTo(args[argPos])); +RegisterAddress Caller::parseAddress(int argPos) const { + if (is_hex_or_dec_int(args[argPos])) { + return RegisterAddress(args[argPos]); } auto det_type = det->getDetectorType().squash(); if (det_type != defs::XILINX_CHIPTESTBOARD && det_type != defs::CHIPTESTBOARD) { @@ -1635,25 +1644,25 @@ defs::RegisterAddress Caller::parseAddress(int argPos) const { return det->getRegisterDefinitionByName(args[argPos]); } - -defs::BitPosition Caller::parseBitNumberAndAddress() const { +BitPosition Caller::parseBitPosition() { // bit name if (args.size() == 1) { + auto det_type = det->getDetectorType().squash(); if (det_type != defs::XILINX_CHIPTESTBOARD && det_type != defs::CHIPTESTBOARD) { throw RuntimeError("Could not parse bit name " + args[0] + ". User defined bit definitions only supported for ctb and xilinx_ctb. Use an actual hard coded bit position for this detector."); } return det->getBitDefinitionByName(args[0]); } - // bit position and address + // address and bit position else if (args.size() == 2) { - return defs::BitPosition(parseAddress(1), StringTo(args[0])); + return BitPosition(parseAddress(0), StringTo(args[1])); } else { WrongNumberOfParameters(1); } } -bool Caller::parseandRemoveValidate() const { +bool Caller::parseandRemoveValidate() { bool validate = false; auto it = std::find(args.begin(), args.end(), "--validate"); if (it != args.end()) { @@ -1663,14 +1672,18 @@ bool Caller::parseandRemoveValidate() const { return validate; } -std::pair Caller::parseRegAddressAndValue() const { +std::pair Caller::parseRegAddressAndValue() { + // address and value + if (args.size() == 2) { + return std::make_pair(parseAddress(0), RegisterValue(args[1])); + } // parse bit name (or concatenation of them) - if (args.size() == 1) { + else if (args.size() == 1) { auto det_type = det->getDetectorType().squash(); if (det_type != defs::XILINX_CHIPTESTBOARD && det_type != defs::CHIPTESTBOARD) { throw RuntimeError("Could not parse reg value " + args[0] + ". User defined bit definitions only supported for ctb and xilinx_ctb. Use an actual hard coded value for this detector."); } - RegisterAddress addr; + RegisterAddress addr; RegisterValue val; std::stringstream ss(args[0]); @@ -1679,20 +1692,20 @@ std::pair Caller::parseRegAddressAnd if (token.empty()) continue; - defs::BitPosition pos1 = det->getBitDefinitionByName(token); + BitPosition pos1 = det->getBitDefinitionByName(token); // if address not set, set it in retval[0] - if (addr.value == 0) { - addr.value = pos1.reg; - } else if (addr.value != pos1.reg) { - throw RuntimeError("Bit names provided are tied to different register addresses."); + if (addr == 0) { + addr = pos1.address(); + } else if (addr != pos1.address()) { + throw RuntimeError( + "Bit names provided are tied to different register " + "addresses: [" + + addr.str() + " " + pos1.address().str() + + "]. Cannot write to different registers at the same time."); } - int bit_pos = pos1.bit; + int bit_pos = pos1.bitPosition(); val |= (1u << bit_pos); } - } - // bit position and address - else if (args.size() == 2) { - return std::make_pait(parseAddress(0), defs::RegisterValue(StringTo(args[1]))); } else { WrongNumberOfParameters(1); } @@ -1730,15 +1743,8 @@ std::string Caller::bitoperations(int action) { throw RuntimeError("Unknown action"); } - // remove --validate if present - bool validate = false; - auto it = std::find(args.begin(), args.end(), "--validate"); - if (it != args.end()) { - args.erase(it); - validate = true; - } - - auto [bit, addr] = parseBitNumberAndAddress(); + bool validate = parseandRemoveValidate(); + auto [bit, addr] = parseBitPosition(); if (action == defs::GET_ACTION) { if (cmd == "setbit" || cmd == "clearbit") throw RuntimeError("Cannot get"); diff --git a/slsSupportLib/include/sls/ToString.h b/slsSupportLib/include/sls/ToString.h index 2ae29801e..962d4b388 100644 --- a/slsSupportLib/include/sls/ToString.h +++ b/slsSupportLib/include/sls/ToString.h @@ -66,9 +66,6 @@ std::ostream &operator<<(std::ostream &os, std::string ToString(const slsDetectorDefs::pedestalParameters &r); std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::pedestalParameters &r); -std::string ToString(const defs::BitPosition s); -std::ostream &operator<<(std::ostream &os, - const defs::BitPosition &p); const std::string &ToString(const std::string &s); diff --git a/slsSupportLib/include/sls/bit_utils.h b/slsSupportLib/include/sls/bit_utils.h index 164d1e3b8..3cc55e1d5 100644 --- a/slsSupportLib/include/sls/bit_utils.h +++ b/slsSupportLib/include/sls/bit_utils.h @@ -18,4 +18,76 @@ template std::vector getSetBits(T val) { } return set_bits; } + +class RegisterAddress { + private: + int addr_{0}; + + public: + constexpr RegisterAddress() noexcept = default; + explicit RegisterAddress(int address); + explicit RegisterAddress(const std::string &address); + + std::string str() const; + operator int() const noexcept { return addr_; } + + constexpr bool operator==(const RegisterAddress &other) const { + return (addr_ == other.addr_); + } + constexpr bool operator!=(const RegisterAddress &other) const { + return (addr_ != other.addr_); + } +} __attribute__((packed)); + +class BitPosition { + private: + RegisterAddress addr_{0}; + int bitPos_{0}; + + public: + constexpr BitPosition() noexcept = default; + BitPosition(RegisterAddress address, int bitPosition); + std::string str() const; + + RegisterAddress address() const noexcept { return addr_; } + int bitPosition() const noexcept { return bitPos_; } + void setAddress(RegisterAddress address) noexcept { addr_ = address; } + void setBitPosition(int bitPosition) noexcept { bitPos_ = bitPosition; } + + constexpr bool operator==(const BitPosition &other) const { + return (addr_ == other.addr_ && bitPos_ == other.bitPos_); + } + constexpr bool operator!=(const BitPosition &other) const { + return !(*this == other && bitPos_ == other.bitPos_); + } +} __attribute__((packed)); + +class RegisterValue { + private: + uint32_t value_{0}; + + public: + constexpr RegisterValue() noexcept = default; + explicit constexpr RegisterValue(uint32_t value) noexcept : value_(value) {} + explicit RegisterValue(const std::string &value); + + std::string str() const; + operator uint32_t() const noexcept { return value_; } + + RegisterValue &operator|=(uint32_t rhs) noexcept { + value_ |= rhs; + return *this; + } + constexpr bool operator==(const RegisterValue &other) const noexcept { + return value_ == other.value_; + } + constexpr bool operator!=(const RegisterValue &other) const noexcept { + return value_ != other.value_; + } +} __attribute__((packed)); + +std::ostream &operator<<(std::ostream &os, const RegisterAddress &r); +std::ostream &operator<<(std::ostream &os, const BitPosition &r); +std::ostream &operator<<(std::ostream &os, const RegisterValue &r); + } // namespace sls diff --git a/slsSupportLib/include/sls/sls_detector_defs.h b/slsSupportLib/include/sls/sls_detector_defs.h index 72e079a91..d028d4238 100644 --- a/slsSupportLib/include/sls/sls_detector_defs.h +++ b/slsSupportLib/include/sls/sls_detector_defs.h @@ -130,36 +130,6 @@ class slsDetectorDefs { return ((x == other.x) && (y == other.y)); } } __attribute__((packed)); - - struct RegisterAddress { - int value{0}; - - explicit RegisterAddress(int v) : value(v) { - if (v < 0) { - throw sls::RuntimeError("Register address cannot be negative."); - } - } - }; - - struct BitPosition { - RegisterAddress reg{0}; - int bit{0}; - - explicit BitPosition(RegisterAddress r, int b) - : reg(r), bit(b) { - if (b < 0 || b > 31) { - throw sls::RuntimeError("Bit position must be between 0 and 31."); - } - } - }; - - struct RegisterValue { - uint32_t value{0}; - - explicit RegisterValue(uint32_t v) - : value(v) {} - }; - #endif /** diff --git a/slsSupportLib/include/sls/string_utils.h b/slsSupportLib/include/sls/string_utils.h index 233b8b24a..fc9bca697 100644 --- a/slsSupportLib/include/sls/string_utils.h +++ b/slsSupportLib/include/sls/string_utils.h @@ -87,7 +87,7 @@ std::string RemoveUnit(std::string &str); bool is_int(const std::string &s); /** '0x200' is also an int here */ -bool is_extended_int(const std::string &s); +bool is_hex_or_dec_int(const std::string &s); bool replace_first(std::string *s, const std::string &substr, const std::string &repl); diff --git a/slsSupportLib/src/ToString.cpp b/slsSupportLib/src/ToString.cpp index 184ea8f62..98790f7cd 100644 --- a/slsSupportLib/src/ToString.cpp +++ b/slsSupportLib/src/ToString.cpp @@ -173,17 +173,6 @@ std::ostream &operator<<(std::ostream &os, return os << ToString(r); } -std::string ToString(const defs::BitPosition s) { - std::ostringstream os; - os << '[' << ToString(s.bit) << ',' << ToStringHex(s.reg.value) << ']'; - return os.str(); -} - -std::ostream &operator<<(std::ostream &os, - const slsDetectorDefs::BitPosition &p) { - return os << ToString(p); -} - std::string ToString(const defs::runStatus s) { switch (s) { case defs::ERROR: diff --git a/slsSupportLib/src/bit_utils.cpp b/slsSupportLib/src/bit_utils.cpp new file mode 100644 index 000000000..0205dfa7e --- /dev/null +++ b/slsSupportLib/src/bit_utils.cpp @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: LGPL-3.0-or-other +// Copyright (C) 2021 Contributors to the SLS Detector Package +#include "sls/bit_utils.h" +#include "sls/sls_detector_exceptions.h" +#include "sls/ToString.h" + +namespace sls { + +RegisterAddress::RegisterAddress(int address) : addr_(address) { + if (address < 0) { + throw RuntimeError("Register address cannot be negative."); + } +} + +RegisterAddress::RegisterAddress(const std::string &address) { + int addr = StringTo(address); + if (addr < 0) { + throw RuntimeError("Register address cannot be negative."); + } + addr_ = addr; +} + +std::string RegisterAddress::str() const { + return ToStringHex(addr_); +} + +BitPosition::BitPosition(RegisterAddress address, int bitPosition) : addr_(address), bitPos_(bitPosition) { + if (bitPosition < 0 || bitPosition > 31) { + throw RuntimeError("Bit position must be between 0 and 31."); + } +} + +std::string BitPosition::str() const { + std::ostringstream os; + os << '[' << addr_.str() << ',' << ToString(bitPos_) << ']'; + return os.str(); +} + +RegisterValue::RegisterValue(const std::string &value) { + uint32_t val = StringTo(value); + value_ = val; +} + +std::string RegisterValue::str() const { + return ToStringHex(value_); +} + +} // namespace sls diff --git a/slsSupportLib/src/string_utils.cpp b/slsSupportLib/src/string_utils.cpp index ff768251b..7214d4ae6 100644 --- a/slsSupportLib/src/string_utils.cpp +++ b/slsSupportLib/src/string_utils.cpp @@ -43,7 +43,7 @@ bool is_int(const std::string &s) { }) == s.end(); } -bool is_extended_int(const std::string &s) { +bool is_hex_or_dec_int(const std::string &s) { try { StringTo(s); return true;