Skip to content

Commit

Permalink
Merge pull request #85 from Spooky-Firefox/simulator_state
Browse files Browse the repository at this point in the history
Egui update and simulator state to keep track of component condition
  • Loading branch information
onsdagens authored Sep 11, 2024
2 parents c7cc820 + 0b624ec commit 1e04d8c
Show file tree
Hide file tree
Showing 23 changed files with 445 additions and 248 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

Tracking changes per date:

## 240911
- Added so that simulator now tracks what component condition
- Added simulator running state, such as running, halt or error
- Added stepping functionality
- Added functionality to gui to show running state and component condition

## 240909

- Added un-clock history for set of active components
Expand Down
14 changes: 4 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ serde_derive = "1.0.171"
serde_json = "1.0.103"
typetag = "0.2.10"


[dependencies.vizia]
git = "https://github.com/vizia/vizia.git"
rev = "7093bfd518c4bee5544a75c2ffc92dfe4f817bc0"
Expand All @@ -30,26 +29,21 @@ optional = true

[dependencies.egui]
optional = true
version = "0.23.0"

[dependencies.winapi]
optional = true
version = "0.3.9"
features = ["winuser"]
version = "0.28.0"

[dependencies.eframe]
optional = true
version = "0.23.0"
version = "0.28.0"

[dependencies.epaint]
optional = true
version = "0.23.0"
version = "0.28.0"

[features]
default = ["gui-egui"]
components = []
gui-vizia = ["vizia", "components"]
gui-egui = ["egui", "eframe", "epaint", "winapi", "components"]
gui-egui = ["egui", "eframe", "epaint", "components"]

[profile.dev]
debug = 1 # faster build, still allows for stack back trace
Expand Down
4 changes: 4 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ Each target (e.g. `mips`, has a separate `TODO.md`).
- Better tooltips for components. (Complexity moderate.)

- Better popups for components. (Complexity moderate.)

## Egui

- Add better formatted tooltip for probe, maybe use ``LayoutJob``, if style is not respected maybe force to ``galley`` (Complexity low, but weird egui stuff)
4 changes: 2 additions & 2 deletions riscv/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ log = "0.4.19"
num_enum = "0.7.2"
fern = "0.6.2"
xmas-elf = "0.9.0"
egui = "0.23.0"
egui = "0.28.0"
asm_riscv = { git = 'https://github.com/onsdagens/wari' }
gimli = "0.27.3"
object = "0.31.1"
memmap2 = "0.7.1"
riscv_asm_strings = { git = 'https://github.com/perlindgren/riscv_asm_strings' }
priority-queue = { version = "1.3.2", features = ["serde"] }
riscv-rt = "0.11.0"
egui_extras = "0.23.0"
egui_extras = "0.28.0"

