Skip to content

Commit

Permalink
[cider2] Make minimally-sized clonable simulator (#2345)
Browse files Browse the repository at this point in the history
Creates a new `BaseSimulator` object that can be used independently of
`Simulator`. Also, things are cloneable now. The rationale is we can now
write a model checker using cider by cloning cider contexts at forks.
  • Loading branch information
ethanuppal authored Nov 12, 2024
1 parent 5bd3599 commit 33255f9
Show file tree
Hide file tree
Showing 12 changed files with 258 additions and 75 deletions.
1 change: 0 additions & 1 deletion interp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ baa = { version = "0.14.0", features = ["bigint", "serde1", "fraction1"] }
fst-writer = "0.2.1"
bon = "2.3"


[dev-dependencies]
proptest = "1.0.0"

Expand Down
15 changes: 15 additions & 0 deletions interp/src/flatten/primitives/combinational.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use baa::{BitVecOps, BitVecValue};

use super::prim_trait::UpdateResult;

#[derive(Clone)]
pub struct StdConst {
value: BitVecValue,
out: GlobalPortIdx,
Expand Down Expand Up @@ -44,8 +45,13 @@ impl Primitive for StdConst {
fn has_stateful(&self) -> bool {
false
}

fn clone_boxed(&self) -> Box<dyn Primitive> {
Box::new(self.clone())
}
}

#[derive(Clone)]
pub struct StdMux {
base: GlobalPortIdx,
}
Expand Down Expand Up @@ -80,6 +86,10 @@ impl Primitive for StdMux {
fn has_stateful(&self) -> bool {
false
}

fn clone_boxed(&self) -> Box<dyn Primitive> {
Box::new(self.clone())
}
}

comb_primitive!(StdNot(input [0]) -> (out [1]) {
Expand Down Expand Up @@ -275,6 +285,7 @@ comb_primitive!(StdUnsynSmod[WIDTH](left [0], right [1]) -> (out [2]) {
Ok(Some(BitVecValue::from_big_int(&res, WIDTH)))
});

#[derive(Clone)]
pub struct StdUndef(GlobalPortIdx);

impl StdUndef {
Expand All @@ -288,4 +299,8 @@ impl Primitive for StdUndef {
port_map.write_undef(self.0)?;
Ok(UpdateStatus::Unchanged)
}

fn clone_boxed(&self) -> Box<dyn Primitive> {
Box::new(self.clone())
}
}
6 changes: 6 additions & 0 deletions interp/src/flatten/primitives/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ macro_rules! comb_primitive {
false
}

fn clone_boxed(&self) -> Box<dyn $crate::flatten::primitives::Primitive> {
Box::new(Self {
base_port: self.base_port,
$($($param: self.$param,)+)?
})
}
}
};

Expand Down
11 changes: 10 additions & 1 deletion interp/src/flatten/primitives/prim_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ pub trait Primitive {
fn dump_memory_state(&self) -> Option<Vec<u8>> {
None
}

fn clone_boxed(&self) -> Box<dyn Primitive>;
}

pub trait RaceDetectionPrimitive: Primitive {
Expand All @@ -158,10 +160,13 @@ pub trait RaceDetectionPrimitive: Primitive {
/// Get a reference to the underlying primitive. Unfortunately cannot add an
/// optional default implementation due to size rules
fn as_primitive(&self) -> &dyn Primitive;

fn clone_boxed_rd(&self) -> Box<dyn RaceDetectionPrimitive>;
}

/// An empty primitive implementation used for testing. It does not do anything
/// and has no ports of any kind
#[derive(Clone, Copy)]
pub struct DummyPrimitive;

impl DummyPrimitive {
Expand All @@ -170,4 +175,8 @@ impl DummyPrimitive {
}
}

impl Primitive for DummyPrimitive {}
impl Primitive for DummyPrimitive {
fn clone_boxed(&self) -> Box<dyn Primitive> {
Box::new(*self)
}
}
24 changes: 24 additions & 0 deletions interp/src/flatten/primitives/stateful/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::flatten::{
use baa::{BitVecOps, BitVecValue, WidthInt};
use num_traits::Euclid;

#[derive(Clone)]
pub struct StdMultPipe<const DEPTH: usize> {
base_port: GlobalPortIdx,
pipeline: ShiftBuffer<(PortValue, PortValue), DEPTH>,
Expand All @@ -32,6 +33,10 @@ impl<const DEPTH: usize> StdMultPipe<DEPTH> {
}

impl<const DEPTH: usize> Primitive for StdMultPipe<DEPTH> {
fn clone_boxed(&self) -> Box<dyn Primitive> {
Box::new(self.clone())
}

fn exec_comb(&self, port_map: &mut PortMap) -> UpdateResult {
ports![&self.base_port; out: Self::OUT, done: Self::DONE];

Expand Down Expand Up @@ -106,6 +111,7 @@ impl<const DEPTH: usize> Primitive for StdMultPipe<DEPTH> {
}
}

#[derive(Clone)]
pub struct StdDivPipe<const DEPTH: usize, const SIGNED: bool> {
base_port: GlobalPortIdx,
pipeline: ShiftBuffer<(PortValue, PortValue), DEPTH>,
Expand All @@ -132,6 +138,10 @@ impl<const DEPTH: usize, const SIGNED: bool> StdDivPipe<DEPTH, SIGNED> {
impl<const DEPTH: usize, const SIGNED: bool> Primitive
for StdDivPipe<DEPTH, SIGNED>
{
fn clone_boxed(&self) -> Box<dyn Primitive> {
Box::new(self.clone())
}

fn exec_comb(&self, port_map: &mut PortMap) -> UpdateResult {
ports![&self.base_port;
out_quot: Self::OUT_QUOTIENT,
Expand Down Expand Up @@ -253,6 +263,10 @@ impl<const IS_FIXED_POINT: bool> Sqrt<IS_FIXED_POINT> {
}

impl<const IS_FIXED_POINT: bool> Primitive for Sqrt<IS_FIXED_POINT> {
fn clone_boxed(&self) -> Box<dyn Primitive> {
Box::new(self.clone())
}

fn exec_comb(&self, port_map: &mut PortMap) -> UpdateResult {
ports![&self.base_port; out: Self::OUT, done: Self::DONE];

Expand Down Expand Up @@ -309,6 +323,7 @@ impl<const IS_FIXED_POINT: bool> Primitive for Sqrt<IS_FIXED_POINT> {
}
}

#[derive(Clone)]
pub struct FxpMultPipe<const DEPTH: usize> {
base_port: GlobalPortIdx,
pipeline: ShiftBuffer<(PortValue, PortValue), DEPTH>,
Expand Down Expand Up @@ -339,6 +354,10 @@ impl<const DEPTH: usize> FxpMultPipe<DEPTH> {
}

impl<const DEPTH: usize> Primitive for FxpMultPipe<DEPTH> {
fn clone_boxed(&self) -> Box<dyn Primitive> {
Box::new(self.clone())
}

fn exec_comb(&self, port_map: &mut PortMap) -> UpdateResult {
ports![&self.base_port; out: Self::OUT, done: Self::DONE];

Expand Down Expand Up @@ -422,6 +441,7 @@ impl<const DEPTH: usize> Primitive for FxpMultPipe<DEPTH> {
}
}

#[derive(Clone)]
pub struct FxpDivPipe<const DEPTH: usize, const SIGNED: bool> {
base_port: GlobalPortIdx,
pipeline: ShiftBuffer<(PortValue, PortValue), DEPTH>,
Expand Down Expand Up @@ -460,6 +480,10 @@ impl<const DEPTH: usize, const SIGNED: bool> FxpDivPipe<DEPTH, SIGNED> {
impl<const DEPTH: usize, const SIGNED: bool> Primitive
for FxpDivPipe<DEPTH, SIGNED>
{
fn clone_boxed(&self) -> Box<dyn Primitive> {
Box::new(self.clone())
}

fn exec_comb(&self, port_map: &mut PortMap) -> UpdateResult {
ports![&self.base_port;
out_quot: Self::OUT_QUOTIENT,
Expand Down
28 changes: 28 additions & 0 deletions interp/src/flatten/primitives/stateful/memories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use crate::{

use baa::{BitVecOps, BitVecValue, WidthInt};

#[derive(Clone)]
pub struct StdReg {
base_port: GlobalPortIdx,
internal_state: ValueWithClock,
Expand Down Expand Up @@ -55,6 +56,10 @@ impl StdReg {
}

impl Primitive for StdReg {
fn clone_boxed(&self) -> Box<dyn Primitive> {
Box::new(self.clone())
}

fn exec_cycle(&mut self, port_map: &mut PortMap) -> UpdateResult {
ports![&self.base_port;
input: Self::IN,
Expand Down Expand Up @@ -139,6 +144,10 @@ impl Primitive for StdReg {
}

impl RaceDetectionPrimitive for StdReg {
fn clone_boxed_rd(&self) -> Box<dyn RaceDetectionPrimitive> {
Box::new(self.clone())
}

fn as_primitive(&self) -> &dyn Primitive {
self
}
Expand Down Expand Up @@ -176,6 +185,7 @@ impl RaceDetectionPrimitive for StdReg {
}
}

#[derive(Clone)]
pub struct MemDx<const SEQ: bool> {
shape: Shape,
}
Expand Down Expand Up @@ -389,6 +399,7 @@ impl<const SEQ: bool> MemDx<SEQ> {
}
}

#[derive(Clone)]
pub struct CombMem {
base_port: GlobalPortIdx,
internal_state: Vec<ValueWithClock>,
Expand Down Expand Up @@ -508,6 +519,10 @@ impl CombMem {
}

impl Primitive for CombMem {
fn clone_boxed(&self) -> Box<dyn Primitive> {
Box::new(self.clone())
}

fn exec_comb(&self, port_map: &mut PortMap) -> UpdateResult {
let addr: Option<usize> = self
.addresser
Expand Down Expand Up @@ -609,6 +624,10 @@ impl Primitive for CombMem {
}

impl RaceDetectionPrimitive for CombMem {
fn clone_boxed_rd(&self) -> Box<dyn RaceDetectionPrimitive> {
Box::new(self.clone())
}

fn as_primitive(&self) -> &dyn Primitive {
self
}
Expand Down Expand Up @@ -674,6 +693,7 @@ impl RaceDetectionPrimitive for CombMem {
}
}

#[derive(Clone)]
pub struct SeqMem {
base_port: GlobalPortIdx,
internal_state: Vec<ValueWithClock>,
Expand Down Expand Up @@ -812,6 +832,10 @@ impl SeqMem {
}

impl Primitive for SeqMem {
fn clone_boxed(&self) -> Box<dyn Primitive> {
Box::new(self.clone())
}

fn exec_comb(&self, port_map: &mut PortMap) -> UpdateResult {
let done_signal = port_map.insert_val_general(
self.done(),
Expand Down Expand Up @@ -915,6 +939,10 @@ impl Primitive for SeqMem {
}

impl RaceDetectionPrimitive for SeqMem {
fn clone_boxed_rd(&self) -> Box<dyn RaceDetectionPrimitive> {
Box::new(self.clone())
}

fn as_primitive(&self) -> &dyn Primitive {
self
}
Expand Down
1 change: 1 addition & 0 deletions interp/src/flatten/primitives/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub(crate) fn int_sqrt(i: &BigUint) -> BigUint {
}

/// A shift buffer of a fixed size
#[derive(Clone)]
pub struct ShiftBuffer<T, const N: usize> {
buffer: VecDeque<Option<T>>,
}
Expand Down
Loading

0 comments on commit 33255f9

Please sign in to comment.