rust_hdl_core/
bits.rs

1//! The [Bits] type is used to capture values with arbitrarily large (but known) bit length
2//!
3//! One significant difference between hardware design and software programming is the need
4//! (and indeed ability) to easily manipulate collections of bits that are of various lengths.
5//! While Rust has built in types to represent 8, 16, 32, 64, and 128 bits (at the time of this
6//! writing, anyway), it is difficult to represent a 5 bit type.  Or a 256 bit type.  Or indeed
7//! any bit length that differs from one of the supported values.
8//!
9//! In hardware design, the bit size is nearly always unusual, as bits occupy physical space,
10//! and as a result, as a logic designer, you will intentionally use the smallest number of
11//! bits needed to capture a value.  For example, if you are reading a single nibble at a
12//! time from a bus, this is clearly a 4 bit value, and storing it in a `u8` is a waste of
13//! space and resources.
14//!
15//! To model this behavior in RustHDL, we have the [Bits] type, which attempts to be as close
16//! as possible to a hardware bit vector.  The size must be known at compile time, and there is
17//! some internal optimization for short bitvectors being represented efficiently, but ideally
18//! you should be able to think of it as a bit of arbitrary length.  Note that the [Bits]
19//! type is `Copy`, which is quite important.  This means in your RustHDL code, you can freely
20//! copy and assign bitvectors without worrying about the borrow checker or trying to call
21//! `clone` in the midst of your HDL.
22//!
23//! For the most part, the [Bits] type is meant to act like a `u32` or `u128` type as far
24//! as your code is concerned.  But the emulation of built-in types is not perfect, and
25//! you may struggle with them a bit.
26//!
27//! # Constructing [Bits]
28//! There are several ways to construct a [Bits] type.  It includes an implementation of
29//! the [Default](std::default::Default), trait, so if you need a zero value, you can use
30//! that form:
31//! ```
32//! # use rust_hdl_core::prelude::*;
33//! let x: Bits<50> = Default::default();
34//! ```
35//! This will construct a length 50 bit vector that is initialized to all `0`.
36//!
37//! You can also convert from literals into bit vectors using the [From] and [Into] traits,
38//! provided the literals are of the `u64` type.
39//!
40//! ```
41//! # use rust_hdl_core::prelude::*;
42//! let x: Bits<50> = 0xBEEF.into();
43//! ```
44//!
45//! In some cases, Rust complains about literals, and you may need to provide a suffix:
46//! ```
47//! # use rust_hdl_core::prelude::*;
48//! let x: Bits<50> = 0xDEAD_BEEF_u64.into();
49//! ```
50//! However, in most cases, you can leave literals suffix-free, and Rust will automatically
51//! determine the type from the context.
52//!
53//! You can construct a larger constant using the [bits] function.  If you have a literal of up to
54//! 128 bits, it provides a functional form
55//! ```
56//! # use rust_hdl_core::prelude::*;
57//! let x: Bits<200> = bits(0xDEAD_BEEE); // Works for up to 128 bit constants.
58//! ```
59//!
60//! There is also the [ToBits] trait, which is implemented on the basic unsigned integer types.
61//! This trait allows you to handily convert from different integer values
62//!
63//! ```
64//! # use rust_hdl_core::prelude::*;
65//! let x: Bits<10> = 32_u8.to_bits();
66//! ```
67//!
68//!
69//! # Operations
70//! Only a subset of operations are defined for [Bits].  These are the operations that can
71//! be synthesized in hardware without surprises (generally speaking).  In Rust, you can
72//! operate between [Bits] types and other [Bits] of the _same width_, or you can
73//! use integer literals.  *Be careful!* Especially when manipulating signed quantities.  Use the
74//! [Signed](crate::signed::Signed) type for those.
75//!
76//! ## Addition
77//! You can perform wrapping addition using the `+` operator.
78//! Here are some simple examples of addition. First the version using a literal
79//! ```
80//! # use rust_hdl_core::prelude::*;
81//! let x: Bits<200> = bits(0xDEAD_BEEE);
82//! let y: Bits<200> = x + 1;
83//! assert_eq!(y, bits(0xDEAD_BEEF));
84//! ```
85//!
86//! And now a second example that uses two [Bits] values
87//! ```
88//! # use rust_hdl_core::prelude::*;
89//! let x: Bits<40> = bits(0xDEAD_0000);
90//! let y: Bits<40> = bits(0x0000_CAFE);
91//! let z = x + y;
92//! assert_eq!(z, bits(0xDEAD_CAFE));
93//! ```
94//!
95//! Note that the addition operator is _silently wrapping_.  In other words the carry
96//! bit is discarded silently (again - this is what hardware typically does).  So you
97//! may find this result surprising:
98//! ```
99//! # use rust_hdl_core::prelude::*;
100//! let x: Bits<40> = bits(0xFF_FFFF_FFFF);
101//! let y = x + 1;
102//! assert_eq!(y, bits(0));
103//! ```
104//!
105//! In this case, the addition of 1 caused [x] to wrap to all zeros.  This is totally normal,
106//! and what one would expect from hardware addition (without a carry).  If you _need_ the
107//! carry bit, then the solution is to first cast to 1 higher bit, and then add, or alternately,
108//! to compute the carry directly.
109//! ```
110//! # use rust_hdl_core::prelude::*;
111//! let x: Bits<40> = bits(0xFF_FFFF_FFFF);
112//! let y = bit_cast::<41, 40>(x) + 1;
113//! assert_eq!(y, bits(0x100_0000_0000));
114//! ```
115//!
116//! The order of the arguments does not matter.  The bit width of the calculation will be
117//! determined by the [Bits] width.
118//! ```
119//! # use rust_hdl_core::prelude::*;
120//! let x : Bits<25> = bits(0xCAFD);
121//! let y = 1 + x;
122//! assert_eq!(y, bits(0xCAFE));
123//! ```
124//!
125//! However, you cannot combine two different width [Bits] values in a single expression.
126//! ```compile_fail
127//! # use rust_hdl_core::prelude::*;
128//! let x: Bits<20> = bits(0x1234);
129//! let y: Bits<21> = bits(0x5123);
130//! let z = x + y; // Won't compile!
131//! ```
132//!
133//! ## Subtraction
134//! Hardware subtraction is defined using 2-s complement representation for negative numbers.
135//! This is pretty much a universal standard for representing negative numbers in binary, and
136//! has the added advantage that a hardware subtractor can be built from an adder and some basic
137//! gates.  Subtraction operates much like the [Wrapping] class.  Note that overflow and underflow
138//! are _not_ detected in RustHDL (nor are they detected in most hardware implementations either).
139//!
140//! Here is a simple example with a literal and subtraction that does not cause udnerflow
141//! ```
142//! # use rust_hdl_core::prelude::*;
143//! let x: Bits<40> = bits(0xDEAD_BEF0);
144//! let y = x - 1;
145//! assert_eq!(y, bits(0xDEAD_BEEF));
146//! ```
147//!
148//! When values underflow, the representation is still valid as a 2-s complement number.  For
149//! example,
150//!
151//! ```
152//! # use rust_hdl_core::prelude::*;
153//! let x: Bits<16> = bits(0x40);
154//! let y: Bits<16> = bits(0x60);
155//! let z = x - y;
156//! assert_eq!(z, bits(0xFFFF-0x20+1));
157//! ```
158//!
159//! Here, we compare the value of `z` with `0xFFFF-0x20+1` which is the 2-s complement
160//! representation of `-0x20`.
161//!
162//! You can also put the literal on the left side of the subtraction expression, as expected.  The
163//! bitwidth of the computation will be driven by the width of the [Bits] in the expression.
164//! ```
165//! # use rust_hdl_core::prelude::*;
166//! let x = bits::<32>(0xBABE);
167//! let z = 0xB_BABE - x;
168//! assert_eq!(z, bits(0xB_0000));
169//! ```
170//!
171//! ## Bitwise And
172//!
173//! You can combine [Bits] using the and operator `&`.  In general, avoid using the shortcut
174//! logical operator `&&`, since this operator is really only defined for logical (scalar) values
175//! of type `bool`.
176//!
177//! ```
178//! # use  rust_hdl_core::prelude::*;
179//! let x: Bits<32> = bits(0xDEAD_BEEF);
180//! let y: Bits<32> = bits(0xFFFF_0000);
181//! let z = x & y;
182//! assert_eq!(z, bits(0xDEAD_0000));
183//! ```
184//!
185//! Of course, you can also use a literal value in the `and` operation.
186//! ```
187//! # use rust_hdl_core::prelude::*;
188//! let x: Bits<32> = bits(0xDEAD_BEEF);
189//! let z = x & 0x0000_FFFF;
190//! assert_eq!(z, bits(0xBEEF))
191//! ```
192//!
193//! and similarly, the literal can appear on the left of the `and` expression.
194//! ```
195//! # use rust_hdl_core::prelude::*;
196//! let x: Bits<32> = bits(0xCAFE_BEEF);
197//! let z = 0xFFFF_0000 & x;
198//! assert_eq!(z, bits(0xCAFE_0000));
199//! ```
200//!
201//! Just like all other binary operations, you cannot mix widths (unless one of the
202//! values is a literal).
203//! ```compile_fail
204//! # use rust_hdl_core::prelude::*;
205//! let x: Bits<16> = bits(0xFEED_FACE);
206//! let y: Bits<17> = bits(0xABCE);
207//! let z = x & y; // Won't compile!
208//! ```
209//!
210//! ## Bitwise Or
211//!
212//! There is also a bitwise-OR operation using the `|` symbol.  Note that the logical OR
213//! (or shortcut OR) operator `||` is not supported for [Bits], as it is only defined for
214//! scalar boolean values.
215//!
216//! ```
217//! # use rust_hdl_core::prelude::*;
218//! let x : Bits<32> = bits(0xBEEF_0000);
219//! let y : Bits<32> = bits(0x0000_CAFE);
220//! let z = x | y;
221//! assert_eq!(z, bits(0xBEEF_CAFE));
222//! ```
223//!
224//! You can also use literals
225//! ```
226//! # use rust_hdl_core::prelude::*;
227//! let x : Bits<32> = bits(0xBEEF_0000);
228//! let z = x | 0x0000_CAFE;
229//! assert_eq!(z, bits(0xBEEF_CAFE));
230//! ```
231//!
232//! The caveat about mixing [Bits] of different widths still applies.
233//!
234//! ## Bitwise Xor
235//!
236//! There is a bitwise-Xor operation using the `^` operator.  This will compute the
237//! bitwise exclusive OR of the two values.
238//!
239//! ```
240//! # use rust_hdl_core::prelude::*;
241//! let x : Bits<32> = bits(0xCAFE_BABE);
242//! let y : Bits<32> = bits(0xFF00_00FF);
243//! let z = y ^ x;
244//! let w = z ^ y; // XOR applied twice is a null-op
245//! assert_eq!(w, x);
246//! ```
247//!
248//! ## Bitwise comparison
249//!
250//! The equality operator `==` can compare two [Bits] for bit-wise equality.
251//!
252//!```
253//! # use rust_hdl_core::prelude::*;
254//! let x: Bits<16> = bits(0x5ea1);
255//! let y: Bits<16> = bits(0xbadb);
256//! assert_eq!(x == y, false)
257//!```
258//!
259//! Again, it is a compile time failure to attempt to compare [Bits] of different
260//! widths.
261//!
262//!```compile_fail
263//! # use rust_hdl_core::prelude::*;
264//! let x: Bits<15> = bits(52);
265//! let y: Bits<16> = bits(32);
266//! let z = x == y; // Won't compile - bit widths must match
267//!```
268//!
269//! You can compare to literals, as they will automatically extended (or truncated) to match the
270//! bitwidth of the [Bits] value.
271//!
272//! ```
273//! # use rust_hdl_core::prelude::*;
274//! let x : Bits<16> = bits(32);
275//! let z = x == 32;
276//! let y = 32 == x;
277//! assert!(z);
278//! assert!(y);
279//! ```
280//!
281//! ## Unsigned comparison
282//!
283//! The [Bits] type only supports unsigned comparisons.  If you compare a [Bits] value
284//! to a signed integer, it will first convert the signed integer into 2s complement
285//! representation and then perform an unsigned comparison.  That is most likely _not_ what
286//! you want.  However, until there is full support for signed integer computations, that is
287//! the behavior you get.  Hardware signed comparisons require more circuitry and logic
288//! than unsigned comparisons, so the rationale is to not inadvertently bloat your hardware
289//! designs with sign-aware circuitry when you don't explicitly invoke it.  If you want signed
290//! values, use [Signed].
291//!
292//! Here are some simple examples.
293//! ```
294//! # use rust_hdl_core::prelude::*;
295//! let x: Bits<16> = bits(52);
296//! let y: Bits<16> = bits(13);
297//! assert!(y < x)
298//! ```
299//!
300//! We can also compare with literals, which RustHDL will expand out to match the bit width
301//! of the [Bits] being compared to.
302//! ```
303//! # use rust_hdl_core::prelude::*;
304//! let x: Bits<16> = bits(52);
305//! let y = x < 135;  // Converts the 135 to a Bits<16> and then compares
306//! assert!(y)
307//! ```
308//!
309//! ## Shift Left
310//!
311//! RustHDl supports left shift bit operations using the `<<` operator.
312//! Bits that shift off the left end of
313//! the bit vector (most significant bits).
314//!
315//! ```
316//! # use rust_hdl_core::prelude::*;
317//! let x: Bits<16> = bits(0xDEAD);
318//! let y = x << 8;
319//! assert_eq!(y, bits(0xAD00));
320//! ```
321//!
322//! ## Shift Right
323//!
324//! Right shifting is also supported using the `>>` operator.
325//! Bits that shift off the right end of the
326//! the bit vector (least significant bits).
327//!
328//! ```
329//! # use rust_hdl_core::prelude::*;
330//! let x: Bits<16> = bits(0xDEAD);
331//! let y = x >> 8;
332//! assert_eq!(y, bits(0x00DE));
333//! ```
334
335use crate::bitvec::BitVec;
336use crate::short_bit_vec::{ShortBitVec, ShortType, SHORT_BITS};
337use crate::synth::VCDValue;
338use num_bigint::BigUint;
339use num_traits::ToPrimitive;
340use std::cmp::Ordering;
341use std::fmt::{Binary, Debug, Formatter, LowerHex, UpperHex};
342use std::hash::Hasher;
343use std::num::Wrapping;
344
345// This comes with a few invariants that must be maintained for short representation
346// The short value must be less than 2^N
347// N <= SHORT_BITS --> Short repr, otherwise Long repr
348
349/// The [LiteralType] is used to set the type for literals that appear in RustHDL
350/// expressions.  Because of how Rust's type inference currently works, an expression
351/// like
352/// ```
353/// # use rust_hdl_core::prelude::*;
354///
355/// let x: Bits<32> = 0xDEADBEEF.into();
356/// let y : Bits<32> = x + 1;
357/// ```
358/// only works if Rust can unambiguously assign a type to the literal (either `DEADBEEF` or `1`).
359/// In earlier versions of RustHDL, this required adding a suffix to the literal like `0xDEADBEEF_u32`,
360/// but those suffixes in turn littered the code and made it difficult to read.  Now, only one type
361/// of literal is supported [LiteralType], which is an alias for [u64].  As such, any un-suffixed
362/// number is assumed to be at most a 64 bit integer.  This does not limit you in any way from
363/// using suffixed literals.  You can express, for example, up to 128 bit constants using standard
364/// Rust notation, and using the [to_bits] trait to convert it to a [Bits] type.
365/// ```
366/// # use rust_hdl_core::prelude::*;
367///
368/// let x: Bits<128> = 0xDEADBEEF_CAFE_1234_u128.to_bits();  // Works!
369/// ```
370/// However, the following will fail, since the [From] trait is only implemented on [LiteralType]
371/// to make the conversion unambiguous.
372/// ```compile_fail
373/// # use rust_hdl_core::prelude::*;
374///
375/// let x: Bits<128> = 0xDEADBEEF_CAFE_1234_u128.into();  // Fails to compile, since conversion from [u128] is not defined
376/// ```
377pub type LiteralType = u64;
378/// [LITERAL_BITS] is set to the number of bits in the [LiteralType].  I.e., it is guaranteed that
379/// the number of bits in [LiteralType] is [LITERAL_BITS].
380pub const LITERAL_BITS: usize = 64;
381
382/// Compute the minimum number of bits to represent a container with t items.
383/// This is basically `ceil(log2(t))` as a constant (compile time computable) function.
384/// You can use it where a const generic (bit width) argument is required.
385///
386/// Example
387///
388/// Unfortunately, with stable Rust, this function is not of much use.
389/// For now, const generic arguments cannot be used in expressions yet.
390/// Suppose we want to design a simple state machine that counts from
391/// from 0 to some maximum number N-1, and then cycles again.  We
392/// want to specify the maximum number, not the number of bits needed
393/// to represent it.  In this case, we would like to use the
394/// compile time `clog2` function to compute the bit width of
395/// the signal that holds the count.
396///
397/// ```rust, compile_fail
398/// # use rust_hdl_core::prelude::*;
399///
400/// #[derive(LogicBlock, Default)]
401/// struct CountToN<const N: usize> {
402///     signal_out: Signal<Out, Bits<{clog2({N})}>>,
403/// }
404/// ```
405///
406///
407pub const fn clog2(t: usize) -> usize {
408    let mut p = 0;
409    let mut b = 1;
410    while b < t {
411        p += 1;
412        b *= 2;
413    }
414    p
415}
416
417#[test]
418fn test_clog2_is_correct() {
419    assert_eq!(clog2(1024), 10);
420}
421
422/// The [Bits] type holds a bit array of size [N].
423#[derive(Clone, Debug, Copy)]
424pub enum Bits<const N: usize> {
425    #[doc(hidden)]
426    Short(ShortBitVec<N>),
427    #[doc(hidden)]
428    Long(BitVec<N>),
429}
430
431/// Convert from a [BigUint] to a [Bits].  Will panic if the number of bits
432/// needed to represent the value are greater than the width of the [Bits].
433/// ```
434/// # use num_bigint::BigUint;
435/// # use rust_hdl_core::bits::Bits;
436/// let x = BigUint::parse_bytes(b"10111000101", 2).unwrap();
437/// let y : Bits<16> = x.into();
438/// println!("y = {:x}", y); // Prints y = 02c5
439/// ```
440/// The following will panic, because the value cannot be represented in the
441/// given number of bits.
442/// ```
443/// # use rust_hdl_core::prelude::*;
444/// # use num_bigint::BigUint;
445/// let x = BigUint::parse_bytes(b"10111000101", 2).unwrap();
446/// let y : Bits<12> = x.into(); // Panics
447/// ```
448impl<const N: usize> From<BigUint> for Bits<N> {
449    fn from(x: BigUint) -> Self {
450        assert!(
451            x.bits() <= N as u64,
452            "cannot fit value from BigUInt with {} bits into Bits<{}>",
453            x.bits(),
454            N
455        );
456        if N <= SHORT_BITS {
457            x.to_u64().unwrap().into()
458        } else {
459            let mut ret = [false; N];
460            (0..N).for_each(|i| ret[i] = x.bit(i as u64));
461            Bits::Long(ret.into())
462        }
463    }
464}
465
466/// Convert from a [Bits] to a [BigUint].
467/// ```
468/// # use rust_hdl_core::prelude::*;
469/// # use num_bigint::BigUint;
470/// let x : Bits<128> = 0xDEAD_BEEF_CAFE_BABE_1234_5678_u128.to_bits();
471/// let y : BigUint = x.into();
472/// println!("y = {:x}", y); // Prints 0xDEAD_BEEF_CAFE_BABE_1234_5678
473/// ```
474impl<const N: usize> From<Bits<N>> for BigUint {
475    fn from(y: Bits<N>) -> Self {
476        let mut x = BigUint::default();
477        for i in 0..N {
478            x.set_bit(i as u64, y.get_bit(i));
479        }
480        x
481    }
482}
483
484#[cfg(test)]
485fn random_bits<const N: usize>() -> Bits<N> {
486    use rand::random;
487    let mut x = Bits::default();
488    for bit in 0..N {
489        if random::<bool>() {
490            x = x.replace_bit(bit, true);
491        }
492    }
493    x
494}
495
496#[test]
497fn test_biguint_roundtrip() {
498    use rand::random;
499    use seq_macro::seq;
500
501    seq!(N in 5..150 {
502        for _iters in 0..10 {
503            let y: Bits<N> = random_bits();
504            let z: BigUint = y.into();
505            let h: Bits<N> = z.into();
506            assert_eq!(h, y);
507        }
508    });
509    seq!(N in 5..150 {
510        for _iters in 0..10 {
511            let bits = (0..N).map(|_| if random::<bool>() {
512                b"1"[0]
513            } else {
514                b"0"[0]
515            }).collect::<Vec<u8>>();
516            let y = BigUint::parse_bytes(&bits, 2).unwrap();
517            let z : Bits<N> = y.clone().into();
518            let h : BigUint = z.into();
519            assert_eq!(h, y);
520        }
521    });
522}
523
524#[test]
525fn test_cast_from_biguint() {
526    let x = BigUint::parse_bytes(b"1011000101", 2).unwrap();
527    let y: Bits<16> = x.into();
528    let p = format!("y = {:x}", y);
529    assert_eq!(p, "y = 02c5");
530    println!("y = {:x}", y);
531}
532
533/// Allows you to format a [Bits] as a binary string
534/// ```
535/// # use rust_hdl_core::bits::Bits;
536/// let y = Bits::<16>::from(0b1011_0100_0010_0000);
537/// println!("y = {:b}", y); // Prints y = 1011010000100000
538/// ```
539impl<const N: usize> Binary for Bits<N> {
540    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
541        for i in 0..N {
542            if self.get_bit(N - 1 - i) {
543                write!(f, "1")?;
544            } else {
545                write!(f, "0")?;
546            }
547        }
548        Ok(())
549    }
550}
551
552#[test]
553fn test_print_as_binary() {
554    let x = Bits::<16>::from(0b_1011_0100_1000_0000);
555    let p = format!("x = {:b}", x);
556    assert_eq!(p, "x = 1011010010000000")
557}
558
559/// Allows you to format a [Bits] as a lowercase hex string
560/// ```
561/// # use rust_hdl_core::bits::Bits;
562/// let y = Bits::<16>::from(0xcafe);
563/// println!("y = {:x}", y); // Prints y = cafe
564/// ```
565impl<const N: usize> LowerHex for Bits<N> {
566    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
567        let m: usize = N + (4 - (N % 4)) % 4; // Round up to an integer number of nibbles
568        let digits: usize = m / 4;
569        for digit in 0..digits {
570            let nibble: Bits<4> = self.get_bits(4 * (digits - 1 - digit));
571            let nibble_u8: LiteralType = nibble.into();
572            std::fmt::LowerHex::fmt(&nibble_u8, f)?;
573        }
574        Ok(())
575    }
576}
577
578#[test]
579fn test_print_as_lowercase_hex() {
580    let x = Bits::<16>::from(0xcafe);
581    let p = format!("x = {:x}", x);
582    assert_eq!(p, "x = cafe");
583}
584
585/// Allows you to format a [Bits] as an uppercase hex string
586/// ```
587/// # use rust_hdl_core::bits::Bits;
588/// let y = Bits::<16>::from(0xcafe);
589/// println!("y = {:X}", y); // Prints y = CAFE
590/// ```
591impl<const N: usize> UpperHex for Bits<N> {
592    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
593        let m: usize = N + (4 - (N % 4)) % 4; // Round up to an integer number of nibbles
594        let digits: usize = m / 4;
595        for digit in 0..digits {
596            let nibble: Bits<4> = self.get_bits(4 * (digits - 1 - digit));
597            let nibble_u8: LiteralType = nibble.into();
598            std::fmt::UpperHex::fmt(&nibble_u8, f)?;
599        }
600        Ok(())
601    }
602}
603
604#[test]
605fn test_print_as_uppercase_hex() {
606    let x = Bits::<16>::from(0xcafe);
607    let p = format!("x = {:X}", x);
608    assert_eq!(p, "x = CAFE");
609}
610
611/// Convenience function to construct [Bits] from an unsigned literal
612/// Sometimes, you know you will be working with a value that is smaller than
613/// 128 bits (the current maximum sized built-in unsigned integer in Rust).
614/// In those cases, the [bits] function can make construction slightly
615/// simpler.
616/// ```
617/// # use rust_hdl_core::prelude::*;
618/// let x : Bits<14> = bits(0xDEA);
619/// assert_eq!("0dea", format!("{:x}", x))
620/// ```
621/// In most cases, it's easier to use `into`:
622/// ```
623/// # use rust_hdl_core::prelude::*;
624/// let x: Bits<14> = 0xDEA.into();
625/// assert_eq!("0dea", format!("{:x}", x))
626/// ```
627pub fn bits<const N: usize>(x: LiteralType) -> Bits<N> {
628    let t: Bits<N> = x.into();
629    t
630}
631
632/// The [ToBits] trait is used to provide a way to convert Rust standard unsigned
633/// types (currently `u8, u16, u32, u64, u128`) into [Bits] of different lengths.
634/// Note that RustHDL will panic if you attempt to convert an unsigned type into
635/// a [Bits] that is too small to hold the value.
636pub trait ToBits {
637    /// Convert the underlying type to a [Bits] of the specified size.  Invoked
638    /// using
639    /// ```
640    /// # use rust_hdl_core::prelude::*;
641    /// let x : Bits<4> = 0xF_u8.to_bits();
642    ///```
643    fn to_bits<const N: usize>(self) -> Bits<N>;
644}
645
646impl ToBits for u8 {
647    fn to_bits<const N: usize>(self) -> Bits<N> {
648        (self as LiteralType).into()
649    }
650}
651
652impl ToBits for u16 {
653    fn to_bits<const N: usize>(self) -> Bits<N> {
654        (self as LiteralType).into()
655    }
656}
657
658impl ToBits for u32 {
659    fn to_bits<const N: usize>(self) -> Bits<N> {
660        (self as LiteralType).into()
661    }
662}
663
664impl ToBits for u64 {
665    fn to_bits<const N: usize>(self) -> Bits<N> {
666        (self as LiteralType).into()
667    }
668}
669
670impl ToBits for usize {
671    fn to_bits<const N: usize>(self) -> Bits<N> {
672        (self as LiteralType).into()
673    }
674}
675
676impl ToBits for u128 {
677    fn to_bits<const N: usize>(self) -> Bits<N> {
678        Bits::<N>::from(BigUint::from(self))
679    }
680}
681
682/// Cast from one bit width to another with truncation or zero padding
683/// The [bit_cast] function allows you to convert from one bit width
684/// to another.  It handles the different widths in the following simplified
685/// manner:
686///    - if casting to a narrower bit width, the most significant bits are
687///      discarded until the new value fits into the specified bits
688///    - if casting to a wider bit width, the most significant bits are
689///      padded with zeros until the new value occupies the specified bits
690/// This may seem a bit counterintuitive, but it fits logical circuitry
691/// behavior.  Narrowing is usually done by preserving the least significant
692/// bits (so that the carry bits are discarded when adding, for example).
693/// Widening is also usually done (for unsigned values) by zero extending
694/// the most significant bits.  The [bit_cast] operation does both of
695/// these operations depending on the arguments.
696///
697/// First, an example of widening, in this case, an extra nibble is
698/// added to the most significant bits, and is set to zero.
699///```
700/// # use rust_hdl_core::prelude::*;
701/// let x : Bits<12> = bits(0xEAF);
702/// let y : Bits<16> = bit_cast(x); // M = 16, N = 12
703/// assert_eq!(y, bits::<16>(0x0EAF));
704///```
705///
706/// In the second example, we downcast, this time, discarding the most
707/// significant nibble.
708/// ```
709/// # use rust_hdl_core::prelude::*;
710/// let x : Bits<16> = bits(0xDEAF);
711/// let y : Bits<12> = bit_cast(x); // M = 12, N = 16
712/// assert_eq!(y, bits::<12>(0xEAF));
713/// ```
714///
715/// Note that internally, you can [bit_cast] from an arbitrary bit length
716/// to another arbitrary bit length without losing information because of
717/// any internal Rust limit.
718///
719/// Note also that bit-casting does _not_ preserve signedness.  Generally,
720/// RustHDL follows hardware conventions that values are unsigned.  If you
721/// want to work with signed bit vectors, use [Signed] instead.
722pub fn bit_cast<const M: usize, const N: usize>(x: Bits<N>) -> Bits<M> {
723    match x {
724        Bits::Short(t) => {
725            let t: ShortType = t.into();
726            let t = if M < N {
727                t & ShortBitVec::<M>::mask().short()
728            } else {
729                t
730            };
731            let k: Bits<M> = (t as LiteralType).into();
732            k
733        }
734        Bits::Long(t) => {
735            if M > SHORT_BITS {
736                Bits::Long(t.resize())
737            } else {
738                let k: ShortType = t.into();
739                Bits::Short(k.into())
740            }
741        }
742    }
743}
744
745#[doc(hidden)]
746impl<const N: usize> From<Bits<N>> for VCDValue {
747    fn from(val: Bits<N>) -> Self {
748        if N == 1 {
749            if val.get_bit(0) {
750                VCDValue::Single(vcd::Value::V1)
751            } else {
752                VCDValue::Single(vcd::Value::V0)
753            }
754        } else {
755            let mut x = vec![];
756            for i in 0..N {
757                if val.get_bit(N - 1 - i) {
758                    x.push(vcd::Value::V1)
759                } else {
760                    x.push(vcd::Value::V0)
761                }
762            }
763            VCDValue::Vector(x)
764        }
765    }
766}
767
768#[test]
769fn test_bits_from_int_via_bits() {
770    let x: Bits<23> = bits(23);
771    let u: LiteralType = x.into();
772    assert_eq!(u, 23);
773}
774
775impl<const N: usize> Bits<N> {
776    #[inline(always)]
777    /// The [any] function returns true if any of the
778    /// individual bits are true, and false otherwise.
779    /// This reduction operation is equivalent to a logical
780    /// OR of all the bits in the vector.
781    /// ```
782    /// # use rust_hdl_core::prelude::*;
783    /// let x : Bits<14> = bits(0xDEA);
784    /// assert_eq!(x.any(), true);
785    /// let y : Bits<14> = Bits::default();
786    /// assert_eq!(y.any(), false);
787    /// ```
788    pub fn any(&self) -> bool {
789        match self {
790            Bits::Short(x) => x.any(),
791            Bits::Long(x) => x.any(),
792        }
793    }
794
795    #[inline(always)]
796    /// The [all] function returns true if all of the individual
797    /// bits are true, and false otherwise.  This reduction
798    /// operation is equivalent to a logical AND of all the bits
799    /// in the vector.
800    /// ```
801    /// # use rust_hdl_core::prelude::*;
802    /// let x : Bits<14> = bits(0xDEA);
803    /// assert_eq!(x.all(), false);
804    /// let y : Bits<14> = bits(0x3FFF);
805    /// assert_eq!(y.all(), true);
806    /// ```
807    pub fn all(&self) -> bool {
808        match self {
809            Bits::Short(x) => x.all(),
810            Bits::Long(x) => x.all(),
811        }
812    }
813
814    #[inline(always)]
815    /// The [xor] function computes the exclusive OR of all
816    /// the bits in the vector.  This is equivalent to counting
817    /// the number of ones.  If the number is odd, the XOR will
818    /// be true.  If even, it will be false.
819    /// ```
820    /// # use rust_hdl_core::prelude::*;
821    /// let x: Bits<12> = bits(0b1100_0100_1100);
822    /// assert_eq!(x.xor(), true);
823    /// let y: Bits<12> = bits(0b1100_0110_1100);
824    /// assert_eq!(y.xor(), false);
825    /// ```
826    pub fn xor(&self) -> bool {
827        match self {
828            Bits::Short(x) => x.xor(),
829            Bits::Long(x) => x.xor(),
830        }
831    }
832
833    /// The [index] function is used when a [Bits] is going
834    /// to be used to index into an array or some other bit vector.
835    /// This is typically a very specialized hardware operation,
836    /// so there are limited cases in which it can be used.  Also,
837    /// there is an assumption that the [Bits] being used as
838    /// an index is sufficiently small to fit in a natural word (assume 32 bits, here
839    /// for safety).  In practice, that means, that if you are
840    /// indexing into a register using some other register/value,
841    /// the _length_ of the register is limited to a few billion bits.
842    /// ```
843    /// # use rust_hdl_core::prelude::*;
844    /// let x: Bits<12> = bits(0b1100_0100_1100);
845    /// assert_eq!(x.index(), 0b1100_0100_1100_usize);
846    /// ```
847    pub fn index(&self) -> usize {
848        match self {
849            Bits::Short(x) => x.short() as usize,
850            Bits::Long(_x) => panic!("Cannot map long bit vector to index type"),
851        }
852    }
853
854    #[inline(always)]
855    /// Return the number of bits in the current [Bits].
856    /// Because this is determined at compile time, it is
857    /// of limited use as a runtime function, but is there
858    /// nonetheless.
859    /// ```
860    /// # use rust_hdl_core::prelude::*;
861    /// let x : Bits<14> = Bits::default();
862    /// assert_eq!(x.len(), 14);
863    /// ```
864    pub fn len(&self) -> usize {
865        N
866    }
867
868    #[inline(always)]
869    /// Return true if this [Bits] contains no actual bits (i.e., N = 0).
870    pub fn is_empty(&self) -> bool {
871        N == 0
872    }
873
874    /// Compute the number of possible values that a [Bits]
875    /// can take.  This is basically 2 raised to the Nth
876    /// power.  Because the result is returned as a [usize],
877    /// you must be careful, since this can easily overflow.
878    /// A [Bits<256>] for example, cannot represent [count]
879    /// on a normal 64 bit machine.
880    /// ```
881    /// # use rust_hdl_core::prelude::*;
882    /// assert_eq!(Bits::<16>::count(), 1 << 16);
883    /// ```
884    pub fn count() -> u128 {
885        1 << N
886    }
887
888    #[inline(always)]
889    /// Extract the [index] bit from the given [Bits]. This will
890    /// cause a runtime panic if the [index] bit is out of range
891    /// of the width of the bitvector.
892    /// ```
893    /// # use rust_hdl_core::prelude::*;
894    /// let x : Bits<14> = bits(0b10110);
895    /// assert_eq!(x.get_bit(0), false);
896    /// assert_eq!(x.get_bit(1), true);
897    /// assert_eq!(x.get_bit(2), true); // You get the idea
898    /// ```
899    pub fn get_bit(&self, index: usize) -> bool {
900        assert!(index < N);
901        match self {
902            Bits::Short(x) => x.get_bit(index),
903            Bits::Long(x) => x.get_bit(index),
904        }
905    }
906
907    /// Replace the given bit of a [Bits] with a new bit value.
908    /// This method leaves the original value alone, and returns
909    /// a new [Bits] with all bits except the designated one left
910    /// alone.
911    /// ```
912    /// # use rust_hdl_core::prelude::*;
913    /// let x: Bits<16> = bits(0b1100_0000);
914    /// let x = x.replace_bit(0, true);
915    /// let x = x.replace_bit(7, false);
916    /// assert_eq!(x, bits(0b0100_0001));
917    /// ```
918    pub fn replace_bit(&self, index: usize, val: bool) -> Self {
919        assert!(index < N);
920        match self {
921            Bits::Short(x) => Bits::Short(x.replace_bit(index, val)),
922            Bits::Long(x) => Bits::Long(x.replace_bit(index, val)),
923        }
924    }
925
926    #[inline(always)]
927    /// Return a subset of bits from a [Bits] value, with a given offset.
928    /// To preserve the feasibility of representing this in hardware, the width
929    /// of the result must be fixed (the argument [M]), and only the offset
930    /// can be computed.
931    /// ```
932    /// # use rust_hdl_core::prelude::*;
933    /// let x: Bits<40> = bits(0xDEAD_BEEF_CA);
934    /// let y = x.get_bits::<32>(8);
935    /// assert_eq!(y, bits(0xDEAD_BEEF))
936    /// ```
937    pub fn get_bits<const M: usize>(&self, index: usize) -> Bits<M> {
938        assert!(index <= N);
939        bit_cast::<M, N>(*self >> index as LiteralType)
940    }
941
942    #[inline(always)]
943    /// Set a group of bits in a value.  This operation modifies the
944    /// value in place.
945    /// ```
946    /// # use rust_hdl_core::prelude::*;
947    /// let mut x: Bits<40> = bits(0xDEAD_BEEF_CA);
948    /// x.set_bits::<16>(8, bits(0xCAFE));
949    /// assert_eq!(x, bits(0xDEAD_CAFE_CA));
950    /// ```
951    pub fn set_bits<const M: usize>(&mut self, index: usize, rhs: Bits<M>) {
952        assert!(index <= N);
953        assert!(index + M <= N);
954        let mask = !(bit_cast::<N, M>(Bits::<M>::mask()) << index as LiteralType);
955        let masked = *self & mask;
956        let replace = bit_cast::<N, M>(rhs) << index as LiteralType;
957        *self = masked | replace
958    }
959
960    #[inline(always)]
961    /// Returns a [Bits] value that contains [N] ones.
962    /// ```
963    /// # use rust_hdl_core::prelude::*;
964    /// let x = Bits::<40>::mask();
965    /// assert_eq!(x, bits(0xFF_FFFF_FFFF));
966    /// ```
967    pub fn mask() -> Bits<N> {
968        if N <= SHORT_BITS {
969            Bits::Short(ShortBitVec::<N>::mask())
970        } else {
971            Bits::Long([true; N].into())
972        }
973    }
974
975    /// Returns the width in bits of the [BitVec].
976    /// Note that this is the number of bits allocated.
977    /// It does not depend on the value at all.
978    /// ```
979    /// # use rust_hdl_core::prelude::*;
980    /// assert_eq!(Bits::<40>::width(), 40);
981    /// ```
982    pub const fn width() -> usize {
983        N
984    }
985
986    /// Convert [Bits] to an [u8].
987    /// ```
988    /// # use rust_hdl_core::prelude::*;
989    /// let x : Bits<6> = 12.into();
990    /// let y = x.to_u8();
991    /// assert_eq!(y, 12_u8);
992    /// ```
993    /// Note that this will panic if the width of the
994    /// bitvector is larger than 8 bits.
995    /// ```should_panic
996    /// # use rust_hdl_core::prelude::*;
997    /// let x: Bits<12> = 0xADE.into();
998    /// let y = x.to_u8(); // Panics - too many bits
999    /// ```
1000    pub fn to_u8(self) -> u8 {
1001        assert!(N <= 8, "Cannot convert Bits::<{}> to u8 - too many bits", N);
1002        let x: LiteralType = self.into();
1003        x as u8
1004    }
1005
1006    /// Convert [Bits] to an [u16].
1007    /// ```
1008    /// # use rust_hdl_core::prelude::*;
1009    /// let x : Bits<12> = 12.into();
1010    /// let y = x.to_u16();
1011    /// assert_eq!(y, 12_u16);
1012    /// ```
1013    /// Note that this will panic if the width of the
1014    /// bitvector is larger than 16 bits.
1015    /// ```should_panic
1016    /// # use rust_hdl_core::prelude::*;
1017    /// let x: Bits<20> = 0xADE.into();
1018    /// let y = x.to_u16(); // Panics - too many bits
1019    /// ```
1020    pub fn to_u16(self) -> u16 {
1021        assert!(
1022            N <= 16,
1023            "Cannot convert Bits::<{}> to u16 - too many bits",
1024            N
1025        );
1026        let x: LiteralType = self.into();
1027        x as u16
1028    }
1029
1030    /// Convert [Bits] to an [u32].
1031    /// ```
1032    /// # use rust_hdl_core::prelude::*;
1033    /// let x : Bits<24> = 12.into();
1034    /// let y = x.to_u32();
1035    /// assert_eq!(y, 12_u32);
1036    /// ```
1037    /// Note that this will panic if the width of the
1038    /// bitvector is larger than 32 bits.
1039    /// ```should_panic
1040    /// # use rust_hdl_core::prelude::*;
1041    /// let x: Bits<40> = 0xADE.into();
1042    /// let y = x.to_u32(); // Panics - too many bits
1043    /// ```
1044    pub fn to_u32(self) -> u32 {
1045        assert!(
1046            N <= 32,
1047            "Cannot convert Bits::<{}> to u32 - too many bits",
1048            N
1049        );
1050        let x: LiteralType = self.into();
1051        x as u32
1052    }
1053
1054    /// Convert [Bits] to an [u64].
1055    /// ```
1056    /// # use rust_hdl_core::prelude::*;
1057    /// let x : Bits<40> = 12.into();
1058    /// let y = x.to_u64();
1059    /// assert_eq!(y, 12_u64);
1060    /// ```
1061    /// Note that this will panic if the width of the
1062    /// bitvector is larger than 64 bits.
1063    /// ```should_panic
1064    /// # use rust_hdl_core::prelude::*;
1065    /// let x: Bits<80> = 0xADE.into();
1066    /// let y = x.to_u64(); // Panics - too many bits
1067    /// ```
1068    pub fn to_u64(self) -> u64 {
1069        assert!(
1070            N <= 64,
1071            "Cannot convert Bits::<{}> to u64 - too many bits",
1072            N
1073        );
1074        let x: LiteralType = self.into();
1075        x
1076    }
1077
1078    /// Convert [Bits] to an [u128].
1079    /// ```
1080    /// # use rust_hdl_core::prelude::*;
1081    /// let x : Bits<80> = 12.into();
1082    /// let y = x.to_u128();
1083    /// assert_eq!(y, 12_u128);
1084    /// ```
1085    /// Note that this will panic if the width of the
1086    /// bitvector is larger than 128 bits.
1087    /// ```should_panic
1088    /// # use rust_hdl_core::prelude::*;
1089    /// let x: Bits<140> = 0xADE.into();
1090    /// let y = x.to_u128(); // Panics - too many bits
1091    /// ```
1092    pub fn to_u128(self) -> u128 {
1093        match self {
1094            Bits::Short(x) => x.to_u128(),
1095            Bits::Long(x) => x.to_u128(),
1096        }
1097    }
1098}
1099
1100impl From<bool> for Bits<1> {
1101    #[inline(always)]
1102    /// Convenience method that allows you to convert
1103    /// a boolean into a single bit-width [Bits].
1104    /// ```
1105    /// # use rust_hdl_core::prelude::*;
1106    /// let x : Bits<1> = true.into();
1107    /// assert_eq!(x, bits(1))
1108    /// ```
1109    fn from(x: bool) -> Self {
1110        if x {
1111            1.into()
1112        } else {
1113            0.into()
1114        }
1115    }
1116}
1117
1118impl From<Bits<1>> for bool {
1119    #[inline(always)]
1120    /// Convenience method for converting a 1-bit
1121    /// width [Bits] value into a boolean value.
1122    /// ```
1123    /// # use rust_hdl_core::prelude::*;
1124    /// let x : Bits<1> = bits(1);
1125    /// let y : bool = x.into();
1126    /// assert!(y)
1127    /// ```
1128    fn from(val: Bits<1>) -> Self {
1129        val.get_bit(0)
1130    }
1131}
1132
1133/// Convert from [LiteralType] to [Bits].  Because of some restrictions on
1134/// how Rust's type inference works, when you work with unsized
1135/// literals (e.g., `x = 3`), there must either be a unique integer type
1136/// that can fit the expression, or it will default to `i32`.  Unfortunately,
1137/// in general, [Bits] are used to represent unsigned types.  The upshot
1138/// of all this is that RustHDL selects one unsigned integer type to represent
1139/// literals.  Although not ideal, RustHDL uses a [LiteralType] (currently 'u64') to represent literals
1140/// so as to make HDL expressions close to Verilog or VHDL.  This choice should not affect
1141/// any hardware implementation, as hardware registers need to be of [Bits] type.
1142/// ```
1143/// # use rust_hdl_core::prelude::*;
1144/// let x: Bits<16> = 0xDEAD.into(); // This is interpreteed as a 128 bit constant by Rust
1145/// ```
1146/// This example is the largest bit width literal you can express using current
1147/// edition Rust:
1148/// ```
1149/// # use rust_hdl_core::prelude::*;
1150/// let x: Bits<128> = 0xDEADBEEF_CAFEBABE_1234ABCD_00005EA1_u128.to_bits();
1151/// ```
1152/// From a safety perspective, RustHDL will panic if the argument is too large to fit
1153/// into the bit vector.  Thus, this example will panic, since the literal cannot be
1154/// fit into 16 bits without truncation:
1155/// ```should_panic
1156/// # use rust_hdl_core::prelude::*;
1157/// let x: Bits<16> = 0xDEADBEEF.into(); // This will panic!
1158/// ```
1159impl<const N: usize> From<LiteralType> for Bits<N> {
1160    fn from(x: LiteralType) -> Self {
1161        if N > SHORT_BITS {
1162            let y: BitVec<N> = x.into();
1163            Bits::Long(y)
1164        } else {
1165            assert!(
1166                x <= ShortBitVec::<N>::max_legal(),
1167                "Value 0x{:x} does not fit into bitvector of length {}",
1168                x,
1169                N
1170            );
1171            Bits::Short((x as ShortType).into())
1172        }
1173    }
1174}
1175
1176impl<const N: usize> From<Wrapping<LiteralType>> for Bits<N> {
1177    fn from(x: Wrapping<LiteralType>) -> Self {
1178        x.0.into()
1179    }
1180}
1181
1182/// Convert a [Bits] back to [u128].  Until Rust supports larger integers, the [u128] is
1183/// the largest integer type you can use without resorting to [BigUint].  RustHDL will panic
1184/// if you try to convert a [Bits] that is more than 128 bits to a literal.  Even if the
1185/// value in the bitvector would fit.
1186///```
1187///# use rust_hdl_core::prelude::*;
1188/// let x: Bits<16> = 0xDEAD.into();
1189/// let y: u128 = x.to_u128();
1190/// assert_eq!(y, 0xDEAD);
1191///```
1192///The following will panic even through the literal value stored in the 256 bit vector
1193///is less than 128 bits.
1194///```should_panic
1195///# use rust_hdl_core::prelude::*;
1196///let x : Bits<256> = 42.into();
1197///let y: u128 = x.to_u128(); // Panics!
1198/// ```
1199impl<const N: usize> From<Bits<N>> for LiteralType {
1200    fn from(x: Bits<N>) -> Self {
1201        assert!(N <= LITERAL_BITS);
1202        match x {
1203            Bits::Short(t) => {
1204                let p: ShortType = t.into();
1205                p as LiteralType
1206            }
1207            Bits::Long(t) => t.into(),
1208        }
1209    }
1210}
1211
1212#[inline(always)]
1213#[doc(hidden)]
1214fn binop<Tshort, TLong, const N: usize>(
1215    a: Bits<N>,
1216    b: Bits<N>,
1217    short_op: Tshort,
1218    long_op: TLong,
1219) -> Bits<N>
1220where
1221    Tshort: Fn(ShortBitVec<N>, ShortBitVec<N>) -> ShortBitVec<N>,
1222    TLong: Fn(BitVec<N>, BitVec<N>) -> BitVec<N>,
1223{
1224    match a {
1225        Bits::Short(x) => match b {
1226            Bits::Short(y) => Bits::Short(short_op(x, y)),
1227            _ => {
1228                unreachable!()
1229            }
1230        },
1231        Bits::Long(x) => match b {
1232            Bits::Long(y) => Bits::Long(long_op(x, y)),
1233            _ => {
1234                unreachable!()
1235            }
1236        },
1237    }
1238}
1239
1240macro_rules! op {
1241    ($func: ident, $method: ident, $op: tt) => {
1242        #[doc(hidden)]
1243        impl<const N: usize> std::ops::$method<Bits<N>> for Bits<N> {
1244            type Output = Bits<N>;
1245
1246            #[inline(always)]
1247            fn $func(self, rhs: Bits<N>) -> Self::Output {
1248                binop(self, rhs, |a, b| a $op b, |a, b| a $op b)
1249            }
1250        }
1251
1252        impl<const N: usize> std::ops::$method<LiteralType> for Bits<N> {
1253            type Output = Bits<N>;
1254
1255            fn $func(self, rhs: LiteralType) -> Self::Output {
1256                binop(self, rhs.into(), |a, b| a $op b, |a, b| a $op b)
1257            }
1258        }
1259
1260        impl<const N: usize> std::ops::$method<Bits<N>> for LiteralType {
1261            type Output = Bits<N>;
1262
1263            #[inline(always)]
1264            fn $func(self, rhs: Bits<N>) -> Self::Output {
1265                binop(self.into(), rhs.into(), |a, b| a $op b, |a, b| a $op b)
1266            }
1267        }
1268    }
1269}
1270
1271op!(add, Add, +);
1272op!(sub, Sub, -);
1273op!(bitor, BitOr, |);
1274op!(bitand, BitAnd, &);
1275op!(bitxor, BitXor, ^);
1276
1277macro_rules! op_shift {
1278    ($func: ident, $method: ident, $op: tt) => {
1279        impl<const M: usize, const N: usize> std::ops::$method<Bits<M>> for Bits<N> {
1280            type Output = Bits<N>;
1281
1282            #[inline(always)]
1283            fn $func(self, rhs: Bits<M>) -> Self::Output {
1284                self $op rhs.to_u64()
1285            }
1286        }
1287
1288        impl<const N: usize> std::ops::$method<LiteralType> for Bits<N> {
1289            type Output = Bits<N>;
1290
1291            fn $func(self, rhs: LiteralType) -> Self::Output {
1292                match self {
1293                    Bits::Short(x) => Bits::Short(x $op rhs),
1294                    Bits::Long(x) =>
1295                        Bits::Long(x $op rhs),
1296                }
1297            }
1298        }
1299
1300        impl<const N: usize> std::ops::$method<Bits<N>> for LiteralType {
1301            type Output = Bits<LITERAL_BITS>;
1302
1303            fn $func(self, rhs: Bits<N>) -> Self::Output {
1304                binop(self.into(), bit_cast(rhs), |a, b| a $op b, |a, b| a $op b)
1305            }
1306        }
1307
1308    }
1309}
1310
1311op_shift!(shr, Shr, >>);
1312op_shift!(shl, Shl, <<);
1313
1314/// Construct a default [Bits] - i.e., a zero bit vector of length N.
1315/// ```
1316/// # use rust_hdl_core::prelude::*;
1317/// let x : Bits<200> = Default::default();
1318/// assert_eq!(x, bits(0));
1319/// ```
1320impl<const N: usize> Default for Bits<N> {
1321    fn default() -> Bits<N> {
1322        bits::<N>(0)
1323    }
1324}
1325
1326/// Bitwise inversion of a [Bits] vector
1327/// The `!` operator will invert each bit in a [Bits] vector.
1328/// ```
1329/// # use rust_hdl_core::prelude::*;
1330/// let x : Bits<16> = bits(0xAAAA);
1331/// let y = !x;
1332/// assert_eq!(y, bits(0x5555))
1333/// ```
1334impl<const N: usize> std::ops::Not for Bits<N> {
1335    type Output = Bits<N>;
1336
1337    fn not(self) -> Self::Output {
1338        match self {
1339            Bits::Short(x) => Bits::Short(!x),
1340            Bits::Long(x) => Bits::Long(!x),
1341        }
1342    }
1343}
1344
1345#[doc(hidden)]
1346impl<const N: usize> Ord for Bits<N> {
1347    fn cmp(&self, other: &Bits<N>) -> Ordering {
1348        self.partial_cmp(other).unwrap()
1349    }
1350}
1351
1352#[doc(hidden)]
1353impl<const N: usize> PartialOrd<Bits<N>> for LiteralType {
1354    fn partial_cmp(&self, other: &Bits<N>) -> Option<Ordering> {
1355        let self_as_bits: Bits<N> = (*self).into();
1356        self_as_bits.partial_cmp(other)
1357    }
1358}
1359
1360#[doc(hidden)]
1361impl<const N: usize> PartialOrd<LiteralType> for Bits<N> {
1362    fn partial_cmp(&self, other: &LiteralType) -> Option<Ordering> {
1363        let other_as_bits: Bits<N> = (*other).into();
1364        self.partial_cmp(&other_as_bits)
1365    }
1366}
1367
1368#[doc(hidden)]
1369impl<const N: usize> PartialOrd<Bits<N>> for Bits<N> {
1370    #[inline(always)]
1371    fn partial_cmp(&self, other: &Bits<N>) -> Option<Ordering> {
1372        match self {
1373            Bits::Short(x) => match other {
1374                Bits::Short(y) => x.partial_cmp(y),
1375                _ => panic!("Short Long case"),
1376            },
1377            Bits::Long(x) => match other {
1378                Bits::Long(y) => x.partial_cmp(y),
1379                _ => panic!("Long short case"),
1380            },
1381        }
1382    }
1383}
1384
1385#[doc(hidden)]
1386impl<const N: usize> PartialEq<Bits<N>> for Bits<N> {
1387    #[inline(always)]
1388    fn eq(&self, other: &Bits<N>) -> bool {
1389        match self {
1390            Bits::Short(x) => match other {
1391                Bits::Short(y) => x == y,
1392                _ => panic!("Short Long case"),
1393            },
1394            Bits::Long(x) => match other {
1395                Bits::Long(y) => x == y,
1396                _ => panic!("Long Short case"),
1397            },
1398        }
1399    }
1400}
1401
1402#[doc(hidden)]
1403impl<const N: usize> PartialEq<LiteralType> for Bits<N> {
1404    fn eq(&self, other: &LiteralType) -> bool {
1405        let other_as_bits: Bits<N> = (*other).into();
1406        self.eq(&other_as_bits)
1407    }
1408}
1409
1410#[doc(hidden)]
1411impl<const N: usize> PartialEq<Bits<N>> for LiteralType {
1412    fn eq(&self, other: &Bits<N>) -> bool {
1413        let self_as_bits: Bits<N> = (*self).into();
1414        self_as_bits.eq(other)
1415    }
1416}
1417
1418#[doc(hidden)]
1419impl PartialEq<bool> for Bits<1> {
1420    #[inline(always)]
1421    fn eq(&self, other: &bool) -> bool {
1422        self.get_bit(0) == *other
1423    }
1424}
1425
1426#[doc(hidden)]
1427impl PartialEq<Bits<1>> for bool {
1428    fn eq(&self, other: &Bits<1>) -> bool {
1429        *self == other.get_bit(0)
1430    }
1431}
1432
1433#[doc(hidden)]
1434impl<const N: usize> Eq for Bits<N> {}
1435
1436#[doc(hidden)]
1437impl<const N: usize> std::hash::Hash for Bits<N> {
1438    fn hash<H: Hasher>(&self, state: &mut H) {
1439        match self {
1440            Bits::Short(t) => t.hash(state),
1441            Bits::Long(t) => t.hash(state),
1442        }
1443    }
1444}
1445
1446#[doc(hidden)]
1447impl<const N: usize> std::ops::Add<bool> for Bits<N> {
1448    type Output = Bits<N>;
1449
1450    fn add(self, rhs: bool) -> Self::Output {
1451        if rhs {
1452            self + Bits::<N>::from(1)
1453        } else {
1454            self
1455        }
1456    }
1457}
1458
1459#[cfg(test)]
1460mod tests {
1461    use super::{bit_cast, clog2, Bits};
1462    use crate::bits::random_bits;
1463    use crate::bits::{LiteralType, ToBits};
1464    use num_bigint::BigUint;
1465    use num_traits::One;
1466    use seq_macro::seq;
1467    use std::num::Wrapping;
1468
1469    #[test]
1470    fn test_get_bits_section() {
1471        let x: Bits<40> = 0xD_ADBE_EFCA.into();
1472        let y = x.get_bits::<32>(8).to_u32();
1473        let answer = 0xDAD_BEEF;
1474        assert_eq!(y, answer);
1475    }
1476
1477    #[test]
1478    fn test_short_from_u8() {
1479        let x: Bits<4> = 15.into();
1480        let y: LiteralType = x.into();
1481        assert_eq!(y, 15 & (0x0F));
1482    }
1483
1484    #[test]
1485    fn test_short_from_u16() {
1486        let x: Bits<12> = 1432.into();
1487        let y: LiteralType = x.into();
1488        assert_eq!(y, 1432 & (0x0FFF));
1489    }
1490
1491    #[test]
1492    fn test_short_from_u32() {
1493        let x: Bits<64> = 12434234.into();
1494        let y: LiteralType = x.into();
1495        assert_eq!(y, 12434234);
1496    }
1497
1498    #[test]
1499    fn test_from_u32() {
1500        let x: Bits<64> = 0xFFFF_FFFF.into();
1501        let y: LiteralType = x.into();
1502        assert_eq!(y, 0xFFFF_FFFF);
1503    }
1504
1505    #[test]
1506    fn or_test() {
1507        let a: Bits<32> = 45.into();
1508        let b: Bits<32> = 10395.into();
1509        let c = a | b;
1510        let c_u32: LiteralType = c.into();
1511        assert_eq!(c_u32, 45 | 10395)
1512    }
1513    #[test]
1514    fn and_test() {
1515        let a: Bits<32> = 45.into();
1516        let b: Bits<32> = 10395.into();
1517        let c = a & b;
1518        let c_u32: LiteralType = c.into();
1519        assert_eq!(c_u32, 45 & 10395)
1520    }
1521    #[test]
1522    fn xor_test() {
1523        let a: Bits<32> = 45.into();
1524        let b: Bits<32> = 10395.into();
1525        let c = a ^ b;
1526        let c_u32: LiteralType = c.into();
1527        assert_eq!(c_u32, 45 ^ 10395)
1528    }
1529    #[test]
1530    fn not_test() {
1531        let a: Bits<32> = 45.into();
1532        let c = !a;
1533        let c_u32: LiteralType = c.into();
1534        assert_eq!(c_u32, (!45_u32) as LiteralType);
1535    }
1536    #[test]
1537    fn shr_test() {
1538        let a: Bits<32> = 10395.into();
1539        let c: Bits<32> = a >> 4;
1540        let c_u32: LiteralType = c.into();
1541        assert_eq!(c_u32, 10395 >> 4);
1542    }
1543    #[test]
1544    fn shr_test_pair() {
1545        let a: Bits<32> = 10395.into();
1546        let b: Bits<32> = 4.into();
1547        let c = a >> b;
1548        let c_u32: LiteralType = c.into();
1549        assert_eq!(c_u32, 10395 >> 4);
1550    }
1551    #[test]
1552    fn shl_test() {
1553        let a: Bits<32> = 10395.into();
1554        let c = a << 24;
1555        let c_u32 = c.to_u32();
1556        assert_eq!(c_u32, 10395 << 24);
1557    }
1558    #[test]
1559    fn shl_test_pair() {
1560        let a: Bits<32> = 10395.into();
1561        let b: Bits<32> = 4.into();
1562        let c = a << b;
1563        let c_u32: LiteralType = c.into();
1564        assert_eq!(c_u32, 10395 << 4);
1565    }
1566    #[test]
1567    fn add_works() {
1568        let a: Bits<32> = 10234.into();
1569        let b: Bits<32> = 19423.into();
1570        let c = a + b;
1571        let c_u32: LiteralType = c.into();
1572        assert_eq!(c_u32, 10234 + 19423);
1573    }
1574    #[test]
1575    fn add_int_works() {
1576        let a: Bits<32> = 10234.into();
1577        let b = 19423;
1578        let c: Bits<32> = a + b;
1579        let c_u32: LiteralType = c.into();
1580        assert_eq!(c_u32, 10234 + 19423);
1581    }
1582    #[test]
1583    fn add_works_with_overflow() {
1584        let x = 2_042_102_334_u32;
1585        let y = 2_942_142_512_u32;
1586        let a: Bits<32> = x.to_bits();
1587        let b: Bits<32> = y.to_bits();
1588        let c = a + b;
1589        let c_u32 = c.to_u32();
1590        assert_eq!(Wrapping(c_u32), Wrapping(x) + Wrapping(y));
1591    }
1592    #[test]
1593    fn sub_works() {
1594        let x = 2_042_102_334_u32;
1595        let y = 2_942_142_512_u32;
1596        let a: Bits<32> = x.to_bits();
1597        let b: Bits<32> = y.to_bits();
1598        let c = a - b;
1599        let c_u32 = c.to_u32();
1600        assert_eq!(Wrapping(c_u32), Wrapping(x) - Wrapping(y));
1601    }
1602    #[test]
1603    fn sub_int_works() {
1604        let x = 2_042_102_334_u32;
1605        let y = 2_942_142_512;
1606        let a: Bits<32> = x.to_bits();
1607        let c = a - y;
1608        let c_u32 = c.to_u32();
1609        assert_eq!(Wrapping(c_u32), Wrapping(x) - Wrapping(y as u32));
1610    }
1611    #[test]
1612    fn eq_works() {
1613        let x = 2_032_142_351;
1614        let y = 2_942_142_512;
1615        let a: Bits<32> = x.into();
1616        let b: Bits<32> = x.into();
1617        let c: Bits<32> = y.into();
1618        assert_eq!(a, b);
1619        assert_ne!(a, c)
1620    }
1621    #[test]
1622    fn mask_works() {
1623        let a: Bits<48> = 0xFFFF_FFFF_FFFF.into();
1624        let b = Bits::<48>::mask();
1625        assert_eq!(a, b);
1626        let a: Bits<16> = 0xFFFF.into();
1627        let b = Bits::<16>::mask();
1628        assert_eq!(a, b)
1629    }
1630    #[test]
1631    fn get_bit_works() {
1632        // 0101 = 5
1633        let a: Bits<48> = 0xFFFF_FFFF_FFF5.into();
1634        assert!(a.get_bit(0));
1635        assert!(!a.get_bit(1));
1636        assert!(a.get_bit(2));
1637        assert!(!a.get_bit(3));
1638        let c: Bits<5> = 3.into();
1639        assert!(!a.get_bit(c.index()));
1640    }
1641    #[test]
1642    fn test_bit_cast_short() {
1643        let a: Bits<8> = 0xFF.into();
1644        let b: Bits<16> = bit_cast(a);
1645        assert_eq!(b, 0xFF);
1646        let c: Bits<4> = bit_cast(a);
1647        assert_eq!(c, 0xF);
1648    }
1649    #[test]
1650    fn test_bit_cast_long() {
1651        let a: Bits<48> = 0xdead_cafe_babe.into();
1652        let b: Bits<44> = bit_cast(a);
1653        assert_eq!(b, 0xead_cafe_babe);
1654        let b: Bits<32> = bit_cast(a);
1655        assert_eq!(b, 0xcafe_babe);
1656    }
1657    #[test]
1658    fn test_bit_extract_long() {
1659        let a: Bits<48> = 0xdead_cafe_babe.into();
1660        let b: Bits<44> = a.get_bits(4);
1661        assert_eq!(b, 0x0dea_dcaf_ebab);
1662        let b: Bits<32> = a.get_bits(16);
1663        assert_eq!(b, 0xdead_cafe);
1664    }
1665    #[test]
1666    fn test_set_bit() {
1667        let a: Bits<48> = 0xdead_cafe_babe.into();
1668        let mut b = a;
1669        for i in 4..8 {
1670            b = b.replace_bit(i, false)
1671        }
1672        assert_eq!(b, 0xdead_cafe_ba0e);
1673    }
1674    #[test]
1675    fn test_set_bits() {
1676        let a: Bits<16> = 0xdead.into();
1677        let b: Bits<4> = 0xf.into();
1678        let mut c = a;
1679        c.set_bits(4, b);
1680        assert_eq!(c, 0xdefd);
1681        let a: Bits<48> = 0xdead_cafe_babe.into();
1682        let b: Bits<8> = 0xde.into();
1683        let mut c = a;
1684        c.set_bits(16, b);
1685        assert_eq!(c, 0xdead_cade_babe);
1686    }
1687
1688    #[test]
1689    fn test_constants_and_bits() {
1690        let a: Bits<16> = 0xdead.into();
1691        let b = a + 1;
1692        let c = 1 + a;
1693        println!("{:x}", b);
1694        assert_eq!(b, 0xdeae);
1695        assert_eq!(b, c);
1696    }
1697    #[test]
1698    fn test_clog2() {
1699        const A_WIDTH: usize = clog2(250);
1700        let a: Bits<{ A_WIDTH }> = 153.into();
1701        println!("{:x}", a);
1702        assert_eq!(a.len(), 8);
1703        assert_eq!(clog2(1024), 10);
1704    }
1705
1706    #[test]
1707    fn test_clog2_inline() {
1708        const A_WIDTH: usize = clog2(1000);
1709        let a: Bits<A_WIDTH> = 1023.into();
1710        assert_eq!(a.len(), 10);
1711    }
1712
1713    #[test]
1714    fn test_default() {
1715        const N: usize = 128;
1716        let a = Bits::<N>::default();
1717        assert_eq!(a, 0);
1718    }
1719
1720    #[test]
1721    fn test_get_bits() {
1722        fn get_bits_test<const N: usize, const M: usize>() {
1723            for offset in 0_usize..N {
1724                let y: Bits<N> = random_bits();
1725                let z = y.get_bits::<M>(offset);
1726                let yb: BigUint = y.into();
1727                let yb = (yb >> offset) & ((BigUint::one() << M) - BigUint::one());
1728                let zb: BigUint = z.into();
1729                assert_eq!(zb, yb);
1730            }
1731        }
1732        seq!(N in 0..16 {
1733            get_bits_test::<8, N>();
1734        });
1735        seq!(N in 0..64 {
1736            get_bits_test::<32, N>();
1737        });
1738        seq!(N in 0..65 {
1739            get_bits_test::<64, N>();
1740        });
1741        seq!(N in 0..300 {
1742            get_bits_test::<256, N>();
1743        });
1744        seq!(N in 0..150 {
1745            get_bits_test::<125, N>();
1746        });
1747    }
1748
1749    #[test]
1750    fn test_bitcast() {
1751        fn bitcast_test<const N: usize, const M: usize>() {
1752            let y: Bits<N> = random_bits();
1753            let z = bit_cast::<M, N>(y);
1754            let yb: BigUint = y.into();
1755            let zb = yb & ((BigUint::one() << M) - BigUint::one());
1756            let zc: BigUint = z.into();
1757            assert_eq!(zb, zc);
1758        }
1759        fn bitcast_test_set<const M: usize>() {
1760            bitcast_test::<M, 1>();
1761            bitcast_test::<M, 8>();
1762            bitcast_test::<M, 16>();
1763            bitcast_test::<M, 32>();
1764            bitcast_test::<M, 64>();
1765            bitcast_test::<M, 128>();
1766            bitcast_test::<M, 256>();
1767        }
1768        bitcast_test_set::<1>();
1769        bitcast_test_set::<8>();
1770        bitcast_test_set::<16>();
1771        bitcast_test_set::<32>();
1772        bitcast_test_set::<64>();
1773        bitcast_test_set::<128>();
1774        bitcast_test_set::<256>();
1775    }
1776
1777    #[test]
1778    fn test_any() {
1779        seq!(N in 1..150 {
1780            for _rep in 0..10 {
1781                let y: Bits<N> = random_bits();
1782                let z : BigUint = y.into();
1783                let y_any = y.any();
1784                let z_any = z.count_ones() != 0;
1785                assert_eq!(y_any, z_any)
1786            }
1787            let y = Bits::<N>::default();
1788            assert!(!y.any());
1789        });
1790    }
1791
1792    #[test]
1793    fn test_all() {
1794        seq!(N in 1..150 {
1795            for _rep in 0..10 {
1796                let y: Bits<N> = random_bits();
1797                let z : BigUint = y.into();
1798                let y_all = y.all();
1799                let z_all = z.count_ones() == N;
1800                assert_eq!(y_all, z_all)
1801            }
1802            let y = Bits::<N>::mask();
1803            assert!(y.all());
1804        });
1805    }
1806
1807    #[test]
1808    fn test_shl_var_bitwidths_driver() {
1809        fn test_shl_var_bitwidths<const N: usize, const M: usize>() {
1810            for _iter in 0..100 {
1811                let y: Bits<N> = random_bits();
1812                let z: Bits<M> = random_bits();
1813                let r = y << z;
1814                let y1: BigUint = y.into();
1815                let mask: BigUint = (BigUint::one() << N) - BigUint::one();
1816                let z1: u128 = z.to_u128();
1817                let r1 = (y1 << z1) & mask;
1818                let convert: BigUint = r.into();
1819                assert_eq!(convert, r1);
1820            }
1821        }
1822        fn test_shl_var_bitwidths_set<const N: usize>() {
1823            test_shl_var_bitwidths::<N, 1>();
1824            test_shl_var_bitwidths::<N, 2>();
1825            test_shl_var_bitwidths::<N, 4>();
1826            test_shl_var_bitwidths::<N, 8>();
1827            test_shl_var_bitwidths::<N, 16>();
1828        }
1829        test_shl_var_bitwidths_set::<1>();
1830        test_shl_var_bitwidths_set::<2>();
1831        test_shl_var_bitwidths_set::<4>();
1832        test_shl_var_bitwidths_set::<8>();
1833        test_shl_var_bitwidths_set::<16>();
1834        test_shl_var_bitwidths_set::<32>();
1835        test_shl_var_bitwidths_set::<64>();
1836        test_shl_var_bitwidths_set::<128>();
1837        test_shl_var_bitwidths_set::<256>();
1838    }
1839
1840    #[test]
1841    fn test_shr_var_bitwidths_driver() {
1842        fn test_shr_var_bitwidths<const N: usize, const M: usize>() {
1843            for _iter in 0..100 {
1844                let y: Bits<N> = random_bits();
1845                let z: Bits<M> = random_bits();
1846                let r = y >> z;
1847                let y1: BigUint = y.into();
1848                let mask: BigUint = (BigUint::one() << N) - BigUint::one();
1849                let z1: u128 = z.to_u128();
1850                let r1 = (y1 >> z1) & mask;
1851                let convert: BigUint = r.into();
1852                assert_eq!(convert, r1);
1853            }
1854        }
1855        fn test_shr_var_bitwidths_set<const N: usize>() {
1856            test_shr_var_bitwidths::<N, 1>();
1857            test_shr_var_bitwidths::<N, 2>();
1858            test_shr_var_bitwidths::<N, 4>();
1859            test_shr_var_bitwidths::<N, 8>();
1860            test_shr_var_bitwidths::<N, 16>();
1861        }
1862        test_shr_var_bitwidths_set::<1>();
1863        test_shr_var_bitwidths_set::<2>();
1864        test_shr_var_bitwidths_set::<4>();
1865        test_shr_var_bitwidths_set::<8>();
1866        test_shr_var_bitwidths_set::<16>();
1867        test_shr_var_bitwidths_set::<32>();
1868        test_shr_var_bitwidths_set::<64>();
1869        test_shr_var_bitwidths_set::<128>();
1870        test_shr_var_bitwidths_set::<256>();
1871    }
1872
1873    #[test]
1874    fn test_shl_to_zero() {
1875        let y: Bits<1> = 1.into();
1876        let z: Bits<8> = 128.into();
1877        let r = y << z;
1878        assert_eq!(r, 0);
1879    }
1880
1881    #[test]
1882    fn test_shl() {
1883        seq!(N in 1..150 {
1884            for l in 0..N {
1885                let y: Bits<N> = random_bits();
1886                let z: Bits<N> = y << l;
1887                let y1 : BigUint = y.into();
1888                let mask : BigUint = (BigUint::one() << N) - BigUint::one();
1889                let z1 = (y1 << l) & mask;
1890                let convert : BigUint = z.into();
1891                assert_eq!(z1, convert)
1892            }
1893        });
1894    }
1895
1896    #[test]
1897    fn test_shr() {
1898        seq!(N in 1..150 {
1899            for l in 0..N {
1900                let y: Bits<N> = random_bits();
1901                let z: Bits<N> = y >> l;
1902                let y1 : BigUint = y.into();
1903                let mask : BigUint = (BigUint::one() << N) - BigUint::one();
1904                let z1 = (y1 >> l) & mask;
1905                let convert : BigUint = z.into();
1906                assert_eq!(z1, convert)
1907            }
1908        });
1909    }
1910
1911    macro_rules! test_op_with_values {
1912        ($func: ident) => {
1913            seq!(N in 1..150 {
1914                for _iters in 0..10 {
1915                    let y: Bits<N> = random_bits();
1916                    let z: Bits<N> = random_bits();
1917                    let v1_as_bint : BigUint = y.into();
1918                    let v2_as_bint : BigUint = z.into();
1919                    let mask : BigUint = (BigUint::one() << N) - BigUint::one();
1920                    let (lib_answer, biguint_answer) = $func(y, z, v1_as_bint, v2_as_bint, mask);
1921                    let convert : BigUint = lib_answer.into();
1922                    assert_eq!(biguint_answer, convert)
1923                }
1924            });
1925        }
1926    }
1927
1928    #[test]
1929    fn test_add() {
1930        fn add<const N: usize>(
1931            y: Bits<N>,
1932            z: Bits<N>,
1933            y1: BigUint,
1934            z1: BigUint,
1935            mask: BigUint,
1936        ) -> (Bits<N>, BigUint) {
1937            (y + z, (y1 + z1) & mask)
1938        }
1939        test_op_with_values!(add);
1940    }
1941
1942    #[test]
1943    fn test_sub() {
1944        fn sub<const N: usize>(
1945            y: Bits<N>,
1946            z: Bits<N>,
1947            y1: BigUint,
1948            z1: BigUint,
1949            mask: BigUint,
1950        ) -> (Bits<N>, BigUint) {
1951            if z1 <= y1 {
1952                (y - z, (y1 - z1))
1953            } else {
1954                (y - z, mask + BigUint::one() + y1 - z1)
1955            }
1956        }
1957        test_op_with_values!(sub);
1958    }
1959
1960    #[test]
1961    fn test_bitor() {
1962        fn bor<const N: usize>(
1963            y: Bits<N>,
1964            z: Bits<N>,
1965            y1: BigUint,
1966            z1: BigUint,
1967            mask: BigUint,
1968        ) -> (Bits<N>, BigUint) {
1969            (y | z, (y1 | z1) & mask)
1970        }
1971        test_op_with_values!(bor);
1972    }
1973
1974    #[test]
1975    fn test_bitand() {
1976        fn band<const N: usize>(
1977            y: Bits<N>,
1978            z: Bits<N>,
1979            y1: BigUint,
1980            z1: BigUint,
1981            mask: BigUint,
1982        ) -> (Bits<N>, BigUint) {
1983            (y & z, (y1 & z1) & mask)
1984        }
1985        test_op_with_values!(band);
1986    }
1987
1988    #[test]
1989    fn test_bitxor() {
1990        fn bxor<const N: usize>(
1991            y: Bits<N>,
1992            z: Bits<N>,
1993            y1: BigUint,
1994            z1: BigUint,
1995            mask: BigUint,
1996        ) -> (Bits<N>, BigUint) {
1997            (y ^ z, (y1 ^ z1) & mask)
1998        }
1999        test_op_with_values!(bxor);
2000    }
2001
2002    #[test]
2003    fn test_not() {
2004        fn not<const N: usize>(
2005            y: Bits<N>,
2006            _z: Bits<N>,
2007            y1: BigUint,
2008            _z1: BigUint,
2009            mask: BigUint,
2010        ) -> (Bits<N>, BigUint) {
2011            (!y, (y1 ^ mask))
2012        }
2013        test_op_with_values!(not);
2014    }
2015
2016    macro_rules! test_cmp_with_values {
2017        ($func: ident) => {
2018            seq!(N in 1..256 {
2019                for _iters in 0..10 {
2020                    let y: Bits<N> = random_bits();
2021                    let z: Bits<N> = random_bits();
2022                    let v1_as_bint : BigUint = y.into();
2023                    let v2_as_bint : BigUint = z.into();
2024                    let (lib_answer, biguint_answer) = $func(y, z, v1_as_bint, v2_as_bint);
2025                    assert_eq!(lib_answer, biguint_answer)
2026                }
2027            });
2028        }
2029    }
2030
2031    #[test]
2032    fn test_lt() {
2033        fn lt<const N: usize>(y: Bits<N>, z: Bits<N>, y1: BigUint, z1: BigUint) -> (bool, bool) {
2034            (y < z, y1 < z1)
2035        }
2036        test_cmp_with_values!(lt);
2037    }
2038
2039    #[test]
2040    fn test_le() {
2041        fn le<const N: usize>(y: Bits<N>, z: Bits<N>, y1: BigUint, z1: BigUint) -> (bool, bool) {
2042            (y <= z, y1 <= z1)
2043        }
2044        test_cmp_with_values!(le);
2045    }
2046
2047    #[test]
2048    fn test_eq() {
2049        fn eq<const N: usize>(y: Bits<N>, z: Bits<N>, y1: BigUint, z1: BigUint) -> (bool, bool) {
2050            (y == z, y1 == z1)
2051        }
2052        test_cmp_with_values!(eq);
2053    }
2054
2055    #[test]
2056    fn test_neq() {
2057        fn neq<const N: usize>(y: Bits<N>, z: Bits<N>, y1: BigUint, z1: BigUint) -> (bool, bool) {
2058            (y != z, y1 != z1)
2059        }
2060        test_cmp_with_values!(neq);
2061    }
2062
2063    #[test]
2064    fn test_ge() {
2065        fn ge<const N: usize>(y: Bits<N>, z: Bits<N>, y1: BigUint, z1: BigUint) -> (bool, bool) {
2066            (y >= z, y1 >= z1)
2067        }
2068        test_cmp_with_values!(ge);
2069    }
2070
2071    #[test]
2072    fn test_gt() {
2073        fn gt<const N: usize>(y: Bits<N>, z: Bits<N>, y1: BigUint, z1: BigUint) -> (bool, bool) {
2074            (y > z, y1 > z1)
2075        }
2076        test_cmp_with_values!(gt);
2077    }
2078}
2079
2080/// A type alias for a simple bool.  You can use them interchangeably.
2081pub type Bit = bool;
2082
2083/// Multipliers are special, so we only implement multipliers that we think are
2084/// synthesizable.  In this case, we implement a 16 x 16 bit multiplier
2085/// which yields a 32 bit result.
2086impl std::ops::Mul<Bits<16>> for Bits<16> {
2087    type Output = Bits<32>;
2088
2089    fn mul(self, rhs: Bits<16>) -> Self::Output {
2090        let x = match self {
2091            Bits::Short(x) => x.short(),
2092            Bits::Long(_) => {
2093                panic!("unreachable!")
2094            }
2095        };
2096        let y = match rhs {
2097            Bits::Short(x) => x.short(),
2098            Bits::Long(_) => {
2099                panic!("unreachable!")
2100            }
2101        };
2102        Bits::Short(ShortBitVec::from(x * y))
2103    }
2104}