Skip to content
Snippets Groups Projects
Commit 55ef00d5 authored by Per Lindgren's avatar Per Lindgren
Browse files

moved to const generic array repr

parent 35523276
No related branches found
No related tags found
No related merge requests found
mod signal; mod signal;
pub use signal::*; pub use signal::*;
pub struct Component { // pub struct Component {
pub inputs: Vec<Signal>, // pub inputs: Vec<Signal>,
pub outputs: Vec<(Signal, Box<Component>)>, // pub outputs: Vec<(Signal, Box<Component>)>,
} // }
pub trait Eval { pub trait Eval {
fn eval(&mut self) -> (); fn eval(&self) -> ();
} }
use core::fmt;
use rsim::*; use rsim::*;
// fn main() { // fn main() {
...@@ -63,35 +65,58 @@ use rsim::*; ...@@ -63,35 +65,58 @@ use rsim::*;
// file.write_all(out.as_bytes()).unwrap(); // file.write_all(out.as_bytes()).unwrap();
// } // }
use std::cell::Cell;
#[derive(Debug)] #[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)] impl<'a, const I: usize, const S: usize, const N: usize> Eval for Mux<'a, I, S, N> {
struct MuxIn<'a> { fn eval(&self) {
a: &'a CSignal, let s: u8 = self.sel.clone().into();
b: &'a CSignal, println!("s {}", s);
sel: &'a CSignal,
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)] fn main() {
// struct Mux<'a> { let s1: Signal<8> = 0b10101u8.into();
// inputs: MuxIn<'a>, println!("s1 {:?}", s1);
// output: CSignal, println!("s1 {:b}", s1);
// }
// impl<'a> Eval for Mux<'a> { let s2: Signal<8> = 0b00110u8.into();
// fn eval(&mut self) { println!("s2 {:b}", s2);
// self.output = match self.inputs.sel[0] {
// false => self.inputs.a.get(), let s3 = &s1 & &s2;
// true => self.inputs.b,
// } println!("s3 {:b}", s3);
// .clone()
// } 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)] // #[derive(Debug)]
// struct AndIn<'a> { // struct AndIn<'a> {
......
use std::cell::Cell;
use std::convert::{From, Into}; use std::convert::{From, Into};
use std::fmt; use std::fmt;
use std::ops::{BitAnd, Index}; use std::ops::{BitAnd, BitOr, Deref, Index};
use std::string::String; use std::string::String;
#[derive(Debug, PartialEq, Copy, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct Signal(Vec<bool>); pub struct Signal<const N: usize> {
// we should probably have set/get instead of exposing store
impl Signal { pub store: Cell<[bool; N]>,
pub fn new() -> Self {
Self { 0: Vec::new() }
} }
pub fn new_zeroed(n: usize) -> Self { impl<const N: usize> Signal<N> {
let mut bs = Signal::new(); pub fn new() -> Self {
for i in 0..n { Self {
bs.push(false) store: Cell::new([false; N]),
} }
bs
} }
pub fn push(&mut self, b: bool) { // pub fn set(&mut self, i: usize, b: bool) {
self.0.push(b) // self.0[i] = b;
// }
} }
pub fn pop(&mut self) -> Option<bool> { impl<const N: usize> fmt::Binary for Signal<N> {
self.0.pop()
}
pub fn set(&mut self, i: usize, b: bool) {
self.0[i] = b;
}
}
impl fmt::Binary for Signal {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut s = String::new(); 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' }); s.push(if *i { '1' } else { '0' });
} }
write!(f, "{}", s) write!(f, "{}", s)
} }
} }
impl Index<usize> for Signal { // impl<const N: usize> Deref for Signal<N> {
type Output = bool; // type Target = [bool; N];
#[inline] // fn deref(&self) -> Self::Target {
fn index(&self, index: usize) -> &Self::Output { // self.store.get()
&self.0[index] // }
} // }
}
// impl Index<usize> for Signal {
// type Output = bool;
// #[inline]
// fn index(&self, index: usize) -> &Self::Output {
// &self.0[index]
// }
// }
// operations on signal // operations on signal
impl BitAnd for &Signal { impl<const N: usize> BitAnd for &Signal<N> {
type Output = Signal; type Output = Signal<N>;
// rhs is the "right-hand side" of the expression `a & b` // rhs is the "right-hand side" of the expression `a & b`
fn bitand(self, rhs: Self) -> Self::Output { fn bitand(self, rhs: Self) -> Self::Output {
let mut bs = Signal::new(); let mut bs = [false; N];
for (a, b) in self.0.iter().zip(&rhs.0) { let a = self.store.get();
bs.push(a & b); 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 { fn from(u: u8) -> Self {
let mut bs = Signal::new(); let mut bs = [false; N];
for i in 0..8 { for i in 0..8 {
bs.push(u & (1 << i) != 0) bs[i] = u & (1 << i) != 0
}
bs
} }
Signal {
store: Cell::new(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 }
}
u
} }
} }
impl From<u32> for Signal { impl<const N: usize> From<[bool; N]> for Signal<N> {
fn from(u: u32) -> Self { fn from(a: [bool; N]) -> Self {
let mut bs = Signal::new(); Signal {
for i in 0..32 { store: Cell::new(a),
bs.push(u & (1 << i) != 0)
} }
bs
} }
} }
impl From<Signal> for u32 { impl<const N: usize> From<Signal<N>> for u8 {
fn from(b: Signal) -> u32 { fn from(s: Signal<N>) -> u8 {
// check that it fits u8
assert!(N < 8);
let mut u = 0; let mut u = 0;
for (n, b) in b.0.iter().enumerate() { let a = s.store.get();
u |= if *b { 1 << n } else { 0 }
for i in 0..N {
u |= if a[i] { 1 << i } else { 0 }
} }
u u
} }
} }
#[test] // impl From<u32> for Signal {
fn test_partial_eq() { // fn from(u: u32) -> Self {
let b: Signal = 12345u32.into(); // let mut bs = Signal::new();
let c: Signal = 1245u32.into(); // for i in 0..32 {
assert!(b != c); // bs.push(u & (1 << i) != 0)
assert!(b == b); // }
} // bs
// }
#[test] // }
fn test_and() {
let a = 0x15u8; // impl From<Signal> for u32 {
let b = 0x51u8; // fn from(b: Signal) -> u32 {
// let mut u = 0;
let a_bs: Signal = a.into(); // for (n, b) in b.0.iter().enumerate() {
let b_bs: Signal = b.into(); // u |= if *b { 1 << n } else { 0 }
let c_bs = &a_bs & &b_bs; // }
assert!(a & b == c_bs.into()); // 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());
// }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment