From 11023d1fc1c2d8302e557683c9c7388fdbd6a09a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kevin=20L=C3=A4ufer?= Date: Thu, 9 Nov 2023 15:53:44 -0500 Subject: [PATCH] fix thread overlap problem --- src/vcd.rs | 24 +++++++++++++++--------- tests/diff_tests.rs | 24 ++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/vcd.rs b/src/vcd.rs index 393b1ee..e45c6d0 100644 --- a/src/vcd.rs +++ b/src/vcd.rs @@ -498,8 +498,8 @@ fn read_single_stream_of_values<'a>( ) -> crate::wavemem::Encoder { let mut encoder = crate::wavemem::Encoder::new(hierarchy); - let input2 = if is_first { - input + let (input2, offset) = if is_first { + (input, 0) } else { advance_to_first_newline(input) }; @@ -514,8 +514,8 @@ fn read_single_stream_of_values<'a>( } loop { if let Some((pos, cmd)) = reader.next() { - if pos > stop_pos { - if let BodyCmd::Time(_) = cmd { + if (pos + offset) > stop_pos { + if let BodyCmd::Time(value) = cmd { break; // stop before the next time value when we go beyond the stop position } } @@ -541,16 +541,16 @@ fn read_single_stream_of_values<'a>( } #[inline] -fn advance_to_first_newline(input: &[u8]) -> &[u8] { +fn advance_to_first_newline(input: &[u8]) -> (&[u8], usize) { for (pos, byte) in input.iter().enumerate() { match *byte { b'\n' => { - return &input[pos..]; + return (&input[pos..], pos); } _ => {} } } - &[] // no whitespaces found + (&[], 0) // no whitespaces found } struct BodyReader<'a> { @@ -633,6 +633,7 @@ impl<'a> BodyReader<'a> { impl<'a> Iterator for BodyReader<'a> { type Item = (usize, BodyCmd<'a>); + /// returns the starting position and the body of the command #[inline] fn next(&mut self) -> Option<(usize, BodyCmd<'a>)> { if self.pos >= self.input.len() { @@ -641,6 +642,7 @@ impl<'a> Iterator for BodyReader<'a> { let mut token_start: Option = None; let mut prev_token: Option<&'a [u8]> = None; let mut pending_lines = 0; + let mut start_pos = 0; for (offset, b) in self.input[self.pos..].iter().enumerate() { let pos = self.pos + offset; match b { @@ -663,7 +665,7 @@ impl<'a> Iterator for BodyReader<'a> { if *b == b'\n' { self.lines_read += 1; } - return Some((pos, cmd)); + return Some((start_pos, cmd)); } } } @@ -671,6 +673,10 @@ impl<'a> Iterator for BodyReader<'a> { _ => match token_start { None => { token_start = Some(pos); + if prev_token.is_none() { + // remember the start of the first token + start_pos = pos; + } } Some(_) => {} }, @@ -682,7 +688,7 @@ impl<'a> Iterator for BodyReader<'a> { match self.try_finish_token(self.pos, &mut token_start, &mut prev_token) { None => {} Some(cmd) => { - return Some((self.pos, cmd)); + return Some((start_pos, cmd)); } } // now we are done diff --git a/tests/diff_tests.rs b/tests/diff_tests.rs index 1da299c..3983fa6 100644 --- a/tests/diff_tests.rs +++ b/tests/diff_tests.rs @@ -141,9 +141,9 @@ fn diff_signals(ref_reader: &mut vcd::Parser, our: &mut Waveform) for cmd_res in ref_reader { match cmd_res.unwrap() { vcd::Command::Timestamp(new_time) => { - current_time = new_time; - if new_time > 0 { + if new_time > current_time { time_table_idx += 1; + current_time = new_time; } assert_eq!(current_time, time_table[time_table_idx]); } @@ -243,6 +243,26 @@ fn diff_ghdl_alu() { run_diff_test("inputs/ghdl/alu.vcd", "inputs/ghdl/alu.vcd.fst"); } +#[test] +#[ignore] // TODO: this test requires VHDL 9-state support +fn diff_ghdl_idea() { + run_diff_test("inputs/ghdl/idea.vcd", "inputs/ghdl/idea.vcd.fst"); +} + +#[test] +#[ignore] // TODO: this test requires VHDL 9-state support +fn diff_ghdl_pcpu() { + run_diff_test("inputs/ghdl/pcpu.vcd", "inputs/ghdl/pcpu.vcd.fst"); +} + +#[test] +fn diff_gtkwave_perm_current() { + run_diff_test( + "inputs/gtkwave-analyzer/perm_current.vcd", + "inputs/gtkwave-analyzer/perm_current.vcd.fst", + ); +} + #[test] fn diff_treadle_gcd() { run_diff_test("inputs/treadle/GCD.vcd", "inputs/treadle/GCD.vcd.fst");