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}