Refactor signal #6

Merged
ThePerfectComputer merged 5 commits from refactor-signal into main 2022-10-26 06:23:08 +00:00
4 changed files with 51 additions and 80 deletions
Showing only changes of commit b4cbbf29cc - Show all commits

View file

@ -92,11 +92,8 @@ Here's a command to test on a malformed VCD:
- [ ] once the access patterns of the GUI frontend are well understood, - [ ] once the access patterns of the GUI frontend are well understood,
create specific functions and restrict as many types to private create specific functions and restrict as many types to private
as possible as possible
- [ ] be explicit with imports, remove exports as possible
once FastWave is known to be fairly stable.
- [ ] Print out git commit or release number. - [ ] Print out git commit or release number.
- [ ] do a read through all the code - look for uneeded code - [ ] do a read through all the code - look for uneeded code
- [ ] Take a look at GTKWave parser to compare efficiency.
- [ ] Move part of the performance section to another markdown file. - [ ] Move part of the performance section to another markdown file.
## Repairs ## Repairs
@ -108,7 +105,6 @@ Here's a command to test on a malformed VCD:
able to successfully parse all sample VCDs. able to successfully parse all sample VCDs.
## Code Consistency ## Code Consistency
- [ ] split impls in signal.rs into groups
- [ ] Change error messages to line and filenames. Go through all calls to unwrap. - [ ] Change error messages to line and filenames. Go through all calls to unwrap.
- [ ] search for any unwraps or any direct vectors indexing - [ ] search for any unwraps or any direct vectors indexing
- [ ] Handle TODOs - [ ] Handle TODOs

View file

@ -4,7 +4,7 @@
// the root of the folder containing the sources for this program. // the root of the folder containing the sources for this program.
use std::fs::File; use std::fs::File;
use fastwave_backend::{ScopeIdx, VCD, parse_vcd}; use fastwave_backend::{ScopeIdx, VCD, parse_vcd, SignalIdx};
fn indented_print(indent : u8, name : &String) { fn indented_print(indent : u8, name : &String) {
for _ in 0..indent {print!(" |");} for _ in 0..indent {print!(" |");}
@ -12,29 +12,26 @@ fn indented_print(indent : u8, name : &String) {
println!("{name}"); println!("{name}");
} }
fn print_root_scope_tree(root_idx: ScopeIdx, vcd: &VCD, indent : u8) { // TODO: refactor into more general visitor pattern that takes a
if vcd.child_scopes_by_idx(root_idx).is_empty() { // function as an argument.
} else { fn visit_all_scopes(vcd: &VCD) {
for child_scope_idx in vcd.child_scopes_by_idx(root_idx) { fn visit_all_scope_children(root_idx: ScopeIdx, vcd: &VCD, indent : u8) {
indented_print(indent, vcd.scope_name_by_idx(child_scope_idx)); if vcd.child_scopes_by_idx(root_idx).is_empty() {
// for signal_idx in vcd.get_children_signal_idxs(child_scope_idx) { } else {
// let signal = vcd.try_signal_idx_to_signal(signal_idx).unwrap(); for child_scope_idx in vcd.child_scopes_by_idx(root_idx) {
// match signal { indented_print(indent, vcd.scope_name_by_idx(child_scope_idx));
// Signal::Data {..} => {} for signal_idx in vcd.get_children_signal_idxs(child_scope_idx) {
// Signal::Alias {..} => {} let signal = vcd.signal_from_signal_idx(signal_idx);
// } let SignalIdx(idx) = signal_idx;
// // let to_print = format!("{},{}", signal.name(), ) indented_print(indent + 1, &format!("{},{}", signal.name(), idx));
// } }
// vcd.try_signal_idx_to_signal(idx) visit_all_scope_children(child_scope_idx, vcd.clone(), indent + 1);
print_root_scope_tree(child_scope_idx, vcd.clone(), indent + 1); }
} }
} }
}
fn ui_all_scopes(vcd: &VCD) {
for root_scope_idx in vcd.root_scopes_by_idx() { for root_scope_idx in vcd.root_scopes_by_idx() {
indented_print(0, vcd.scope_name_by_idx(root_scope_idx)); indented_print(0, vcd.scope_name_by_idx(root_scope_idx));
print_root_scope_tree(root_scope_idx, vcd, 1u8); visit_all_scope_children(root_scope_idx, vcd, 1u8);
} }
} }
@ -42,6 +39,8 @@ fn main() -> std::io::Result<()> {
use std::time::Instant; use std::time::Instant;
// we start by printing out the entire signal tree of
// a parsed VCD
let now = Instant::now(); let now = Instant::now();
let file_path = "tests/vcd-files/icarus/CPU.vcd"; let file_path = "tests/vcd-files/icarus/CPU.vcd";
let file = File::open(file_path)?; let file = File::open(file_path)?;
@ -50,25 +49,36 @@ fn main() -> std::io::Result<()> {
println!("Parsed VCD file {} : {:.2?}", file_path, elapsed); println!("Parsed VCD file {} : {:.2?}", file_path, elapsed);
println!("Printing Scopes"); println!("Printing Scopes");
ui_all_scopes(&vcd); visit_all_scopes(&vcd);
println!("Done Printing Scopes");
println!();
// we then parse another VCD, print its signal tree and
// query some values on its timeline
let now = Instant::now();
let file_path = "tests/vcd-files/amaranth/up_counter.vcd"; let file_path = "tests/vcd-files/amaranth/up_counter.vcd";
let file = File::open(file_path)?; let file = File::open(file_path)?;
let vcd = parse_vcd(file).unwrap(); let vcd = parse_vcd(file).unwrap();
// let state_signal = vcd.all_si let elapsed = now.elapsed();
// for signal_idx in vcd.si println!("Parsed VCD file {} : {:.2?}", file_path, elapsed);
// let name = state_signal.name();
// let time = BigUint::from(57760000u32);
// let val = state_signal
// .query_string_val_on_tmln(
// &time,
// &vcd.tmstmps_encoded_as_u8s,
// &vcd.all_signals,
// )
// .unwrap();
// println!("Signal `{name}` has value `{val}` at time `{time}`");
println!("Printing Scopes");
visit_all_scopes(&vcd);
println!("Done Printing Scopes");
let state_signal = vcd.signal_from_signal_idx(SignalIdx(4));
let name = state_signal.name();
let timestamps = vec![31499_000u32, 31500_000u32, 57760_000u32];
for timestamp in timestamps {
let time = num::BigUint::from(timestamp);
let val = state_signal
.query_string_val_on_tmln(&time, &vcd)
.unwrap();
println!("Signal `{name}` has value `{val}` at time `{time}`");
}
Ok(()) Ok(())
} }

