From 28634dc9ae22b8d01a82550e9065da3cf53bcc0b Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Tue, 25 Jul 2023 23:47:45 +0200 Subject: [PATCH 01/14] wip --- mips/src/components/reg_file.rs | 6 +- src/common.rs | 133 ++++++++++++++++++++--- src/components/add.rs | 8 +- src/components/constant.rs | 2 +- src/components/mem.rs | 15 +-- src/components/mux.rs | 9 +- src/components/probe_assert.rs | 2 +- src/components/probe_edit.rs | 4 +- src/components/probe_stim.rs | 8 +- src/components/sext.rs | 4 +- src/gui_vizia/components/probe_assert.rs | 4 +- src/gui_vizia/components/probe_edit.rs | 18 +-- src/gui_vizia/components/probe_stim.rs | 4 +- src/simulator.rs | 16 +-- 14 files changed, 172 insertions(+), 61 deletions(-) diff --git a/mips/src/components/reg_file.rs b/mips/src/components/reg_file.rs index 7899ce14..2fffd75c 100644 --- a/mips/src/components/reg_file.rs +++ b/mips/src/components/reg_file.rs @@ -3,7 +3,7 @@ use num_enum::TryFromPrimitive; use serde::{Deserialize, Serialize}; use std::ops::{Deref, Range}; use std::{cell::RefCell, rc::Rc}; -use syncrim::common::{Component, Input, OutputType, Ports, Signal, SignalUnsigned, Simulator}; +use syncrim::common::{Component, Input, OutputType, Ports, SignalUnsigned, Simulator}; #[allow(non_camel_case_types)] #[rustfmt::skip] @@ -168,11 +168,11 @@ impl Component for RegFile { // read after write let reg_value_a = self.read_reg(simulator, &self.read_addr1); trace!("reg_value {}", reg_value_a); - simulator.set_out_val(&self.id, "reg_a", Signal::Data(reg_value_a)); + simulator.set_out_val(&self.id, "reg_a", reg_value_a); let reg_value_b = self.read_reg(simulator, &self.read_addr2); trace!("reg_value {}", reg_value_b); - simulator.set_out_val(&self.id, "reg_b", Signal::Data(reg_value_b)); + simulator.set_out_val(&self.id, "reg_b", reg_value_b); } } diff --git a/src/common.rs b/src/common.rs index 2687f957..1baa6752 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,8 +1,11 @@ +use num_enum::IntoPrimitive; use petgraph::Graph; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; use std::{ + ascii::escape_default, + collections::HashMap, convert::{From, TryFrom}, + fmt, rc::Rc, }; @@ -15,8 +18,34 @@ pub type Id = String; pub type SignalUnsigned = u32; pub type SignalSigned = i32; + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Copy, Clone)] +pub struct Signal { + data: SignalData, + fmt: SignalFmt, +} + +impl Signal { + /// set data field + pub fn set_data(&mut self, data: SignalData) { + self.data = data + } + /// set fmt field + pub fn set_fmt(&mut self, fmt: SignalFmt) { + self.fmt = fmt + } + /// get data field + pub fn get_data(&self) -> SignalData { + self.data + } + /// get fmt field + pub fn get_fmt(&self) -> SignalFmt { + self.fmt + } +} + #[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)] -pub enum Signal { +pub enum SignalData { Uninitialized, Unknown, DontCare, @@ -27,23 +56,107 @@ impl TryFrom for SignalUnsigned { type Error = String; fn try_from(signal: Signal) -> Result { - if let Signal::Data(data) = signal { + if let SignalData::Data(data) = signal.data { + Ok(data) + } else { + Err(format!( + "Could not convert {:?} into SignalUnsigned", + signal + )) + } + } +} + +impl TryFrom for SignalUnsigned { + type Error = String; + + fn try_from(data: SignalData) -> Result { + if let SignalData::Data(data) = data { Ok(data) } else { - Err(format!("could not convert {:?} into u32", signal)) + Err(format!("Could not convert {:?} into SignalUnsigned", data)) + } + } +} + +impl From for Signal { + fn from(data: SignalData) -> Signal { + Signal { + data, + fmt: SignalFmt::Hex(SignalSize::_32), } } } impl From for Signal { fn from(data: u32) -> Signal { - Signal::Data(data) + Signal { + data: SignalData::Data(data), + fmt: SignalFmt::Hex(SignalSize::_32), + } } } impl From for Signal { fn from(b: bool) -> Signal { - Signal::Data(b as SignalUnsigned) + Signal { + data: SignalData::Data(b as SignalUnsigned), + fmt: SignalFmt::Hex(SignalSize::_32), + } + } +} + +impl From for SignalData { + fn from(data: u32) -> SignalData { + SignalData::Data(data) + } +} + +impl From for SignalData { + fn from(b: bool) -> SignalData { + SignalData::Data(b as SignalUnsigned) + } +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Copy, Clone)] +pub enum SignalFmt { + Ascii(SignalSize), + Unsigned(SignalSize), + Signed(SignalSize), + Hex(SignalSize), + Binary(u8), // just to set a limit to the number of bits + Bool, // treats it as true/false +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Copy, Clone, IntoPrimitive)] +#[repr(u8)] +pub enum SignalSize { + _8 = 1, + _16 = 2, + _32 = 4, +} + +impl fmt::Display for Signal { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.data { + SignalData::Data(value) => match self.fmt { + SignalFmt::Ascii(signal_size) => { + let s: u8 = signal_size.into(); + + let bytes = &value.to_be_bytes()[0..s as usize]; + // let x: Vec = bytes.iter().map(|b| escape_default(*b)).flatten().collect(); + // write!(f, "{:?}", self.bytes), + unimplemented!() + } + SignalFmt::Binary(u) => unimplemented!(), + SignalFmt::Unsigned(_) => todo!(), + SignalFmt::Signed(_) => todo!(), + SignalFmt::Hex(_) => todo!(), + SignalFmt::Bool => todo!(), + // _ => write!(f, "{:?}", self.data), + }, + _ => write!(f, "{:?}", self.data), + } } } @@ -170,11 +283,3 @@ pub enum OutputType { // Will be evaluated as synchronous from input to output Sequential, } - -// #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] -// pub enum Output { -// // Will be evaluated as a constant (function without inputs) -// Constant(Signal), -// // Will be evaluated as a function -// Function, -// } diff --git a/src/components/add.rs b/src/components/add.rs index bcb78cff..b1a23968 100644 --- a/src/components/add.rs +++ b/src/components/add.rs @@ -1,5 +1,5 @@ use crate::common::{ - Component, Id, Input, OutputType, Ports, Signal, SignalSigned, SignalUnsigned, Simulator, + Component, Id, Input, OutputType, Ports, SignalData, SignalSigned, SignalUnsigned, Simulator, }; use log::*; use serde::{Deserialize, Serialize}; @@ -40,11 +40,11 @@ impl Component for Add { let (res, overflow) = SignalSigned::overflowing_add(*a as SignalSigned, *b as SignalSigned); ( - Signal::Data(res as SignalUnsigned), - Signal::Data(overflow as SignalUnsigned), + (res as SignalUnsigned).into(), + (overflow as SignalUnsigned).into(), ) } - _ => (Signal::Unknown, Signal::Unknown), + _ => (SignalData::Unknown, SignalData::Unknown), }; trace!( diff --git a/src/components/constant.rs b/src/components/constant.rs index b4739763..5f43e1b3 100644 --- a/src/components/constant.rs +++ b/src/components/constant.rs @@ -28,7 +28,7 @@ impl Component for Constant { } fn clock(&self, simulator: &mut Simulator) { - simulator.set_out_val(&self.id, "out", self.value); + simulator.set_out_val(&self.id, "out", self.value.get_data()); } } diff --git a/src/components/mem.rs b/src/components/mem.rs index 0bcea32c..1fe603cd 100644 --- a/src/components/mem.rs +++ b/src/components/mem.rs @@ -1,5 +1,5 @@ use crate::common::{ - Component, Id, Input, OutputType, Ports, Signal, SignalSigned, SignalUnsigned, Simulator, + Component, Id, Input, OutputType, Ports, SignalData, SignalSigned, SignalUnsigned, Simulator, }; use log::*; use num_enum::IntoPrimitive; @@ -47,11 +47,11 @@ impl Memory { } } - fn align(&self, addr: usize, size: usize) -> Signal { - Signal::Data((addr % size != 0) as SignalUnsigned) + fn align(&self, addr: usize, size: usize) -> SignalData { + ((addr % size != 0) as SignalUnsigned).into() } - fn read(&self, addr: usize, size: usize, sign: bool, big_endian: bool) -> Signal { + fn read(&self, addr: usize, size: usize, sign: bool, big_endian: bool) -> SignalData { let data: Vec = (0..size) .map(|i| *self.bytes.borrow().get(&(addr + i)).unwrap_or(&0)) .collect(); @@ -60,7 +60,7 @@ impl Memory { trace!("{:x?}", data); - Signal::Data(match size { + match size { 1 => { if sign { data[0] as i8 as SignalSigned as SignalUnsigned @@ -115,10 +115,11 @@ impl Memory { } } _ => panic!("illegal sized memory operation"), - }) + } + .into() } - fn write(&self, addr: usize, size: usize, big_endian: bool, data: Signal) { + fn write(&self, addr: usize, size: usize, big_endian: bool, data: SignalData) { let data: SignalUnsigned = data.try_into().unwrap(); match size { 1 => { diff --git a/src/components/mux.rs b/src/components/mux.rs index 38a8fb3e..1e6bd821 100644 --- a/src/components/mux.rs +++ b/src/components/mux.rs @@ -1,4 +1,6 @@ -use crate::common::{Component, Id, Input, OutputType, Ports, Signal, SignalUnsigned, Simulator}; +use crate::common::{ + Component, Id, Input, OutputType, Ports, SignalData, SignalUnsigned, Simulator, +}; use log::*; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] @@ -33,13 +35,14 @@ impl Component for Mux { // propagate selected input value to output fn clock(&self, simulator: &mut Simulator) { // get input value - let select: SignalUnsigned = simulator.get_input_val(&self.select).try_into().unwrap(); + let select: SignalData = simulator.get_input_val(&self.select); + let select: SignalUnsigned = select.try_into().unwrap(); let select = select as usize; trace!("select {}", select); let value = if select < self.m_in.len() { simulator.get_input_val(&self.m_in[select]) } else { - Signal::Unknown + SignalData::Unknown }; // set output diff --git a/src/components/probe_assert.rs b/src/components/probe_assert.rs index 4ffe123a..29c5506f 100644 --- a/src/components/probe_assert.rs +++ b/src/components/probe_assert.rs @@ -30,7 +30,7 @@ impl Component for ProbeAssert { #[cfg(test)] assert_eq!( simulator.get_input_val(&self.input), - self.values[simulator.cycle] + self.values[simulator.cycle].get_data() ); } diff --git a/src/components/probe_edit.rs b/src/components/probe_edit.rs index 5433b172..e0e6b181 100644 --- a/src/components/probe_edit.rs +++ b/src/components/probe_edit.rs @@ -44,7 +44,7 @@ impl Component for ProbeEdit { trace!("{} history {:?}", self.id, history); let current = history.last().unwrap().clone(); // set output to current value - simulator.set_out_val(&self.id, "out", current.signal); + simulator.set_out_val(&self.id, "out", current.signal.get_data()); // push to prepare data for next; history.push(current); } @@ -72,7 +72,7 @@ impl ProbeEdit { // initiate internal history edit_history: Arc::new(RwLock::new(vec![TextSignal { text: "0".to_string(), - signal: Signal::Data(0), + signal: 0.into(), }])), } } diff --git a/src/components/probe_stim.rs b/src/components/probe_stim.rs index 26b1e9f2..7637fea2 100644 --- a/src/components/probe_stim.rs +++ b/src/components/probe_stim.rs @@ -1,4 +1,4 @@ -use crate::common::{Component, Id, OutputType, Ports, Signal, Simulator}; +use crate::common::{Component, Id, OutputType, Ports, Signal, SignalData, Simulator}; use log::*; use serde::{Deserialize, Serialize}; use std::rc::Rc; @@ -30,10 +30,10 @@ impl Component for ProbeStim { fn clock(&self, simulator: &mut Simulator) { trace!("-- cycle {} --", simulator.cycle); - let out = if let Some(value) = self.values.get(simulator.cycle) { - *value + let out = if let Some(signal) = self.values.get(simulator.cycle) { + signal.get_data() } else { - Signal::Unknown + SignalData::Unknown }; simulator.set_out_val(&self.id, "out", out); } diff --git a/src/components/sext.rs b/src/components/sext.rs index 2b6599a7..b5f3fa8e 100644 --- a/src/components/sext.rs +++ b/src/components/sext.rs @@ -1,6 +1,6 @@ // use std::fmt::Alignment; use crate::common::{ - Component, Id, Input, OutputType, Ports, Signal, SignalSigned, SignalUnsigned, Simulator, + Component, Id, Input, OutputType, Ports, SignalSigned, SignalUnsigned, Simulator, }; use log::*; use serde::{Deserialize, Serialize}; @@ -49,7 +49,7 @@ impl Component for Sext { value >>= to_shr; // set output - simulator.set_out_val(&self.id, "out", Signal::Data(value)); + simulator.set_out_val(&self.id, "out", value); } } diff --git a/src/gui_vizia/components/probe_assert.rs b/src/gui_vizia/components/probe_assert.rs index 5f59bd33..d55f076b 100644 --- a/src/gui_vizia/components/probe_assert.rs +++ b/src/gui_vizia/components/probe_assert.rs @@ -1,5 +1,5 @@ use crate::{ - common::{Component, Signal, Simulator, ViziaComponent}, + common::{Component, SignalData, Simulator, ViziaComponent}, components::ProbeAssert, gui_vizia::{popup::NewPopup, tooltip::new_component_tooltip, GuiData}, }; @@ -25,7 +25,7 @@ impl ViziaComponent for ProbeAssert { let rhs = if let Some(value) = values.get(cycle - 1) { *value } else { - Signal::Unknown + (SignalData::Unknown).into() }; Label::new(cx, { let simulator = GuiData::simulator.get(cx); diff --git a/src/gui_vizia/components/probe_edit.rs b/src/gui_vizia/components/probe_edit.rs index 82d4d961..8dca0a44 100644 --- a/src/gui_vizia/components/probe_edit.rs +++ b/src/gui_vizia/components/probe_edit.rs @@ -1,6 +1,6 @@ use crate::gui_vizia::GuiData; use crate::{ - common::{Signal, SignalSigned, SignalUnsigned, Simulator, ViziaComponent}, + common::{SignalData, SignalSigned, SignalUnsigned, Simulator, ViziaComponent}, components::{ProbeEdit, TextSignal}, }; use vizia::prelude::*; @@ -37,12 +37,12 @@ impl ViziaComponent for ProbeEdit { .on_edit(move |_ex, text| { trace!("edit: text {}", text); - let signal = parse_signal(&text); + let value = parse_signal(&text); *history_submit.write().unwrap().last_mut().unwrap() = TextSignal { text: text.clone(), - signal, + signal: value.into(), }; - trace!("signal {:?}", signal); + trace!("signal {:?}", value); }) .position_type(PositionType::SelfDirected) .left(Pixels(self.pos.0 - 40.0)) @@ -57,18 +57,18 @@ pub struct ProbeEditView { editable_text: String, } -fn parse_signal(text: &str) -> Signal { +fn parse_signal(text: &str) -> SignalData { let text = text.trim(); if let Ok(signal) = text.parse::() { - Signal::Data(signal as SignalUnsigned) + (signal as SignalUnsigned).into() } else if let Some(hex) = text.strip_prefix("0x") { if let Ok(signal) = SignalUnsigned::from_str_radix(hex, 16) { - Signal::Data(signal) + signal.into() } else { - Signal::Unknown + SignalData::Unknown } } else { - Signal::Unknown + SignalData::Unknown } } diff --git a/src/gui_vizia/components/probe_stim.rs b/src/gui_vizia/components/probe_stim.rs index 2cfa7fa4..c4f63e75 100644 --- a/src/gui_vizia/components/probe_stim.rs +++ b/src/gui_vizia/components/probe_stim.rs @@ -1,5 +1,5 @@ use crate::{ - common::{Component, Signal, Simulator, ViziaComponent}, + common::{Component, SignalData, Simulator, ViziaComponent}, components::ProbeStim, gui_vizia::{popup::NewPopup, tooltip::new_component_tooltip}, }; @@ -23,7 +23,7 @@ impl ViziaComponent for ProbeStim { let rhs = if let Some(value) = values.get(cycle - 1) { *value } else { - Signal::Unknown + (SignalData::Unknown).into() }; Label::new(cx, &format!("{:?}", rhs)).hoverable(false); }, diff --git a/src/simulator.rs b/src/simulator.rs index 83a55d7d..baebb1f4 100644 --- a/src/simulator.rs +++ b/src/simulator.rs @@ -1,4 +1,6 @@ -use crate::common::{Component, ComponentStore, Id, Input, OutputType, Signal, Simulator}; +use crate::common::{ + Component, ComponentStore, Id, Input, OutputType, Signal, SignalData, Simulator, +}; use petgraph::{ algo::toposort, dot::{Config, Dot}, @@ -144,7 +146,7 @@ impl Simulator { } /// get input value - pub fn get_input_val(&self, input: &Input) -> Signal { + pub fn get_input_val(&self, input: &Input) -> SignalData { let nr_out = *self.id_nr_outputs.get(&input.id).unwrap(); let index = *self .id_field_index @@ -157,7 +159,7 @@ impl Simulator { }); if index < nr_out { let start_index = *self.id_start_index.get(&input.id).unwrap(); - self.get(start_index + index) + self.get(start_index + index).get_data() } else { panic!( "ICE: Attempt to read {:?} at index {}, where {:?} has only {} outputs.", @@ -172,18 +174,18 @@ impl Simulator { } // set value by index - fn set(&mut self, index: usize, value: Signal) { - self.sim_state[index] = value; + fn set_data(&mut self, index: usize, value: SignalData) { + self.sim_state[index].set_data(value); } /// set value by Id (instance) and Id (field) - pub fn set_out_val(&mut self, id: &str, field: &str, value: impl Into) { + pub fn set_out_val(&mut self, id: &str, field: &str, value: impl Into) { let index = *self .id_field_index .get(&(id.into(), field.into())) .unwrap_or_else(|| panic!("Component {}, field {} not found.", id, field)); let start_index = self.get_id_start_index(id); - self.set(start_index + index, value.into()); + self.set_data(start_index + index, value.into()); } /// iterate over the evaluators and increase clock by one From 0e1fc2b77e13e0f6c2220ccc9877f5b6ffcc95e6 Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Wed, 26 Jul 2023 07:09:30 +0200 Subject: [PATCH 02/14] Signal refactor, ProbeAssert --- .vscode/settings.json | 1 + examples/probe_stim_assert.rs | 2 +- mips/Cargo.toml | 6 +- src/common.rs | 157 +---------- src/gui_vizia/components/probe_assert.rs | 19 +- src/lib.rs | 1 + src/signal.rs | 326 +++++++++++++++++++++++ src/simulator.rs | 11 +- 8 files changed, 353 insertions(+), 170 deletions(-) create mode 100644 src/signal.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index 2a1cb9c2..8ac09f28 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -22,6 +22,7 @@ "hoverable", "lightcoral", "lightgray", + "lightgreen", "menubutton", "petgraph", "println", diff --git a/examples/probe_stim_assert.rs b/examples/probe_stim_assert.rs index 52c41596..85c5e1df 100644 --- a/examples/probe_stim_assert.rs +++ b/examples/probe_stim_assert.rs @@ -9,7 +9,7 @@ fn main() { fern_setup(); let cs = ComponentStore { store: vec![ - ProbeStim::rc_new("stim", (100.0, 100.0), vec![0, 1, 2]), + ProbeStim::rc_new("stim", (100.0, 100.0), vec![42, 1, 2]), ProbeAssert::rc_new( "assert", (200.0, 100.0), diff --git a/mips/Cargo.toml b/mips/Cargo.toml index c773b077..2b675098 100644 --- a/mips/Cargo.toml +++ b/mips/Cargo.toml @@ -6,9 +6,9 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -serde = "1.0.171" -serde_derive = "1.0.171" -typetag = "0.2.10" +serde = "1.0.175" +serde_derive = "1.0.175" +typetag = "0.2.12" serde_json = "1.0.103" fern = "0.6.2" log = "0.4.19" diff --git a/src/common.rs b/src/common.rs index 1baa6752..8fa420a2 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,164 +1,11 @@ -use num_enum::IntoPrimitive; use petgraph::Graph; use serde::{Deserialize, Serialize}; -use std::{ - ascii::escape_default, - collections::HashMap, - convert::{From, TryFrom}, - fmt, - rc::Rc, -}; +use std::{collections::HashMap, rc::Rc}; #[cfg(feature = "gui-vizia")] use vizia::prelude::*; -// pub type Signal = u32; -// pub type SignedSignal = i32; -pub type Id = String; - -pub type SignalUnsigned = u32; -pub type SignalSigned = i32; - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Copy, Clone)] -pub struct Signal { - data: SignalData, - fmt: SignalFmt, -} - -impl Signal { - /// set data field - pub fn set_data(&mut self, data: SignalData) { - self.data = data - } - /// set fmt field - pub fn set_fmt(&mut self, fmt: SignalFmt) { - self.fmt = fmt - } - /// get data field - pub fn get_data(&self) -> SignalData { - self.data - } - /// get fmt field - pub fn get_fmt(&self) -> SignalFmt { - self.fmt - } -} - -#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)] -pub enum SignalData { - Uninitialized, - Unknown, - DontCare, - Data(SignalUnsigned), // Maybe we should have something even more generic here -} - -impl TryFrom for SignalUnsigned { - type Error = String; - - fn try_from(signal: Signal) -> Result { - if let SignalData::Data(data) = signal.data { - Ok(data) - } else { - Err(format!( - "Could not convert {:?} into SignalUnsigned", - signal - )) - } - } -} - -impl TryFrom for SignalUnsigned { - type Error = String; - - fn try_from(data: SignalData) -> Result { - if let SignalData::Data(data) = data { - Ok(data) - } else { - Err(format!("Could not convert {:?} into SignalUnsigned", data)) - } - } -} - -impl From for Signal { - fn from(data: SignalData) -> Signal { - Signal { - data, - fmt: SignalFmt::Hex(SignalSize::_32), - } - } -} - -impl From for Signal { - fn from(data: u32) -> Signal { - Signal { - data: SignalData::Data(data), - fmt: SignalFmt::Hex(SignalSize::_32), - } - } -} - -impl From for Signal { - fn from(b: bool) -> Signal { - Signal { - data: SignalData::Data(b as SignalUnsigned), - fmt: SignalFmt::Hex(SignalSize::_32), - } - } -} - -impl From for SignalData { - fn from(data: u32) -> SignalData { - SignalData::Data(data) - } -} - -impl From for SignalData { - fn from(b: bool) -> SignalData { - SignalData::Data(b as SignalUnsigned) - } -} - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Copy, Clone)] -pub enum SignalFmt { - Ascii(SignalSize), - Unsigned(SignalSize), - Signed(SignalSize), - Hex(SignalSize), - Binary(u8), // just to set a limit to the number of bits - Bool, // treats it as true/false -} - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Copy, Clone, IntoPrimitive)] -#[repr(u8)] -pub enum SignalSize { - _8 = 1, - _16 = 2, - _32 = 4, -} - -impl fmt::Display for Signal { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.data { - SignalData::Data(value) => match self.fmt { - SignalFmt::Ascii(signal_size) => { - let s: u8 = signal_size.into(); - - let bytes = &value.to_be_bytes()[0..s as usize]; - // let x: Vec = bytes.iter().map(|b| escape_default(*b)).flatten().collect(); - // write!(f, "{:?}", self.bytes), - unimplemented!() - } - SignalFmt::Binary(u) => unimplemented!(), - SignalFmt::Unsigned(_) => todo!(), - SignalFmt::Signed(_) => todo!(), - SignalFmt::Hex(_) => todo!(), - SignalFmt::Bool => todo!(), - // _ => write!(f, "{:?}", self.data), - }, - _ => write!(f, "{:?}", self.data), - } - } -} +pub use crate::signal::*; #[cfg(not(any(feature = "gui-vizia", feature = "gui-egui")))] type Components = Vec>; diff --git a/src/gui_vizia/components/probe_assert.rs b/src/gui_vizia/components/probe_assert.rs index d55f076b..41c8c836 100644 --- a/src/gui_vizia/components/probe_assert.rs +++ b/src/gui_vizia/components/probe_assert.rs @@ -1,5 +1,5 @@ use crate::{ - common::{Component, SignalData, Simulator, ViziaComponent}, + common::{Component, Signal, SignalData, Simulator, ViziaComponent}, components::ProbeAssert, gui_vizia::{popup::NewPopup, tooltip::new_component_tooltip, GuiData}, }; @@ -22,22 +22,25 @@ impl ViziaComponent for ProbeAssert { crate::gui_vizia::GuiData::simulator.then(Simulator::cycle), move |cx, cycle| { let cycle = cycle.get(cx); - let rhs = if let Some(value) = values.get(cycle - 1) { + let assert = if let Some(value) = values.get(cycle - 1) { *value } else { (SignalData::Unknown).into() }; - Label::new(cx, { - let simulator = GuiData::simulator.get(cx); - &format!("{:?} == {:?}", simulator.get_input_val(&input), rhs) - }) - .hoverable(false); + let simulator = GuiData::simulator.get(cx); + let signal = simulator.get_input_signal(&input); + Label::new(cx, &format!("{} == {}", signal, assert)) + .hoverable(false) + .background_color(if signal == assert { + Color::lightgreen() + } else { + Color::lightcoral() + }); }, ); NewPopup::new(cx, self.get_id_ports()).position_type(PositionType::SelfDirected); }) .position_type(PositionType::SelfDirected) - .background_color(Color::lightcoral()) .left(Pixels(self.pos.0 - 10.0)) .top(Pixels(self.pos.1 - 10.0)) // .width(Pixels(20.0)) // TODO, maybe some max width diff --git a/src/lib.rs b/src/lib.rs index 3f05948a..1578e478 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ pub mod common; pub mod component_store; pub mod fern; +pub mod signal; pub mod simulator; // Default provided components diff --git a/src/signal.rs b/src/signal.rs new file mode 100644 index 00000000..57c2ec14 --- /dev/null +++ b/src/signal.rs @@ -0,0 +1,326 @@ +use num_enum::IntoPrimitive; + +use serde::{Deserialize, Serialize}; +use std::{ + convert::{From, TryFrom}, + fmt, +}; + +// pub type Signal = u32; +// pub type SignedSignal = i32; +pub type Id = String; + +pub type SignalUnsigned = u32; +pub type SignalSigned = i32; + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Copy, Clone)] +pub struct Signal { + data: SignalData, + fmt: SignalFmt, +} + +impl Signal { + /// set data field + pub fn set_data(&mut self, data: SignalData) { + self.data = data + } + /// set fmt field + pub fn set_fmt(&mut self, fmt: SignalFmt) { + self.fmt = fmt + } + /// get data field + pub fn get_data(&self) -> SignalData { + self.data + } + /// get fmt field + pub fn get_fmt(&self) -> SignalFmt { + self.fmt + } +} + +#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)] +pub enum SignalData { + Uninitialized, + Unknown, + DontCare, + Data(SignalUnsigned), // Maybe we should have something even more generic here +} + +impl TryFrom for SignalUnsigned { + type Error = String; + + fn try_from(signal: Signal) -> Result { + if let SignalData::Data(data) = signal.data { + Ok(data) + } else { + Err(format!( + "Could not convert {:?} into SignalUnsigned", + signal + )) + } + } +} + +impl TryFrom for SignalUnsigned { + type Error = String; + + fn try_from(data: SignalData) -> Result { + if let SignalData::Data(data) = data { + Ok(data) + } else { + Err(format!("Could not convert {:?} into SignalUnsigned", data)) + } + } +} + +impl From for Signal { + fn from(data: SignalData) -> Signal { + Signal { + data, + fmt: SignalFmt::Hex(SignalSize::_32), + } + } +} + +impl From for Signal { + fn from(data: u32) -> Signal { + Signal { + data: SignalData::Data(data), + fmt: SignalFmt::Hex(SignalSize::_32), + } + } +} + +impl From for Signal { + fn from(b: bool) -> Signal { + Signal { + data: SignalData::Data(b as SignalUnsigned), + fmt: SignalFmt::Hex(SignalSize::_32), + } + } +} + +impl From for SignalData { + fn from(data: u32) -> SignalData { + SignalData::Data(data) + } +} + +impl From for SignalData { + fn from(b: bool) -> SignalData { + SignalData::Data(b as SignalUnsigned) + } +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Copy, Clone)] +pub enum SignalFmt { + Ascii(SignalSize), + Unsigned(SignalSize), + Signed(SignalSize), + Hex(SignalSize), + Binary(u8), // just to set a limit to the number of bits + Bool, // treats it as true/false +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Copy, Clone, IntoPrimitive)] +#[repr(u8)] +pub enum SignalSize { + _8 = 1, + _16 = 2, + _32 = 4, +} + +impl fmt::Display for Signal { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.data { + SignalData::Data(value) => match self.fmt { + SignalFmt::Ascii(signal_size) => { + let s: u8 = signal_size.into(); + + let bytes = &value.to_ne_bytes()[0..s as usize]; + let s: String = bytes + .into_iter() + .map(|b| { + let c = *b as char; + if c.is_ascii_graphic() || c == ' ' as char { + c + } else { + '¤' as char + } + }) + .rev() + .collect(); + + write!(f, "{}", s) + } + SignalFmt::Binary(size) => { + write!(f, "0b{}", &format!("{:032b}", value)[32 - size as usize..]) + } + SignalFmt::Unsigned(size) => write!( + f, + "{}", + match size { + SignalSize::_8 => format!("{}", value as u8), + SignalSize::_16 => format!("{}", value as u16), + SignalSize::_32 => format!("{}", value as u32), + } + ), + SignalFmt::Signed(size) => write!( + f, + "{}", + match size { + SignalSize::_8 => format!("{}", value as i8), + SignalSize::_16 => format!("{}", value as i16), + SignalSize::_32 => format!("{}", value as i32), + } + ), + SignalFmt::Hex(size) => write!( + f, + "{}", + match size { + SignalSize::_8 => format!("{:#04x}", value as u8), + SignalSize::_16 => format!("{:#06x}", value as u16), + SignalSize::_32 => format!("{:#010x}", value as u32), + } + ), + SignalFmt::Bool => write!(f, "{}", !(value == 0)), + }, + _ => write!(f, "{:?}", self.data), + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_bool_fmt() { + let mut signal: Signal = false.into(); + + // test bool + signal.set_fmt(SignalFmt::Bool); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "false"); + + signal.set_data(true.into()); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "true"); + } + + #[test] + fn test_hex_fmt() { + let mut signal: Signal = 0x0234_0608.into(); + + // test hex + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "0x02340608"); + + signal.set_fmt(SignalFmt::Hex(SignalSize::_16)); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "0x0608"); + + signal.set_fmt(SignalFmt::Hex(SignalSize::_8)); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "0x08"); + } + + #[test] + fn test_unsigned_fmt() { + let mut signal: Signal = 0xF000_0000.into(); + + // test unsigned + signal.set_fmt(SignalFmt::Unsigned(SignalSize::_32)); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "4026531840"); + + signal.set_fmt(SignalFmt::Unsigned(SignalSize::_16)); + signal.set_data(0xF000_E000.into()); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "57344"); + + signal.set_fmt(SignalFmt::Unsigned(SignalSize::_8)); + signal.set_data(0xF000_E0D0.into()); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "208"); + } + + #[test] + fn test_signed_fmt() { + let mut signal: Signal = 0xF000_0000.into(); + + // test signed + signal.set_fmt(SignalFmt::Signed(SignalSize::_32)); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "-268435456"); + + signal.set_fmt(SignalFmt::Signed(SignalSize::_16)); + signal.set_data(0xF000_E000.into()); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "-8192"); + + signal.set_fmt(SignalFmt::Signed(SignalSize::_8)); + signal.set_data(0xF000_E0D0.into()); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "-48"); + } + + #[test] + fn test_binary_fmt() { + let mut signal: Signal = 0b0000_0000_0000_0001_0001_0000_0000_0010.into(); + + // test binary + signal.set_fmt(SignalFmt::Binary(32)); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "0b00000000000000010001000000000010"); + + signal.set_fmt(SignalFmt::Binary(31)); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "0b0000000000000010001000000000010"); + + signal.set_fmt(SignalFmt::Binary(2)); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "0b10"); + + signal.set_fmt(SignalFmt::Binary(1)); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "0b0"); + } + + #[test] + fn test_ascii_fmt() { + let text = 0x4142_4300; + let mut signal: Signal = text.into(); + + // test ascii + signal.set_fmt(SignalFmt::Ascii(SignalSize::_32)); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(s, "ABC¤"); + + signal.set_fmt(SignalFmt::Ascii(SignalSize::_16)); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(s, "C¤"); + + signal.set_fmt(SignalFmt::Ascii(SignalSize::_8)); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(s, "¤"); + } +} diff --git a/src/simulator.rs b/src/simulator.rs index baebb1f4..c58ebfb4 100644 --- a/src/simulator.rs +++ b/src/simulator.rs @@ -145,8 +145,8 @@ impl Simulator { self.sim_state[index] } - /// get input value - pub fn get_input_val(&self, input: &Input) -> SignalData { + /// get input signal + pub fn get_input_signal(&self, input: &Input) -> Signal { let nr_out = *self.id_nr_outputs.get(&input.id).unwrap(); let index = *self .id_field_index @@ -159,7 +159,7 @@ impl Simulator { }); if index < nr_out { let start_index = *self.id_start_index.get(&input.id).unwrap(); - self.get(start_index + index).get_data() + self.get(start_index + index) } else { panic!( "ICE: Attempt to read {:?} at index {}, where {:?} has only {} outputs.", @@ -168,6 +168,11 @@ impl Simulator { } } + /// get input value + pub fn get_input_val(&self, input: &Input) -> SignalData { + self.get_input_signal(input).get_data() + } + /// get start index by id pub(crate) fn get_id_start_index(&self, id: &str) -> usize { *self.id_start_index.get(id).unwrap() From 9a24639e38d1a4925787375c1155c685e6b3b07e Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Wed, 26 Jul 2023 07:29:05 +0200 Subject: [PATCH 03/14] Probe/Constant --- src/gui_vizia/components/constant.rs | 28 +++++------------------- src/gui_vizia/components/probe.rs | 5 +++-- src/gui_vizia/components/probe_assert.rs | 17 +++++++------- src/gui_vizia/components/probe_stim.rs | 2 +- 4 files changed, 18 insertions(+), 34 deletions(-) diff --git a/src/gui_vizia/components/constant.rs b/src/gui_vizia/components/constant.rs index 3b059612..bca69d3d 100644 --- a/src/gui_vizia/components/constant.rs +++ b/src/gui_vizia/components/constant.rs @@ -4,10 +4,7 @@ use crate::{ gui_vizia::{popup::NewPopup, tooltip::new_component_tooltip}, }; -use vizia::{ - prelude::*, - vg::{Paint, Path}, -}; +use vizia::prelude::*; use log::*; @@ -17,14 +14,16 @@ impl ViziaComponent for Constant { fn view(&self, cx: &mut Context) { trace!("---- Create Constant View"); View::build(ConstantView {}, cx, |cx| { - Label::new(cx, &format!("{:?}", self.value)).hoverable(false); + Label::new(cx, &format!("{}", self.value)).hoverable(false); NewPopup::new(cx, self.get_id_ports()).position_type(PositionType::SelfDirected); }) .position_type(PositionType::SelfDirected) .left(Pixels(self.pos.0 - 10.0)) .top(Pixels(self.pos.1 - 10.0)) - .width(Pixels(20.0)) + //.width(Pixels(20.0)) // TODO, max width? + .width(Auto) .height(Pixels(20.0)) + .background_color(Color::lightblue()) // TODO: do we want/need tooltip/popup for constants .on_press(|ex| ex.emit(PopupEvent::Switch)) .tooltip(|cx| new_component_tooltip(cx, self)); @@ -36,21 +35,4 @@ impl View for ConstantView { fn element(&self) -> Option<&'static str> { Some("Constant") } - - fn draw(&self, cx: &mut DrawContext<'_>, canvas: &mut Canvas) { - let bounds = cx.bounds(); - // trace!("Constant draw {:?}", bounds); - - let mut path = Path::new(); - let mut paint = Paint::color(vizia::vg::Color::rgbf(0.0, 1.0, 0.0)); - paint.set_line_width(cx.logical_to_physical(1.0)); - - path.move_to(bounds.left() + 0.5, bounds.top() + 0.5); - path.line_to(bounds.right() + 0.5, bounds.top() + 0.5); - path.line_to(bounds.right() + 0.5, bounds.bottom() + 0.5); - path.line_to(bounds.left() + 0.5, bounds.bottom() + 0.5); - path.line_to(bounds.left() + 0.5, bounds.top() + 0.5); - - canvas.fill_path(&path, &paint); - } } diff --git a/src/gui_vizia/components/probe.rs b/src/gui_vizia/components/probe.rs index 04d854cc..9d9d5ff2 100644 --- a/src/gui_vizia/components/probe.rs +++ b/src/gui_vizia/components/probe.rs @@ -25,7 +25,7 @@ impl ViziaComponent for Probe { move |cx, _| { Label::new(cx, { let simulator = GuiData::simulator.get(cx); - &format!(" {:?}", simulator.get_input_val(&input)) + &format!("{}", simulator.get_input_signal(&input)) }) .hoverable(false); }, @@ -35,7 +35,8 @@ impl ViziaComponent for Probe { .position_type(PositionType::SelfDirected) .left(Pixels(self.pos.0 - 10.0)) .top(Pixels(self.pos.1 - 10.0)) - .width(Pixels(20.0)) + // .width(Pixels(20.0)) // TODO, max width? + .width(Auto) .height(Pixels(20.0)) .on_press(|ex| ex.emit(PopupEvent::Switch)) .tooltip(|cx| new_component_tooltip(cx, self)); diff --git a/src/gui_vizia/components/probe_assert.rs b/src/gui_vizia/components/probe_assert.rs index 41c8c836..322152ba 100644 --- a/src/gui_vizia/components/probe_assert.rs +++ b/src/gui_vizia/components/probe_assert.rs @@ -1,5 +1,5 @@ use crate::{ - common::{Component, Signal, SignalData, Simulator, ViziaComponent}, + common::{Component, SignalData, Simulator, ViziaComponent}, components::ProbeAssert, gui_vizia::{popup::NewPopup, tooltip::new_component_tooltip, GuiData}, }; @@ -29,13 +29,14 @@ impl ViziaComponent for ProbeAssert { }; let simulator = GuiData::simulator.get(cx); let signal = simulator.get_input_signal(&input); - Label::new(cx, &format!("{} == {}", signal, assert)) - .hoverable(false) - .background_color(if signal == assert { - Color::lightgreen() - } else { - Color::lightcoral() - }); + if signal == assert { + Label::new(cx, &format!("{} == {}", signal, assert)) + .background_color(Color::lightgreen()) + } else { + Label::new(cx, &format!("{} != {}", signal, assert)) + .background_color(Color::lightcoral()) + } + .hoverable(false); }, ); NewPopup::new(cx, self.get_id_ports()).position_type(PositionType::SelfDirected); diff --git a/src/gui_vizia/components/probe_stim.rs b/src/gui_vizia/components/probe_stim.rs index c4f63e75..ab566a16 100644 --- a/src/gui_vizia/components/probe_stim.rs +++ b/src/gui_vizia/components/probe_stim.rs @@ -25,7 +25,7 @@ impl ViziaComponent for ProbeStim { } else { (SignalData::Unknown).into() }; - Label::new(cx, &format!("{:?}", rhs)).hoverable(false); + Label::new(cx, &format!("{}", rhs)).hoverable(false); }, ); NewPopup::new(cx, self.get_id_ports()).position_type(PositionType::SelfDirected); From fdbe1749a7ccb4ac092808efbd1a7b5794c53c09 Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Wed, 26 Jul 2023 07:37:26 +0200 Subject: [PATCH 04/14] Hex Padding --- src/signal.rs | 51 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/src/signal.rs b/src/signal.rs index 57c2ec14..88fa0040 100644 --- a/src/signal.rs +++ b/src/signal.rs @@ -77,7 +77,7 @@ impl From for Signal { fn from(data: SignalData) -> Signal { Signal { data, - fmt: SignalFmt::Hex(SignalSize::_32), + fmt: SignalFmt::Hex(SignalSize::_32, false), } } } @@ -86,7 +86,7 @@ impl From for Signal { fn from(data: u32) -> Signal { Signal { data: SignalData::Data(data), - fmt: SignalFmt::Hex(SignalSize::_32), + fmt: SignalFmt::Hex(SignalSize::_32, false), } } } @@ -95,7 +95,7 @@ impl From for Signal { fn from(b: bool) -> Signal { Signal { data: SignalData::Data(b as SignalUnsigned), - fmt: SignalFmt::Hex(SignalSize::_32), + fmt: SignalFmt::Hex(SignalSize::_32, false), } } } @@ -117,9 +117,9 @@ pub enum SignalFmt { Ascii(SignalSize), Unsigned(SignalSize), Signed(SignalSize), - Hex(SignalSize), - Binary(u8), // just to set a limit to the number of bits - Bool, // treats it as true/false + Hex(SignalSize, bool), // bool == true for padding + Binary(u8), // just to set a limit to the number of bits + Bool, // treats it as true/false } #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Copy, Clone, IntoPrimitive)] @@ -174,7 +174,7 @@ impl fmt::Display for Signal { SignalSize::_32 => format!("{}", value as i32), } ), - SignalFmt::Hex(size) => write!( + SignalFmt::Hex(size, true) => write!( f, "{}", match size { @@ -183,6 +183,15 @@ impl fmt::Display for Signal { SignalSize::_32 => format!("{:#010x}", value as u32), } ), + SignalFmt::Hex(size, false) => write!( + f, + "{}", + match size { + SignalSize::_8 => format!("{:#x}", value as u8), + SignalSize::_16 => format!("{:#x}", value as u16), + SignalSize::_32 => format!("{:#x}", value as u32), + } + ), SignalFmt::Bool => write!(f, "{}", !(value == 0)), }, _ => write!(f, "{:?}", self.data), @@ -211,25 +220,47 @@ mod test { } #[test] - fn test_hex_fmt() { + fn test_hex_pad_fmt() { let mut signal: Signal = 0x0234_0608.into(); // test hex + signal.set_fmt(SignalFmt::Hex(SignalSize::_32, true)); let s = format!("{}", signal); println!("{}", s); assert_eq!(&s, "0x02340608"); - signal.set_fmt(SignalFmt::Hex(SignalSize::_16)); + signal.set_fmt(SignalFmt::Hex(SignalSize::_16, true)); let s = format!("{}", signal); println!("{}", s); assert_eq!(&s, "0x0608"); - signal.set_fmt(SignalFmt::Hex(SignalSize::_8)); + signal.set_fmt(SignalFmt::Hex(SignalSize::_8, true)); let s = format!("{}", signal); println!("{}", s); assert_eq!(&s, "0x08"); } + #[test] + fn test_hex_fmt() { + let mut signal: Signal = 0x0234_0608.into(); + + // test hex + signal.set_fmt(SignalFmt::Hex(SignalSize::_32, false)); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "0x2340608"); + + signal.set_fmt(SignalFmt::Hex(SignalSize::_16, false)); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "0x608"); + + signal.set_fmt(SignalFmt::Hex(SignalSize::_8, false)); + let s = format!("{}", signal); + println!("{}", s); + assert_eq!(&s, "0x8"); + } + #[test] fn test_unsigned_fmt() { let mut signal: Signal = 0xF000_0000.into(); From cecaee50806b5c3c8107d7a7096a30880e41b798 Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Wed, 26 Jul 2023 09:55:37 +0200 Subject: [PATCH 05/14] examples --- examples/add_reg.rs | 9 +++-- mips/examples/reg_file.rs | 67 +++++++++++++++++++++++++++++++++++--- src/components/constant.rs | 12 ++++--- src/components/probe.rs | 6 ++-- src/components/wire.rs | 15 +++++++++ src/signal.rs | 11 ++++++- 6 files changed, 105 insertions(+), 15 deletions(-) diff --git a/examples/add_reg.rs b/examples/add_reg.rs index 94eea5bd..b50bebfb 100644 --- a/examples/add_reg.rs +++ b/examples/add_reg.rs @@ -1,12 +1,13 @@ use std::{path::PathBuf, rc::Rc}; use syncrim::{ - common::{ComponentStore, Input}, + common::{ComponentStore, Input, Signal, SignalFmt, SignalSize}, components::*, fern::fern_setup, }; fn main() { fern_setup(); + let cs = ComponentStore { store: vec![ Rc::new(Add { @@ -15,7 +16,11 @@ fn main() { a_in: Input::new("c", "out"), b_in: Input::new("reg", "out"), }), - Constant::rc_new("c", (100.0, 100.0), 3), + Constant::rc_new( + "c", + (100.0, 100.0), + (3, SignalFmt::Unsigned(SignalSize::_32)), + ), Rc::new(Register { id: "reg".to_string(), pos: (100.0, 140.0), diff --git a/mips/examples/reg_file.rs b/mips/examples/reg_file.rs index 3da9690b..cd00ccff 100644 --- a/mips/examples/reg_file.rs +++ b/mips/examples/reg_file.rs @@ -1,7 +1,7 @@ use mips::components::*; use std::{path::PathBuf, rc::Rc}; use syncrim::{ - common::{ComponentStore, Input}, + common::{ComponentStore, Input, SignalFmt, SignalSize}, components::*, fern::fern_setup, }; @@ -11,11 +11,31 @@ fn main() { fern_setup(); let cs = ComponentStore { store: vec![ - Constant::rc_new("c_read_reg_1", (100.0, 100.0), 3), - Constant::rc_new("c_read_reg_2", (100.0, 200.0), 4), - Constant::rc_new("c_write_data", (100.0, 140.0), 42), - Constant::rc_new("c_write_addr", (100.0, 160.0), 4), + Constant::rc_new( + "c_read_reg_1", + (100.0, 100.0), + // Format as binary + (3, SignalFmt::Binary(5)), + ), + Constant::rc_new( + "c_write_addr", + (100.0, 160.0), + // Format as hex with padding + (4, SignalFmt::Binary(5)), + ), Constant::rc_new("c_write_enable", (100.0, 180.0), true), + Constant::rc_new( + "c_write_data", + (100.0, 220.0), + // Format as hex with padding + (42, SignalFmt::Hex(SignalSize::_32, true)), + ), + Constant::rc_new( + "c_read_reg_2", + (100.0, 300.0), + // Format as binary + (4, SignalFmt::Binary(5)), + ), // regfile Rc::new(RegFile { id: "reg_file".to_string(), @@ -34,6 +54,43 @@ fn main() { registers: RegStore::new(), history: RegHistory::new(), }), + Probe::rc_new("p_reg_a", (500.0, 100.0), Input::new("reg_file", "reg_a")), + Probe::rc_new("p_reg_b", (500.0, 300.0), Input::new("reg_file", "reg_b")), + Wire::rc_new( + "w_read_reg_1", + vec![(180.0, 100.0), (200.0, 100.0)], + Input::new("c_read_reg_1", "out"), + ), + Wire::rc_new( + "w_read_reg_2", + vec![(180.0, 300.0), (200.0, 300.0)], + Input::new("c_read_reg_2", "out"), + ), + Wire::rc_new( + "w_write_addr", + vec![(180.0, 160.0), (200.0, 160.0)], + Input::new("c_write_addr", "out"), + ), + Wire::rc_new( + "w_write_enable", + vec![(180.0, 180.0), (200.0, 180.0)], + Input::new("c_write_enable", "out"), + ), + Wire::rc_new( + "w_write_data", + vec![(180.0, 220.0), (200.0, 220.0)], + Input::new("c_write_data", "out"), + ), + Wire::rc_new( + "w_reg_a", + vec![(400.0, 100.0), (490.0, 100.0)], + Input::new("reg_file", "reg_a"), + ), + Wire::rc_new( + "w_reg_b", + vec![(400.0, 300.0), (490.0, 300.0)], + Input::new("reg_file", "reg_b"), + ), ], }; diff --git a/src/components/constant.rs b/src/components/constant.rs index 5f43e1b3..0b465a2f 100644 --- a/src/components/constant.rs +++ b/src/components/constant.rs @@ -1,7 +1,7 @@ use crate::common::{Component, Id, OutputType, Ports, Signal, Simulator}; use log::*; use serde::{Deserialize, Serialize}; -use std::rc::Rc; +use std::{convert::Into, rc::Rc}; #[derive(Serialize, Deserialize)] pub struct Constant { pub id: Id, @@ -33,15 +33,19 @@ impl Component for Constant { } impl Constant { - pub fn new(id: &str, pos: (f32, f32), value: impl Into) -> Self { + pub fn new(id: &str, pos: (impl Into, impl Into), value: impl Into) -> Self { Constant { id: id.to_string(), - pos, + pos: (pos.0.into(), pos.1.into()), value: value.into(), } } - pub fn rc_new(id: &str, pos: (f32, f32), value: impl Into) -> Rc { + pub fn rc_new( + id: &str, + pos: (impl Into, impl Into), + value: impl Into, + ) -> Rc { Rc::new(Constant::new(id, pos, value)) } } diff --git a/src/components/probe.rs b/src/components/probe.rs index ac3bf45d..d8d92eda 100644 --- a/src/components/probe.rs +++ b/src/components/probe.rs @@ -1,7 +1,7 @@ use crate::common::{Component, Id, Input, OutputType, Ports}; use log::*; use serde::{Deserialize, Serialize}; -use std::rc::Rc; +use std::{convert::Into, rc::Rc}; #[derive(Serialize, Deserialize)] pub struct Probe { pub id: Id, @@ -30,10 +30,10 @@ impl Component for Probe { } impl Probe { - pub fn new(id: &str, pos: (f32, f32), input: Input) -> Self { + pub fn new(id: &str, pos: (impl Into, impl Into), input: Input) -> Self { Probe { id: id.to_string(), - pos, + pos: (pos.0.into(), pos.1.into()), input, } } diff --git a/src/components/wire.rs b/src/components/wire.rs index 3904b787..7165b072 100644 --- a/src/components/wire.rs +++ b/src/components/wire.rs @@ -1,6 +1,7 @@ use crate::common::{Component, Id, Input, OutputType, Ports}; use log::*; use serde::{Deserialize, Serialize}; +use std::{convert::Into, rc::Rc}; #[derive(Serialize, Deserialize)] pub struct Wire { pub id: Id, @@ -27,3 +28,17 @@ impl Component for Wire { ) } } + +impl Wire { + pub fn new(id: &str, pos: Vec<(impl Into, impl Into)>, input: Input) -> Self { + Wire { + id: id.to_string(), + pos: pos.into_iter().map(|p| (p.0.into(), p.1.into())).collect(), + input, + } + } + + pub fn rc_new(id: &str, pos: Vec<(impl Into, impl Into)>, input: Input) -> Rc { + Rc::new(Wire::new(id, pos, input)) + } +} diff --git a/src/signal.rs b/src/signal.rs index 88fa0040..2025dbb3 100644 --- a/src/signal.rs +++ b/src/signal.rs @@ -82,6 +82,15 @@ impl From for Signal { } } +impl From<(SignalUnsigned, SignalFmt)> for Signal { + fn from((data, fmt): (SignalUnsigned, SignalFmt)) -> Signal { + Signal { + data: data.into(), + fmt, + } + } +} + impl From for Signal { fn from(data: u32) -> Signal { Signal { @@ -95,7 +104,7 @@ impl From for Signal { fn from(b: bool) -> Signal { Signal { data: SignalData::Data(b as SignalUnsigned), - fmt: SignalFmt::Hex(SignalSize::_32, false), + fmt: SignalFmt::Bool, } } } From 89dedaad04ef89a8d9f82065c56ff133479e3c8f Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Wed, 26 Jul 2023 10:41:28 +0200 Subject: [PATCH 06/14] wip --- examples/add_reg.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/add_reg.rs b/examples/add_reg.rs index b50bebfb..ee33ea71 100644 --- a/examples/add_reg.rs +++ b/examples/add_reg.rs @@ -66,11 +66,7 @@ fn main() { pos: (280.0, 120.0), input: Input::new("add", "out"), }), - Rc::new(Probe { - id: "p_reg".to_string(), - pos: (130.0, 120.0), - input: Input::new("reg", "out"), - }), + Probe::rc_new("p_reg", (130.0, 120.0), Input::new("reg", "out")), ], }; From 38e91d696bb0df05a95fa52d2e1e4ef3c8fec134 Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Wed, 26 Jul 2023 10:41:50 +0200 Subject: [PATCH 07/14] Wip --- src/components/probe.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/probe.rs b/src/components/probe.rs index d8d92eda..0d677cd1 100644 --- a/src/components/probe.rs +++ b/src/components/probe.rs @@ -38,7 +38,7 @@ impl Probe { } } - pub fn rc_new(id: &str, pos: (f32, f32), input: Input) -> Rc { + pub fn rc_new(id: &str, pos: (impl Into, impl Into), input: Input) -> Rc { Rc::new(Probe::new(id, pos, input)) } } From b456597c04f1299f8542704168b820471fcc958b Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Thu, 27 Jul 2023 00:13:19 +0200 Subject: [PATCH 08/14] rc_new --- Cargo.toml | 20 ++-- examples/add.rs | 51 +++++----- examples/add_edit.rs | 55 +++++----- examples/add_mux.rs | 160 ++++++++++++++---------------- examples/add_reg.rs | 98 +++++++++--------- examples/add_reg_compound_wire.rs | 62 +++++------- examples/data_mem.rs | 102 +++++++------------ examples/mux.rs | 94 ------------------ examples/mux_edit.rs | 70 +++++++++++++ examples/probe_edit.rs | 10 +- examples/reg.rs | 44 -------- examples/sext.rs | 36 +++---- mips/examples/mips.rs | 126 +++++++++-------------- mips/examples/reg_file.rs | 30 +++--- mips/src/components/instr_mem.rs | 18 +++- mips/src/components/reg_file.rs | 74 ++++++++++++-- src/components/add.rs | 16 +++ src/components/constant.rs | 10 +- src/components/mux.rs | 31 +++++- src/components/probe.rs | 8 +- src/components/register.rs | 16 +++ src/components/sext.rs | 25 ++++- src/components/wire.rs | 8 +- src/signal.rs | 14 +-- 24 files changed, 570 insertions(+), 608 deletions(-) delete mode 100644 examples/mux.rs create mode 100644 examples/mux_edit.rs delete mode 100644 examples/reg.rs diff --git a/Cargo.toml b/Cargo.toml index ae61c421..6eded9e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,33 +60,41 @@ name = "component_tests" required-features = ["components"] [[example]] -name = "add" +name = "add_edit" required-features = ["components"] [[example]] name = "add_mux" required-features = ["components"] +[[example]] +name = "add_reg_compound_wire" +required-features = ["components"] + [[example]] name = "add_reg" required-features = ["components"] [[example]] -name = "mux" +name = "add" +required-features = ["components"] + +[[example]] +name = "data_mem" required-features = ["components"] [[example]] -name = "reg" +name = "mux_edit" required-features = ["components"] [[example]] -name = "sext" +name = "probe_edit" required-features = ["components"] [[example]] -name = "data_mem" +name = "probe_stim_assert" required-features = ["components"] [[example]] -name = "add_reg_compound_wire" +name = "sext" required-features = ["components"] diff --git a/examples/add.rs b/examples/add.rs index 9edf511f..45d5b0d9 100644 --- a/examples/add.rs +++ b/examples/add.rs @@ -1,4 +1,4 @@ -use std::{path::PathBuf, rc::Rc}; +use std::path::PathBuf; use syncrim::{ common::{ComponentStore, Input}, components::*, @@ -9,35 +9,30 @@ fn main() { fern_setup(); let cs = ComponentStore { store: vec![ - Rc::new(Add { - id: "add".to_string(), - pos: (200.0, 120.0), - a_in: Input::new("c1", "out"), - - b_in: Input::new("c2", "out"), - }), + Add::rc_new( + "add", + (200.0, 120.0), + Input::new("c1", "out"), + Input::new("c2", "out"), + ), Constant::rc_new("c1", (60.0, 100.0), 3), Constant::rc_new("c2", (60.0, 140.0), 4), - Rc::new(Wire { - id: "w1".to_string(), - pos: vec![(110.0, 100.0), (180.0, 100.0)], - input: Input::new("c1", "out"), - }), - Rc::new(Wire { - id: "w2".to_string(), - pos: vec![(110.0, 140.0), (180.0, 140.0)], - input: Input::new("c2", "out"), - }), - Rc::new(Wire { - id: "w3".to_string(), - pos: vec![(220.0, 120.0), (260.0, 120.0)], - input: Input::new("add", "out"), - }), - Rc::new(Probe { - id: "p1".to_string(), - pos: (270.0, 120.0), - input: Input::new("add", "out"), - }), + Wire::rc_new( + "w1", + vec![(110.0, 100.0), (180.0, 100.0)], + Input::new("c1", "out"), + ), + Wire::rc_new( + "w2", + vec![(110.0, 140.0), (180.0, 140.0)], + Input::new("c2", "out"), + ), + Wire::rc_new( + "w3", + vec![(220.0, 120.0), (260.0, 120.0)], + Input::new("add", "out"), + ), + Probe::rc_new("p1", (270.0, 120.0), Input::new("add", "out")), ], }; diff --git a/examples/add_edit.rs b/examples/add_edit.rs index 11761cb6..ebb16edd 100644 --- a/examples/add_edit.rs +++ b/examples/add_edit.rs @@ -1,4 +1,4 @@ -use std::{path::PathBuf, rc::Rc}; +use std::path::PathBuf; use syncrim::{ common::{ComponentStore, Input}, components::*, @@ -9,35 +9,30 @@ fn main() { fern_setup(); let cs = ComponentStore { store: vec![ - Rc::new(Add { - id: "add".to_string(), - pos: (200.0, 120.0), - a_in: Input::new("c1", "out"), - - b_in: Input::new("c2", "out"), - }), - Rc::new(ProbeEdit::new("c1", (60.0, 100.0))), - Rc::new(ProbeEdit::new("c2", (60.0, 140.0))), - Rc::new(Wire { - id: "w1".to_string(), - pos: vec![(110.0, 100.0), (180.0, 100.0)], - input: Input::new("c1", "out"), - }), - Rc::new(Wire { - id: "w2".to_string(), - pos: vec![(110.0, 140.0), (180.0, 140.0)], - input: Input::new("c2", "out"), - }), - Rc::new(Wire { - id: "w3".to_string(), - pos: vec![(220.0, 120.0), (260.0, 120.0)], - input: Input::new("add", "out"), - }), - Rc::new(Probe { - id: "p1".to_string(), - pos: (270.0, 120.0), - input: Input::new("add", "out"), - }), + Add::rc_new( + "add", + (200.0, 120.0), + Input::new("c1", "out"), + Input::new("c2", "out"), + ), + ProbeEdit::rc_new("c1", (60.0, 100.0)), + ProbeEdit::rc_new("c2", (60.0, 140.0)), + Wire::rc_new( + "w1", + vec![(110.0, 100.0), (180.0, 100.0)], + Input::new("c1", "out"), + ), + Wire::rc_new( + "w2", + vec![(110.0, 140.0), (180.0, 140.0)], + Input::new("c2", "out"), + ), + Wire::rc_new( + "w3", + vec![(220.0, 120.0), (260.0, 120.0)], + Input::new("add", "out"), + ), + Probe::rc_new("p1", (270.0, 120.0), Input::new("add", "out")), ], }; diff --git a/examples/add_mux.rs b/examples/add_mux.rs index 0609d719..ba8f82f8 100644 --- a/examples/add_mux.rs +++ b/examples/add_mux.rs @@ -9,63 +9,55 @@ fn main() { fern_setup(); let cs = ComponentStore { store: vec![ - Rc::new(Add { - id: "add".to_string(), - pos: (200.0, 120.0), - a_in: Input::new("c", "out"), - b_in: Input::new("r1", "out"), - }), + Add::rc_new( + "add", + (200.0, 120.0), + Input::new("c", "out"), + Input::new("r1", "out"), + ), Constant::rc_new("c", (100.0, 100.0), 1), Rc::new(Register { id: "r1".to_string(), pos: (100.0, 140.0), r_in: Input::new("add", "out"), }), - Rc::new(Wire { - id: "w1".to_string(), - pos: vec![(110.0, 100.0), (180.0, 100.0)], - input: Input::new("c", "out"), - }), - Rc::new(Wire { - id: "w2".to_string(), - pos: vec![(110.0, 140.0), (180.0, 140.0)], - input: Input::new("r1", "out"), - }), - Rc::new(Wire { - id: "w3".to_string(), - pos: vec![(220.0, 120.0), (260.0, 120.0)], - input: Input::new("add", "out"), - }), - Rc::new(Wire { - id: "w4".to_string(), - pos: vec![(260.0, 120.0), (260.0, 180.0)], - input: Input::new("add", "out"), - }), - Rc::new(Wire { - id: "w5".to_string(), - pos: vec![(60.0, 180.0), (260.0, 180.0)], - input: Input::new("add", "out"), - }), - Rc::new(Wire { - id: "w6".to_string(), - pos: vec![(60.0, 140.0), (60.0, 180.0)], - input: Input::new("add", "out"), - }), - Rc::new(Wire { - id: "w7".to_string(), - pos: vec![(60.0, 140.0), (90.0, 140.0)], - input: Input::new("add", "out"), - }), - Rc::new(Probe { - id: "p_add".to_string(), - pos: (280.0, 120.0), - input: Input::new("add", "out"), - }), - Rc::new(Probe { - id: "p_reg".to_string(), - pos: (130.0, 120.0), - input: Input::new("r1", "out"), - }), + Wire::rc_new( + "w1", + vec![(110.0, 100.0), (180.0, 100.0)], + Input::new("c", "out"), + ), + Wire::rc_new( + "w2", + vec![(110.0, 140.0), (180.0, 140.0)], + Input::new("r1", "out"), + ), + Wire::rc_new( + "w3", + vec![(220.0, 120.0), (260.0, 120.0)], + Input::new("add", "out"), + ), + Wire::rc_new( + "w4", + vec![(260.0, 120.0), (260.0, 180.0)], + Input::new("add", "out"), + ), + Wire::rc_new( + "w5", + vec![(60.0, 180.0), (260.0, 180.0)], + Input::new("add", "out"), + ), + Wire::rc_new( + "w6", + vec![(60.0, 140.0), (60.0, 180.0)], + Input::new("add", "out"), + ), + Wire::rc_new( + "w7", + vec![(60.0, 140.0), (90.0, 140.0)], + Input::new("add", "out"), + ), + Probe::rc_new("p_add", (280.0, 120.0), Input::new("add", "out")), + Probe::rc_new("p_reg", (130.0, 120.0), Input::new("r1", "out")), Rc::new(Mux { id: "mux".to_string(), pos: (270.0, 300.0), @@ -81,41 +73,37 @@ fn main() { Constant::rc_new("mc2", (150.0, 290.0), 1), Constant::rc_new("mc3", (150.0, 310.0), 2), Constant::rc_new("mc4", (150.0, 330.0), 3), - Rc::new(Wire { - id: "wm_sel".to_string(), - pos: vec![(260.0, 180.0), (260.0, 250.0)], - input: Input::new("add", "out"), - }), - Rc::new(Wire { - id: "wm1".to_string(), - pos: vec![(200.0, 270.0), (250.0, 270.0)], - input: Input::new("mc1", "out"), - }), - Rc::new(Wire { - id: "wm2".to_string(), - pos: vec![(200.0, 290.0), (250.0, 290.0)], - input: Input::new("mc2", "out"), - }), - Rc::new(Wire { - id: "wm3".to_string(), - pos: vec![(200.0, 310.0), (250.0, 310.0)], - input: Input::new("mc3", "out"), - }), - Rc::new(Wire { - id: "wm4".to_string(), - pos: vec![(200.0, 330.0), (250.0, 330.0)], - input: Input::new("mc4", "out"), - }), - Rc::new(Wire { - id: "wm_o0".to_string(), - pos: vec![(290.0, 300.0), (340.0, 300.0)], - input: Input::new("mux", "out"), - }), - Rc::new(Probe { - id: "p_mux".to_string(), - pos: (350.0, 300.0), - input: Input::new("mux", "out"), - }), + Wire::rc_new( + "wm_sel", + vec![(260.0, 180.0), (260.0, 250.0)], + Input::new("add", "out"), + ), + Wire::rc_new( + "wm1", + vec![(200.0, 270.0), (250.0, 270.0)], + Input::new("mc1", "out"), + ), + Wire::rc_new( + "wm2", + vec![(200.0, 290.0), (250.0, 290.0)], + Input::new("mc2", "out"), + ), + Wire::rc_new( + "wm3", + vec![(200.0, 310.0), (250.0, 310.0)], + Input::new("mc3", "out"), + ), + Wire::rc_new( + "wm4", + vec![(200.0, 330.0), (250.0, 330.0)], + Input::new("mc4", "out"), + ), + Wire::rc_new( + "wm_o0", + vec![(290.0, 300.0), (340.0, 300.0)], + Input::new("mux", "out"), + ), + Probe::rc_new("p_mux", (350.0, 300.0), Input::new("mux", "out")), ], }; diff --git a/examples/add_reg.rs b/examples/add_reg.rs index ee33ea71..bdbe2a7a 100644 --- a/examples/add_reg.rs +++ b/examples/add_reg.rs @@ -1,6 +1,6 @@ -use std::{path::PathBuf, rc::Rc}; +use std::path::PathBuf; use syncrim::{ - common::{ComponentStore, Input, Signal, SignalFmt, SignalSize}, + common::{ComponentStore, Input, SignalFmt, SignalSize}, components::*, fern::fern_setup, }; @@ -10,62 +10,54 @@ fn main() { let cs = ComponentStore { store: vec![ - Rc::new(Add { - id: "add".to_string(), - pos: (200.0, 120.0), - a_in: Input::new("c", "out"), - b_in: Input::new("reg", "out"), - }), + Add::rc_new( + "add", + (200., 120.0), + Input::new("c", "out"), + Input::new("reg", "out"), + ), Constant::rc_new( "c", (100.0, 100.0), (3, SignalFmt::Unsigned(SignalSize::_32)), ), - Rc::new(Register { - id: "reg".to_string(), - pos: (100.0, 140.0), - r_in: Input::new("add", "out"), - }), - Rc::new(Wire { - id: "w1".to_string(), - pos: vec![(110.0, 100.0), (180.0, 100.0)], - input: Input::new("c", "out"), - }), - Rc::new(Wire { - id: "w2".to_string(), - pos: vec![(110.0, 140.0), (180.0, 140.0)], - input: Input::new("reg", "out"), - }), - Rc::new(Wire { - id: "w3".to_string(), - pos: vec![(220.0, 120.0), (260.0, 120.0)], - input: Input::new("add", "out"), - }), - Rc::new(Wire { - id: "w4".to_string(), - pos: vec![(260.0, 120.0), (260.0, 180.0)], - input: Input::new("add", "out"), - }), - Rc::new(Wire { - id: "w5".to_string(), - pos: vec![(60.0, 180.0), (260.0, 180.0)], - input: Input::new("add", "out"), - }), - Rc::new(Wire { - id: "w6".to_string(), - pos: vec![(60.0, 140.0), (60.0, 180.0)], - input: Input::new("add", "out"), - }), - Rc::new(Wire { - id: "w7".to_string(), - pos: vec![(60.0, 140.0), (90.0, 140.0)], - input: Input::new("add", "out"), - }), - Rc::new(Probe { - id: "p_add".to_string(), - pos: (280.0, 120.0), - input: Input::new("add", "out"), - }), + Register::rc_new("reg", (100.0, 140.0), Input::new("add", "out")), + Wire::rc_new( + "w1", + vec![(110.0, 100.0), (180.0, 100.0)], + Input::new("c", "out"), + ), + Wire::rc_new( + "w2", + vec![(110.0, 140.0), (180.0, 140.0)], + Input::new("reg", "out"), + ), + Wire::rc_new( + "w3", + vec![(220.0, 120.0), (260.0, 120.0)], + Input::new("add", "out"), + ), + Wire::rc_new( + "w4", + vec![(260.0, 120.0), (260.0, 180.0)], + Input::new("add", "out"), + ), + Wire::rc_new( + "w5", + vec![(60.0, 180.0), (260.0, 180.0)], + Input::new("add", "out"), + ), + Wire::rc_new( + "w6", + vec![(60.0, 140.0), (60.0, 180.0)], + Input::new("add", "out"), + ), + Wire::rc_new( + "w7", + vec![(60.0, 140.0), (90.0, 140.0)], + Input::new("add", "out"), + ), + Probe::rc_new("p_add", (280.0, 120.0), Input::new("add", "out")), Probe::rc_new("p_reg", (130.0, 120.0), Input::new("reg", "out")), ], }; diff --git a/examples/add_reg_compound_wire.rs b/examples/add_reg_compound_wire.rs index b75f6089..3fdabf08 100644 --- a/examples/add_reg_compound_wire.rs +++ b/examples/add_reg_compound_wire.rs @@ -1,4 +1,4 @@ -use std::{path::PathBuf, rc::Rc}; +use std::path::PathBuf; use syncrim::{ common::{ComponentStore, Input}, components::*, @@ -9,31 +9,27 @@ fn main() { fern_setup(); let cs = ComponentStore { store: vec![ - Rc::new(Add { - id: "add".to_string(), - pos: (200.0, 120.0), - a_in: Input::new("c", "out"), - b_in: Input::new("reg", "out"), - }), + Add::rc_new( + "add", + (200.0, 120.0), + Input::new("c", "out"), + Input::new("reg", "out"), + ), Constant::rc_new("c", (100.0, 100.0), 3), - Rc::new(Register { - id: "reg".to_string(), - pos: (100.0, 140.0), - r_in: Input::new("add", "out"), - }), - Rc::new(Wire { - id: "w1".to_string(), - pos: vec![(110.0, 100.0), (180.0, 100.0)], - input: Input::new("c", "out"), - }), - Rc::new(Wire { - id: "w2".to_string(), - pos: vec![(110.0, 140.0), (180.0, 140.0)], - input: Input::new("reg", "out"), - }), - Rc::new(Wire { - id: "w3".to_string(), - pos: vec![ + Register::rc_new("reg", (100.0, 140.0), Input::new("add", "out")), + Wire::rc_new( + "w1", + vec![(110.0, 100.0), (180.0, 100.0)], + Input::new("c", "out"), + ), + Wire::rc_new( + "w2", + vec![(110.0, 140.0), (180.0, 140.0)], + Input::new("reg", "out"), + ), + Wire::rc_new( + "w3", + vec![ (220.0, 120.0), (260.0, 120.0), (260.0, 180.0), @@ -41,18 +37,10 @@ fn main() { (60.0, 140.0), (90.0, 140.0), ], - input: Input::new("add", "out"), - }), - Rc::new(Probe { - id: "p_add".to_string(), - pos: (280.0, 120.0), - input: Input::new("add", "out"), - }), - Rc::new(Probe { - id: "p_reg".to_string(), - pos: (130.0, 120.0), - input: Input::new("reg", "out"), - }), + Input::new("add", "out"), + ), + Probe::rc_new("p_add", (280.0, 120.0), Input::new("add", "out")), + Probe::rc_new("p_reg", (130.0, 120.0), Input::new("reg", "out")), ], }; diff --git a/examples/data_mem.rs b/examples/data_mem.rs index d95f6abe..d6e98ce8 100644 --- a/examples/data_mem.rs +++ b/examples/data_mem.rs @@ -30,73 +30,45 @@ fn main() { memory: Memory::new(), // later history... tbd }), - Rc::new(Constant { - id: "data".to_string(), - pos: (100.0, 100.0), - value: 3.into(), - }), - Rc::new(Constant { - id: "addr".to_string(), - pos: (120.0, 100.0), - value: 4.into(), - }), - Rc::new(Constant { - id: "ctrl".to_string(), - pos: (140.0, 100.0), - value: (MemCtrl::Write as SignalUnsigned).into(), - }), - Rc::new(Constant { - id: "sext".to_string(), - pos: (160.0, 100.0), - value: (false as SignalUnsigned).into(), - }), - Rc::new(Constant { - id: "size".to_string(), - pos: (180.0, 100.0), - value: 1.into(), // byte - }), + Constant::rc_new("data", (100.0, 100.0), 3), + Constant::rc_new("addr", (120.0, 100.0), 4), + Constant::rc_new("ctrl", (140.0, 100.0), MemCtrl::Write as SignalUnsigned), + Constant::rc_new("sext", (160.0, 100.0), false), + Constant::rc_new("size", (180.0, 100.0), 1), // byte // Wires - Rc::new(Wire { - id: "w1".to_string(), - pos: vec![(100.0, 110.0), (100.0, 150.0)], - input: Input::new("data", "out"), - }), - Rc::new(Wire { - id: "w2".to_string(), - pos: vec![(120.0, 110.0), (120.0, 150.0)], - input: Input::new("addr", "out"), - }), - Rc::new(Wire { - id: "w3".to_string(), - pos: vec![(140.0, 110.0), (140.0, 150.0)], - input: Input::new("sext", "out"), - }), - Rc::new(Wire { - id: "w4".to_string(), - pos: vec![(160.0, 110.0), (160.0, 150.0)], - input: Input::new("size", "out"), - }), - Rc::new(Wire { - id: "w5".to_string(), - pos: vec![(220.0, 110.0), (220.0, 150.0)], - input: Input::new("mem", "data"), - }), - Rc::new(Wire { - id: "w6".to_string(), - pos: vec![(240.0, 110.0), (240.0, 150.0)], - input: Input::new("mem", "err"), - }), + Wire::rc_new( + "w1", + vec![(100.0, 110.0), (100.0, 150.0)], + Input::new("data", "out"), + ), + Wire::rc_new( + "w2", + vec![(120.0, 110.0), (120.0, 150.0)], + Input::new("addr", "out"), + ), + Wire::rc_new( + "w3", + vec![(140.0, 110.0), (140.0, 150.0)], + Input::new("sext", "out"), + ), + Wire::rc_new( + "w4", + vec![(160.0, 110.0), (160.0, 150.0)], + Input::new("size", "out"), + ), + Wire::rc_new( + "w5", + vec![(220.0, 110.0), (220.0, 150.0)], + Input::new("mem", "data"), + ), + Wire::rc_new( + "w6", + vec![(240.0, 110.0), (240.0, 150.0)], + Input::new("mem", "err"), + ), // probes - Rc::new(Probe { - id: "out".to_string(), - pos: (220.0, 100.0), - input: Input::new("mem", "data"), - }), - Rc::new(Probe { - id: "err".to_string(), - pos: (240.0, 100.0), - input: Input::new("mem", "err"), - }), + Probe::rc_new("out", (220.0, 100.0), Input::new("mem", "data")), + Probe::rc_new("err", (240.0, 100.0), Input::new("mem", "err")), ], }; diff --git a/examples/mux.rs b/examples/mux.rs deleted file mode 100644 index adbcf345..00000000 --- a/examples/mux.rs +++ /dev/null @@ -1,94 +0,0 @@ -use std::{path::PathBuf, rc::Rc}; -use syncrim::{ - common::{ComponentStore, Input}, - components::*, - fern::fern_setup, -}; - -fn main() { - fern_setup(); - let cs = ComponentStore { - store: vec![ - Rc::new(Mux { - id: "mux".to_string(), - pos: (200.0, 200.0), - select: Input::new("c0", "out"), - m_in: vec![ - Input::new("c1", "out"), - Input::new("c2", "out"), - Input::new("c3", "out"), - Input::new("c4", "out"), - ], - }), - Rc::new(Constant { - id: "c0".to_string(), - pos: (190.0, 100.0), - value: 3.into(), - }), - Rc::new(Wire { - id: "w0".to_string(), - pos: vec![(190.0, 110.0), (190.0, 150.0)], - input: Input::new("c0", "out"), - }), - Rc::new(Constant { - id: "c1".to_string(), - pos: (140.0, 170.0), - value: 0.into(), - }), - Rc::new(Constant { - id: "c2".to_string(), - pos: (140.0, 190.0), - value: 1.into(), - }), - Rc::new(Constant { - id: "c3".to_string(), - pos: (140.0, 210.0), - value: 2.into(), - }), - Rc::new(Constant { - id: "c4".to_string(), - pos: (140.0, 230.0), - value: 3.into(), - }), - Rc::new(Wire { - id: "w1".to_string(), - pos: vec![(150.0, 170.0), (180.0, 170.0)], - input: Input::new("c1", "out"), - }), - Rc::new(Wire { - id: "w2".to_string(), - pos: vec![(150.0, 190.0), (180.0, 190.0)], - input: Input::new("c2", "out"), - }), - Rc::new(Wire { - id: "w3".to_string(), - pos: vec![(150.0, 210.0), (180.0, 210.0)], - input: Input::new("c3", "out"), - }), - Rc::new(Wire { - id: "w4".to_string(), - pos: vec![(150.0, 230.0), (180.0, 230.0)], - input: Input::new("c4", "out"), - }), - Rc::new(Wire { - id: "w5".to_string(), - pos: vec![(220.0, 200.0), (250.0, 200.0)], - input: Input::new("mux", "out"), - }), - Rc::new(Probe { - id: "p_mux".to_string(), - pos: (260.0, 200.0), - input: Input::new("mux", "out"), - }), - ], - }; - - let path = PathBuf::from("add.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); -} diff --git a/examples/mux_edit.rs b/examples/mux_edit.rs new file mode 100644 index 00000000..61055fa1 --- /dev/null +++ b/examples/mux_edit.rs @@ -0,0 +1,70 @@ +use std::path::PathBuf; +use syncrim::{ + common::{ComponentStore, Input}, + components::*, + fern::fern_setup, +}; + +fn main() { + fern_setup(); + let cs = ComponentStore { + store: vec![ + Mux::rc_new( + "mux", + (200.0, 200.0), + Input::new("ctrl", "out"), + vec![ + Input::new("c1", "out"), + Input::new("c2", "out"), + Input::new("c3", "out"), + Input::new("c4", "out"), + ], + ), + ProbeEdit::rc_new("ctrl", (190.0, 100.0)), + Wire::rc_new( + "w0", + vec![(190.0, 110.0), (190.0, 150.0)], + Input::new("ctrl", "out"), + ), + Constant::rc_new("c1", (140.0, 170.0), 0), + Constant::rc_new("c2", (140.0, 190.0), 1), + Constant::rc_new("c3", (140.0, 210.0), 2), + Constant::rc_new("c4", (140.0, 230.0), 3), + Wire::rc_new( + "w1", + vec![(150.0, 170.0), (180.0, 170.0)], + Input::new("c1", "out"), + ), + Wire::rc_new( + "w2", + vec![(150.0, 190.0), (180.0, 190.0)], + Input::new("c2", "out"), + ), + Wire::rc_new( + "w3", + vec![(150.0, 210.0), (180.0, 210.0)], + Input::new("c3", "out"), + ), + Wire::rc_new( + "w4", + vec![(150.0, 230.0), (180.0, 230.0)], + Input::new("c4", "out"), + ), + Wire::rc_new( + "w5", + vec![(220.0, 200.0), (250.0, 200.0)], + Input::new("mux", "out"), + ), + Probe::rc_new("p_mux", (260.0, 200.0), Input::new("mux", "out")), + ], + }; + + let path = PathBuf::from("mux_edit.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); +} diff --git a/examples/probe_edit.rs b/examples/probe_edit.rs index 4dc9e0e2..6f24a398 100644 --- a/examples/probe_edit.rs +++ b/examples/probe_edit.rs @@ -1,4 +1,4 @@ -use std::{path::PathBuf, rc::Rc}; +use std::path::PathBuf; use syncrim::{ common::{ComponentStore, Input}, components::*, @@ -9,12 +9,8 @@ fn main() { fern_setup(); let cs = ComponentStore { store: vec![ - Rc::new(ProbeEdit::new("probe_edit", (100.0, 100.0))), - Rc::new(Probe { - id: "probe".to_string(), - pos: (250.0, 100.0), - input: Input::new("probe_edit", "out"), - }), + ProbeEdit::rc_new("probe_edit", (100.0, 100.0)), + Probe::rc_new("probe", (250.0, 100.0), Input::new("probe_edit", "out")), ], }; diff --git a/examples/reg.rs b/examples/reg.rs deleted file mode 100644 index 40eae986..00000000 --- a/examples/reg.rs +++ /dev/null @@ -1,44 +0,0 @@ -use std::{path::PathBuf, rc::Rc}; -use syncrim::{ - common::{ComponentStore, Input}, - components::*, - fern::fern_setup, -}; - -fn main() { - fern_setup(); - let cs = ComponentStore { - store: vec![ - Constant::rc_new("c", (150.0, 100.0), 3), - Rc::new(Register { - id: "reg".to_string(), - pos: (200.0, 100.0), - r_in: Input::new("c", "out"), - }), - Rc::new(Wire { - id: "w1".to_string(), - pos: vec![(160.0, 100.0), (190.0, 100.0)], - input: Input::new("c", "out"), - }), - Rc::new(Wire { - id: "w2".to_string(), - pos: vec![(210.0, 100.0), (240.0, 100.0)], - input: Input::new("reg", "out"), - }), - Rc::new(Probe { - id: "p_reg".to_string(), - pos: (250.0, 100.0), - input: Input::new("reg", "out"), - }), - ], - }; - - let path = PathBuf::from("reg.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); -} diff --git a/examples/sext.rs b/examples/sext.rs index 3dd39156..c2779b91 100644 --- a/examples/sext.rs +++ b/examples/sext.rs @@ -1,4 +1,4 @@ -use std::{path::PathBuf, rc::Rc}; +use std::path::PathBuf; use syncrim::{ common::{ComponentStore, Input}, components::*, @@ -10,28 +10,18 @@ fn main() { let cs = ComponentStore { store: vec![ Constant::rc_new("c0", (100.0, 110.0), 32768), - Rc::new(Wire { - id: "w0".to_string(), - pos: vec![(110.0, 110.0), (140.0, 110.0)], - input: Input::new("c0", "out"), - }), - Rc::new(Sext { - id: "sxt0".to_string(), - pos: (180.0, 100.0), - sext_in: Input::new("c0", "out"), - in_size: 16, - out_size: 24, - }), - Rc::new(Wire { - id: "w1".to_string(), - pos: vec![(220.0, 100.0), (250.0, 100.0)], - input: Input::new("sxt0", "out"), - }), - Rc::new(Probe { - id: "p1".to_string(), - pos: (260.0, 100.0), - input: Input::new("sxt0", "out"), - }), + Wire::rc_new( + "w0", + vec![(110.0, 110.0), (140.0, 110.0)], + Input::new("c0", "out"), + ), + Sext::rc_new("sxt0", (180.0, 100.0), Input::new("c0", "out"), 16, 24), + Wire::rc_new( + "w1", + vec![(220.0, 100.0), (250.0, 100.0)], + Input::new("sxt0", "out"), + ), + Probe::rc_new("p1", (260.0, 100.0), Input::new("sxt0", "out")), ], }; diff --git a/mips/examples/mips.rs b/mips/examples/mips.rs index efcbe0cf..67e6333b 100644 --- a/mips/examples/mips.rs +++ b/mips/examples/mips.rs @@ -1,7 +1,7 @@ // An example MIPS model use mips::components::*; -use std::{path::PathBuf, rc::Rc}; +use std::path::PathBuf; use syncrim::{ common::{ComponentStore, Input}, components::*, @@ -12,85 +12,55 @@ fn main() { fern_setup(); let cs = ComponentStore { store: vec![ - Rc::new(Add { - id: "add".to_string(), - pos: (200.0, 120.0), - a_in: Input::new("c1", "out"), - b_in: Input::new("reg", "out"), - }), + Add::rc_new( + "add", + (200.0, 120.0), + Input::new("c1", "out"), + Input::new("reg", "out"), + ), Constant::rc_new("c1", (100.0, 100.0), 4), - Rc::new(Register { - id: "reg".to_string(), - pos: (100.0, 140.0), - r_in: Input::new("add", "out"), - }), - Rc::new(Wire { - id: "c1_to_add_a".to_string(), - pos: vec![(110.0, 100.0), (180.0, 100.0)], - input: Input::new("c1", "out"), - }), - Rc::new(Wire { - id: "reg_to_add_b".to_string(), - pos: vec![(110.0, 140.0), (180.0, 140.0)], - input: Input::new("reg", "out"), - }), - Rc::new(Wire { - id: "add_to_right".to_string(), - pos: vec![(220.0, 120.0), (260.0, 120.0)], - input: Input::new("add", "out"), - }), - Rc::new(Wire { - id: "add_to_up".to_string(), - pos: vec![(260.0, 60.0), (260.0, 120.0)], - input: Input::new("add", "out"), - }), - Rc::new(Wire { - id: "add_to_left".to_string(), - pos: vec![(60.0, 60.0), (260.0, 60.0)], - input: Input::new("add", "out"), - }), - Rc::new(Wire { - id: "add_to_down".to_string(), - pos: vec![(60.0, 60.0), (60.0, 140.0)], - input: Input::new("add", "out"), - }), - Rc::new(Wire { - id: "reg_in".to_string(), - pos: vec![(60.0, 140.0), (90.0, 140.0)], - input: Input::new("add", "out"), - }), - Rc::new(Wire { - id: "pc_to_down".to_string(), - pos: vec![(140.0, 140.0), (140.0, 180.0)], - input: Input::new("reg", "out"), - }), - Rc::new(Wire { - id: "pc_to_right".to_string(), - pos: vec![(140.0, 180.0), (350.0, 180.0)], - input: Input::new("reg", "out"), - }), - Rc::new(InstrMem { - id: "instr_mem".to_string(), - pos: (400.0, 150.0), - pc: Input::new("reg", "out"), + Register::rc_new("reg", (100.0, 140.0), Input::new("add", "out")), + Wire::rc_new( + "c1_to_add_a", + vec![(110.0, 100.0), (180.0, 100.0)], + Input::new("c1", "out"), + ), + Wire::rc_new( + "reg_to_add_b", + vec![(110.0, 140.0), (180.0, 140.0)], + Input::new("reg", "out"), + ), + Wire::rc_new( + "add_to_reg", + vec![ + (220.0, 120.0), + (260.0, 120.0), + (260.0, 60.0), + (60.0, 60.0), + (60.0, 140.0), + (90.0, 140.0), + ], + Input::new("add", "out"), + ), + Wire::rc_new( + "pc_to_down", + vec![(140.0, 140.0), (140.0, 180.0), (350.0, 180.0)], + Input::new("reg", "out"), + ), + InstrMem::rc_new( + "instr_mem", + (400.0, 150.0), + Input::new("reg", "out"), // fake instructions just to show the relation between input address and instruction - instr: vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9], - }), - Rc::new(Wire { - id: "w8".to_string(), - pos: vec![(450.0, 120.0), (520.0, 120.0)], - input: Input::new("instr_mem", "out"), - }), - Rc::new(Probe { - id: "p1".to_string(), - pos: (280.0, 160.0), - input: Input::new("reg", "out"), - }), - Rc::new(Probe { - id: "p2".to_string(), - pos: (500.0, 100.0), - input: Input::new("instr_mem", "out"), - }), + vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + ), + Wire::rc_new( + "w8", + vec![(450.0, 120.0), (520.0, 120.0)], + Input::new("instr_mem", "out"), + ), + Probe::rc_new("p1", (280.0, 160.0), Input::new("reg", "out")), + Probe::rc_new("p2", (500.0, 100.0), Input::new("instr_mem", "out")), ], }; diff --git a/mips/examples/reg_file.rs b/mips/examples/reg_file.rs index cd00ccff..56ef3f62 100644 --- a/mips/examples/reg_file.rs +++ b/mips/examples/reg_file.rs @@ -1,12 +1,11 @@ use mips::components::*; -use std::{path::PathBuf, rc::Rc}; +use std::path::PathBuf; use syncrim::{ common::{ComponentStore, Input, SignalFmt, SignalSize}, components::*, fern::fern_setup, }; -// TODO: fix wires and layout fn main() { fern_setup(); let cs = ComponentStore { @@ -37,23 +36,18 @@ fn main() { (4, SignalFmt::Binary(5)), ), // regfile - Rc::new(RegFile { - id: "reg_file".to_string(), - pos: (300.0, 200.0), - width: 200.0, - height: 300.0, - + RegFile::rc_new( + "reg_file", + (300.0, 200.0), + 200.0, + 300.0, // ports - read_addr1: Input::new("c_read_reg_1", "out"), - read_addr2: Input::new("c_read_reg_2", "out"), - write_data: Input::new("c_write_data", "out"), - write_addr: Input::new("c_write_addr", "out"), - write_enable: Input::new("c_write_enable", "out"), - - // data - registers: RegStore::new(), - history: RegHistory::new(), - }), + Input::new("c_read_reg_1", "out"), + Input::new("c_read_reg_2", "out"), + Input::new("c_write_data", "out"), + Input::new("c_write_addr", "out"), + Input::new("c_write_enable", "out"), + ), Probe::rc_new("p_reg_a", (500.0, 100.0), Input::new("reg_file", "reg_a")), Probe::rc_new("p_reg_b", (500.0, 300.0), Input::new("reg_file", "reg_b")), Wire::rc_new( diff --git a/mips/src/components/instr_mem.rs b/mips/src/components/instr_mem.rs index 433b8ac6..2accfe38 100644 --- a/mips/src/components/instr_mem.rs +++ b/mips/src/components/instr_mem.rs @@ -1,12 +1,13 @@ use serde::{Deserialize, Serialize}; +use std::rc::Rc; use syncrim::common::{Component, Input, OutputType, Ports, Simulator}; #[derive(Serialize, Deserialize)] pub struct InstrMem { pub id: String, pub pos: (f32, f32), - pub instr: Vec, pub pc: Input, + pub instr: Vec, } use log::*; @@ -39,3 +40,18 @@ impl Component for InstrMem { simulator.set_out_val(&self.id, "out", instr); } } + +impl InstrMem { + pub fn new(id: &str, pos: (f32, f32), pc: Input, instr: Vec) -> Self { + InstrMem { + id: id.to_string(), + pos, + pc, + instr, + } + } + + pub fn rc_new(id: &str, pos: (f32, f32), pc: Input, instr: Vec) -> Rc { + Rc::new(InstrMem::new(id, pos, pc, instr)) + } +} diff --git a/mips/src/components/reg_file.rs b/mips/src/components/reg_file.rs index 2fffd75c..668e2495 100644 --- a/mips/src/components/reg_file.rs +++ b/mips/src/components/reg_file.rs @@ -46,17 +46,17 @@ pub enum Reg { #[derive(Serialize, Deserialize)] pub struct RegFile { - pub id: String, - pub pos: (f32, f32), - pub width: f32, - pub height: f32, + pub(crate) id: String, + pub(crate) pos: (f32, f32), + pub(crate) width: f32, + pub(crate) height: f32, // ports - pub read_addr1: Input, - pub read_addr2: Input, - pub write_data: Input, - pub write_addr: Input, - pub write_enable: Input, + read_addr1: Input, + read_addr2: Input, + write_data: Input, + write_addr: Input, + write_enable: Input, // data pub registers: RegStore, @@ -123,6 +123,62 @@ impl Deref for RegStore { } impl RegFile { + #[allow(clippy::too_many_arguments)] + pub fn new( + id: &str, + pos: (f32, f32), + width: f32, + height: f32, + read_addr1: Input, + read_addr2: Input, + write_data: Input, + write_addr: Input, + write_enable: Input, + ) -> Self { + RegFile { + id: id.to_string(), + pos, + width, + height, + + // ports + read_addr1, + read_addr2, + write_data, + write_addr, + write_enable, + + // data + registers: RegStore::new(), + history: RegHistory::new(), + } + } + + #[allow(clippy::too_many_arguments)] + pub fn rc_new( + id: &str, + pos: (f32, f32), + width: f32, + height: f32, + read_addr1: Input, + read_addr2: Input, + write_data: Input, + write_addr: Input, + write_enable: Input, + ) -> Rc { + Rc::new(RegFile::new( + id, + pos, + width, + height, + read_addr1, + read_addr2, + write_data, + write_addr, + write_enable, + )) + } + fn read_reg(&self, simulator: &Simulator, input: &Input) -> u32 { let read_addr: SignalUnsigned = simulator.get_input_val(input).try_into().unwrap(); trace!("read_addr {}", read_addr); diff --git a/src/components/add.rs b/src/components/add.rs index b1a23968..948cc198 100644 --- a/src/components/add.rs +++ b/src/components/add.rs @@ -3,6 +3,7 @@ use crate::common::{ }; use log::*; use serde::{Deserialize, Serialize}; +use std::rc::Rc; #[derive(Serialize, Deserialize)] pub struct Add { @@ -61,6 +62,21 @@ impl Component for Add { } } +impl Add { + pub fn new(id: &str, pos: (f32, f32), a_in: Input, b_in: Input) -> Self { + Add { + id: id.to_string(), + pos, + a_in, + b_in, + } + } + + pub fn rc_new(id: &str, pos: (f32, f32), a_in: Input, b_in: Input) -> Rc { + Rc::new(Add::new(id, pos, a_in, b_in)) + } +} + #[cfg(test)] mod test { use super::*; diff --git a/src/components/constant.rs b/src/components/constant.rs index 0b465a2f..82a5db38 100644 --- a/src/components/constant.rs +++ b/src/components/constant.rs @@ -33,19 +33,15 @@ impl Component for Constant { } impl Constant { - pub fn new(id: &str, pos: (impl Into, impl Into), value: impl Into) -> Self { + pub fn new(id: &str, pos: (f32, f32), value: impl Into) -> Self { Constant { id: id.to_string(), - pos: (pos.0.into(), pos.1.into()), + pos, value: value.into(), } } - pub fn rc_new( - id: &str, - pos: (impl Into, impl Into), - value: impl Into, - ) -> Rc { + pub fn rc_new(id: &str, pos: (f32, f32), value: impl Into) -> Rc { Rc::new(Constant::new(id, pos, value)) } } diff --git a/src/components/mux.rs b/src/components/mux.rs index 1e6bd821..c8844547 100644 --- a/src/components/mux.rs +++ b/src/components/mux.rs @@ -3,6 +3,8 @@ use crate::common::{ }; use log::*; use serde::{Deserialize, Serialize}; +use std::rc::Rc; + #[derive(Serialize, Deserialize)] pub struct Mux { pub id: Id, @@ -36,11 +38,15 @@ impl Component for Mux { fn clock(&self, simulator: &mut Simulator) { // get input value let select: SignalData = simulator.get_input_val(&self.select); - let select: SignalUnsigned = select.try_into().unwrap(); - let select = select as usize; - trace!("select {}", select); - let value = if select < self.m_in.len() { - simulator.get_input_val(&self.m_in[select]) + + let value = if let Ok(select) = TryInto::::try_into(select) { + let select = select as usize; + trace!("select {}", select); + if select < self.m_in.len() { + simulator.get_input_val(&self.m_in[select]) + } else { + SignalData::Unknown + } } else { SignalData::Unknown }; @@ -49,3 +55,18 @@ impl Component for Mux { simulator.set_out_val(&self.id, "out", value); } } + +impl Mux { + pub fn new(id: &str, pos: (f32, f32), select: Input, m_in: Vec) -> Self { + Mux { + id: id.to_string(), + pos, + select, + m_in, + } + } + + pub fn rc_new(id: &str, pos: (f32, f32), select: Input, m_in: Vec) -> Rc { + Rc::new(Mux::new(id, pos, select, m_in)) + } +} diff --git a/src/components/probe.rs b/src/components/probe.rs index 0d677cd1..ac3bf45d 100644 --- a/src/components/probe.rs +++ b/src/components/probe.rs @@ -1,7 +1,7 @@ use crate::common::{Component, Id, Input, OutputType, Ports}; use log::*; use serde::{Deserialize, Serialize}; -use std::{convert::Into, rc::Rc}; +use std::rc::Rc; #[derive(Serialize, Deserialize)] pub struct Probe { pub id: Id, @@ -30,15 +30,15 @@ impl Component for Probe { } impl Probe { - pub fn new(id: &str, pos: (impl Into, impl Into), input: Input) -> Self { + pub fn new(id: &str, pos: (f32, f32), input: Input) -> Self { Probe { id: id.to_string(), - pos: (pos.0.into(), pos.1.into()), + pos, input, } } - pub fn rc_new(id: &str, pos: (impl Into, impl Into), input: Input) -> Rc { + pub fn rc_new(id: &str, pos: (f32, f32), input: Input) -> Rc { Rc::new(Probe::new(id, pos, input)) } } diff --git a/src/components/register.rs b/src/components/register.rs index 23902620..e04893b1 100644 --- a/src/components/register.rs +++ b/src/components/register.rs @@ -1,6 +1,8 @@ use crate::common::{Component, Id, Input, OutputType, Ports, Simulator}; use log::*; use serde::{Deserialize, Serialize}; +use std::rc::Rc; + #[derive(Serialize, Deserialize)] pub struct Register { pub id: Id, @@ -35,3 +37,17 @@ impl Component for Register { trace!("eval: register id {} in {:?}", self.id, value); } } + +impl Register { + pub fn new(id: &str, pos: (f32, f32), r_in: Input) -> Self { + Register { + id: id.to_string(), + pos, + r_in, + } + } + + pub fn rc_new(id: &str, pos: (f32, f32), r_in: Input) -> Rc { + Rc::new(Register::new(id, pos, r_in)) + } +} diff --git a/src/components/sext.rs b/src/components/sext.rs index b5f3fa8e..37f9f8bd 100644 --- a/src/components/sext.rs +++ b/src/components/sext.rs @@ -4,6 +4,7 @@ use crate::common::{ }; use log::*; use serde::{Deserialize, Serialize}; +use std::rc::Rc; #[derive(Serialize, Deserialize)] pub struct Sext { pub id: Id, @@ -53,12 +54,32 @@ impl Component for Sext { } } +impl Sext { + pub fn new(id: &str, pos: (f32, f32), sext_in: Input, in_size: u32, out_size: u32) -> Self { + Sext { + id: id.to_string(), + pos, + sext_in, + in_size, + out_size, + } + } + + pub fn rc_new( + id: &str, + pos: (f32, f32), + sext_in: Input, + in_size: u32, + out_size: u32, + ) -> Rc { + Rc::new(Sext::new(id, pos, sext_in, in_size, out_size)) + } +} + #[cfg(test)] mod test { - use super::*; use crate::{common::ComponentStore, components::ProbeOut}; - use std::rc::Rc; #[test] fn test_sext() { diff --git a/src/components/wire.rs b/src/components/wire.rs index 7165b072..75e9e225 100644 --- a/src/components/wire.rs +++ b/src/components/wire.rs @@ -1,7 +1,7 @@ use crate::common::{Component, Id, Input, OutputType, Ports}; use log::*; use serde::{Deserialize, Serialize}; -use std::{convert::Into, rc::Rc}; +use std::rc::Rc; #[derive(Serialize, Deserialize)] pub struct Wire { pub id: Id, @@ -30,15 +30,15 @@ impl Component for Wire { } impl Wire { - pub fn new(id: &str, pos: Vec<(impl Into, impl Into)>, input: Input) -> Self { + pub fn new(id: &str, pos: Vec<(f32, f32)>, input: Input) -> Self { Wire { id: id.to_string(), - pos: pos.into_iter().map(|p| (p.0.into(), p.1.into())).collect(), + pos, input, } } - pub fn rc_new(id: &str, pos: Vec<(impl Into, impl Into)>, input: Input) -> Rc { + pub fn rc_new(id: &str, pos: Vec<(f32, f32)>, input: Input) -> Rc { Rc::new(Wire::new(id, pos, input)) } } diff --git a/src/signal.rs b/src/signal.rs index 2025dbb3..154f3d15 100644 --- a/src/signal.rs +++ b/src/signal.rs @@ -148,13 +148,13 @@ impl fmt::Display for Signal { let bytes = &value.to_ne_bytes()[0..s as usize]; let s: String = bytes - .into_iter() + .iter() .map(|b| { let c = *b as char; - if c.is_ascii_graphic() || c == ' ' as char { + if c.is_ascii_graphic() || c == ' ' { c } else { - '¤' as char + '¤' } }) .rev() @@ -171,7 +171,7 @@ impl fmt::Display for Signal { match size { SignalSize::_8 => format!("{}", value as u8), SignalSize::_16 => format!("{}", value as u16), - SignalSize::_32 => format!("{}", value as u32), + SignalSize::_32 => format!("{}", value), } ), SignalFmt::Signed(size) => write!( @@ -189,7 +189,7 @@ impl fmt::Display for Signal { match size { SignalSize::_8 => format!("{:#04x}", value as u8), SignalSize::_16 => format!("{:#06x}", value as u16), - SignalSize::_32 => format!("{:#010x}", value as u32), + SignalSize::_32 => format!("{:#010x}", value), } ), SignalFmt::Hex(size, false) => write!( @@ -198,10 +198,10 @@ impl fmt::Display for Signal { match size { SignalSize::_8 => format!("{:#x}", value as u8), SignalSize::_16 => format!("{:#x}", value as u16), - SignalSize::_32 => format!("{:#x}", value as u32), + SignalSize::_32 => format!("{:#x}", value), } ), - SignalFmt::Bool => write!(f, "{}", !(value == 0)), + SignalFmt::Bool => write!(f, "{}", value != 0), }, _ => write!(f, "{:?}", self.data), } From c4f107a0e2b0a8707fd04ddb91f1bf99ebff1a0b Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Thu, 27 Jul 2023 00:34:38 +0200 Subject: [PATCH 09/14] data mem still buggy --- examples/data_mem.rs | 30 ++++++-------- mips/src/components/instr_mem.rs | 8 ++-- mips/src/components/reg_file.rs | 2 +- src/components/add.rs | 8 ++-- src/components/constant.rs | 6 +-- src/components/mem.rs | 68 ++++++++++++++++++++++++++------ 6 files changed, 81 insertions(+), 41 deletions(-) diff --git a/examples/data_mem.rs b/examples/data_mem.rs index d6e98ce8..64c4fef2 100644 --- a/examples/data_mem.rs +++ b/examples/data_mem.rs @@ -9,27 +9,21 @@ fn main() { fern_setup(); let cs = ComponentStore { store: vec![ - Rc::new(Mem { - id: "mem".to_string(), - pos: (180.0, 200.0), - - width: 200.0, - height: 100.0, - + Mem::rc_new( + "mem", + (180.0, 200.0), + 200.0, + 100.0, // configuration - big_endian: true, - + true, // ports - data: Input::new("data", "out"), - addr: Input::new("addr", "out"), - ctrl: Input::new("ctrl", "out"), - sign: Input::new("sext", "out"), - size: Input::new("size", "out"), - - // memory - memory: Memory::new(), + Input::new("data", "out"), + Input::new("addr", "out"), + Input::new("ctrl", "out"), + Input::new("sext", "out"), + Input::new("size", "out"), // later history... tbd - }), + ), Constant::rc_new("data", (100.0, 100.0), 3), Constant::rc_new("addr", (120.0, 100.0), 4), Constant::rc_new("ctrl", (140.0, 100.0), MemCtrl::Write as SignalUnsigned), diff --git a/mips/src/components/instr_mem.rs b/mips/src/components/instr_mem.rs index 2accfe38..619fcef2 100644 --- a/mips/src/components/instr_mem.rs +++ b/mips/src/components/instr_mem.rs @@ -4,10 +4,10 @@ use syncrim::common::{Component, Input, OutputType, Ports, Simulator}; #[derive(Serialize, Deserialize)] pub struct InstrMem { - pub id: String, - pub pos: (f32, f32), - pub pc: Input, - pub instr: Vec, + id: String, + pub(crate) pos: (f32, f32), + pc: Input, + instr: Vec, } use log::*; diff --git a/mips/src/components/reg_file.rs b/mips/src/components/reg_file.rs index 668e2495..c37d50cf 100644 --- a/mips/src/components/reg_file.rs +++ b/mips/src/components/reg_file.rs @@ -46,7 +46,7 @@ pub enum Reg { #[derive(Serialize, Deserialize)] pub struct RegFile { - pub(crate) id: String, + id: String, pub(crate) pos: (f32, f32), pub(crate) width: f32, pub(crate) height: f32, diff --git a/src/components/add.rs b/src/components/add.rs index 948cc198..0ea50984 100644 --- a/src/components/add.rs +++ b/src/components/add.rs @@ -7,10 +7,10 @@ use std::rc::Rc; #[derive(Serialize, Deserialize)] pub struct Add { - pub id: Id, - pub pos: (f32, f32), - pub a_in: Input, - pub b_in: Input, + id: Id, + pub(crate) pos: (f32, f32), + a_in: Input, + b_in: Input, } #[typetag::serde] diff --git a/src/components/constant.rs b/src/components/constant.rs index 82a5db38..e23c1e9d 100644 --- a/src/components/constant.rs +++ b/src/components/constant.rs @@ -4,9 +4,9 @@ use serde::{Deserialize, Serialize}; use std::{convert::Into, rc::Rc}; #[derive(Serialize, Deserialize)] pub struct Constant { - pub id: Id, - pub pos: (f32, f32), - pub value: Signal, + id: Id, + pub(crate) pos: (f32, f32), + pub(crate) value: Signal, } #[typetag::serde] diff --git a/src/components/mem.rs b/src/components/mem.rs index 1fe603cd..84d35837 100644 --- a/src/components/mem.rs +++ b/src/components/mem.rs @@ -5,30 +5,76 @@ use log::*; use num_enum::IntoPrimitive; use num_enum::TryFromPrimitive; use serde::{Deserialize, Serialize}; -use std::{cell::RefCell, collections::HashMap, convert::TryFrom}; +use std::{cell::RefCell, collections::HashMap, convert::TryFrom, rc::Rc}; #[derive(Serialize, Deserialize)] pub struct Mem { - pub id: Id, - pub pos: (f32, f32), - pub width: f32, - pub height: f32, + id: Id, + pub(crate) pos: (f32, f32), + pub(crate) width: f32, + pub(crate) height: f32, // configuration pub big_endian: bool, // ports - pub data: Input, - pub addr: Input, - pub ctrl: Input, - pub sign: Input, - pub size: Input, + data: Input, + addr: Input, + ctrl: Input, + sign: Input, + size: Input, // memory - pub memory: Memory, + memory: Memory, // later history... tbd } +impl Mem { + pub fn new( + id: &str, + pos: (f32, f32), + width: f32, + height: f32, + big_endian: bool, + data: Input, + addr: Input, + ctrl: Input, + sign: Input, + size: Input, + ) -> Self { + Mem { + id: id.to_string(), + pos, + width, + height, + big_endian, + data, + addr, + ctrl, + sign, + size, + memory: Memory::new(), + } + } + + pub fn rc_new( + id: &str, + pos: (f32, f32), + width: f32, + height: f32, + big_endian: bool, + data: Input, + addr: Input, + ctrl: Input, + sign: Input, + size: Input, + ) -> Rc { + Rc::new(Mem::new( + id, pos, width, height, big_endian, data, addr, ctrl, sign, size, + )) + } +} + #[derive(Serialize, Deserialize, Debug)] pub struct Memory { bytes: RefCell>, From e419ce8a85cda6a209821a9f5572c4fd7c79e789 Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Thu, 27 Jul 2023 09:21:19 +0200 Subject: [PATCH 10/14] improed robustness --- examples/data_mem.rs | 2 +- mips/src/components/instr_mem.rs | 20 ++++++++++++++------ src/simulator.rs | 10 +++++++--- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/examples/data_mem.rs b/examples/data_mem.rs index 64c4fef2..5c5e22f0 100644 --- a/examples/data_mem.rs +++ b/examples/data_mem.rs @@ -1,4 +1,4 @@ -use std::{path::PathBuf, rc::Rc}; +use std::path::PathBuf; use syncrim::{ common::{ComponentStore, Input, SignalUnsigned}, components::*, diff --git a/mips/src/components/instr_mem.rs b/mips/src/components/instr_mem.rs index 619fcef2..51c74df5 100644 --- a/mips/src/components/instr_mem.rs +++ b/mips/src/components/instr_mem.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; use std::rc::Rc; -use syncrim::common::{Component, Input, OutputType, Ports, Simulator}; +use syncrim::common::{Component, Input, OutputType, Ports, SignalData, SignalUnsigned, Simulator}; #[derive(Serialize, Deserialize)] pub struct InstrMem { @@ -30,13 +30,21 @@ impl Component for InstrMem { } fn clock(&self, simulator: &mut Simulator) { - // get instr at pc/4 - let pc: u32 = simulator.get_input_val(&self.pc).try_into().unwrap(); + let instr: SignalData = + match TryInto::::try_into(simulator.get_input_val(&self.pc)) { + Ok(pc) => { + trace!("--- evaluate instr mem: pc {:?}", pc); + // get instr at pc/4 + match self.instr.get((pc / 4) as usize) { + Some(instr) => (*instr).into(), + _ => SignalData::Unknown, + } + } + _ => SignalData::Unknown, + }; - trace!("--- evaluate instr mem: pc {:?}", pc); - let instr = self.instr[(pc / 4) as usize]; // set output - trace!("--- output {}", instr); + trace!("--- output {:?}", instr); simulator.set_out_val(&self.id, "out", instr); } } diff --git a/src/simulator.rs b/src/simulator.rs index c58ebfb4..f3582ea0 100644 --- a/src/simulator.rs +++ b/src/simulator.rs @@ -107,12 +107,11 @@ impl Simulator { // topological order let top = toposort(&graph, None).expect("Topological sort failed, your model contains loops."); - trace!("--- top \n{:?}", top); + trace!("--- topologically ordered graph \n{:?}", top); let mut ordered_components = vec![]; for node in &top { - // #[allow(clippy::clone_double_ref)] // old lint - #[allow(suspicious_double_ref_op)] // changed in Rust 1.71 + #[allow(suspicious_double_ref_op)] let c = (**node_comp.get(node).unwrap()).clone(); ordered_components.push(c); } @@ -122,6 +121,11 @@ impl Simulator { .map(|c| c.get_id_ports().0) .collect(); + trace!( + "--- topologically ordered component identifiers \n{:?}", + component_ids + ); + let mut simulator = Simulator { cycle: 0, id_start_index, From c12f5ff1b3d4771c014daa1bcfebf88c75a549ce Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Thu, 27 Jul 2023 09:51:47 +0200 Subject: [PATCH 11/14] examples now works --- examples/data_mem.rs | 19 ++++++++++++------- mips/src/components/reg_file.rs | 8 +++++++- src/components/mem.rs | 18 +++++++++--------- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/examples/data_mem.rs b/examples/data_mem.rs index 5c5e22f0..73181852 100644 --- a/examples/data_mem.rs +++ b/examples/data_mem.rs @@ -31,32 +31,37 @@ fn main() { Constant::rc_new("size", (180.0, 100.0), 1), // byte // Wires Wire::rc_new( - "w1", + "w_data", vec![(100.0, 110.0), (100.0, 150.0)], Input::new("data", "out"), ), Wire::rc_new( - "w2", + "w_addr", vec![(120.0, 110.0), (120.0, 150.0)], Input::new("addr", "out"), ), Wire::rc_new( - "w3", + "w_ctrl", vec![(140.0, 110.0), (140.0, 150.0)], - Input::new("sext", "out"), + Input::new("ctrl", "out"), ), Wire::rc_new( - "w4", + "w_sext", vec![(160.0, 110.0), (160.0, 150.0)], + Input::new("sext", "out"), + ), + Wire::rc_new( + "w_size", + vec![(180.0, 110.0), (180.0, 150.0)], Input::new("size", "out"), ), Wire::rc_new( - "w5", + "w_mem_data", vec![(220.0, 110.0), (220.0, 150.0)], Input::new("mem", "data"), ), Wire::rc_new( - "w6", + "w_mem_err", vec![(240.0, 110.0), (240.0, 150.0)], Input::new("mem", "err"), ), diff --git a/mips/src/components/reg_file.rs b/mips/src/components/reg_file.rs index c37d50cf..dce02c66 100644 --- a/mips/src/components/reg_file.rs +++ b/mips/src/components/reg_file.rs @@ -202,7 +202,13 @@ impl Component for RegFile { ( self.id.clone(), Ports { - inputs: vec![self.read_addr1.clone(), self.read_addr2.clone()], + inputs: vec![ + self.read_addr1.clone(), + self.read_addr2.clone(), + self.write_addr.clone(), + self.write_data.clone(), + self.write_enable.clone(), + ], out_type: OutputType::Combinatorial, outputs: vec!["reg_a".into(), "reg_b".into()], }, diff --git a/src/components/mem.rs b/src/components/mem.rs index 84d35837..fe2b0844 100644 --- a/src/components/mem.rs +++ b/src/components/mem.rs @@ -21,7 +21,7 @@ pub struct Mem { data: Input, addr: Input, ctrl: Input, - sign: Input, + sext: Input, size: Input, // memory @@ -39,7 +39,7 @@ impl Mem { data: Input, addr: Input, ctrl: Input, - sign: Input, + sext: Input, size: Input, ) -> Self { Mem { @@ -51,7 +51,7 @@ impl Mem { data, addr, ctrl, - sign, + sext, size, memory: Memory::new(), } @@ -66,11 +66,11 @@ impl Mem { data: Input, addr: Input, ctrl: Input, - sign: Input, + sext: Input, size: Input, ) -> Rc { Rc::new(Mem::new( - id, pos, width, height, big_endian, data, addr, ctrl, sign, size, + id, pos, width, height, big_endian, data, addr, ctrl, sext, size, )) } } @@ -238,7 +238,7 @@ impl Component for Mem { ( self.id.clone(), Ports::new( - vec![&self.data, &self.addr, &self.ctrl], + vec![&self.data, &self.addr, &self.ctrl, &self.sext, &self.size], OutputType::Combinatorial, vec!["data", "err"], ), @@ -253,7 +253,7 @@ impl Component for Mem { let ctrl = MemCtrl::try_from(ctrl as u8).unwrap(); let size: SignalUnsigned = simulator.get_input_val(&self.size).try_into().unwrap(); let size = size as usize; - let sign: SignalUnsigned = simulator.get_input_val(&self.sign).try_into().unwrap(); + let sign: SignalUnsigned = simulator.get_input_val(&self.sext).try_into().unwrap(); let sign = sign != 0; match ctrl { @@ -311,7 +311,7 @@ mod test { addr: Input::new("addr", "out"), ctrl: Input::new("ctrl", "out"), size: Input::new("size", "out"), - sign: Input::new("sign", "out"), + sext: Input::new("sign", "out"), // memory memory: Memory { @@ -491,7 +491,7 @@ mod test { addr: Input::new("addr", "out"), ctrl: Input::new("ctrl", "out"), size: Input::new("size", "out"), - sign: Input::new("sign", "out"), + sext: Input::new("sign", "out"), // memory memory: Memory { From 7b4c2f3da9113016d6d78e1153d09d88ffc76f2d Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Thu, 27 Jul 2023 19:15:52 +0200 Subject: [PATCH 12/14] pub(crate) for Component fields --- examples/add_mux.rs | 20 ++++++++------------ mips/src/components/instr_mem.rs | 6 +++--- mips/src/components/reg_file.rs | 16 ++++++++-------- src/components/add.rs | 6 +++--- src/components/constant.rs | 2 +- src/components/mem.rs | 16 +++++++++------- src/components/mux.rs | 8 ++++---- src/components/probe.rs | 6 +++--- src/components/probe_assert.rs | 8 ++++---- src/components/probe_edit.rs | 6 +++--- src/components/probe_out.rs | 2 +- src/components/probe_stim.rs | 6 +++--- src/components/register.rs | 6 +++--- src/components/sext.rs | 10 +++++----- src/components/wire.rs | 6 +++--- src/gui_egui/components/mod.rs | 2 ++ src/gui_egui/components/probe_edit.rs | 5 +++++ src/gui_egui/components/probe_stim.rs | 5 +++++ 18 files changed, 73 insertions(+), 63 deletions(-) create mode 100644 src/gui_egui/components/probe_edit.rs create mode 100644 src/gui_egui/components/probe_stim.rs diff --git a/examples/add_mux.rs b/examples/add_mux.rs index ba8f82f8..f2601558 100644 --- a/examples/add_mux.rs +++ b/examples/add_mux.rs @@ -1,4 +1,4 @@ -use std::{path::PathBuf, rc::Rc}; +use std::path::PathBuf; use syncrim::{ common::{ComponentStore, Input}, components::*, @@ -16,11 +16,7 @@ fn main() { Input::new("r1", "out"), ), Constant::rc_new("c", (100.0, 100.0), 1), - Rc::new(Register { - id: "r1".to_string(), - pos: (100.0, 140.0), - r_in: Input::new("add", "out"), - }), + Register::rc_new("r1", (100.0, 140.0), Input::new("add", "out")), Wire::rc_new( "w1", vec![(110.0, 100.0), (180.0, 100.0)], @@ -58,17 +54,17 @@ fn main() { ), Probe::rc_new("p_add", (280.0, 120.0), Input::new("add", "out")), Probe::rc_new("p_reg", (130.0, 120.0), Input::new("r1", "out")), - Rc::new(Mux { - id: "mux".to_string(), - pos: (270.0, 300.0), - select: Input::new("add", "out"), - m_in: vec![ + Mux::rc_new( + "mux", + (270.0, 300.0), + Input::new("add", "out"), + vec![ Input::new("mc1", "out"), Input::new("mc2", "out"), Input::new("mc3", "out"), Input::new("mc4", "out"), ], - }), + ), Constant::rc_new("mc1", (150.0, 270.0), 0), Constant::rc_new("mc2", (150.0, 290.0), 1), Constant::rc_new("mc3", (150.0, 310.0), 2), diff --git a/mips/src/components/instr_mem.rs b/mips/src/components/instr_mem.rs index 51c74df5..284d3416 100644 --- a/mips/src/components/instr_mem.rs +++ b/mips/src/components/instr_mem.rs @@ -4,10 +4,10 @@ use syncrim::common::{Component, Input, OutputType, Ports, SignalData, SignalUns #[derive(Serialize, Deserialize)] pub struct InstrMem { - id: String, + pub(crate) id: String, pub(crate) pos: (f32, f32), - pc: Input, - instr: Vec, + pub(crate) pc: Input, + pub(crate) instr: Vec, } use log::*; diff --git a/mips/src/components/reg_file.rs b/mips/src/components/reg_file.rs index dce02c66..da12e144 100644 --- a/mips/src/components/reg_file.rs +++ b/mips/src/components/reg_file.rs @@ -46,21 +46,21 @@ pub enum Reg { #[derive(Serialize, Deserialize)] pub struct RegFile { - id: String, + pub(crate) id: String, pub(crate) pos: (f32, f32), pub(crate) width: f32, pub(crate) height: f32, // ports - read_addr1: Input, - read_addr2: Input, - write_data: Input, - write_addr: Input, - write_enable: Input, + pub(crate) read_addr1: Input, + pub(crate) read_addr2: Input, + pub(crate) write_data: Input, + pub(crate) write_addr: Input, + pub(crate) write_enable: Input, // data - pub registers: RegStore, - pub history: RegHistory, + pub(crate) registers: RegStore, + pub(crate) history: RegHistory, } #[derive(Serialize, Deserialize, Clone)] diff --git a/src/components/add.rs b/src/components/add.rs index 0ea50984..702739c9 100644 --- a/src/components/add.rs +++ b/src/components/add.rs @@ -7,10 +7,10 @@ use std::rc::Rc; #[derive(Serialize, Deserialize)] pub struct Add { - id: Id, + pub(crate) id: Id, pub(crate) pos: (f32, f32), - a_in: Input, - b_in: Input, + pub(crate) a_in: Input, + pub(crate) b_in: Input, } #[typetag::serde] diff --git a/src/components/constant.rs b/src/components/constant.rs index e23c1e9d..e0598f5d 100644 --- a/src/components/constant.rs +++ b/src/components/constant.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use std::{convert::Into, rc::Rc}; #[derive(Serialize, Deserialize)] pub struct Constant { - id: Id, + pub(crate) id: Id, pub(crate) pos: (f32, f32), pub(crate) value: Signal, } diff --git a/src/components/mem.rs b/src/components/mem.rs index fe2b0844..19ef54d0 100644 --- a/src/components/mem.rs +++ b/src/components/mem.rs @@ -9,7 +9,7 @@ use std::{cell::RefCell, collections::HashMap, convert::TryFrom, rc::Rc}; #[derive(Serialize, Deserialize)] pub struct Mem { - id: Id, + pub(crate) id: Id, pub(crate) pos: (f32, f32), pub(crate) width: f32, pub(crate) height: f32, @@ -18,18 +18,19 @@ pub struct Mem { pub big_endian: bool, // ports - data: Input, - addr: Input, - ctrl: Input, - sext: Input, - size: Input, + pub(crate) data: Input, + pub(crate) addr: Input, + pub(crate) ctrl: Input, + pub(crate) sext: Input, + pub(crate) size: Input, // memory - memory: Memory, + pub(crate) memory: Memory, // later history... tbd } impl Mem { + #[allow(clippy::too_many_arguments)] pub fn new( id: &str, pos: (f32, f32), @@ -57,6 +58,7 @@ impl Mem { } } + #[allow(clippy::too_many_arguments)] pub fn rc_new( id: &str, pos: (f32, f32), diff --git a/src/components/mux.rs b/src/components/mux.rs index c8844547..7403a410 100644 --- a/src/components/mux.rs +++ b/src/components/mux.rs @@ -7,10 +7,10 @@ use std::rc::Rc; #[derive(Serialize, Deserialize)] pub struct Mux { - pub id: Id, - pub pos: (f32, f32), - pub select: Input, - pub m_in: Vec, + pub(crate) id: Id, + pub(crate) pos: (f32, f32), + pub(crate) select: Input, + pub(crate) m_in: Vec, } #[typetag::serde] diff --git a/src/components/probe.rs b/src/components/probe.rs index ac3bf45d..0d5259cf 100644 --- a/src/components/probe.rs +++ b/src/components/probe.rs @@ -4,9 +4,9 @@ use serde::{Deserialize, Serialize}; use std::rc::Rc; #[derive(Serialize, Deserialize)] pub struct Probe { - pub id: Id, - pub pos: (f32, f32), - pub input: Input, + pub(crate) id: Id, + pub(crate) pos: (f32, f32), + pub(crate) input: Input, } #[typetag::serde] diff --git a/src/components/probe_assert.rs b/src/components/probe_assert.rs index 29c5506f..31ea1bea 100644 --- a/src/components/probe_assert.rs +++ b/src/components/probe_assert.rs @@ -5,10 +5,10 @@ use std::rc::Rc; #[derive(Serialize, Deserialize)] pub struct ProbeAssert { - pub id: Id, - pub pos: (f32, f32), - pub input: Input, - pub values: Vec, + pub(crate) id: Id, + pub(crate) pos: (f32, f32), + pub(crate) input: Input, + pub(crate) values: Vec, } #[typetag::serde] diff --git a/src/components/probe_edit.rs b/src/components/probe_edit.rs index e0e6b181..4fea58f6 100644 --- a/src/components/probe_edit.rs +++ b/src/components/probe_edit.rs @@ -8,9 +8,9 @@ use std::{ #[derive(Serialize, Deserialize, Clone)] pub struct ProbeEdit { - pub id: Id, - pub pos: (f32, f32), - pub edit_history: Arc>>, // will contain the next editable value + pub(crate) id: Id, + pub(crate) pos: (f32, f32), + pub(crate) edit_history: Arc>>, // will contain the next editable value } #[derive(Serialize, Deserialize, Clone, Debug)] diff --git a/src/components/probe_out.rs b/src/components/probe_out.rs index 1fedf4ca..9c07361d 100644 --- a/src/components/probe_out.rs +++ b/src/components/probe_out.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] pub struct ProbeOut { - pub id: Id, + pub(crate) id: Id, } #[typetag::serde] diff --git a/src/components/probe_stim.rs b/src/components/probe_stim.rs index 7637fea2..2c7a59fd 100644 --- a/src/components/probe_stim.rs +++ b/src/components/probe_stim.rs @@ -5,9 +5,9 @@ use std::rc::Rc; #[derive(Serialize, Deserialize)] pub struct ProbeStim { - pub id: Id, - pub pos: (f32, f32), - pub values: Vec, + pub(crate) id: Id, + pub(crate) pos: (f32, f32), + pub(crate) values: Vec, } #[typetag::serde] diff --git a/src/components/register.rs b/src/components/register.rs index e04893b1..5dd0e2b6 100644 --- a/src/components/register.rs +++ b/src/components/register.rs @@ -5,9 +5,9 @@ use std::rc::Rc; #[derive(Serialize, Deserialize)] pub struct Register { - pub id: Id, - pub pos: (f32, f32), - pub r_in: Input, + pub(crate) id: Id, + pub(crate) pos: (f32, f32), + pub(crate) r_in: Input, } #[typetag::serde] diff --git a/src/components/sext.rs b/src/components/sext.rs index 37f9f8bd..b24b946c 100644 --- a/src/components/sext.rs +++ b/src/components/sext.rs @@ -7,11 +7,11 @@ use serde::{Deserialize, Serialize}; use std::rc::Rc; #[derive(Serialize, Deserialize)] pub struct Sext { - pub id: Id, - pub pos: (f32, f32), - pub sext_in: Input, - pub in_size: u32, - pub out_size: u32, + pub(crate) id: Id, + pub(crate) pos: (f32, f32), + pub(crate) sext_in: Input, + pub(crate) in_size: u32, + pub(crate) out_size: u32, } #[typetag::serde] diff --git a/src/components/wire.rs b/src/components/wire.rs index 75e9e225..0f5c4cc1 100644 --- a/src/components/wire.rs +++ b/src/components/wire.rs @@ -4,9 +4,9 @@ use serde::{Deserialize, Serialize}; use std::rc::Rc; #[derive(Serialize, Deserialize)] pub struct Wire { - pub id: Id, - pub pos: Vec<(f32, f32)>, - pub input: Input, + pub(crate) id: Id, + pub(crate) pos: Vec<(f32, f32)>, + pub(crate) input: Input, } #[typetag::serde] diff --git a/src/gui_egui/components/mod.rs b/src/gui_egui/components/mod.rs index 849105bb..11a74478 100644 --- a/src/gui_egui/components/mod.rs +++ b/src/gui_egui/components/mod.rs @@ -4,7 +4,9 @@ mod mem; mod mux; mod probe; mod probe_assert; +mod probe_edit; mod probe_out; +mod probe_stim; mod register; mod sext; mod wire; diff --git a/src/gui_egui/components/probe_edit.rs b/src/gui_egui/components/probe_edit.rs new file mode 100644 index 00000000..9e7eb49c --- /dev/null +++ b/src/gui_egui/components/probe_edit.rs @@ -0,0 +1,5 @@ +use crate::common::EguiComponent; +use crate::components::ProbeEdit; + +#[typetag::serde] +impl EguiComponent for ProbeEdit {} diff --git a/src/gui_egui/components/probe_stim.rs b/src/gui_egui/components/probe_stim.rs new file mode 100644 index 00000000..b28797fa --- /dev/null +++ b/src/gui_egui/components/probe_stim.rs @@ -0,0 +1,5 @@ +use crate::common::EguiComponent; +use crate::components::ProbeStim; + +#[typetag::serde] +impl EguiComponent for ProbeStim {} From cb277238da7ce393bd1d73e206c5cbcbb82e0434 Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Thu, 27 Jul 2023 19:29:05 +0200 Subject: [PATCH 13/14] vizia bug? (fix) --- mips/src/gui_vizia/components/reg_file.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/mips/src/gui_vizia/components/reg_file.rs b/mips/src/gui_vizia/components/reg_file.rs index 25011341..983e0c3e 100644 --- a/mips/src/gui_vizia/components/reg_file.rs +++ b/mips/src/gui_vizia/components/reg_file.rs @@ -104,6 +104,7 @@ impl ViziaComponent for RegFile { }, ) .position_type(PositionType::SelfDirected) + .overflow(Overflow::Hidden) .left(Pixels(self.pos.0 - self.width / 2.0)) .top(Pixels(self.pos.1 - self.height / 2.0)) .background_color(Color::lightgrey()) From 4a7c9d3bb76a3cf6c2a21c9f5fa2b474def5a1e4 Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Thu, 27 Jul 2023 19:42:34 +0200 Subject: [PATCH 14/14] CHANGELOG --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a12ca6be..14b51988 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ Tracking changes per date: +## 230727 + +- `Signal` type now incorporates formatting. This allows the default formatting to be set on a signal on creation. The data and formatting can be read/written separately by setters/getters. + +- Internal component fields are now `pub(crate)`. This allows internal component structure to be hidden outside the crate, thus examples and other users cannot affect the component state, also we are free to change internal repr without affecting examples/users (given that the API can remain stable). + +- `rc_new` implemented for all components. (Examples updated.) We might want to change `new` to `_new` and `rc_new` to `new`. + ## 230725 - Implemented the `ProbeAssert` component, that assert a set sequence of inputs. Made some updates so reading outside of the assert/stim buffers gives `Signal::Unknown` instead of panic (if not in test mode).