rust_hdl_lib_core/
short_bit_vec.rs

1use 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}