rust_hdl_lib_core/
short_bit_vec.rs1use num_bigint::BigUint;
2use num_traits::{One, ToPrimitive};
3
4use crate::bits::LiteralType;
5use std::cmp::Ordering;
6use std::num::Wrapping;
7
8pub type ShortType = u32;
9pub const SHORT_BITS: usize = 32;
10
11#[derive(Clone, Debug, Copy, PartialEq, Hash)]
12pub struct ShortBitVec<const N: usize>(ShortType);
13
14#[test]
15fn test_max_legal_calc() {
16 let k = ShortBitVec::<16>::max_legal();
17 assert_eq!(k, 65535);
18}
19
20impl<const N: usize> ShortBitVec<N> {
21 pub fn max_legal() -> u64 {
22 (1_u64 << N) - 1
23 }
24
25 pub fn short(&self) -> ShortType {
26 self.0
27 }
28
29 pub fn to_u128(&self) -> u128 {
30 self.0 as u128
31 }
32
33 #[inline(always)]
34 pub fn replace_bit(&self, index: usize, val: bool) -> Self {
35 assert!(index < N);
36 let m: ShortType = 1 << index;
37 Self(if val { self.0 | m } else { self.0 & !m })
38 }
39
40 #[inline(always)]
41 pub fn get_bit(&self, index: usize) -> bool {
42 self.0 & (1 << index) != 0
43 }
44
45 #[inline(always)]
46 const fn bit_mask() -> ShortType {
47 if N == SHORT_BITS {
48 !0
49 } else {
50 (1 << N) - 1
51 }
52 }
53
54 #[inline(always)]
55 pub fn mask() -> Self {
56 Self::bit_mask().into()
57 }
58
59 #[inline(always)]
60 pub fn any(&self) -> bool {
61 self.0 != 0
62 }
63
64 #[inline(always)]
65 pub fn all(&self) -> bool {
66 self.0 == Self::bit_mask()
67 }
68
69 #[inline(always)]
70 pub fn xor(&self) -> bool {
71 let mut ret = false;
72 let mut x = self.0;
73 for _ in 0..N {
74 ret = ret ^ (x & 0x1 != 0);
75 x = x >> 1;
76 }
77 ret
78 }
79}
80
81impl<const N: usize> From<ShortType> for ShortBitVec<N> {
82 #[inline(always)]
83 fn from(t: ShortType) -> Self {
84 Self(t & Self::bit_mask())
85 }
86}
87
88impl<const N: usize> From<ShortBitVec<N>> for ShortType {
89 #[inline(always)]
90 fn from(t: ShortBitVec<N>) -> ShortType {
91 t.0
92 }
93}
94
95impl<const N: usize> std::ops::Add<ShortBitVec<N>> for ShortBitVec<N> {
96 type Output = ShortBitVec<N>;
97
98 #[inline(always)]
99 fn add(self, rhs: ShortBitVec<N>) -> Self::Output {
100 let tmp = (Wrapping(self.0) + Wrapping(rhs.0)).0;
101 (tmp & ShortBitVec::<N>::bit_mask()).into()
102 }
103}
104
105impl<const N: usize> std::ops::Sub<ShortBitVec<N>> for ShortBitVec<N> {
106 type Output = ShortBitVec<N>;
107
108 #[inline(always)]
109 fn sub(self, rhs: ShortBitVec<N>) -> Self::Output {
110 (Wrapping(self.0) + !Wrapping(rhs.0) + Wrapping(1_u32 as ShortType))
111 .0
112 .into()
113 }
114}
115
116impl<const N: usize> std::ops::BitOr<ShortBitVec<N>> for ShortBitVec<N> {
117 type Output = ShortBitVec<N>;
118
119 #[inline(always)]
120 fn bitor(self, rhs: ShortBitVec<N>) -> Self::Output {
121 (self.0 | rhs.0).into()
122 }
123}
124
125impl<const N: usize> std::ops::BitAnd<ShortBitVec<N>> for ShortBitVec<N> {
126 type Output = ShortBitVec<N>;
127
128 #[inline(always)]
129 fn bitand(self, rhs: ShortBitVec<N>) -> Self::Output {
130 (self.0 & rhs.0).into()
131 }
132}
133
134impl<const N: usize> std::ops::BitXor<ShortBitVec<N>> for ShortBitVec<N> {
135 type Output = ShortBitVec<N>;
136
137 #[inline(always)]
138 fn bitxor(self, rhs: ShortBitVec<N>) -> Self::Output {
139 (self.0 ^ rhs.0).into()
140 }
141}
142
143impl<const N: usize> std::ops::Not for ShortBitVec<N> {
144 type Output = ShortBitVec<N>;
145
146 #[inline(always)]
147 fn not(self) -> Self::Output {
148 (!self.0).into()
149 }
150}
151
152impl<const N: usize> std::cmp::PartialOrd for ShortBitVec<N> {
153 #[inline(always)]
154 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
155 self.0.partial_cmp(&other.0)
156 }
157}
158
159impl<const N: usize> std::ops::Shr<LiteralType> for ShortBitVec<N> {
160 type Output = ShortBitVec<N>;
161
162 #[inline(always)]
163 fn shr(self, rhs: LiteralType) -> Self::Output {
164 let x: BigUint = self.0.into();
165 let mask: BigUint = (BigUint::one() << N) - BigUint::one();
166 ShortBitVec::<N>(((x >> rhs) & mask).to_u32().unwrap())
167 }
168}
169
170impl<const M: usize, const N: usize> std::ops::Shr<ShortBitVec<M>> for ShortBitVec<N> {
171 type Output = ShortBitVec<N>;
172
173 #[inline(always)]
174 fn shr(self, rhs: ShortBitVec<M>) -> Self::Output {
175 let r = rhs.short() as LiteralType;
176 self >> r
177 }
178}
179
180impl<const N: usize> std::ops::Shl<LiteralType> for ShortBitVec<N> {
181 type Output = ShortBitVec<N>;
182
183 #[inline(always)]
184 fn shl(self, rhs: LiteralType) -> Self::Output {
185 let x: BigUint = self.0.into();
186 let mask: BigUint = (BigUint::one() << N) - BigUint::one();
187 ShortBitVec::<N>(((x << rhs) & mask).to_u32().unwrap())
188 }
189}
190
191impl<const M: usize, const N: usize> std::ops::Shl<ShortBitVec<M>> for ShortBitVec<N> {
192 type Output = ShortBitVec<N>;
193
194 #[inline(always)]
195 fn shl(self, rhs: ShortBitVec<M>) -> Self::Output {
196 let r: LiteralType = rhs.short() as LiteralType;
197 self << r
198 }
199}