scc 2025.09
SystemC components library
bit_field.h
1/*---------------------------------------------------------
2Copyright (c) 2015 Jeff Preshing
3
4This software is provided 'as-is', without any express or implied
5warranty. In no event will the authors be held liable for any damages
6arising from the use of this software.
7
8Permission is granted to anyone to use this software for any purpose,
9including commercial applications, and to alter it and redistribute it
10freely, subject to the following restrictions:
11
121. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgement in the product documentation would be
15 appreciated but is not required.
162. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
183. This notice may not be removed or altered from any source distribution.
19---------------------------------------------------------*/
20
21#ifndef __CPP11OM_BITFIELD_H__
22#define __CPP11OM_BITFIELD_H__
23
24#include <cassert>
30namespace util {
39template <typename T, int Offset, int Bits> struct BitFieldMember {
40 T value;
41
42 static_assert(Offset + Bits <= (int)sizeof(T) * 8, "Member exceeds bitfield boundaries");
43 static_assert(Bits < (int)sizeof(T) * 8, "Can't fill entire bitfield with one member");
44
45 static constexpr T Maximum = (T(1) << Bits) - 1;
46 static constexpr T Mask = Maximum << Offset;
47 T maximum() const { return Maximum; }
48 T one() const { return T(1) << Offset; }
49
50 operator T() const { return (value >> Offset) & Maximum; }
51
52 BitFieldMember& operator=(T v) {
53 assert(v <= Maximum); // v must fit inside the bitfield member
54 value = (value & ~Mask) | (v << Offset);
55 return *this;
56 }
57
58 BitFieldMember& operator+=(T v) {
59 assert(T(*this) + v <= Maximum); // result must fit inside the bitfield member
60 value += v << Offset;
61 return *this;
62 }
63
64 BitFieldMember& operator-=(T v) {
65 assert(T(*this) >= v); // result must not underflow
66 value -= v << Offset;
67 return *this;
68 }
69
70 BitFieldMember& operator++() { return *this += 1; }
71 BitFieldMember operator++(int) { // postfix form
72 BitFieldMember tmp(*this);
73 operator++();
74 return tmp;
75 }
76 BitFieldMember& operator--() { return *this -= 1; }
77 BitFieldMember operator--(int) { // postfix form
78 BitFieldMember tmp(*this);
79 operator--();
80 return tmp;
81 }
82};
83
91template <typename T, int BaseOffset, int BitsPerItem, int NumItems> class BitFieldArray {
92public:
93 T value;
94
95 static_assert(BaseOffset + BitsPerItem * NumItems <= (int)sizeof(T) * 8, "Array exceeds bitfield boundaries");
96 static_assert(BitsPerItem < (int)sizeof(T) * 8, "Can't fill entire bitfield with one array element");
97
98 static const T Maximum = (T(1) << BitsPerItem) - 1;
99 T maximum() const { return Maximum; }
100 int numItems() const { return NumItems; }
101
102 class Element {
103 private:
104 T& value;
105 int offset;
106
107 public:
108 Element(T& value, int offset)
109 : value(value)
110 , offset(offset) {}
111 T mask() const { return Maximum << offset; }
112
113 operator T() const { return (value >> offset) & Maximum; }
114
115 Element& operator=(T v) {
116 assert(v <= Maximum); // v must fit inside the bitfield member
117 value = (value & ~mask()) | (v << offset);
118 return *this;
119 }
120
121 Element& operator+=(T v) {
122 assert(T(*this) + v <= Maximum); // result must fit inside the bitfield member
123 value += v << offset;
124 return *this;
125 }
126
127 Element& operator-=(T v) {
128 assert(T(*this) >= v); // result must not underflow
129 value -= v << offset;
130 return *this;
131 }
132
133 Element& operator++() { return *this += 1; }
134 Element operator++(int) { // postfix form
135 Element tmp(*this);
136 operator++();
137 return tmp;
138 }
139 Element& operator--() { return *this -= 1; }
140 Element operator--(int) { // postfix form
141 Element tmp(*this);
142 operator--();
143 return tmp;
144 }
145 };
146
147 Element operator[](int i) {
148 assert(i >= 0 && i < NumItems); // array index must be in range
149 return Element(value, BaseOffset + BitsPerItem * i);
150 }
151
152 const Element operator[](int i) const {
153 assert(i >= 0 && i < NumItems); // array index must be in range
154 return Element(value, BaseOffset + BitsPerItem * i);
155 }
156};
157} // namespace util
158
164#define BEGIN_BF_DECL(typeName, T) \
165 union typeName { \
166 struct { \
167 T val; \
168 } backing; \
169 typeName(T v = 0) { backing.val = v; } \
170 typeName& operator=(T v) { \
171 backing.val = v; \
172 return *this; \
173 } \
174 operator T&() { return backing.val; } \
175 operator T() const { return backing.val; } \
176 T operator()() const { return backing.val; } \
177 using StorageType = T;
178
179#define BF_FIELD(memberName, offset, bits) util::BitFieldMember<StorageType, offset, bits> memberName;
180
181#define BF_ARRAY(memberName, offset, bits, numItems) util::BitFieldArray<StorageType, offset, bits, numItems> memberName;
182
183#define END_BF_DECL() }
185#endif // __CPP11OM_BITFIELD_H__
array of bit field elements
Definition bit_field.h:91
SCC common utilities.
Definition bit_field.h:30
bit field element
Definition bit_field.h:39