From aeb796c46b1cf597a988afdc319524bb9e0bda17 Mon Sep 17 00:00:00 2001 From: Yehowshua Immanuel Date: Fri, 2 Sep 2022 15:05:33 -0400 Subject: [PATCH] ordered search now working --- src/vcd/parse.rs | 14 +++++++ src/vcd/parse/events.rs | 85 ++++++++++++++++++++++++++++++----------- src/vcd/parse/scopes.rs | 2 +- src/vcd/signal.rs | 40 ++++++++++++------- 4 files changed, 103 insertions(+), 38 deletions(-) diff --git a/src/vcd/parse.rs b/src/vcd/parse.rs index e3771d9..5260604 100644 --- a/src/vcd/parse.rs +++ b/src/vcd/parse.rs @@ -39,6 +39,20 @@ pub fn parse_vcd(file: File) -> Result { parse_scopes(&mut word_gen, &mut vcd, &mut signal_map)?; parse_events(&mut word_gen, &mut vcd, &mut signal_map)?; + let signal = vcd.try_dereference_alias(signal_map.get("Q").unwrap())?; + let name = match signal { + Signal::Data { name, .. } => name, + _ => "ERROR", + }; + let val = signal + .query_num_val_on_tmln( + BigUint::from(4687u32), + &vcd.tmstmps_encoded_as_u8s, + &vcd.all_signals, + ) + .unwrap(); + dbg!(format!("{val:#X}")); + dbg!(name); Ok(vcd) } diff --git a/src/vcd/parse/events.rs b/src/vcd/parse/events.rs index 8e3d18b..053a22b 100644 --- a/src/vcd/parse/events.rs +++ b/src/vcd/parse/events.rs @@ -1,3 +1,5 @@ +use num::Zero; + use super::*; pub(super) fn parse_events<'a>( @@ -7,6 +9,7 @@ pub(super) fn parse_events<'a>( ) -> Result<(), String> { let mut curr_tmstmp_lsb_idx = 0u32; let mut curr_tmstmp_len_u8 = 0u8; + let mut curr_time = BigUint::zero(); loop { let next_word = word_reader.next_word(); @@ -35,6 +38,7 @@ pub(super) fn parse_events<'a>( "Error near {f}:{l}. Failed to parse {value} as BigInt at {cursor:?}" ) })?; + curr_time = value.clone(); let mut value = value.to_bytes_le(); // TODO : u32 helps with less memory, but should ideally likely be // configurable. @@ -45,16 +49,15 @@ pub(super) fn parse_events<'a>( line!() ) })?; - vcd.tmstmps_encoded_as_u8s.append(&mut value); curr_tmstmp_lsb_idx = u32::try_from(vcd.tmstmps_encoded_as_u8s.len()).map_err(|_| { format!( - "Error near {}:{}. Failed to convert from usize to u8.", + "Error near {}:{}. Failed to convert from usize to u32.", file!(), line!() ) })?; - // curr_tmstmp_lsb_idx = vcd.tmstmps_encoded_as_u8s.len(); + vcd.tmstmps_encoded_as_u8s.append(&mut value); } // handle the case of an n bit signal whose value must be parsed @@ -111,10 +114,6 @@ pub(super) fn parse_events<'a>( let signal = vcd.try_dereference_alias_mut(signal_idx)?; - // we may have to dereference a signal if it's pointing at an alias - // let signal = &vcd.all_signals[*signal_idx]; - // let signal = signal.try_dereference_alias_mut(&vcd.all_signals)?; - match signal { Signal::Data { name, @@ -172,6 +171,19 @@ pub(super) fn parse_events<'a>( string_vals.push(value_string); Ok(()) } else { + // timestamp stuff + lsb_indxs_of_num_tmstmp_vals_on_tmln + .push(LsbIdxOfTmstmpValOnTmln(curr_tmstmp_lsb_idx)); + byte_len_of_num_tmstmp_vals_on_tmln.push(curr_tmstmp_len_u8); + + // value stuff + // we may need to zero extend values + // so that we end up storing all values + // of a particular signal in a consistent + // amount of bytes + let bytes_required = num_bytes.ok_or_else(|| { + format!("Error near {}:{}. num_bytes empty.", file!(), line!()) + })?; let mut curr_num_bytes = u8::try_from(value_u8.len()).map_err(|_| { format!( @@ -182,22 +194,12 @@ pub(super) fn parse_events<'a>( line!() ) })?; - lsb_indxs_of_num_tmstmp_vals_on_tmln - .push(LsbIdxOfTmstmpValOnTmln(curr_tmstmp_lsb_idx)); - - // we may need to zero extend values - // so that we end up storing all values - // of a particular signal in a consistent - // amount of bytes - let bytes_required = num_bytes.ok_or_else(|| { - format!("Error near {}:{}. num_bytes empty.", file!(), line!()) - })?; + nums_encoded_as_fixed_width_le_u8.append(&mut value_u8); while curr_num_bytes < bytes_required { nums_encoded_as_fixed_width_le_u8.push(0u8); curr_num_bytes += 1; } - byte_len_of_num_tmstmp_vals_on_tmln.push(curr_tmstmp_len_u8); Ok(()) } } @@ -231,6 +233,7 @@ pub(super) fn parse_events<'a>( sig_type, ref mut signal_error, num_bits, + num_bytes, nums_encoded_as_fixed_width_le_u8, lsb_indxs_of_num_tmstmp_vals_on_tmln, byte_len_of_num_tmstmp_vals_on_tmln, @@ -271,10 +274,25 @@ pub(super) fn parse_events<'a>( Err(msg)?; } }; - nums_encoded_as_fixed_width_le_u8.push(0u8); + // timestamp stuff lsb_indxs_of_num_tmstmp_vals_on_tmln .push(LsbIdxOfTmstmpValOnTmln(curr_tmstmp_lsb_idx)); byte_len_of_num_tmstmp_vals_on_tmln.push(curr_tmstmp_len_u8); + + // value stuff + // we may need to zero extend values + // so that we end up storing all values + // of a particular signal in a consistent + // amount of bytes + let bytes_required = num_bytes.ok_or_else(|| { + format!("Error near {}:{}. num_bytes empty.", file!(), line!()) + })?; + nums_encoded_as_fixed_width_le_u8.push(0u8); + let mut curr_num_bytes = 1; + while curr_num_bytes < bytes_required { + nums_encoded_as_fixed_width_le_u8.push(0u8); + curr_num_bytes += 1; + } Ok(()) } Signal::Alias { .. } => { @@ -306,6 +324,7 @@ pub(super) fn parse_events<'a>( sig_type, ref mut signal_error, num_bits, + num_bytes, nums_encoded_as_fixed_width_le_u8, lsb_indxs_of_num_tmstmp_vals_on_tmln, byte_len_of_num_tmstmp_vals_on_tmln, @@ -346,10 +365,25 @@ pub(super) fn parse_events<'a>( Err(msg)?; } }; - nums_encoded_as_fixed_width_le_u8.push(1u8); + // timestamp stuff lsb_indxs_of_num_tmstmp_vals_on_tmln .push(LsbIdxOfTmstmpValOnTmln(curr_tmstmp_lsb_idx)); byte_len_of_num_tmstmp_vals_on_tmln.push(curr_tmstmp_len_u8); + + // value stuff + // we may need to zero extend values + // so that we end up storing all values + // of a particular signal in a consistent + // amount of bytes + let bytes_required = num_bytes.ok_or_else(|| { + format!("Error near {}:{}. num_bytes empty.", file!(), line!()) + })?; + nums_encoded_as_fixed_width_le_u8.push(1u8); + let mut curr_num_bytes = 1; + while curr_num_bytes < bytes_required { + nums_encoded_as_fixed_width_le_u8.push(0u8); + curr_num_bytes += 1; + } Ok(()) } Signal::Alias { .. } => { @@ -362,7 +396,7 @@ pub(super) fn parse_events<'a>( }?; } - // other one bit cases + // // other one bit cases "x" | "X" | "z" | "Z" | "u" | "U" => { let val = word.to_string(); // lokup signal idx @@ -385,6 +419,7 @@ pub(super) fn parse_events<'a>( num_bits, string_vals, byte_len_of_num_tmstmp_vals_on_tmln, + byte_len_of_string_tmstmp_vals_on_tmln, lsb_indxs_of_string_tmstmp_vals_on_tmln, .. } => { @@ -423,10 +458,14 @@ pub(super) fn parse_events<'a>( Err(msg)?; } }; - string_vals.push(val); + + // record timestamp at which this event occurs lsb_indxs_of_string_tmstmp_vals_on_tmln .push(LsbIdxOfTmstmpValOnTmln(curr_tmstmp_lsb_idx)); - byte_len_of_num_tmstmp_vals_on_tmln.push(curr_tmstmp_len_u8); + byte_len_of_string_tmstmp_vals_on_tmln.push(curr_tmstmp_len_u8); + + // record value + string_vals.push(val); Ok(()) } Signal::Alias { .. } => { diff --git a/src/vcd/parse/scopes.rs b/src/vcd/parse/scopes.rs index a4cfc07..c48888c 100644 --- a/src/vcd/parse/scopes.rs +++ b/src/vcd/parse/scopes.rs @@ -122,8 +122,8 @@ pub(super) fn parse_var<'a>( string_vals: vec![], lsb_indxs_of_num_tmstmp_vals_on_tmln: vec![], byte_len_of_num_tmstmp_vals_on_tmln: vec![], - lsb_indxs_of_string_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) diff --git a/src/vcd/signal.rs b/src/vcd/signal.rs index b09fe3a..5582182 100644 --- a/src/vcd/signal.rs +++ b/src/vcd/signal.rs @@ -58,8 +58,8 @@ pub(super) enum Signal { // a particular timestamp is composed of. lsb_indxs_of_num_tmstmp_vals_on_tmln: Vec, byte_len_of_num_tmstmp_vals_on_tmln: Vec, - lsb_indxs_of_string_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 { @@ -76,9 +76,12 @@ pub(super) enum SignalErrors { }, EmptyTimeline, TimelineNotMultiple, - OrderingFailure, + OrderingFailure { + lhs_time: BigUint, + mid_time: BigUint, + rhs_time: BigUint, + }, PointsToAlias, - NoNumBits, NoNumBytes, Other(String), } @@ -100,9 +103,9 @@ impl Signal { })?; Ok(bytes_required) } - pub fn lookup_time_and_val( + pub(super) fn lookup_time_and_val( &self, - idx: usize, + event_idx: usize, tmstmps_encoded_as_u8s: &Vec, ) -> Result<(TimeStamp, SignalValNum), SignalErrors> { let ( @@ -127,25 +130,26 @@ impl Signal { }?; // get index - let LsbIdxOfTmstmpValOnTmln(timestamp_idx) = lsb_indxs_of_num_tmstmp_vals_on_tmln[idx]; + let LsbIdxOfTmstmpValOnTmln(timestamp_idx) = + lsb_indxs_of_num_tmstmp_vals_on_tmln[event_idx]; let timestamp_idx = timestamp_idx as usize; // form timestamp - let byte_len = byte_len_of_num_tmstmp_vals_on_tmln[timestamp_idx] as usize; + let byte_len = byte_len_of_num_tmstmp_vals_on_tmln[event_idx] as usize; let timestamp = &tmstmps_encoded_as_u8s[timestamp_idx..(timestamp_idx + byte_len)]; let timestamp = BigUint::from_bytes_le(timestamp); // get signal value let bytes_per_value = num_bytes.ok_or_else(|| SignalErrors::NoNumBytes)?; let bytes_per_value = bytes_per_value as usize; - let start_idx = idx * bytes_per_value; - let end_idx = (idx + 1) * bytes_per_value; + let start_idx = event_idx * bytes_per_value; + let end_idx = (event_idx + 1) * bytes_per_value; let signal_val = &nums_encoded_as_fixed_width_le_u8[start_idx..end_idx]; let signal_val = BigUint::from_bytes_le(signal_val); Ok((timestamp, signal_val)) } - pub(super) fn query_num_val_on_tmln( + pub fn query_num_val_on_tmln( &self, desired_time: BigUint, tmstmps_encoded_as_u8s: &Vec, @@ -199,9 +203,13 @@ impl Signal { line!() )) })?; - if lsb_indxs_of_num_tmstmp_vals_on_tmln.len() - != (nums_encoded_as_fixed_width_le_u8.len() * bytes_required as usize) + if nums_encoded_as_fixed_width_le_u8.len() + != (lsb_indxs_of_num_tmstmp_vals_on_tmln.len() * (bytes_required as usize)) { + dbg!(( + nums_encoded_as_fixed_width_le_u8.len(), + (lsb_indxs_of_num_tmstmp_vals_on_tmln.len() * (bytes_required as usize)) + )); return Err(SignalErrors::TimelineNotMultiple); } @@ -252,12 +260,16 @@ impl Signal { let (left_time, left_val) = self.lookup_time_and_val(lower_idx - 1, tmstmps_encoded_as_u8s)?; - let (right_time, _) = self.lookup_time_and_val(lower_idx - 1, tmstmps_encoded_as_u8s)?; + let (right_time, _) = self.lookup_time_and_val(lower_idx, tmstmps_encoded_as_u8s)?; let ordered_left = left_time < desired_time; let ordered_right = desired_time < right_time; if !(ordered_left && ordered_right) { - return Err(SignalErrors::OrderingFailure); + return Err(SignalErrors::OrderingFailure { + lhs_time: left_time, + mid_time: desired_time, + rhs_time: right_time, + }); } return Ok(left_val);