File indexing completed on 2024-04-06 12:19:51
0001 #ifndef L1GCTETTYPES_H
0002 #define L1GCTETTYPES_H
0003
0004 #include <ostream>
0005 #include <cstdint>
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 template <int nBits>
0028 class L1GctTwosComplement {
0029 public:
0030
0031 L1GctTwosComplement();
0032
0033 L1GctTwosComplement(uint32_t raw);
0034
0035 L1GctTwosComplement(int value);
0036
0037 ~L1GctTwosComplement() {}
0038
0039
0040 template <int mBits>
0041 L1GctTwosComplement(const L1GctTwosComplement<mBits>& rhs);
0042
0043
0044 void reset();
0045
0046
0047 void setRaw(uint32_t raw);
0048
0049
0050 void setValue(int value);
0051
0052
0053 void setOverFlow(bool oflow) { m_overFlow = oflow; }
0054
0055
0056 uint32_t raw() const { return m_data; }
0057
0058
0059 int value() const;
0060
0061
0062 bool overFlow() const { return m_overFlow; }
0063
0064
0065 int size() const { return m_nBits; }
0066
0067
0068 L1GctTwosComplement operator+(const L1GctTwosComplement& rhs) const;
0069
0070
0071 L1GctTwosComplement operator-() const;
0072
0073
0074 L1GctTwosComplement& operator=(int value);
0075
0076 private:
0077
0078 int m_nBits;
0079
0080
0081 uint32_t m_data;
0082
0083
0084 bool m_overFlow;
0085
0086 static const int MAX_NBITS = 24;
0087 static const int MAX_VALUE = 1 << (MAX_NBITS - 1);
0088
0089
0090
0091 void checkOverFlow(uint32_t rawValue, uint32_t& maskValue, bool& overFlow);
0092 };
0093
0094 template <int nBits>
0095 std::ostream& operator<<(std::ostream& s, const L1GctTwosComplement<nBits>& data);
0096
0097
0098 template <int nBits>
0099 L1GctTwosComplement<nBits>::L1GctTwosComplement() {
0100 m_nBits = nBits > 0 && nBits < MAX_NBITS ? nBits : 16;
0101 this->reset();
0102 }
0103
0104
0105 template <int nBits>
0106 L1GctTwosComplement<nBits>::L1GctTwosComplement(uint32_t raw) {
0107 m_nBits = nBits > 0 && nBits < MAX_NBITS ? nBits : 16;
0108 m_overFlow = false;
0109 this->setRaw(raw);
0110 }
0111
0112
0113 template <int nBits>
0114 L1GctTwosComplement<nBits>::L1GctTwosComplement(int value) {
0115 m_nBits = nBits > 0 && nBits < MAX_NBITS ? nBits : 16;
0116 m_overFlow = false;
0117 this->setValue(value);
0118 }
0119
0120
0121
0122 template <int nBits>
0123 template <int mBits>
0124 L1GctTwosComplement<nBits>::L1GctTwosComplement(const L1GctTwosComplement<mBits>& rhs) {
0125 m_nBits = nBits > 0 && nBits < MAX_NBITS ? nBits : 16;
0126 this->setRaw(rhs.raw());
0127 this->setOverFlow(this->overFlow() || rhs.overFlow());
0128 }
0129
0130
0131 template <int nBits>
0132 void L1GctTwosComplement<nBits>::reset() {
0133 m_data = static_cast<uint32_t>(0);
0134 m_overFlow = false;
0135 }
0136
0137
0138 template <int nBits>
0139 void L1GctTwosComplement<nBits>::setRaw(uint32_t raw) {
0140 checkOverFlow(raw, m_data, m_overFlow);
0141 }
0142
0143
0144 template <int nBits>
0145 void L1GctTwosComplement<nBits>::setValue(int value) {
0146 int chkValue, posValue;
0147 uint32_t raw;
0148
0149
0150 chkValue = value;
0151 if (chkValue < -MAX_VALUE) {
0152 chkValue = -MAX_VALUE;
0153 m_overFlow = true;
0154 }
0155 if (chkValue >= MAX_VALUE) {
0156 chkValue = MAX_VALUE - 1;
0157 m_overFlow = true;
0158 }
0159
0160
0161 posValue = chkValue < 0 ? chkValue + (1 << MAX_NBITS) : chkValue;
0162 raw = static_cast<uint32_t>(posValue);
0163
0164
0165 this->setRaw(raw);
0166 }
0167
0168
0169 template <int nBits>
0170 int L1GctTwosComplement<nBits>::value() const {
0171 int value, result;
0172 int maxValueInNbits;
0173 maxValueInNbits = 1 << (m_nBits - 1);
0174 value = static_cast<int>(m_data);
0175 result = value < maxValueInNbits ? value : value - (1 << MAX_NBITS);
0176 return result;
0177 }
0178
0179
0180 template <int nBits>
0181 L1GctTwosComplement<nBits> L1GctTwosComplement<nBits>::operator+(const L1GctTwosComplement<nBits>& rhs) const {
0182
0183 L1GctTwosComplement<nBits> temp;
0184 uint32_t sum;
0185 bool ofl;
0186
0187
0188 sum = this->raw() + rhs.raw();
0189 ofl = this->overFlow() || rhs.overFlow();
0190
0191
0192 temp.setRaw(sum);
0193 temp.setOverFlow(temp.overFlow() || ofl);
0194
0195
0196 return temp;
0197 }
0198
0199
0200 template <int nBits>
0201 L1GctTwosComplement<nBits> L1GctTwosComplement<nBits>::operator-() const {
0202 L1GctTwosComplement<nBits> temp;
0203 temp.setValue(-this->value());
0204 temp.setOverFlow(temp.overFlow() || this->overFlow());
0205 return temp;
0206 }
0207
0208
0209 template <int nBits>
0210 L1GctTwosComplement<nBits>& L1GctTwosComplement<nBits>::operator=(int value) {
0211 this->setValue(value);
0212 return *this;
0213 }
0214
0215
0216 template <int nBits>
0217 void L1GctTwosComplement<nBits>::checkOverFlow(uint32_t rawValue, uint32_t& maskValue, bool& overFlow) {
0218 uint32_t signBit = 1 << (m_nBits - 1);
0219 uint32_t signExtendBits = (static_cast<uint32_t>(MAX_VALUE) - signBit) << 1;
0220
0221 uint32_t mskRawValue = rawValue & ((1 << MAX_NBITS) - 1);
0222 uint32_t value;
0223 bool ofl;
0224
0225 if ((mskRawValue & signBit) == 0) {
0226 value = mskRawValue & ~signExtendBits;
0227 } else {
0228 value = mskRawValue | signExtendBits;
0229 }
0230 ofl = value != mskRawValue;
0231
0232 maskValue = value;
0233 overFlow = ofl;
0234 }
0235
0236
0237 template <int nBits>
0238 std::ostream& operator<<(std::ostream& s, const L1GctTwosComplement<nBits>& data) {
0239 s << "L1GctTwosComplement<" << data.size() << "> raw : " << data.raw() << ", "
0240 << "value : " << data.value();
0241 if (data.overFlow()) {
0242 s << " Overflow set! ";
0243 }
0244
0245 return s;
0246 }
0247
0248 #endif