diff --git a/README.md b/README.md index 18f1415..105415f 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ Copyright - Yehowshua Immanuel # Status -July 25 2023: Haven't worked on this in a while. It seems the Zoq is now pushing forward on this codebase. -Check out his frontend here: https://app.surfer-project.org/ (code at https://gitlab.com/surfer-proj/surfer ) +July 25 2022: Haven't worked on this in a while. It seems the Zoq is now pushing forward on this codebase. +Check out his frontend here: https://gitlab.com/TheZoq2/surfer # A High performance, VCD Parser written in Rust diff --git a/src/vcd/parse/metadata.rs b/src/vcd/parse/metadata.rs index 126a334..b908403 100644 --- a/src/vcd/parse/metadata.rs +++ b/src/vcd/parse/metadata.rs @@ -2,7 +2,7 @@ // 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 chrono::prelude::{DateTime, Utc}; +use chrono::prelude::{DateTime, Utc, TimeZone}; use itertools::Itertools; use super::super::reader::{Cursor, WordReader, next_word}; @@ -133,9 +133,9 @@ pub(super) fn parse_date( // unfortunately, the minutes, seconds, and hour could occur in an // unexpected order let full_date = format!("{day} {month} {date} {hh}:{mm}:{ss} {year}"); - let full_date = DateTime::parse_from_str(full_date.as_str(), "%a %b %e %T %Y"); + let full_date = Utc.datetime_from_str(full_date.as_str(), "%a %b %e %T %Y"); if full_date.is_ok() { - return Ok(full_date.unwrap().into()); + return Ok(full_date.unwrap()); } Err(format!( diff --git a/src/vcd/parse/scopes.rs b/src/vcd/parse/scopes.rs index 6a0f28c..ce97277 100644 --- a/src/vcd/parse/scopes.rs +++ b/src/vcd/parse/scopes.rs @@ -98,11 +98,7 @@ pub(super) fn parse_var<'a, R: std::io::Read>( let (word, _) = next_word!(word_reader)?; match word { "$end" => break, - other => { - if !other.starts_with("[") { - full_signal_name.push(word.to_string()) - } - } + _ => full_signal_name.push(word.to_string()) } } let full_signal_name = full_signal_name.join(" "); @@ -386,7 +382,7 @@ pub(super) fn parse_scopes<'a, R: std::io::Read>( ident(word_reader, "$end")?; break; } - "$comment" => { + "comment" => { // although we don't store comments, we still need to advance the // word_reader cursor to the end of the comment loop { diff --git a/src/vcd/signal.rs b/src/vcd/signal.rs index f9c6103..0ac29ef 100644 --- a/src/vcd/signal.rs +++ b/src/vcd/signal.rs @@ -2,8 +2,8 @@ // 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; use super::types::SignalIdx; +use super::types; use num::BigUint; // Index to the least significant byte of a timestamp @@ -39,18 +39,11 @@ impl<'a> Signal<'a> { pub fn path(&self) -> &[String] { match self.0 { - SignalEnum::Data { path, .. } => path, + SignalEnum::Data {path, ..} => path, SignalEnum::Alias { path, .. } => path, } } - pub fn real_idx(&self) -> SignalIdx { - match self.0 { - SignalEnum::Data { self_idx, .. } => *self_idx, - SignalEnum::Alias { signal_alias, .. } => *signal_alias, - } - } - pub fn num_bits(&self) -> Option { let Signal(signal_enum) = &self; signal_enum.bits_required() @@ -62,9 +55,7 @@ impl<'a> Signal<'a> { vcd: &types::VCD, ) -> Result { let Signal(signal_enum) = &self; - signal_enum - .query_string_val_on_tmln(desired_time, &vcd.tmstmps_encoded_as_u8s, &vcd.all_signals) - .map(|(val, _)| val) + signal_enum.query_string_val_on_tmln(desired_time, &vcd.tmstmps_encoded_as_u8s, &vcd.all_signals).map(|(val, _)| val) } pub fn query_num_val_on_tmln( &self, @@ -72,9 +63,7 @@ impl<'a> Signal<'a> { vcd: &types::VCD, ) -> Result { let Signal(signal_enum) = &self; - signal_enum - .query_num_val_on_tmln(desired_time, &vcd.tmstmps_encoded_as_u8s, &vcd.all_signals) - .map(|(val, _)| val) + signal_enum.query_num_val_on_tmln(desired_time, &vcd.tmstmps_encoded_as_u8s, &vcd.all_signals).map(|(val, _)| val) } pub fn query_val_on_tmln( @@ -83,16 +72,18 @@ impl<'a> Signal<'a> { vcd: &types::VCD, ) -> Result<(TimeStamp, SignalValue), SignalErrors> { let Signal(signal_enum) = &self; - let num_val = signal_enum.query_num_val_on_tmln( - desired_time, - &vcd.tmstmps_encoded_as_u8s, - &vcd.all_signals, - ); - let str_val = signal_enum.query_string_val_on_tmln( - desired_time, - &vcd.tmstmps_encoded_as_u8s, - &vcd.all_signals, - ); + let num_val = signal_enum + .query_num_val_on_tmln( + desired_time, + &vcd.tmstmps_encoded_as_u8s, + &vcd.all_signals + ); + let str_val = signal_enum + .query_string_val_on_tmln( + desired_time, + &vcd.tmstmps_encoded_as_u8s, + &vcd.all_signals + ); // Both num and str will return the newest value that is closest to // the desired time. If both have valid values, select the most recent @@ -101,13 +92,14 @@ impl<'a> Signal<'a> { (Ok((num_val, num_time)), Ok((str_val, str_time))) => { if num_time > str_time { Ok((num_time, SignalValue::BigUint(num_val))) - } else { + } + else { Ok((str_time, SignalValue::String(str_val))) } } (Ok((num_val, time)), Err(_)) => Ok((time, SignalValue::BigUint(num_val))), (Err(_), Ok((str_val, time))) => Ok((time, SignalValue::String(str_val))), - (Err(e), _e) => Err(e), + (Err(e), _e) => Err(e) } } } @@ -130,23 +122,23 @@ pub(super) enum SignalEnum { /// A signal may take on a new value and hold that value /// for sometime. We only need to record the value of a signal /// when it changes(the is what VCDs tend to do). - /// A signal may need x amount of bytes to record its largest - /// possible value, so we record every single value of a given + /// A signal may need x amount of bytes to record its largest + /// possible value, so we record every single value of a given /// signal as a sequence of x number of u8s. /// For example, we might find that `my_signal. /// nums_encoded_as_fixed_width_le_u8` /// has two 32 bit values, namely, 1 and 2, encoded as follows: - /// my_signal.nums_encoded_as_fixed_width_le_u8 = vec![1u8, 0u8, + /// my_signal.nums_encoded_as_fixed_width_le_u8 = vec![1u8, 0u8, /// 0u8, 0u8, 2u8, 0u8, 0u8, 0u8]; nums_encoded_as_fixed_width_le_u8: Vec, string_vals: Vec, - /// we could do Vec<(LsbIdxOfTmstmpValOnTmln, u8)>, but I - /// suspect that Vec is more cache - /// friendly. We use ``LsbIdxOfTmstmpValOnTmln`` to index into - /// the LSB of a particular timestamp encoded as the - /// minimum length u8 sequence within + /// we could do Vec<(LsbIdxOfTmstmpValOnTmln, u8)>, but I + /// suspect that Vec is more cache + /// friendly. We use ``LsbIdxOfTmstmpValOnTmln`` to index into + /// the LSB of a particular timestamp encoded as the + /// minimum length u8 sequence within /// ``vcd.tmstmps_encoded_as_u8s``, and we use the values in - /// ``byte_len_of_num_tmstmp_vals_on_tmln`` to determine how + /// ``byte_len_of_num_tmstmp_vals_on_tmln`` to determine how /// many u8 values a particular timestamp is composed of. lsb_indxs_of_num_tmstmp_vals_on_tmln: Vec, byte_len_of_num_tmstmp_vals_on_tmln: Vec, @@ -187,11 +179,11 @@ type SignalValNum = BigUint; impl SignalEnum { pub fn name(&self) -> String { match self { - SignalEnum::Data { name, .. } => name, - SignalEnum::Alias { name, .. } => name, - } - .clone() + SignalEnum::Data { name, ..} => name, + SignalEnum::Alias { name, .. } => name + }.clone() } + } // helper functions ultimately used by Signal's query functions later on @@ -264,8 +256,8 @@ impl SignalEnum { /// global timeline field of a VCD struct instance) and computes /// the time pointed at by event_idx. /// This function also uses the same idx to index into the - /// nums_encoded_as_fixed_width_le_u8 and - /// byte_len_of_num_tmstmp_vals_on_tmln fields of an instance + /// nums_encoded_as_fixed_width_le_u8 and + /// byte_len_of_num_tmstmp_vals_on_tmln fields of an instance /// of the Signal::Data variant to compute the signal's corresponding /// numerical value at the time pointed at by event_didx. /// The function returns a tuple of the timestamp and numerical @@ -319,7 +311,7 @@ impl SignalEnum { fn bits_required(&self) -> Option { match self { - SignalEnum::Data { num_bits, .. } => num_bits.clone(), + SignalEnum::Data {num_bits, ..} => num_bits.clone(), // TODO: Follow aliases? SignalEnum::Alias { .. } => None, } @@ -345,7 +337,7 @@ impl SignalEnum { Self::Alias { name: _, signal_alias, - path: _, + path: _ } => { let SignalIdx(idx) = signal_alias; *idx @@ -358,15 +350,20 @@ impl SignalEnum { // 2. the vector of indices into timeline where events occur // for this signal // else we propagate Err(..). - let (string_vals, lsb_indxs_of_string_tmstmp_vals_on_tmln) = match &all_signals[signal_idx] - { - SignalEnum::Data { - ref string_vals, - ref lsb_indxs_of_string_tmstmp_vals_on_tmln, - .. - } => Ok((string_vals, lsb_indxs_of_string_tmstmp_vals_on_tmln)), - SignalEnum::Alias { .. } => Err(SignalErrors::PointsToAlias), - }?; + let (string_vals, lsb_indxs_of_string_tmstmp_vals_on_tmln) = + match &all_signals[signal_idx] { + SignalEnum::Data { + ref string_vals, + ref lsb_indxs_of_string_tmstmp_vals_on_tmln, + .. + } => { + Ok(( + string_vals, + lsb_indxs_of_string_tmstmp_vals_on_tmln, + )) + } + SignalEnum::Alias { .. } => Err(SignalErrors::PointsToAlias), + }?; // this signal should at least have some events, otherwise, trying to index into // an empty vector later on would fail if lsb_indxs_of_string_tmstmp_vals_on_tmln.is_empty() { diff --git a/tests/files.rs b/tests/files.rs index 7832a85..f5d2ac3 100644 --- a/tests/files.rs +++ b/tests/files.rs @@ -5,7 +5,7 @@ // TODO: we should eventually be able to only test on just // the files const -pub const FILES : [&str; 31] = [ +pub const FILES : [&str; 30] = [ "./tests/vcd-files/aldec/SPI_Write.vcd", "./tests/vcd-files/ghdl/alu.vcd", "./tests/vcd-files/ghdl/idea.vcd", @@ -36,8 +36,7 @@ pub const FILES : [&str; 31] = [ "./tests/vcd-files/xilinx_isim/test.vcd", "./tests/vcd-files/xilinx_isim/test1.vcd", // TODO : add signal ignore list to handle bitwidth mismatches - "./tests/vcd-files/xilinx_isim/test2x2_regex22_string1.vcd", - "./tests/vcd-files/scope_with_comment.vcd", + "./tests/vcd-files/xilinx_isim/test2x2_regex22_string1.vcd" ]; pub const GOOD_DATE_FILES : [&str; 24] = [ @@ -74,4 +73,4 @@ pub const BAD_DATE_FILES : [&str; 6] = [ "./test-vcd-files/systemc/waveform.vcd", "./test-vcd-files/treadle/GCD.vcd", "./test-vcd-files/vivado/iladata.vcd", -]; +]; \ No newline at end of file diff --git a/tests/vcd-files/scope_with_comment.vcd b/tests/vcd-files/scope_with_comment.vcd deleted file mode 100644 index cf17910..0000000 --- a/tests/vcd-files/scope_with_comment.vcd +++ /dev/null @@ -1,296 +0,0 @@ -$date - Sat Dec 26 15:33:14 2020 -$end -$version - ModelSim Version 10.5b -$end -$timescale - 1ns -$end - -$scope module clkdiv2n_tb $end -$comment foo $end -$var reg 1 ! clk $end -$var reg 1 " reset $end -$var wire 1 # clk_out $end - -$scope module t1 $end -$var parameter 32 $ WIDTH $end -$var parameter 32 % N $end -$var wire 1 & clk $end -$var wire 1 ' reset $end -$var wire 1 # clk_out $end -$var reg 3 ( r_reg [2:0] $end -$var wire 1 ) r_nxt [2] $end -$var wire 1 * r_nxt [1] $end -$var wire 1 + r_nxt [0] $end -$var reg 1 , clk_track $end -$upscope $end -$comment foo $end -$upscope $end -$comment foo $end -$enddefinitions $end -#0 -$comment foo $end -$dumpvars -0! -x" -bx ( -x, -b11 $ -b110 % -x# -x+ -x* -x) -x' -0& -$end -#5 -1" -1' -b0 ( -0, -1+ -0* -0) -0# -#10 -1! -1& -#15 -0" -0' -#20 -0! -0& -#30 -1! -1& -b1 ( -0+ -1* -#40 -0! -0& -#50 -1! -1& -b10 ( -1+ -#60 -0! -0& -#70 -1! -1& -b11 ( -0+ -0* -1) -#80 -0! -0& -#90 -1! -1& -b100 ( -1+ -#100 -0! -0& -#110 -1! -1& -b101 ( -0+ -1* -#120 -0! -0& -#130 -1! -1& -b0 ( -1, -1+ -0* -0) -1# -#140 -0! -0& -#150 -1! -1& -b1 ( -0+ -1* -#160 -0! -0& -#170 -1! -1& -b10 ( -1+ -#180 -0! -0& -#190 -1! -1& -b11 ( -0+ -0* -1) -#200 -0! -0& -#210 -1! -1& -b100 ( -1+ -#220 -0! -0& -#230 -1! -1& -b101 ( -0+ -1* -#240 -0! -0& -#250 -1! -1& -b0 ( -0, -1+ -0* -0) -0# -#260 -0! -0& -#270 -1! -1& -b1 ( -0+ -1* -#280 -0! -0& -#290 -1! -1& -b10 ( -1+ -#300 -0! -0& -#310 -1! -1& -b11 ( -0+ -0* -1) -#320 -0! -0& -#330 -1! -1& -b100 ( -1+ -#340 -0! -0& -#350 -1! -1& -b101 ( -0+ -1* -#360 -0! -0& -#370 -1! -1& -b0 ( -1, -1+ -0* -0) -1# -#380 -0! -0& -#390 -1! -1& -b1 ( -0+ -1* -#400 -0! -0& -#410 -1! -1& -b10 ( -1+ -#420 -0! -0& -#430 -1! -1& -b11 ( -0+ -0* -1) -#440 -0! -0& -#450 -1! -1& -b100 ( -1+ -#460 -0! -0& -#470 -1! -1& -b101 ( -0+ -1* -#480 -0! -0& -#490 -1! -1& -b0 ( -0, -1+ -0* -0) -0# -#500 -0! -0& -#510 -1! -1& -b1 ( -0+ -1*