Skip to content

Commit

Permalink
wires: some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rrbutani committed Sep 26, 2019
1 parent dd1ac29 commit 4ddd2d3
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 28 deletions.
46 changes: 27 additions & 19 deletions hdl/src/wires/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,30 @@ repeat_with_n!(8, N, single_impl! {N, FitsInU8});
// }
// }

macro_rules! into_bits_impl {
($type:ty) => {
impl IntoBits for $type {
const BYTES: usize = core::mem::size_of::<Self>();
// type ByteArr = [u8; core::mem::size_of::<Self>()];

// fn to_le_bytes(&self) -> [u8; Self::BYTES as usize] {
// fn to_le_bytes(&self) -> Self::ByteArr {
// self.to_le_bytes()
// }

#[inline]
fn le_bytes(&self) -> Box<[u8]> {
Box::new(self.to_le_bytes())
}

#[inline]
fn num_leading_zeros(&self) -> u32 {
self.leading_zeros()
}
}
};
}

macro_rules! impl_for_size {
($type:ty, $marker_trait:path, $nom:expr) => {
#[doc = "Wires with 0 to 8 bits (0 to 1 bytes) can be represented by a `"]
Expand Down Expand Up @@ -182,25 +206,7 @@ macro_rules! impl_for_size {
}
}

impl IntoBits for $type {
const BYTES: usize = core::mem::size_of::<Self>();
// type ByteArr = [u8; core::mem::size_of::<Self>()];

// fn to_le_bytes(&self) -> [u8; Self::BYTES as usize] {
// fn to_le_bytes(&self) -> Self::ByteArr {
// self.to_le_bytes()
// }

#[inline]
fn le_bytes(&self) -> Box<[u8]> {
Box::new(self.to_le_bytes())
}

#[inline]
fn num_leading_zeros(&self) -> u32 {
self.leading_zeros()
}
}
into_bits_impl!($type);
};

($type:ty, $marker_trait:path) => {
Expand Down Expand Up @@ -274,6 +280,8 @@ impl_for_size!(u32, FitsInU32);
impl_for_size!(u64, FitsInU64);
impl_for_size!(u128, FitsInU128);

into_bits_impl!(usize);

// /// Wires with 0 to 8 bits (0 to 1 bytes) can be represented by a u8.
// impl<const B: BitCountType, const S: usize> From<Wire<{ B }, { S }>> for u8
// where
Expand Down
70 changes: 61 additions & 9 deletions hdl/src/wires/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ pub struct Wire<const B: BitCountType, const S: usize> {
}

// Doesn't work:
type WireAlias<const B: BitCountType> = Wire<{B}, {num_bytes(B)}>;
// type WireAlias<const B: BitCountType> = Wire<{B}, {num_bytes(B)}>;

// Also doesn't work:
// pub fn new<const B: BitCountType>() -> Wire<{B}, {_}> {
Expand All @@ -156,8 +156,13 @@ impl<const B: BitCountType, const S: usize> Wire<{B}, {S}> {
}
}

// Unfortunately this function doesn't appear to work (ICEs whenever it's actually
// invoked like `Wire::get_bytes(&self)`). There's a workaround (calling new and
// then set at the call site) but we'll still leave this function in in-case this
// works once const generics become more stable.
#[inline]
pub fn new_with_val<C: IntoBits>(val: C) -> Self {
#[allow(unused)]
fn new_with_val<C: IntoBits>(val: C) -> Self {
let mut wire = Self::new();
wire.set(val);

Expand All @@ -166,8 +171,8 @@ impl<const B: BitCountType, const S: usize> Wire<{B}, {S}> {

#[inline]
pub fn set<C: IntoBits>(&mut self, val: C) -> &Self {
// Make sure we've got enough bytes to represent the value:
debug_assert!(S >= C::BYTES);
// Make sure our number of bytes matches our number of bits:
debug_assert!(S == num_bytes(B));

// Check that the value we're trying to represent fits in the number of
// bits we've got:
Expand Down Expand Up @@ -201,6 +206,11 @@ impl<const B: BitCountType, const S: usize> Wire<{B}, {S}> {
/// 4 | 4 | 0..4
/// 0 | 8 | 8..8
/// 8 | 8 | 0..8
///
// Unfortunately this function doesn't appear to work (ICEs whenever it's actually
// invoked). We found a workaround that we're using for now, but we'll still leave
// this function in in-case this works once const generics become more stable.
#[allow(unused)]
fn get_bytes</*T: core::marker::Sized, */const U: usize>(&self) -> [u8; U] {
// let mut bytes = [0u8; core::mem::size_of::<T>()];
let mut bytes = ConstU8Arr::<{U}>::new();
Expand All @@ -212,16 +222,58 @@ impl<const B: BitCountType, const S: usize> Wire<{B}, {S}> {
// fn new_with_inference() -> Self
}

mod conversions;

#[cfg(test)]
mod tests {
use super::*;

macro_rules! new_wire {
($bits:expr) => {Wire::<{ $bits }, { num_bytes($bits) }>::new()};
}

// For some reason this fails to compile:
// Update: it's because calls to `Wire::new_with_val` fail to compile (just like
// `Wire::get_bytes`). The below works so we'll use it.
// macro_rules! new_wire_with_val {
// ($bits:expr, $val:expr) => {Wire::<{ $bits }, { num_bytes($bits) }>::new_with_val($val)};
// }

macro_rules! new_wire_with_val {
($bits:expr, $val:expr) => {new_wire!($bits).set($val)};
}

#[test]
fn new() {
new_wire!(0);
new_wire!(1);
}

// #[test]
// fn new_with_val() {
// new_wire!(1).set(1usize);
// }

#[test]
fn new_with_val() {
new_wire_with_val!(0, 0usize);
new_wire_with_val!(1, 1usize);
new_wire_with_val!(2, 2usize);
new_wire_with_val!(2, 3usize);
new_wire_with_val!(3, 4usize);
new_wire_with_val!(4, 15usize);
new_wire_with_val!(32, 4_294_967_295usize);
new_wire_with_val!(33, 4_294_967_296usize);
}

#[test]
#[should_panic]
fn not_enough_bits_1() {
new_wire_with_val!(0, 1usize);
}

#[test]
fn new_direct() {
Wire::<{ 1 }, { 1 }>::new();
Wire::<{ 1 }, { num_bytes(1) }>::new();
#[should_panic]
fn not_enough_bits_2() {
new_wire_with_val!(4, 16usize);
}

// #[test]
Expand Down

0 comments on commit 4ddd2d3

Please sign in to comment.