[dependencies.syncrim]
path = "../"
Expand Down
173 changes: 85 additions & 88 deletions riscv/src/gui_egui/components/instr_mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,98 +44,95 @@ impl InstrMem {
});
})
.body(|body| {
body.rows(
15.0,
(self.range.end - self.range.start) / 4,
|index, mut row| {
let address = index * 4 + self.range.start;
let pc: u32 = {
if simulator.as_ref().is_some() {
simulator
.as_ref()
.unwrap()
.get_input_value(&self.pc)
.try_into()
.unwrap_or(0)
} else {
0
}
};
let (bg_color, fg_color) = {
if pc as usize == address {
(Color32::DARK_GRAY, Color32::WHITE)
} else {
(Color32::TRANSPARENT, Color32::LIGHT_GRAY)
}
};
let breakpoint_color = {
if self.breakpoints.borrow_mut().contains(&address) {
Color32::RED
} else {
Color32::TRANSPARENT
}
};
row.col(|ui| match &self.symbols.get(&address) {
Some(s) => {
ui.add(Label::new(format!("{}:", s)).truncate(true));
}
None => {}
});
//breakpoint
row.col(|ui| {
ui.label(RichText::new("•").color(breakpoint_color));
});
//address
row.col(|ui| {
ui.add(Label::new(format!("0x{:08x}", address)).truncate(true));
});
let mut bytes = [0u8; 4];
if !self.le {
bytes[3] = *self.bytes.get(&address).unwrap();
bytes[2] = *self.bytes.get(&(address + 1)).unwrap();
bytes[1] = *self.bytes.get(&(address + 2)).unwrap();
bytes[0] = *self.bytes.get(&(address + 3)).unwrap();
body.rows(15.0, (self.range.end - self.range.start) / 4, |mut row| {
let index = row.index();
let address = index * 4 + self.range.start;
let pc: u32 = {
if simulator.as_ref().is_some() {
simulator
.as_ref()
.unwrap()
.get_input_value(&self.pc)
.try_into()
.unwrap_or(0)
} else {
0
}
};
let (bg_color, fg_color) = {
if pc as usize == address {
(Color32::DARK_GRAY, Color32::WHITE)
} else {
(Color32::TRANSPARENT, Color32::LIGHT_GRAY)
}
};
let breakpoint_color = {
if self.breakpoints.borrow_mut().contains(&address) {
Color32::RED
} else {
bytes[0] = *self.bytes.get(&address).unwrap();
bytes[1] = *self.bytes.get(&(address + 1)).unwrap();
bytes[2] = *self.bytes.get(&(address + 2)).unwrap();
bytes[3] = *self.bytes.get(&(address + 3)).unwrap();
Color32::TRANSPARENT
}
};
row.col(|ui| match &self.symbols.get(&address) {
Some(s) => {
ui.add(Label::new(format!("{}:", s)).truncate());
}
let instr = ((bytes[3] as u32) << 24)
| ((bytes[2] as u32) << 16)
| ((bytes[1] as u32) << 8)
| (bytes[0] as u32);
None => {}
});
//breakpoint
row.col(|ui| {
ui.label(RichText::new("•").color(breakpoint_color));
});
//address
row.col(|ui| {
ui.add(Label::new(format!("0x{:08x}", address)).truncate());
});
let mut bytes = [0u8; 4];
if !self.le {
bytes[3] = *self.bytes.get(&address).unwrap();
bytes[2] = *self.bytes.get(&(address + 1)).unwrap();
bytes[1] = *self.bytes.get(&(address + 2)).unwrap();
bytes[0] = *self.bytes.get(&(address + 3)).unwrap();
} else {
bytes[0] = *self.bytes.get(&address).unwrap();
bytes[1] = *self.bytes.get(&(address + 1)).unwrap();
bytes[2] = *self.bytes.get(&(address + 2)).unwrap();
bytes[3] = *self.bytes.get(&(address + 3)).unwrap();
}
let instr = ((bytes[3] as u32) << 24)
| ((bytes[2] as u32) << 16)
| ((bytes[1] as u32) << 8)
| (bytes[0] as u32);

let instr_fmt = match asm_riscv::I::try_from(instr) {
Ok(i) => riscv_asm_strings::StringifyUpperHex::to_string(&i),
Err(_) => "Unknown instruction".to_string(),
};
//hex instr
row.col(|ui| {
ui.add(Label::new(format!("0x{:08X}", instr)).truncate(true));
});
row.col(|ui| {
if ui
.add(
Label::new(
RichText::new(instr_fmt)
.color(fg_color)
.background_color(bg_color),
)
.truncate(true)
.sense(Sense::click()),
let instr_fmt = match asm_riscv::I::try_from(instr) {
Ok(i) => riscv_asm_strings::StringifyUpperHex::to_string(&i),
Err(_) => "Unknown instruction".to_string(),
};
//hex instr
row.col(|ui| {
ui.add(Label::new(format!("0x{:08X}", instr)).truncate());
});
row.col(|ui| {
if ui
.add(
Label::new(
RichText::new(instr_fmt)
.color(fg_color)
.background_color(bg_color),
)
.clicked()
{
trace!("clicked");
if !self.breakpoints.borrow_mut().remove(&address) {
self.breakpoints.borrow_mut().insert(address);
}
};
});
row.col(|_| {});
},
);
.truncate()
.sense(Sense::click()),
)
.clicked()
{
trace!("clicked");
if !self.breakpoints.borrow_mut().remove(&address) {
self.breakpoints.borrow_mut().insert(address);
}
};
});
row.col(|_| {});
});
});
});
}
Expand Down
2 changes: 1 addition & 1 deletion riscv/src/gui_egui/components/probe_label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl EguiComponent for ProbeLabel {
Some(s) => s.get_input_value(&input),
None => SignalValue::Uninitialized,
};
let area = Area::new(self.id.to_string())
let area = Area::new(self.id.clone().into())
.order(Order::Middle)
.current_pos(offset.to_pos2())
.movable(false)
Expand Down
3 changes: 2 additions & 1 deletion riscv/src/gui_egui/components/reg_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ impl EguiComponent for RegFile {
15.0 * scale,
RegStore::lo_range().end as usize
- RegStore::lo_range().start as usize,
|index, mut row| {
|mut row| {
let index = row.index();
row.col(|ui| {
ui.add(Label::new(
RichText::new(format!(
Expand Down
8 changes: 4 additions & 4 deletions riscv/src/gui_egui/components/rv_mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ impl RVMem {
body.rows(
15.0,
((self.range.end - self.range.start) / 4) as usize,
|index, mut row| {
//println!("{}", index);
|mut row| {
let index = row.index();
let address = self.range.start as usize + index * 4;
let memory = self.memory.0.borrow().clone();
row.col(|ui| {
Expand Down Expand Up @@ -68,10 +68,10 @@ impl RVMem {
}
}
row.col(|ui| {
ui.add(Label::new(word).truncate(true));
ui.add(Label::new(word).truncate());
});
row.col(|ui| {
ui.add(Label::new(ascii).truncate(true));
ui.add(Label::new(ascii).truncate());
});
},
);
Expand Down
31 changes: 26 additions & 5 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ type Components = Vec<Rc<dyn ViziaComponent>>;
#[cfg(feature = "gui-egui")]
pub type Components = Vec<Rc<dyn EguiComponent>>;

pub enum SimulatorError {
RunningStateIsErr(),
}
#[derive(PartialEq, Clone, Debug)]
pub enum RunningState {
Running,
StepTo(usize),
Halt,
Err,
Stopped,
}

#[cfg_attr(feature = "gui-vizia", derive(Lens))]
#[derive(Clone)]
pub struct Simulator {
Expand All @@ -40,8 +52,17 @@ pub struct Simulator {
pub history: Vec<(Vec<Signal>, HashSet<Id>)>,
pub component_ids: Vec<Id>,
pub graph: Graph<Id, ()>,
// Running state, (do we need it accessible from other crates?)
pub(crate) running: bool,

// if set to true, running state is set to Halt when a component returns Warning
// pub(crate) might not be needed but easier than implementing setters and getters
pub(crate) halt_on_warning: bool,
// says if simulation is running, halted, stopped or stepping to a specific cycle
pub running_state: RunningState,
pub running_state_history: Vec<RunningState>,
// stores if components return a condition
// TODO add component condition history
pub component_condition: Vec<(Id, Condition)>,
pub component_condition_history: Vec<Vec<(Id, Condition)>>,

// Used to determine active components
pub sinks: Vec<Id>,
Expand Down Expand Up @@ -101,12 +122,12 @@ pub trait Component {
fn as_any(&self) -> &dyn Any;
}

#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub enum Condition {
Warning(String),
Error(String),
Assert(String),
Halt(String),
Assert(String),
Error(String),
}

#[cfg(feature = "gui-egui")]
Expand Down
Loading

0 comments on commit 1e04d8c

Please sign in to comment.