rhdl_bits/
bits.rs

1use crate::signed_bits::SignedBits;
2use derive_more::{
3    Binary, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Display, LowerHex,
4    UpperHex,
5};
6
7/// The [Bits] type is a fixed-sized bit vector.  It is meant to
8/// imitate the behavior of bit vectors in hardware.  Due to the
9/// design of the [Bits] type, you can only create a [Bits] type of
10/// up to 128 bits in length for now.  However, you can easily express
11/// larger constructs in hardware using arrays, tuples and structs.
12/// The only real limitation of the [Bits] type being 128 bits is that
13/// you cannot perform arbitrary arithmetic on longer bit values in your
14/// hardware designs.  I don't think this is a significant issue, but
15/// the [Bits] design of the `rust-hdl` crate was much slower and harder
16/// to maintain and use.  I think this is a good trade-off.
17///
18/// Note that the [Bits] type implements 2's complement arithmetic.
19/// See <https://en.wikipedia.org/wiki/Two%27s_complement> for more
20/// information.
21///
22/// Note also that the [Bits] kind is treated as an unsigned value for
23/// the purposes of comparisons.  If you need signed comparisons, you
24/// will need the [SignedBits] type.
25#[derive(
26    Clone,
27    Debug,
28    Copy,
29    PartialEq,
30    Eq,
31    PartialOrd,
32    Ord,
33    Hash,
34    BitAnd,
35    BitAndAssign,
36    BitOr,
37    BitOrAssign,
38    BitXor,
39    BitXorAssign,
40    Display,
41    LowerHex,
42    UpperHex,
43    Binary,
44)]
45#[repr(transparent)]
46pub struct Bits<const N: usize>(pub(crate) u128);
47
48/// Helper function for creating a bits value from
49/// a constant.
50/// ```
51/// # use rhdl_bits::{Bits, bits};
52/// let value : Bits<8> = bits(0b1010_1010);
53/// assert_eq!(value, 0b1010_1010);
54/// ```
55/// Because the function is `const`, you can use it a constant
56/// context:
57/// ```
58/// # use rhdl_bits::{Bits, bits};
59/// const VALUE : Bits<8> = bits(0b1010_1010);
60/// ```
61pub const fn bits<const N: usize>(value: u128) -> Bits<N> {
62    assert!(N <= 128);
63    assert!(value <= Bits::<N>::mask().0);
64    Bits(value)
65}
66
67impl<const N: usize> Bits<N> {
68    /// Defines a constant Bits value with all bits set to 1.
69    pub const MASK: Self = Self::mask();
70    /// Return a [Bits] value with all bits set to 1.
71    /// ```
72    /// # use rhdl_bits::Bits;
73    /// let bits = Bits::<8>::mask();
74    /// assert_eq!(bits, 0xFF);
75    /// ```
76    pub const fn mask() -> Self {
77        // Do not compute this as you will potentially
78        // cause overflow.
79        if N < 128 {
80            Self((1 << N) - 1)
81        } else {
82            Self(u128::MAX)
83        }
84    }
85    /// Set a specific bit of a [Bits] value to 1 or 0.
86    /// Panics if the index of the bit is outside the range
87    /// of the [Bits] value.
88    /// ```
89    /// # use rhdl_bits::Bits;
90    /// let mut bits = Bits::<8>::mask();
91    /// bits.set_bit(0, false);
92    /// assert_eq!(bits, 0xFE);
93    /// bits.set_bit(0, true);
94    /// assert_eq!(bits, 0xFF);
95    /// ```
96    pub fn set_bit(&mut self, bit: usize, value: bool) {
97        assert!(bit < N);
98        if value {
99            self.0 |= 1 << bit;
100        } else {
101            self.0 &= !(1 << bit);
102        }
103    }
104    /// Get the value of a specific bit of a [Bits] value.
105    /// Panics if the index of the bit is outside the range
106    /// of the [Bits] value.
107    /// ```
108    /// # use rhdl_bits::Bits;
109    /// let bits : Bits<8> = 0b1101_1010.into();
110    /// assert!(!bits.get_bit(0));
111    /// assert!(bits.get_bit(7));
112    /// assert!(bits.get_bit(6));
113    /// ```
114    pub fn get_bit(&self, bit: usize) -> bool {
115        assert!(bit < N);
116        (self.0 & (1 << bit)) != 0
117    }
118    /// Returns true if any of the bits are set to 1.
119    /// ```
120    /// # use rhdl_bits::Bits;
121    /// let bits : Bits<8> = 0b1101_1010.into();
122    /// assert!(bits.any());
123    /// let bits : Bits<8> = 0.into();
124    /// assert!(!bits.any());
125    /// ```
126    pub fn any(self) -> bool {
127        (self.0 & Self::mask().0) != 0
128    }
129    /// Returns true if all of the bits are set to 1.
130    /// ```
131    /// # use rhdl_bits::Bits;
132    /// let bits : Bits<8> = 0b1101_1010.into();
133    /// assert!(!bits.all());
134    /// let bits : Bits<8> = Bits::mask();
135    /// assert!(bits.all());
136    /// ```
137    pub fn all(self) -> bool {
138        (self.0 & Self::mask().0) == Self::mask().0
139    }
140    /// Computes the xor of all of the bits in the value.
141    pub fn xor(self) -> bool {
142        let mut x = self.0 & Self::mask().0;
143        x ^= x >> 64;
144        x ^= x >> 32;
145        x ^= x >> 16;
146        x ^= x >> 8;
147        x ^= x >> 4;
148        x ^= x >> 2;
149        x ^= x >> 1;
150        x & 1 == 1
151    }
152    /// Extracts a range of bits from the [Bits] value.
153    pub fn slice<const M: usize>(&self, start: usize) -> Bits<M> {
154        Bits((self.0 >> start) & Bits::<M>::mask().0)
155    }
156    /// Reinterpret the [Bits] value as a [SignedBits] value.
157    pub fn as_signed(self) -> SignedBits<N> {
158        // Need to a sign extension here.
159        if self.get_bit(N - 1) {
160            SignedBits((self.0 | !(Self::mask().0)) as i128)
161        } else {
162            SignedBits(self.0 as i128)
163        }
164    }
165}
166
167/// The default value for a [Bits] value is 0.
168impl<const N: usize> Default for Bits<N> {
169    fn default() -> Self {
170        Self(0)
171    }
172}
173
174/// Provide conversion from a `u128` to a [Bits] value.
175/// This will panic if you try to convert a value that
176/// is larger than the [Bits] value can hold.
177impl<const N: usize> From<u128> for Bits<N> {
178    fn from(value: u128) -> Self {
179        assert!(N <= 128);
180        assert!(value <= Self::mask().0);
181        Self(value)
182    }
183}
184
185impl<const N: usize> PartialEq<u128> for Bits<N> {
186    fn eq(&self, other: &u128) -> bool {
187        self == &Self::from(*other)
188    }
189}
190
191#[cfg(test)]
192mod tests {
193    use super::*;
194
195    #[test]
196    fn test_mask() {
197        let bits = Bits::<128>::mask();
198        assert_eq!(bits.0, u128::MAX);
199        let bits = Bits::<32>::mask();
200        assert_eq!(bits.0, 0xFFFF_FFFF_u128);
201    }
202
203    #[test]
204    fn test_xor() {
205        let bits = Bits::<128>::mask();
206        assert!(!bits.xor());
207        let bits = Bits::<32>::mask();
208        assert!(!bits.xor());
209        let bits = Bits::<1>::mask();
210        assert!(bits.xor());
211        let bits: Bits<5> = 0b11010.into();
212        assert!(bits.xor());
213    }
214
215    #[test]
216    fn test_all() {
217        let bits = Bits::<128>::mask();
218        assert!(bits.all());
219        let bits = Bits::<32>::mask();
220        assert!(bits.all());
221        let bits = Bits::<1>::mask();
222        assert!(bits.all());
223        let bits: Bits<5> = 0b11111.into();
224        assert!(bits.all());
225        let bits: Bits<5> = 0b11110.into();
226        assert!(!bits.all());
227    }
228
229    #[test]
230    fn test_any() {
231        let bits = Bits::<128>::mask();
232        assert!(bits.any());
233        let bits = Bits::<32>::mask();
234        assert!(bits.any());
235        let bits = Bits::<1>::mask();
236        assert!(bits.any());
237        let bits: Bits<5> = 0b11111.into();
238        assert!(bits.any());
239        let bits: Bits<5> = 0b00000.into();
240        assert!(!bits.any());
241    }
242
243    #[test]
244    fn test_set_bit() {
245        let mut bits = Bits::<128>::mask();
246        bits.set_bit(0, false);
247        assert_eq!(bits.0, u128::MAX - 1);
248        bits.set_bit(0, true);
249        assert_eq!(bits.0, u128::MAX);
250        bits.set_bit(127, false);
251        assert_eq!(bits.0, u128::MAX - (1 << 127));
252        bits.set_bit(127, true);
253        assert_eq!(bits.0, u128::MAX);
254        bits.set_bit(64, false);
255        assert_eq!(bits.0, u128::MAX - (1 << 64));
256        bits.set_bit(64, true);
257        assert_eq!(bits.0, u128::MAX);
258        bits.set_bit(32, false);
259        assert_eq!(bits.0, u128::MAX - (1 << 32));
260        bits.set_bit(32, true);
261        assert_eq!(bits.0, u128::MAX);
262        bits.set_bit(16, false);
263        assert_eq!(bits.0, u128::MAX - (1 << 16));
264        bits.set_bit(16, true);
265        assert_eq!(bits.0, u128::MAX);
266        bits.set_bit(8, false);
267        assert_eq!(bits.0, u128::MAX - (1 << 8));
268        bits.set_bit(8, true);
269        assert_eq!(bits.0, u128::MAX);
270        bits.set_bit(4, false);
271        assert_eq!(bits.0, u128::MAX - (1 << 4));
272        bits.set_bit(4, true);
273        assert_eq!(bits.0, u128::MAX);
274        bits.set_bit(2, false);
275        assert_eq!(bits.0, u128::MAX - (1 << 2));
276        bits.set_bit(2, true);
277        assert_eq!(bits.0, u128::MAX);
278        bits.set_bit(1, false);
279        assert_eq!(bits.0, u128::MAX - (1 << 1));
280        bits.set_bit(1, true);
281        assert_eq!(bits.0, u128::MAX);
282    }
283
284    #[test]
285    fn test_get_bit() {
286        let bits = Bits::<128>::mask();
287        assert!(bits.get_bit(0));
288        assert!(bits.get_bit(127));
289        assert!(bits.get_bit(64));
290        assert!(bits.get_bit(32));
291        assert!(bits.get_bit(16));
292        assert!(bits.get_bit(8));
293        assert!(bits.get_bit(4));
294        assert!(bits.get_bit(2));
295        assert!(bits.get_bit(1));
296        let bits = Bits::<32>::mask();
297        assert!(bits.get_bit(0));
298        assert!(bits.get_bit(31));
299        assert!(bits.get_bit(16));
300        assert!(bits.get_bit(8));
301        assert!(bits.get_bit(4));
302        assert!(bits.get_bit(2));
303        assert!(bits.get_bit(1));
304        let bits = Bits::<1>::mask();
305        assert!(bits.get_bit(0));
306        let bits: Bits<5> = 0b11010.into();
307        assert!(bits.get_bit(4));
308        assert!(bits.get_bit(3));
309        assert!(!bits.get_bit(2));
310        assert!(bits.get_bit(1));
311        assert!(!bits.get_bit(0));
312    }
313
314    #[test]
315    fn test_binary_format() {
316        let bits: Bits<8> = 0b1101_1010.into();
317        assert_eq!(format!("{:b}", bits), "11011010");
318    }
319
320    #[test]
321    fn test_hex_format() {
322        let bits: Bits<8> = 0b1101_1010.into();
323        assert_eq!(format!("{:x}", bits), "da");
324        assert_eq!(format!("{:X}", bits), "DA");
325    }
326
327    #[test]
328    fn test_slice_function() {
329        let bits: Bits<8> = 0b1101_1010.into();
330        let result = bits.slice::<4>(0);
331        assert_eq!(result.0, 0b1010);
332        let result = bits.slice::<4>(4);
333        assert_eq!(result.0, 0b1101);
334        let result = bits.slice::<2>(6);
335        assert_eq!(result.0, 0b11);
336    }
337
338    #[test]
339    fn test_round_trip_unsigned_signed() {
340        let bits: Bits<8> = 0b1101_1010.into();
341        let signed = bits.as_signed();
342        println!("{}", signed);
343        assert!(signed.is_negative());
344        let unsigned = signed.as_unsigned();
345        assert_eq!(bits.0, unsigned.0);
346        let signed = unsigned.as_signed();
347        assert!(signed.is_negative());
348    }
349}