Skip to content

Commit

Permalink
Merge pull request #42 from perlindgren/probe_assert
Browse files Browse the repository at this point in the history
ProbeAssert
  • Loading branch information
perlindgren authored Jul 25, 2023
2 parents ea24e87 + bd35351 commit df7c1bc
Show file tree
Hide file tree
Showing 12 changed files with 359 additions and 42 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"epaint",
"graphviz",
"hoverable",
"lightcoral",
"lightgray",
"menubutton",
"petgraph",
Expand Down
30 changes: 30 additions & 0 deletions examples/probe_stim_assert.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use std::path::PathBuf;
use syncrim::{
common::{ComponentStore, Input},
components::*,
fern::fern_setup,
};

fn main() {
fern_setup();
let cs = ComponentStore {
store: vec![
ProbeStim::rc_new("stim", (100.0, 100.0), vec![0, 1, 2]),
ProbeAssert::rc_new(
"assert",
(200.0, 100.0),
Input::new("stim", "out"),
vec![0, 1, 2],
),
],
};

let path = PathBuf::from("probe_stim_assert.json");
cs.save_file(&path);

#[cfg(feature = "gui-egui")]
syncrim::gui_egui::gui(&cs, &path).ok();

#[cfg(feature = "gui-vizia")]
syncrim::gui_vizia::gui(&cs, &path);
}
2 changes: 2 additions & 0 deletions src/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod constant;
mod mem;
mod mux;
mod probe;
mod probe_assert;
mod probe_edit;
mod probe_out;
mod probe_stim;
Expand All @@ -15,6 +16,7 @@ pub use constant::*;
pub use mem::*;
pub use mux::*;
pub use probe::*;
pub use probe_assert::*;
pub use probe_edit::*;
pub use probe_out::*;
pub use probe_stim::*;
Expand Down
214 changes: 214 additions & 0 deletions src/components/probe_assert.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
use crate::common::{Component, Id, Input, OutputType, Ports, Signal, Simulator};
use log::*;
use serde::{Deserialize, Serialize};
use std::rc::Rc;

#[derive(Serialize, Deserialize)]
pub struct ProbeAssert {
pub id: Id,
pub pos: (f32, f32),
pub input: Input,
pub values: Vec<Signal>,
}

#[typetag::serde]
impl Component for ProbeAssert {
fn to_(&self) {
trace!("ProbeAssert {:?}", self.values);
}

fn get_id_ports(&self) -> (Id, Ports) {
(
self.id.clone(),
Ports::new(vec![&self.input], OutputType::Combinatorial, vec![]),
)
}

fn clock(&self, simulator: &mut Simulator) {
trace!("-- cycle {} --", simulator.cycle);
// the assertion is checked only in test mode
#[cfg(test)]
assert_eq!(
simulator.get_input_val(&self.input),
self.values[simulator.cycle]
);
}

// notice we don't implement `un_clock` since the state is already kept in history
}

impl ProbeAssert {
pub fn new(id: &str, pos: (f32, f32), input: Input, values: Vec<impl Into<Signal>>) -> Self {
ProbeAssert {
id: id.to_string(),
pos,
input,
values: values.into_iter().map(|v| v.into()).collect(),
}
}

pub fn rc_new(
id: &str,
pos: (f32, f32),
input: Input,
values: Vec<impl Into<Signal>>,
) -> Rc<Self> {
Rc::new(ProbeAssert::new(id, pos, input, values))
}
}

#[cfg(test)]
mod test {
use super::*;
use crate::{
common::{ComponentStore, Input},
components::ProbeStim,
};

#[test]
fn test_probe_stim() {
let cs = ComponentStore {
store: vec![
ProbeStim::rc_new("stim", (0.0, 0.0), vec![0, 1, 2]),
ProbeAssert::rc_new(
"assert",
(0.0, 0.0),
Input::new("stim", "out"),
vec![0, 1, 2],
),
],
};

let mut simulator = Simulator::new(&cs);
// output
let out = &Input::new("stim", "out");

// reset
println!("<reset>");
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 1);
assert_eq!(simulator.get_input_val(out), 0.into());

println!("<clock>");
simulator.clock();
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 2);
assert_eq!(simulator.get_input_val(out), 1.into());

println!("<clock>");
simulator.clock();
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 3);
assert_eq!(simulator.get_input_val(out), 2.into());

println!("<un_clock>");
simulator.un_clock();
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 2);
assert_eq!(simulator.get_input_val(out), 1.into());

println!("<un_clock>");
simulator.un_clock();
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 1);
assert_eq!(simulator.get_input_val(out), 0.into());

println!("<un_clock (already in reset)>");
simulator.un_clock();
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 1);
assert_eq!(simulator.get_input_val(out), 0.into());

println!("<clock>");
simulator.clock();
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 2);
assert_eq!(simulator.get_input_val(out), 1.into());

println!("<clock>");
simulator.clock();
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 3);
assert_eq!(simulator.get_input_val(out), 2.into());

println!("<reset>");
simulator.reset();
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 1);
assert_eq!(simulator.get_input_val(out), 0.into());
}

