diff --git a/src/lib.rs b/src/lib.rs index f2f7888e17e2b09611670228ab3c4b7dc437dd24..6a790878f555e85d100d0d95daeaef095b7d6725 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,11 @@ mod signal; pub use signal::*; -pub struct Component { - pub inputs: Vec<Signal>, - pub outputs: Vec<(Signal, Box<Component>)>, -} +// pub struct Component { +// pub inputs: Vec<Signal>, +// pub outputs: Vec<(Signal, Box<Component>)>, +// } pub trait Eval { - fn eval(&mut self) -> (); + fn eval(&self) -> (); } diff --git a/src/main.rs b/src/main.rs index 070b5e2070edc8cb03759b1cccad405b66d3a0a9..2e52888420ee3de96d1530ebc564b74d0bd8b65a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +use core::fmt; + use rsim::*; // fn main() { @@ -63,35 +65,58 @@ use rsim::*; // file.write_all(out.as_bytes()).unwrap(); // } -use std::cell::Cell; - #[derive(Debug)] -struct CSignal(Cell<Signal>); +struct Mux<'a, const I: usize, const S: usize, const N: usize> { + inputs: [&'a Signal<N>; I], + sel: &'a Signal<S>, + output: Signal<N>, +} -#[derive(Debug)] -struct MuxIn<'a> { - a: &'a CSignal, - b: &'a CSignal, - sel: &'a CSignal, +impl<'a, const I: usize, const S: usize, const N: usize> Eval for Mux<'a, I, S, N> { + fn eval(&self) { + let s: u8 = self.sel.clone().into(); + println!("s {}", s); + + let o = self.inputs[s as usize]; + + self.output.store.set(o.store.get()) + } } -fn main() {} +impl<'a, const I: usize, const S: usize, const N: usize> fmt::Binary for Mux<'a, I, S, N> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Binary::fmt(&self.output, f) + } +} -// #[derive(Debug)] -// struct Mux<'a> { -// inputs: MuxIn<'a>, -// output: CSignal, -// } +fn main() { + let s1: Signal<8> = 0b10101u8.into(); + println!("s1 {:?}", s1); + println!("s1 {:b}", s1); -// impl<'a> Eval for Mux<'a> { -// fn eval(&mut self) { -// self.output = match self.inputs.sel[0] { -// false => self.inputs.a.get(), -// true => self.inputs.b, -// } -// .clone() -// } -// } + let s2: Signal<8> = 0b00110u8.into(); + println!("s2 {:b}", s2); + + let s3 = &s1 & &s2; + + println!("s3 {:b}", s3); + + let sel: Signal<1> = [true].into(); + + let m: Mux<2, 1, 8> = Mux { + inputs: [&s1, &s2], + sel: &sel, + output: 0u8.into(), + }; + + println!("m {:?}", m); + + println!("m {:b}", m); + + m.eval(); + println!("m {:?}", m); + println!("m {:b}", m); +} // #[derive(Debug)] // struct AndIn<'a> { diff --git a/src/signal.rs b/src/signal.rs index 1011433e4c5be08021087496e0fea01e131cbf0d..834b09cbd5c068d59d442022b83f013d30f92ead 100644 --- a/src/signal.rs +++ b/src/signal.rs @@ -1,125 +1,154 @@ +use std::cell::Cell; use std::convert::{From, Into}; use std::fmt; -use std::ops::{BitAnd, Index}; +use std::ops::{BitAnd, BitOr, Deref, Index}; use std::string::String; -#[derive(Debug, PartialEq, Copy, Clone)] -pub struct Signal(Vec<bool>); +#[derive(Debug, PartialEq, Clone)] +pub struct Signal<const N: usize> { + // we should probably have set/get instead of exposing store + pub store: Cell<[bool; N]>, +} -impl Signal { +impl<const N: usize> Signal<N> { pub fn new() -> Self { - Self { 0: Vec::new() } - } - - pub fn new_zeroed(n: usize) -> Self { - let mut bs = Signal::new(); - for i in 0..n { - bs.push(false) + Self { + store: Cell::new([false; N]), } - bs - } - - pub fn push(&mut self, b: bool) { - self.0.push(b) - } - - pub fn pop(&mut self) -> Option<bool> { - self.0.pop() } - pub fn set(&mut self, i: usize, b: bool) { - self.0[i] = b; - } + // pub fn set(&mut self, i: usize, b: bool) { + // self.0[i] = b; + // } } -impl fmt::Binary for Signal { +impl<const N: usize> fmt::Binary for Signal<N> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut s = String::new(); - for i in self.0.iter().rev() { + for i in self.store.get().iter().rev() { s.push(if *i { '1' } else { '0' }); } write!(f, "{}", s) } } -impl Index<usize> for Signal { - type Output = bool; +// impl<const N: usize> Deref for Signal<N> { +// type Target = [bool; N]; - #[inline] - fn index(&self, index: usize) -> &Self::Output { - &self.0[index] - } -} +// fn deref(&self) -> Self::Target { +// self.store.get() +// } +// } + +// impl Index<usize> for Signal { +// type Output = bool; + +// #[inline] +// fn index(&self, index: usize) -> &Self::Output { +// &self.0[index] +// } +// } // operations on signal -impl BitAnd for &Signal { - type Output = Signal; +impl<const N: usize> BitAnd for &Signal<N> { + type Output = Signal<N>; // rhs is the "right-hand side" of the expression `a & b` fn bitand(self, rhs: Self) -> Self::Output { - let mut bs = Signal::new(); - for (a, b) in self.0.iter().zip(&rhs.0) { - bs.push(a & b); + let mut bs = [false; N]; + let a = self.store.get(); + let b = rhs.store.get(); + for i in 0..self.store.get().len() { + bs[i] = a[i] & b[i] + } + Signal { + store: Cell::new(bs), } - bs } } -impl From<u8> for Signal { +// impl<const N: usize> BitOr for &Signal<N> { +// type Output = Signal<N>; + +// // rhs is the "right-hand side" of the expression `a & b` +// fn bitor(self, rhs: Self) -> Self::Output { +// let mut bs: Signal<N> = Signal::new(); +// for i in 0..self.store.len() { +// bs.store[i] = self.store[i] | rhs.store[i] +// } +// bs +// } +// } + +impl<const N: usize> From<u8> for Signal<N> { fn from(u: u8) -> Self { - let mut bs = Signal::new(); + let mut bs = [false; N]; for i in 0..8 { - bs.push(u & (1 << i) != 0) + bs[i] = u & (1 << i) != 0 } - bs - } -} - -impl From<Signal> for u8 { - fn from(b: Signal) -> u8 { - let mut u = 0; - for (n, b) in b.0.iter().enumerate() { - u |= if *b { 1 << n } else { 0 } + Signal { + store: Cell::new(bs), } - u } } -impl From<u32> for Signal { - fn from(u: u32) -> Self { - let mut bs = Signal::new(); - for i in 0..32 { - bs.push(u & (1 << i) != 0) +impl<const N: usize> From<[bool; N]> for Signal<N> { + fn from(a: [bool; N]) -> Self { + Signal { + store: Cell::new(a), } - bs } } -impl From<Signal> for u32 { - fn from(b: Signal) -> u32 { +impl<const N: usize> From<Signal<N>> for u8 { + fn from(s: Signal<N>) -> u8 { + // check that it fits u8 + assert!(N < 8); let mut u = 0; - for (n, b) in b.0.iter().enumerate() { - u |= if *b { 1 << n } else { 0 } + let a = s.store.get(); + + for i in 0..N { + u |= if a[i] { 1 << i } else { 0 } } u } } -#[test] -fn test_partial_eq() { - let b: Signal = 12345u32.into(); - let c: Signal = 1245u32.into(); - assert!(b != c); - assert!(b == b); -} - -#[test] -fn test_and() { - let a = 0x15u8; - let b = 0x51u8; - - let a_bs: Signal = a.into(); - let b_bs: Signal = b.into(); - let c_bs = &a_bs & &b_bs; - assert!(a & b == c_bs.into()); -} +// impl From<u32> for Signal { +// fn from(u: u32) -> Self { +// let mut bs = Signal::new(); +// for i in 0..32 { +// bs.push(u & (1 << i) != 0) +// } +// bs +// } +// } + +// impl From<Signal> for u32 { +// fn from(b: Signal) -> u32 { +// let mut u = 0; +// for (n, b) in b.0.iter().enumerate() { +// u |= if *b { 1 << n } else { 0 } +// } +// u +// } +// } + +// #[test] +// fn test_partial_eq() { +// let b: Signal = 12345u32.into(); +// let c: Signal = 1245u32.into(); +// assert!(b != c); +// assert!(b == b); +// } + +// #[test] +// fn test_and() { +// let a = 0x15u8; +// let b = 0x51u8; + +// let a_bs: Signal = a.into(); +// let b_bs: Signal = b.into(); +// let c_bs = &a_bs & &b_bs; +// assert!(a & b == c_bs.into()); +// }