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;
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) -> ();
}
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> {
......
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>);
impl Signal {
pub fn new() -> Self {
Self { 0: Vec::new() }
#[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]>,
}
pub fn new_zeroed(n: usize) -> Self {
let mut bs = Signal::new();
for i in 0..n {
bs.push(false)
impl<const N: usize> Signal<N> {
pub fn new() -> Self {
Self {
store: Cell::new([false; N]),
}
bs
}
pub fn push(&mut self, b: bool) {
self.0.push(b)
// pub fn set(&mut self, i: usize, b: bool) {
// self.0[i] = b;
// }
}
pub fn pop(&mut self) -> Option<bool> {
self.0.pop()
}
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
bs[i] = u & (1 << i) != 0
}
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 {
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());
// }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment