diff --git a/src/vcd/parse.rs b/src/vcd/parse.rs index ef2ec61..7229045 100644 --- a/src/vcd/parse.rs +++ b/src/vcd/parse.rs @@ -2,7 +2,6 @@ // This program is distributed under both the GPLV3 license // and the YEHOWSHUA license, both of which can be found at // the root of the folder containing the sources for this program. -use std::fs::File; mod combinator_atoms; mod types; diff --git a/src/vcd/parse/scopes.rs b/src/vcd/parse/scopes.rs index 00a087e..c60deda 100644 --- a/src/vcd/parse/scopes.rs +++ b/src/vcd/parse/scopes.rs @@ -20,6 +20,7 @@ pub(super) fn parse_var<'a, R: std::io::Read>( parent_scope_idx: ScopeIdx, vcd: &'a mut VCD, signal_map: &mut HashMap, + path: &Vec, ) -> Result<(), String> { let (word, cursor) = next_word!(word_reader)?; let expected_types = [ @@ -120,7 +121,8 @@ pub(super) fn parse_var<'a, R: std::io::Read>( Some(ref_signal_idx) => { let signal_idx = SignalIdx(vcd.all_signals.len()); let signal = SignalEnum::Alias { - name: full_signal_name, + name: full_signal_name.clone(), + path: path.iter().cloned().chain([full_signal_name]).collect::>(), signal_alias: *ref_signal_idx, }; (signal, signal_idx) @@ -129,11 +131,12 @@ pub(super) fn parse_var<'a, R: std::io::Read>( let signal_idx = SignalIdx(vcd.all_signals.len()); signal_map.insert(signal_alias.to_string(), signal_idx); let signal = SignalEnum::Data { - name: full_signal_name, + name: full_signal_name.clone(), + path: path.iter().cloned().chain([full_signal_name]).collect::>(), sig_type: var_type, signal_error: None, - num_bits: num_bits, - num_bytes: num_bytes, + num_bits, + num_bytes, self_idx: signal_idx, nums_encoded_as_fixed_width_le_u8: vec![], string_vals: vec![], @@ -141,7 +144,6 @@ pub(super) fn parse_var<'a, R: std::io::Read>( byte_len_of_num_tmstmp_vals_on_tmln: vec![], byte_len_of_string_tmstmp_vals_on_tmln: vec![], lsb_indxs_of_string_tmstmp_vals_on_tmln: vec![], - scope_parent: parent_scope_idx, }; (signal, signal_idx) } @@ -185,7 +187,6 @@ fn parse_orphaned_vars<'a, R: std::io::Read>( if !scope_already_exists { vcd.all_scopes.push(Scope { name: scope_name.to_string(), - parent_idx: None, self_idx: scope_idx, child_signals: vec![], child_scopes: vec![], @@ -195,14 +196,14 @@ fn parse_orphaned_vars<'a, R: std::io::Read>( // we can go ahead and parse the current var as we've already encountered // "$var" before now. - parse_var(word_reader, scope_idx, vcd, signal_map)?; + parse_var(word_reader, scope_idx, vcd, signal_map, &vec![])?; loop { let (word, cursor) = next_word!(word_reader)?; match word { "$var" => { - parse_var(word_reader, scope_idx, vcd, signal_map)?; + parse_var(word_reader, scope_idx, vcd, signal_map, &vec![])?; } "$scope" => break, _ => { @@ -226,6 +227,7 @@ fn parse_scopes_inner<'a, R: std::io::Read>( parent_scope_idx: Option, vcd: &'a mut VCD, signal_map: &mut HashMap, + path: &Vec ) -> Result<(), String> { // $scope module reg_mag_i $end // ^^^^^^ - module keyword @@ -249,6 +251,9 @@ fn parse_scopes_inner<'a, R: std::io::Read>( // ^^^^^^^^^ - scope name let (scope_name, _) = next_word!(word_reader)?; + let mut path = path.clone(); + path.push(scope_name.to_string()); + let curr_scope_idx = ScopeIdx(vcd.all_scopes.len()); // register this scope as a child of the current parent scope @@ -265,7 +270,6 @@ fn parse_scopes_inner<'a, R: std::io::Read>( // add this scope to list of existing scopes vcd.all_scopes.push(Scope { name: scope_name.to_string(), - parent_idx: parent_scope_idx, self_idx: curr_scope_idx, child_signals: vec![], child_scopes: vec![], @@ -275,6 +279,8 @@ fn parse_scopes_inner<'a, R: std::io::Read>( // ^^^^ - end keyword ident(word_reader, "$end")?; + + loop { let (word, cursor) = next_word!(word_reader)?; let ParseResult { matched, residual } = tag(word, "$"); @@ -284,10 +290,10 @@ fn parse_scopes_inner<'a, R: std::io::Read>( match residual { "scope" => { // recursive - parse inside of current scope tree - parse_scopes_inner(word_reader, Some(curr_scope_idx), vcd, signal_map)?; + parse_scopes_inner(word_reader, Some(curr_scope_idx), vcd, signal_map, &path)?; } "var" => { - parse_var(word_reader, curr_scope_idx, vcd, signal_map)?; + parse_var(word_reader, curr_scope_idx, vcd, signal_map, &path)?; } "upscope" => { ident(word_reader, "$end")?; @@ -360,7 +366,7 @@ pub(super) fn parse_scopes<'a, R: std::io::Read>( } // now for the interesting part - parse_scopes_inner(word_reader, None, vcd, signal_map)?; + parse_scopes_inner(word_reader, None, vcd, signal_map, &vec![])?; // let err = format!("reached end of file without parser leaving {}", function_name!()); let expected_keywords = ["$scope", "$enddefinitions"]; @@ -374,7 +380,7 @@ pub(super) fn parse_scopes<'a, R: std::io::Read>( match word { "$scope" => { - parse_scopes_inner(word_reader, None, vcd, signal_map)?; + parse_scopes_inner(word_reader, None, vcd, signal_map, &vec![])?; } "$enddefinitions" => { ident(word_reader, "$end")?; diff --git a/src/vcd/signal.rs b/src/vcd/signal.rs index 503e0f2..0ac29ef 100644 --- a/src/vcd/signal.rs +++ b/src/vcd/signal.rs @@ -2,9 +2,9 @@ // This program is distributed under both the GPLV3 license // and the YEHOWSHUA license, both of which can be found at // the root of the folder containing the sources for this program. -use super::types::{ScopeIdx, SignalIdx}; +use super::types::SignalIdx; use super::types; -use num::{BigUint}; +use num::BigUint; // Index to the least significant byte of a timestamp // value on the timeline @@ -37,6 +37,13 @@ impl<'a> Signal<'a> { signal_enum.name() } + pub fn path(&self) -> &[String] { + match self.0 { + SignalEnum::Data {path, ..} => path, + SignalEnum::Alias { path, .. } => path, + } + } + pub fn num_bits(&self) -> Option { let Signal(signal_enum) = &self; signal_enum.bits_required() @@ -101,6 +108,7 @@ impl<'a> Signal<'a> { pub(super) enum SignalEnum { Data { name: String, + path: Vec, sig_type: SigType, /// I've seen a 0 bit signal parameter in a xilinx /// simulation before that gets assigned 1 bit values. @@ -136,10 +144,10 @@ pub(super) enum SignalEnum { byte_len_of_num_tmstmp_vals_on_tmln: Vec, byte_len_of_string_tmstmp_vals_on_tmln: Vec, lsb_indxs_of_string_tmstmp_vals_on_tmln: Vec, - scope_parent: ScopeIdx, }, Alias { name: String, + path: Vec, signal_alias: SignalIdx, }, } @@ -305,7 +313,7 @@ impl SignalEnum { match self { SignalEnum::Data {num_bits, ..} => num_bits.clone(), // TODO: Follow aliases? - SignalEnum::Alias { name, signal_alias } => None, + SignalEnum::Alias { .. } => None, } } } @@ -329,6 +337,7 @@ impl SignalEnum { Self::Alias { name: _, signal_alias, + path: _ } => { let SignalIdx(idx) = signal_alias; *idx @@ -443,6 +452,7 @@ impl SignalEnum { } Self::Alias { name: _, + path: _, signal_alias, } => { let SignalIdx(idx) = signal_alias; diff --git a/src/vcd/types.rs b/src/vcd/types.rs index d589e73..a53fb6c 100644 --- a/src/vcd/types.rs +++ b/src/vcd/types.rs @@ -40,7 +40,6 @@ pub struct SignalIdx(pub usize); pub(super) struct Scope { pub(super) name: String, - pub(super) parent_idx: Option, pub(super) self_idx: ScopeIdx, pub(super) child_signals: Vec,