#[test]
#[should_panic]
fn test_probe_stim_fail() {
let cs = ComponentStore {
store: vec![
ProbeStim::rc_new("stim", (0.0, 0.0), vec![0, 1, 2]),
ProbeAssert::rc_new(
"assert",
(0.0, 0.0),
Input::new("stim", "out"),
vec![0, 0, 2],
),
],
};

let mut simulator = Simulator::new(&cs);
// output
let out = &Input::new("stim", "out");

// reset
println!("<reset>");
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 1);
assert_eq!(simulator.get_input_val(out), 0.into());

println!("<clock>");
simulator.clock();
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 2);
assert_eq!(simulator.get_input_val(out), 1.into());

println!("<clock>");
simulator.clock();
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 3);
assert_eq!(simulator.get_input_val(out), 2.into());

println!("<un_clock>");
simulator.un_clock();
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 2);
assert_eq!(simulator.get_input_val(out), 1.into());

println!("<un_clock>");
simulator.un_clock();
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 1);
assert_eq!(simulator.get_input_val(out), 0.into());

println!("<un_clock (already in reset)>");
simulator.un_clock();
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 1);
assert_eq!(simulator.get_input_val(out), 0.into());

println!("<clock>");
simulator.clock();
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 2);
assert_eq!(simulator.get_input_val(out), 1.into());

println!("<clock>");
simulator.clock();
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 3);
assert_eq!(simulator.get_input_val(out), 2.into());

println!("<reset>");
simulator.reset();
println!("sim_state {:?}", simulator.sim_state);
assert_eq!(simulator.cycle, 1);
assert_eq!(simulator.get_input_val(out), 0.into());
}
}
29 changes: 18 additions & 11 deletions src/components/probe_edit.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use crate::common::{Component, Id, OutputType, Ports, Signal, Simulator};
use log::*;
use serde::{Deserialize, Serialize};
use std::sync::{Arc, RwLock};
use std::{
rc::Rc,
sync::{Arc, RwLock},
};

#[derive(Serialize, Deserialize, Clone)]
pub struct ProbeEdit {
pub id: Id,
pub pos: (f32, f32),
pub history: Arc<RwLock<Vec<TextSignal>>>, // will contain the next editable value
pub edit_history: Arc<RwLock<Vec<TextSignal>>>, // will contain the next editable value
}

#[derive(Serialize, Deserialize, Clone, Debug)]
Expand Down Expand Up @@ -37,7 +40,7 @@ impl Component for ProbeEdit {

// propagate editable value
fn clock(&self, simulator: &mut Simulator) {
let mut history = self.history.write().unwrap();
let mut history = self.edit_history.write().unwrap();
trace!("{} history {:?}", self.id, history);
let current = history.last().unwrap().clone();
// set output to current value
Expand All @@ -48,16 +51,16 @@ impl Component for ProbeEdit {

// reverse simulation, notice does not touch simulator state, its just internal
fn un_clock(&self) {
let mut history = self.history.write().unwrap();
trace!("{} history {:?}", self.id, history);
let _next = history.pop().unwrap(); // pop the next editable value
let _current = history.pop().unwrap(); // pop current editable value
let prev = history.pop().unwrap(); // pop the prev editable value
let mut edit_history = self.edit_history.write().unwrap();
trace!("{} history {:?}", self.id, edit_history);
let _next = edit_history.pop().unwrap(); // pop the next editable value
let _current = edit_history.pop().unwrap(); // pop current editable value
let prev = edit_history.pop().unwrap(); // pop the prev editable value
trace!("next {:?}", _next);
trace!("current {:?}", _current);
trace!("prev {:?}", prev);
history.push(prev.clone()); // push as current
history.push(prev); // push as next (to be edited)
edit_history.push(prev.clone()); // push as current
edit_history.push(prev); // push as next (to be edited)
}
}

Expand All @@ -67,10 +70,14 @@ impl ProbeEdit {
id: id.into(),
pos,
// initiate internal history
history: Arc::new(RwLock::new(vec![TextSignal {
edit_history: Arc::new(RwLock::new(vec![TextSignal {
text: "0".to_string(),
signal: Signal::Data(0),
}])),
}
}

pub fn rc_new(id: &str, pos: (f32, f32)) -> Rc<Self> {
Rc::new(ProbeEdit::new(id, pos))
}
}
7 changes: 6 additions & 1 deletion src/components/probe_stim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ impl Component for ProbeStim {

fn clock(&self, simulator: &mut Simulator) {
trace!("-- cycle {} --", simulator.cycle);
simulator.set_out_val(&self.id, "out", self.values[simulator.cycle]);
let out = if let Some(value) = self.values.get(simulator.cycle) {
*value
} else {
Signal::Unknown
};
simulator.set_out_val(&self.id, "out", out);
}

// notice we don't implement `un_clock` since the state is already kept in history
Expand Down
1 change: 1 addition & 0 deletions src/gui_egui/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod constant;
mod mem;
mod mux;
mod probe;
mod probe_assert;
mod probe_out;
mod register;
mod sext;
Expand Down
5 changes: 5 additions & 0 deletions src/gui_egui/components/probe_assert.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use crate::common::EguiComponent;
use crate::components::ProbeAssert;

#[typetag::serde]
impl EguiComponent for ProbeAssert {}
3 changes: 2 additions & 1 deletion src/gui_vizia/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ mod constant;
mod mem;
mod mux;
mod probe;
mod probe_assert;
mod probe_edit;
mod probe_out;
mod probe_stim;
mod register;
mod sext;
mod wire;
mod probe_stim;
Loading

0 comments on commit df7c1bc

Please sign in to comment.