View file

@ -39,20 +39,18 @@ impl<'a> Signal<'a> {
pub fn query_string_val_on_tmln( pub fn query_string_val_on_tmln(
&self, &self,
desired_time: &BigUint, desired_time: &BigUint,
tmstmps_encoded_as_u8s: &Vec<u8>,
vcd: &types::VCD, vcd: &types::VCD,
) -> Result<String, SignalErrors> { ) -> Result<String, SignalErrors> {
let Signal(signal_enum) = &self; let Signal(signal_enum) = &self;
signal_enum.query_string_val_on_tmln(desired_time, tmstmps_encoded_as_u8s, &vcd.all_signals) signal_enum.query_string_val_on_tmln(desired_time, &vcd.tmstmps_encoded_as_u8s, &vcd.all_signals)
} }
pub fn query_num_val_on_tmln( pub fn query_num_val_on_tmln(
&self, &self,
desired_time: &BigUint, desired_time: &BigUint,
tmstmps_encoded_as_u8s: &Vec<u8>,
vcd: &types::VCD, vcd: &types::VCD,
) -> Result<BigUint, SignalErrors> { ) -> Result<BigUint, SignalErrors> {
let Signal(signal_enum) = &self; let Signal(signal_enum) = &self;
signal_enum.query_num_val_on_tmln(desired_time, tmstmps_encoded_as_u8s, &vcd.all_signals) signal_enum.query_num_val_on_tmln(desired_time, &vcd.tmstmps_encoded_as_u8s, &vcd.all_signals)
} }
} }

View file

@ -33,7 +33,7 @@ pub struct Metadata {
pub struct ScopeIdx(pub usize); pub struct ScopeIdx(pub usize);
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
pub struct SignalIdx(pub(super) usize); pub struct SignalIdx(pub usize);
#[derive(Debug)] #[derive(Debug)]
pub(super) struct Scope { pub(super) struct Scope {
@ -84,6 +84,11 @@ impl VCD {
let scope = &self.all_scopes[idx]; let scope = &self.all_scopes[idx];
&scope.name &scope.name
} }
pub fn signal_from_signal_idx<'a>(&'a self, idx: SignalIdx) -> Signal<'a> {
let SignalIdx(idx) = idx;
let signal_enum = &self.all_signals[idx];
return Signal(signal_enum);
}
/// We take in a Signal and attempt to de-alias that signal if it is of /// We take in a Signal and attempt to de-alias that signal if it is of
/// variant ``Signal::Alias``. If it is of variant ``Signal::Alias`` and points to /// variant ``Signal::Alias``. If it is of variant ``Signal::Alias`` and points to
/// another alias, that's an error. Otherwise, we return the ``Signal::Data`` /// another alias, that's an error. Otherwise, we return the ``Signal::Data``
@ -116,42 +121,4 @@ impl VCD {
)), )),
} }
} }
pub fn get_signal<'a>(&'a self, idx: SignalIdx) -> Signal<'a> {
let SignalIdx(idx) = idx;
let signal_enum = &self.all_signals[idx];
return Signal(signal_enum);
}
// Takes a signal_idx as input and returns the corresponding signal if the
// corresponding signal is of the Signal::Data variant, else the function the
// SignalIdx in the signal_alias field of Signal::Alias variant to index
// into the signal arena in the all_signals field of the vcd, and returns
// the resulting signal if that signal is a Signal::Data variant, else,
// this function returns an Err.
// pub fn try_signal_idx_to_signal<'a>(
// &'a self,
// idx: SignalIdx,
// ) -> Result<&'a Signal, String> {
// // get the signal pointed to be SignalIdx from the arena
// let SignalIdx(idx) = idx;
// let signal = &self.all_signals[idx];
// // dereference signal if Signal::Alias, or keep idx if Signal::Data
// let signal_idx = match signal {
// Signal::Data { self_idx, .. } => *self_idx,
// Signal::Alias { name, signal_alias } => *signal_alias,
// };
// // Should now point to Signal::Data variant, or else there's an error
// let SignalIdx(idx) = signal_idx;
// let signal = self.all_signals.get(idx).unwrap();
// match signal {
// Signal::Data { .. } => Ok(signal),
// Signal::Alias { .. } => Err(format!(
// "Error near {}:{}. A signal alias shouldn't \
// point to a signal alias.",
// file!(),
// line!()
// )),
// }
// }
} }