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

bit array introduced

parent 9843de52
Branches
No related tags found
No related merge requests found
...@@ -65,7 +65,7 @@ use rsim::*; ...@@ -65,7 +65,7 @@ use rsim::*;
// file.write_all(out.as_bytes()).unwrap(); // file.write_all(out.as_bytes()).unwrap();
// } // }
use std::cell::Cell; //use std::cell::Cell;
// two input mux // two input mux
struct Mux<'a, const N: usize> { struct Mux<'a, const N: usize> {
...@@ -76,28 +76,32 @@ struct Mux<'a, const N: usize> { ...@@ -76,28 +76,32 @@ struct Mux<'a, const N: usize> {
impl<'a, const N: usize> Eval for Mux<'a, N> { impl<'a, const N: usize> Eval for Mux<'a, N> {
fn eval(&self) -> () { fn eval(&self) -> () {
let sel = self.sel[0].get(); self.out.w(match self.sel.r()[0] {
for (i, o) in self.out.iter().enumerate() { false => self.ins.0.r(),
o.set(match sel { true => self.ins.1.r(),
false => self.ins.0[i].get(),
true => self.ins.1[i].get(),
}) })
} }
} }
}
fn main() { fn main() {
let mut in1 = [false, true]; let mut in1: BitArr<2> = 0b10u8.into(); // [false, true];
let mut in2 = [true, false]; println!("{:?}", in1);
println!("{:b}", in1);
let mut in2: BitArr<2> = BitArr([true, false]);
let c = &in1 & &in2;
println!("c {:b}", c);
let c = &in1 | &in2;
println!("c {:b}", c);
let mut sel = [false]; let mut sel = [false];
let sel = Signal::new(&mut sel); let sel = Signal::new(&mut sel);
let mut out = [false, false]; let mut out = [false, false];
let out = &Signal::new(&mut out); let out = &Signal::new(&mut out);
// let s = &(&*out)[0..3]; // .to_slice(0, 1);
let out0: Signal<1> = out.view(0, 1); let out0: Signal<1> = out.view(0, 1);
let out1: Signal<1> = out.view(1, 2); let out1: Signal<1> = out.view(1, 2);
// println!("s {:b}", &s);
let m = Mux { let m = Mux {
ins: (Signal::new(&mut in1), Signal::new(&mut in2)), ins: (Signal::new(&mut in1), Signal::new(&mut in2)),
...@@ -107,18 +111,18 @@ fn main() { ...@@ -107,18 +111,18 @@ fn main() {
println!("m.out {:b}", m.out); println!("m.out {:b}", m.out);
m.eval(); m.eval();
sel[0].set(true); sel.w(BitArr([false]));
m.eval(); m.eval();
println!("m.out {:b}", m.out); println!("m.out {:b}", m.out);
// sel[0].set(false); sel[0].set(false);
sel.store([false]); sel.w(BitArr([false]));
sel.store_slice(&[false]); // sel.store_slice(&[false]);
m.eval(); m.eval();
println!("m.out {:b}", m.out); println!("m.out {:?}", m.out);
println!("out0 {:b}", &out0); println!("out0 {:b}", &out0);
println!("out1 {:b}", &out1); println!("out1 {:b}", &out1);
let p = &m.out[0..1]; let p = &m.out[0..1];
let m: Signal<1> = m.out[0..2].into(); let m: Signal<2> = m.out[0..2].into();
} }
// #[derive(Debug)] // #[derive(Debug)]
// struct Mux<'a, const I: usize, const S: usize, const N: usize> { // struct Mux<'a, const I: usize, const S: usize, const N: usize> {
......
use std::cell::Cell; use std::cell::Cell;
use std::convert::TryFrom;
use std::convert::{From, Into}; use std::convert::{From, Into};
use std::fmt; use std::fmt;
use std::ops::{BitAnd, BitOr, Deref, Index, Range}; use std::ops::{BitAnd, BitOr, Deref, DerefMut, Index, Range};
use std::string::String; use std::string::String;
#[derive(Debug, PartialEq, Clone)]
pub struct BitArr<const N: usize>(pub [bool; N]);
impl<const N: usize> DerefMut for BitArr<N> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<const N: usize> Deref for BitArr<N> {
type Target = [bool; N];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<const N: usize> fmt::Binary for BitArr<N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut s = String::new();
for i in self.0.iter().rev() {
s.push(if *i { '1' } else { '0' });
}
write!(f, "{}", s)
}
}
// Convert a u8 to BitArr<N>
// panic: N is too small to fit all true bits of u8
// if N is larger than 8, other bits set zero
impl<const N: usize> From<u8> for BitArr<N> {
fn from(u: u8) -> Self {
let mut bs = [false; N];
for i in 0..8 {
let b = u & (1 << i);
if b != 0 {
bs[i] = true
}
}
BitArr(bs)
}
}
// Convert a BitArr<N> to u8
// panic: if N > 8
// if N <= 8 upper bits are set 0
impl<const N: usize> From<BitArr<N>> for u8 {
fn from(bs: BitArr<N>) -> Self {
assert!(N <= 8);
let mut b = 0u8;
for i in 0..N {
if bs[i] {
b |= 1 << i
}
}
b
}
}
// operations on bit array
impl<const N: usize> BitAnd for &BitArr<N> {
type Output = BitArr<N>;
// rhs is the "right-hand side" of the expression `a & b`
fn bitand(self, rhs: Self) -> Self::Output {
let mut bs = [false; N];
for i in 0..self.0.len() {
bs[i] = self.0[i] & rhs.0[i]
}
BitArr(bs)
}
}
impl<const N: usize> BitOr for &BitArr<N> {
type Output = BitArr<N>;
// rhs is the "right-hand side" of the expression `a & b`
fn bitor(self, rhs: Self) -> Self::Output {
let mut bs = [false; N];
for i in 0..self.0.len() {
bs[i] = self.0[i] | rhs.0[i]
}
BitArr(bs)
}
}
// representation of stateful signal
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct Signal<'a, const N: usize> { pub struct Signal<'a, const N: usize> {
pub store: &'a [Cell<bool>], store: &'a [Cell<bool>; N],
} }
impl<'a, const N: usize> Signal<'a, N> { impl<'a, const N: usize> Signal<'a, N> {
// construct a signal from a mutable array
pub fn new(arr: &'a mut [bool; N]) -> Self { pub fn new(arr: &'a mut [bool; N]) -> Self {
let cell_slice: &'a Cell<[bool]> = Cell::from_mut(arr); let cell_slice: &'a Cell<[bool]> = Cell::from_mut(arr);
Self { let slice_cell = cell_slice.as_slice_of_cells();
store: cell_slice.as_slice_of_cells(), let a = <&[Cell<bool>; N]>::try_from(slice_cell).unwrap();
} Self { store: a }
} }
pub fn load(&self) -> [bool; N] { // read a signal value to a bit array
pub fn r(&self) -> BitArr<N> {
let mut a = [false; N]; let mut a = [false; N];
for (i, v) in self.store.iter().enumerate() { for (i, v) in self.store.iter().enumerate() {
a[i] = v.get() a[i] = v.get()
} }
a BitArr(a)
} }
pub fn store(&self, a: [bool; N]) { // write a signal to a bit array
pub fn w(&self, a: BitArr<N>) {
for (i, v) in self.store.iter().enumerate() { for (i, v) in self.store.iter().enumerate() {
v.set(a[i]) v.set(a[i])
} }
} }
pub fn store_slice(&self, a: &[bool]) { // not sure if we should support this
for (i, v) in self.store.iter().enumerate() { // pub fn store_slice(&self, a: &[bool]) {
v.set(a[i]) // for (i, v) in self.store.iter().enumerate() {
} // v.set(a[i])
} // }
// }
// create a view of the signal
// for now this view provides both reading and writing
// not sure if this is what we want in the end
pub fn view<const M: usize>(&self, f: usize, t: usize) -> Signal<M> { pub fn view<const M: usize>(&self, f: usize, t: usize) -> Signal<M> {
assert!(M == t - f); let slice_cell = &self.store[f..t];
Signal { let a = <&[Cell<bool>; M]>::try_from(slice_cell).unwrap();
store: &self.store[f..t], Signal { store: a }
}
} }
} }
// impl<'a, const N: usize> From<u8> for Signal<'a, N> { // create a signal from a bit array
// fn from(u: u8) -> Self { impl<'a, const N: usize> From<&'a mut BitArr<N>> for Signal<'a, N> {
// let mut bs = [false; N]; fn from(a: &'a mut BitArr<N>) -> Self {
// for i in 0..8 { Signal::new(&mut a.0)
// bs[i] = 1 << i != 0 }
// } }
// Signal::new(&mut bs)
// }
// }
// create a signal from a slice of the bit array storage
impl<'a, const N: usize> From<&'a [Cell<bool>]> for Signal<'a, N> { impl<'a, const N: usize> From<&'a [Cell<bool>]> for Signal<'a, N> {
fn from(slice: &'a [Cell<bool>]) -> Self { fn from(slice_cell: &'a [Cell<bool>]) -> Self {
assert!(N == slice.len()); let a = <&[Cell<bool>; N]>::try_from(slice_cell).unwrap();
Signal { store: slice } Signal { store: a }
} }
} }
// automatic dereferencing
impl<'a, const N: usize> Deref for Signal<'a, N> { impl<'a, const N: usize> Deref for Signal<'a, N> {
type Target = [Cell<bool>]; type Target = [Cell<bool>];
...@@ -71,6 +164,8 @@ impl<'a, const N: usize> Deref for Signal<'a, N> { ...@@ -71,6 +164,8 @@ impl<'a, const N: usize> Deref for Signal<'a, N> {
} }
} }
// prints the value of a signal
// perhaps we should enforce reading the signal into a bit array first
impl<'a, const N: usize> fmt::Binary for &Signal<'a, N> { impl<'a, const N: usize> fmt::Binary for &Signal<'a, N> {
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();
...@@ -92,32 +187,22 @@ impl<'a, const N: usize> fmt::Binary for &Signal<'a, N> { ...@@ -92,32 +187,22 @@ impl<'a, const N: usize> fmt::Binary for &Signal<'a, N> {
// } // }
// } // }
// impl<'a, const N: usize> Index<usize> for Signal<'a, N> { // // operations on signal
// type Output = Signal<'a, 1>; // impl<'a, const N: usize> BitAnd for Signal<'a, N> {
// type Output = Signal<'a, N>;
// #[inline]
// fn index(&self, index: usize) -> Self::Output {
// Signal {
// store: &[self.store[index].clone()],
// }
// }
// }
// operations on signal
// impl<const N: usize> BitAnd for &Signal<N> {
// 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 = [false; N];
// let a = self.store.get(); // // let mut bs = [false; N];
// let b = rhs.store.get(); // // let a = self.store.get();
// for i in 0..self.store.get().len() { // // let b = rhs.store.get();
// bs[i] = a[i] & b[i] // // for i in 0..self.store.get().len() {
// } // // bs[i] = a[i] & b[i]
// Signal { // // }
// store: Cell::new(bs), // // Signal {
// } // // store: Cell::new(bs),
// // }
// } // }
// } // }
...@@ -134,14 +219,6 @@ impl<'a, const N: usize> fmt::Binary for &Signal<'a, N> { ...@@ -134,14 +219,6 @@ impl<'a, const N: usize> fmt::Binary for &Signal<'a, N> {
// } // }
// } // }
// impl<const N: usize> From<[bool; N]> for Signal<N> {
// fn from(a: [bool; N]) -> Self {
// Signal {
// store: Cell::new(a),
// }
// }
// }
// impl<const N: usize> From<Signal<N>> for u8 { // impl<const N: usize> From<Signal<N>> for u8 {
// fn from(s: Signal<N>) -> u8 { // fn from(s: Signal<N>) -> u8 {
// // check that it fits u8 // // check that it fits u8
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment