commit
fccd65ef8f
|
@ -24,8 +24,11 @@ fn main() -> std::io::Result<()> {
|
||||||
parse_vcd(file).unwrap();
|
parse_vcd(file).unwrap();
|
||||||
let elapsed = now.elapsed();
|
let elapsed = now.elapsed();
|
||||||
|
|
||||||
println!("Parsed VCD file {} : {:.2?}", &args.path.as_os_str().to_str().unwrap(), elapsed);
|
println!(
|
||||||
|
"Parsed VCD file {} : {:.2?}",
|
||||||
|
&args.path.as_os_str().to_str().unwrap(),
|
||||||
|
elapsed
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,12 @@
|
||||||
// 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, SignalIdx};
|
use fastwave_backend::{parse_vcd, ScopeIdx, SignalIdx, VCD};
|
||||||
|
|
||||||
fn indented_print(indent: u8, name: &String) {
|
fn indented_print(indent: u8, name: &String) {
|
||||||
for _ in 0..indent {print!(" |");}
|
for _ in 0..indent {
|
||||||
|
print!(" |");
|
||||||
|
}
|
||||||
print!("---");
|
print!("---");
|
||||||
println!("{name}");
|
println!("{name}");
|
||||||
}
|
}
|
||||||
|
@ -36,7 +38,6 @@ fn visit_all_scopes(vcd: &VCD) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> std::io::Result<()> {
|
fn main() -> std::io::Result<()> {
|
||||||
|
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
// we start by printing out the entire signal tree of
|
// we start by printing out the entire signal tree of
|
||||||
|
@ -53,7 +54,6 @@ fn main() -> std::io::Result<()> {
|
||||||
println!("Done Printing Scopes");
|
println!("Done Printing Scopes");
|
||||||
println!();
|
println!();
|
||||||
|
|
||||||
|
|
||||||
// we then parse another VCD, print its signal tree and
|
// we then parse another VCD, print its signal tree and
|
||||||
// query some values on its timeline
|
// query some values on its timeline
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
|
@ -73,11 +73,8 @@ fn main() -> std::io::Result<()> {
|
||||||
let timestamps = vec![31499_000u32, 31500_000u32, 57760_000u32];
|
let timestamps = vec![31499_000u32, 31500_000u32, 57760_000u32];
|
||||||
for timestamp in timestamps {
|
for timestamp in timestamps {
|
||||||
let time = num::BigUint::from(timestamp);
|
let time = num::BigUint::from(timestamp);
|
||||||
let val = state_signal
|
let val = state_signal.query_string_val_on_tmln(&time, &vcd).unwrap();
|
||||||
.query_string_val_on_tmln(&time, &vcd)
|
|
||||||
.unwrap();
|
|
||||||
println!("Signal `{name}` has value `{val}` at time `{time}`");
|
println!("Signal `{name}` has value `{val}` at time `{time}`");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
|
|
||||||
mod vcd;
|
mod vcd;
|
||||||
pub use vcd::parse::parse_vcd;
|
pub use vcd::parse::parse_vcd;
|
||||||
pub use vcd::types::{ScopeIdx, SignalIdx, VCD};
|
|
||||||
pub use vcd::types::{Metadata, Timescale, Version};
|
|
||||||
pub use vcd::signal::{Signal, SignalValue};
|
pub use vcd::signal::{Signal, SignalValue};
|
||||||
|
pub use vcd::types::{Metadata, Timescale, Version};
|
||||||
|
pub use vcd::types::{ScopeIdx, SignalIdx, VCD};
|
||||||
|
|
||||||
pub use num::BigUint;
|
pub use num::BigUint;
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
// and the YEHOWSHUA license, both of which can be found at
|
// and the YEHOWSHUA license, both of which can be found at
|
||||||
// the root of the folder containing the sources for this program.
|
// the root of the folder containing the sources for this program.
|
||||||
|
|
||||||
mod reader;
|
|
||||||
pub(crate) mod types;
|
|
||||||
pub(crate) mod parse;
|
pub(crate) mod parse;
|
||||||
|
mod reader;
|
||||||
pub(crate) mod signal;
|
pub(crate) mod signal;
|
||||||
|
pub(crate) mod types;
|
||||||
mod utilities;
|
mod utilities;
|
|
@ -4,11 +4,10 @@
|
||||||
// the root of the folder containing the sources for this program.
|
// the root of the folder containing the sources for this program.
|
||||||
|
|
||||||
mod combinator_atoms;
|
mod combinator_atoms;
|
||||||
mod types;
|
mod events;
|
||||||
mod metadata;
|
mod metadata;
|
||||||
mod scopes;
|
mod scopes;
|
||||||
mod events;
|
mod types;
|
||||||
|
|
||||||
|
|
||||||
pub fn parse_vcd(file: impl std::io::Read) -> Result<super::types::VCD, String> {
|
pub fn parse_vcd(file: impl std::io::Read) -> Result<super::types::VCD, String> {
|
||||||
let mut word_gen = super::reader::WordReader::new(file);
|
let mut word_gen = super::reader::WordReader::new(file);
|
||||||
|
@ -26,7 +25,7 @@ pub fn parse_vcd(file: impl std::io::Read) -> Result<super::types::VCD, String>
|
||||||
all_signals: vec![],
|
all_signals: vec![],
|
||||||
all_scopes: vec![],
|
all_scopes: vec![],
|
||||||
root_scopes: vec![],
|
root_scopes: vec![],
|
||||||
largest_timestamp: None
|
largest_timestamp: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
scopes::parse_scopes(&mut word_gen, &mut vcd, &mut signal_map)?;
|
scopes::parse_scopes(&mut word_gen, &mut vcd, &mut signal_map)?;
|
||||||
|
|
|
@ -6,15 +6,13 @@ use super::super::reader::{next_word, WordReader};
|
||||||
use super::types::ParseResult;
|
use super::types::ParseResult;
|
||||||
|
|
||||||
pub(super) fn digit(chr: u8) -> bool {
|
pub(super) fn digit(chr: u8) -> bool {
|
||||||
let zero = b'0' as u8;
|
let zero = b'0';
|
||||||
let nine = b'9' as u8;
|
let nine = b'9';
|
||||||
|
|
||||||
let between_zero_and_nine = (chr >= zero) && (nine >= chr);
|
(chr >= zero) && (nine >= chr)
|
||||||
|
|
||||||
return between_zero_and_nine;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn take_until<'a>(word: &'a str, pattern: u8) -> ParseResult<'a> {
|
pub(super) fn take_until(word: &str, pattern: u8) -> ParseResult<'_> {
|
||||||
let mut new_start = 0;
|
let mut new_start = 0;
|
||||||
|
|
||||||
for chr in word.as_bytes() {
|
for chr in word.as_bytes() {
|
||||||
|
@ -25,13 +23,13 @@ pub(super) fn take_until<'a>(word: &'a str, pattern: u8) -> ParseResult<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParseResult {
|
ParseResult {
|
||||||
matched: &word[0..new_start],
|
matched: &word[0..new_start],
|
||||||
residual: &word[new_start..],
|
residual: &word[new_start..],
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn take_while<'a>(word: &'a str, cond: fn(u8) -> bool) -> ParseResult<'a> {
|
pub(super) fn take_while(word: &str, cond: fn(u8) -> bool) -> ParseResult<'_> {
|
||||||
let mut new_start = 0;
|
let mut new_start = 0;
|
||||||
|
|
||||||
for chr in word.as_bytes() {
|
for chr in word.as_bytes() {
|
||||||
|
@ -42,10 +40,10 @@ pub(super) fn take_while<'a>(word: &'a str, cond: fn(u8) -> bool) -> ParseResult
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParseResult {
|
ParseResult {
|
||||||
matched: &word[0..new_start],
|
matched: &word[0..new_start],
|
||||||
residual: &word[new_start..],
|
residual: &word[new_start..],
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn tag<'a>(word: &'a str, pattern: &'a str) -> ParseResult<'a> {
|
pub(super) fn tag<'a>(word: &'a str, pattern: &'a str) -> ParseResult<'a> {
|
||||||
|
@ -63,10 +61,10 @@ pub(super) fn tag<'a>(word: &'a str, pattern: &'a str) -> ParseResult<'a> {
|
||||||
new_start += 1;
|
new_start += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParseResult {
|
ParseResult {
|
||||||
matched: &word[0..new_start],
|
matched: &word[0..new_start],
|
||||||
residual: &word[new_start..],
|
residual: &word[new_start..],
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn ident<R: std::io::Read>(
|
pub(super) fn ident<R: std::io::Read>(
|
||||||
|
@ -77,9 +75,9 @@ pub(super) fn ident<R: std::io::Read>(
|
||||||
let (word, cursor) = next_word!(word_reader)?;
|
let (word, cursor) = next_word!(word_reader)?;
|
||||||
|
|
||||||
if word == keyword {
|
if word == keyword {
|
||||||
return Ok(());
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
let err = format!("found keyword `{word}` but expected `{keyword}` on {cursor:?}");
|
let err = format!("found keyword `{word}` but expected `{keyword}` on {cursor:?}");
|
||||||
return Err(err);
|
Err(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,18 +3,17 @@
|
||||||
// and the YEHOWSHUA license, both of which can be found at
|
// and the YEHOWSHUA license, both of which can be found at
|
||||||
// the root of the folder containing the sources for this program.
|
// the root of the folder containing the sources for this program.
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use num::BigUint;
|
use num::BigUint;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use super::super::utilities::{BinaryParserErrTypes, binary_str_to_vec_u8};
|
use super::super::reader::{next_word, Cursor, Line, Word, WordReader};
|
||||||
use super::super::signal::{SignalEnum, LsbIdxOfTmstmpValOnTmln};
|
use super::super::signal::{LsbIdxOfTmstmpValOnTmln, SignalEnum};
|
||||||
use super::super::reader::{WordReader, Cursor, Line, Word, next_word};
|
|
||||||
use super::super::types::{SignalIdx, VCD};
|
use super::super::types::{SignalIdx, VCD};
|
||||||
|
use super::super::utilities::{binary_str_to_vec_u8, BinaryParserErrTypes};
|
||||||
|
|
||||||
|
pub(super) fn parse_events<R: std::io::Read>(
|
||||||
pub(super) fn parse_events<'a, R: std::io::Read>(
|
|
||||||
word_reader: &mut WordReader<R>,
|
word_reader: &mut WordReader<R>,
|
||||||
vcd: &'a mut VCD,
|
vcd: &mut VCD,
|
||||||
signal_map: &mut HashMap<String, SignalIdx>,
|
signal_map: &mut HashMap<String, SignalIdx>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let mut curr_tmstmp_lsb_idx = 0u32;
|
let mut curr_tmstmp_lsb_idx = 0u32;
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
use chrono::prelude::{DateTime, Utc};
|
use chrono::prelude::{DateTime, Utc};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use super::super::reader::{Cursor, WordReader, next_word};
|
use super::super::reader::{next_word, Cursor, WordReader};
|
||||||
use super::super::types::{Timescale, Version, Metadata};
|
use super::super::types::{Metadata, Timescale, Version};
|
||||||
|
|
||||||
use super::combinator_atoms::{take_until, take_while, digit, tag};
|
use super::combinator_atoms::{digit, tag, take_until, take_while};
|
||||||
use super::types::{ParseResult};
|
use super::types::ParseResult;
|
||||||
|
|
||||||
pub(super) fn parse_date(
|
pub(super) fn parse_date(
|
||||||
word_and_ctx1: (&str, &Cursor),
|
word_and_ctx1: (&str, &Cursor),
|
||||||
|
@ -145,7 +145,9 @@ pub(super) fn parse_date(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn parse_version<R: std::io::Read>(word_reader: &mut WordReader<R>) -> Result<Version, String> {
|
pub(super) fn parse_version<R: std::io::Read>(
|
||||||
|
word_reader: &mut WordReader<R>,
|
||||||
|
) -> Result<Version, String> {
|
||||||
let mut version = String::new();
|
let mut version = String::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -157,7 +159,7 @@ pub(super) fn parse_version<R: std::io::Read>(word_reader: &mut WordReader<R>) -
|
||||||
return Ok(Version(version));
|
return Ok(Version(version));
|
||||||
} else {
|
} else {
|
||||||
version.push_str(word);
|
version.push_str(word);
|
||||||
version.push_str(" ");
|
version.push(' ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,7 +179,7 @@ pub(super) fn parse_timescale<R: std::io::Read>(
|
||||||
.map_err(|e| format!("Error near {}:{}. {e}", file!(), line!()))?;
|
.map_err(|e| format!("Error near {}:{}. {e}", file!(), line!()))?;
|
||||||
|
|
||||||
let timescale = {
|
let timescale = {
|
||||||
if residual == "" {
|
if residual.is_empty() {
|
||||||
let (word, _) = next_word!(word_reader)?;
|
let (word, _) = next_word!(word_reader)?;
|
||||||
let unit = match word {
|
let unit = match word {
|
||||||
"fs" => Ok(Timescale::Fs),
|
"fs" => Ok(Timescale::Fs),
|
||||||
|
@ -217,10 +219,12 @@ pub(super) fn parse_timescale<R: std::io::Read>(
|
||||||
let (word, _) = next_word!(word_reader)?;
|
let (word, _) = next_word!(word_reader)?;
|
||||||
tag(word, "$end").assert_match()?;
|
tag(word, "$end").assert_match()?;
|
||||||
|
|
||||||
return Ok(timescale);
|
Ok(timescale)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn parse_metadata<R: std::io::Read>(word_reader: &mut WordReader<R>) -> Result<Metadata, String> {
|
pub(super) fn parse_metadata<R: std::io::Read>(
|
||||||
|
word_reader: &mut WordReader<R>,
|
||||||
|
) -> Result<Metadata, String> {
|
||||||
let mut metadata = Metadata {
|
let mut metadata = Metadata {
|
||||||
date: None,
|
date: None,
|
||||||
version: None,
|
version: None,
|
||||||
|
@ -327,5 +331,5 @@ pub(super) fn parse_metadata<R: std::io::Read>(word_reader: &mut WordReader<R>)
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Ok(metadata);
|
Ok(metadata)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,20 +5,19 @@
|
||||||
|
|
||||||
/// part of the vcd parser that handles parsing the signal tree and
|
/// part of the vcd parser that handles parsing the signal tree and
|
||||||
/// building the resulting signal tree
|
/// building the resulting signal tree
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use super::super::reader::{WordReader, next_word, curr_word};
|
use super::super::reader::{curr_word, next_word, WordReader};
|
||||||
use super::super::types::{VCD, Scope, ScopeIdx, SignalIdx};
|
|
||||||
use super::super::signal::{SigType, SignalEnum};
|
use super::super::signal::{SigType, SignalEnum};
|
||||||
|
use super::super::types::{Scope, ScopeIdx, SignalIdx, VCD};
|
||||||
|
|
||||||
use super::combinator_atoms::{tag, ident};
|
use super::combinator_atoms::{ident, tag};
|
||||||
use super::types::{ParseResult};
|
use super::types::ParseResult;
|
||||||
|
|
||||||
pub(super) fn parse_var<'a, R: std::io::Read>(
|
pub(super) fn parse_var<R: std::io::Read>(
|
||||||
word_reader: &mut WordReader<R>,
|
word_reader: &mut WordReader<R>,
|
||||||
parent_scope_idx: ScopeIdx,
|
parent_scope_idx: ScopeIdx,
|
||||||
vcd: &'a mut VCD,
|
vcd: &mut VCD,
|
||||||
signal_map: &mut HashMap<String, SignalIdx>,
|
signal_map: &mut HashMap<String, SignalIdx>,
|
||||||
path: &Vec<String>,
|
path: &Vec<String>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
|
@ -71,7 +70,9 @@ pub(super) fn parse_var<'a, R: std::io::Read>(
|
||||||
| SigType::Wire
|
| SigType::Wire
|
||||||
| SigType::Tri1
|
| SigType::Tri1
|
||||||
| SigType::Time => {
|
| SigType::Time => {
|
||||||
let num_bits = word.parse::<usize>().expect(parse_err.as_str());
|
let num_bits = word
|
||||||
|
.parse::<usize>()
|
||||||
|
.unwrap_or_else(|_| panic!("{}", parse_err));
|
||||||
let num_bits = u16::try_from(num_bits).map_err(|_| {
|
let num_bits = u16::try_from(num_bits).map_err(|_| {
|
||||||
format!(
|
format!(
|
||||||
"Error near {}:{} while parsing vcd file at {cursor:?}. \
|
"Error near {}:{} while parsing vcd file at {cursor:?}. \
|
||||||
|
@ -98,7 +99,7 @@ pub(super) fn parse_var<'a, R: std::io::Read>(
|
||||||
let (word, _) = next_word!(word_reader)?;
|
let (word, _) = next_word!(word_reader)?;
|
||||||
match word {
|
match word {
|
||||||
"$end" => break,
|
"$end" => break,
|
||||||
_ => full_signal_name.push(word.to_string())
|
_ => full_signal_name.push(word.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let full_signal_name = full_signal_name.join(" ");
|
let full_signal_name = full_signal_name.join(" ");
|
||||||
|
@ -118,7 +119,11 @@ pub(super) fn parse_var<'a, R: std::io::Read>(
|
||||||
let signal_idx = SignalIdx(vcd.all_signals.len());
|
let signal_idx = SignalIdx(vcd.all_signals.len());
|
||||||
let signal = SignalEnum::Alias {
|
let signal = SignalEnum::Alias {
|
||||||
name: full_signal_name.clone(),
|
name: full_signal_name.clone(),
|
||||||
path: path.iter().cloned().chain([full_signal_name]).collect::<Vec<String>>(),
|
path: path
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.chain([full_signal_name])
|
||||||
|
.collect::<Vec<String>>(),
|
||||||
signal_alias: *ref_signal_idx,
|
signal_alias: *ref_signal_idx,
|
||||||
};
|
};
|
||||||
(signal, signal_idx)
|
(signal, signal_idx)
|
||||||
|
@ -128,7 +133,11 @@ pub(super) fn parse_var<'a, R: std::io::Read>(
|
||||||
signal_map.insert(signal_alias.to_string(), signal_idx);
|
signal_map.insert(signal_alias.to_string(), signal_idx);
|
||||||
let signal = SignalEnum::Data {
|
let signal = SignalEnum::Data {
|
||||||
name: full_signal_name.clone(),
|
name: full_signal_name.clone(),
|
||||||
path: path.iter().cloned().chain([full_signal_name]).collect::<Vec<String>>(),
|
path: path
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.chain([full_signal_name])
|
||||||
|
.collect::<Vec<String>>(),
|
||||||
sig_type: var_type,
|
sig_type: var_type,
|
||||||
signal_error: None,
|
signal_error: None,
|
||||||
num_bits,
|
num_bits,
|
||||||
|
@ -155,9 +164,9 @@ pub(super) fn parse_var<'a, R: std::io::Read>(
|
||||||
|
|
||||||
/// Sometimes, variables can be listed outside of scopes.
|
/// Sometimes, variables can be listed outside of scopes.
|
||||||
/// We call these orphaned vars.
|
/// We call these orphaned vars.
|
||||||
fn parse_orphaned_vars<'a, R: std::io::Read>(
|
fn parse_orphaned_vars<R: std::io::Read>(
|
||||||
word_reader: &mut WordReader<R>,
|
word_reader: &mut WordReader<R>,
|
||||||
vcd: &'a mut VCD,
|
vcd: &mut VCD,
|
||||||
signal_map: &mut HashMap<String, SignalIdx>,
|
signal_map: &mut HashMap<String, SignalIdx>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
// create scope for unscoped signals if such a scope does not
|
// create scope for unscoped signals if such a scope does not
|
||||||
|
@ -218,12 +227,12 @@ fn parse_orphaned_vars<'a, R: std::io::Read>(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_scopes_inner<'a, R: std::io::Read>(
|
fn parse_scopes_inner<R: std::io::Read>(
|
||||||
word_reader: &mut WordReader<R>,
|
word_reader: &mut WordReader<R>,
|
||||||
parent_scope_idx: Option<ScopeIdx>,
|
parent_scope_idx: Option<ScopeIdx>,
|
||||||
vcd: &'a mut VCD,
|
vcd: &mut VCD,
|
||||||
signal_map: &mut HashMap<String, SignalIdx>,
|
signal_map: &mut HashMap<String, SignalIdx>,
|
||||||
path: &Vec<String>
|
path: &Vec<String>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
// $scope module reg_mag_i $end
|
// $scope module reg_mag_i $end
|
||||||
// ^^^^^^ - module keyword
|
// ^^^^^^ - module keyword
|
||||||
|
@ -275,8 +284,6 @@ fn parse_scopes_inner<'a, R: std::io::Read>(
|
||||||
// ^^^^ - end keyword
|
// ^^^^ - end keyword
|
||||||
ident(word_reader, "$end")?;
|
ident(word_reader, "$end")?;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let (word, cursor) = next_word!(word_reader)?;
|
let (word, cursor) = next_word!(word_reader)?;
|
||||||
let ParseResult { matched, residual } = tag(word, "$");
|
let ParseResult { matched, residual } = tag(word, "$");
|
||||||
|
@ -286,7 +293,13 @@ fn parse_scopes_inner<'a, R: std::io::Read>(
|
||||||
match residual {
|
match residual {
|
||||||
"scope" => {
|
"scope" => {
|
||||||
// recursive - parse inside of current scope tree
|
// recursive - parse inside of current scope tree
|
||||||
parse_scopes_inner(word_reader, Some(curr_scope_idx), vcd, signal_map, &path)?;
|
parse_scopes_inner(
|
||||||
|
word_reader,
|
||||||
|
Some(curr_scope_idx),
|
||||||
|
vcd,
|
||||||
|
signal_map,
|
||||||
|
&path,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
"var" => {
|
"var" => {
|
||||||
parse_var(word_reader, curr_scope_idx, vcd, signal_map, &path)?;
|
parse_var(word_reader, curr_scope_idx, vcd, signal_map, &path)?;
|
||||||
|
@ -330,9 +343,9 @@ fn parse_scopes_inner<'a, R: std::io::Read>(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn parse_scopes<'a, R: std::io::Read>(
|
pub(super) fn parse_scopes<R: std::io::Read>(
|
||||||
word_reader: &mut WordReader<R>,
|
word_reader: &mut WordReader<R>,
|
||||||
vcd: &'a mut VCD,
|
vcd: &mut VCD,
|
||||||
signal_map: &mut HashMap<String, SignalIdx>,
|
signal_map: &mut HashMap<String, SignalIdx>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
// get the current word
|
// get the current word
|
||||||
|
|
|
@ -5,25 +5,23 @@
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct ParseResult<'a> {
|
pub(super) struct ParseResult<'a> {
|
||||||
pub(super) matched: &'a str,
|
pub(super) matched: &'a str,
|
||||||
pub(super) residual : &'a str}
|
pub(super) residual: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> ParseResult<'a> {
|
impl<'a> ParseResult<'a> {
|
||||||
|
|
||||||
pub(super) fn assert_match(&self) -> Result<&str, String> {
|
pub(super) fn assert_match(&self) -> Result<&str, String> {
|
||||||
if self.matched == "" {
|
if self.matched.is_empty() {
|
||||||
return Err("no match".to_string())
|
Err("no match".to_string())
|
||||||
}
|
} else {
|
||||||
else {
|
Ok(self.matched)
|
||||||
return Ok(self.matched)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn assert_residual(&self) -> Result<&str, String> {
|
pub(super) fn assert_residual(&self) -> Result<&str, String> {
|
||||||
if self.residual == "" {
|
if self.residual.is_empty() {
|
||||||
return Err("no residual".to_string())
|
Err("no residual".to_string())
|
||||||
}
|
} else {
|
||||||
else {
|
Ok(self.residual)
|
||||||
return Ok(self.residual)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -319,7 +319,7 @@ impl SignalEnum {
|
||||||
|
|
||||||
fn bits_required(&self) -> Option<u16> {
|
fn bits_required(&self) -> Option<u16> {
|
||||||
match self {
|
match self {
|
||||||
SignalEnum::Data { num_bits, .. } => num_bits.clone(),
|
SignalEnum::Data { num_bits, .. } => *num_bits,
|
||||||
// TODO: Follow aliases?
|
// TODO: Follow aliases?
|
||||||
SignalEnum::Alias { .. } => None,
|
SignalEnum::Alias { .. } => None,
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
// This program is distributed under both the GPLV3 license
|
// This program is distributed under both the GPLV3 license
|
||||||
// and the YEHOWSHUA license, both of which can be found at
|
// and the YEHOWSHUA license, both of which can be found at
|
||||||
// the root of the folder containing the sources for this program.
|
// the root of the folder containing the sources for this program.
|
||||||
|
use super::signal::{Signal, SignalEnum};
|
||||||
use chrono::prelude::{DateTime, Utc};
|
use chrono::prelude::{DateTime, Utc};
|
||||||
use num::BigUint;
|
use num::BigUint;
|
||||||
use super::signal::{Signal, SignalEnum};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Version(pub String);
|
pub struct Version(pub String);
|
||||||
|
@ -63,7 +63,7 @@ pub struct VCD {
|
||||||
pub(super) all_signals: Vec<SignalEnum>,
|
pub(super) all_signals: Vec<SignalEnum>,
|
||||||
pub(super) all_scopes: Vec<Scope>,
|
pub(super) all_scopes: Vec<Scope>,
|
||||||
pub(super) root_scopes: Vec<ScopeIdx>,
|
pub(super) root_scopes: Vec<ScopeIdx>,
|
||||||
pub(super) largest_timestamp: Option<BigUint>
|
pub(super) largest_timestamp: Option<BigUint>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VCD {
|
impl VCD {
|
||||||
|
@ -85,7 +85,7 @@ 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> {
|
pub fn signal_from_signal_idx(&self, idx: SignalIdx) -> Signal<'_> {
|
||||||
let SignalIdx(idx) = idx;
|
let SignalIdx(idx) = idx;
|
||||||
let signal_enum = &self.all_signals[idx];
|
let signal_enum = &self.all_signals[idx];
|
||||||
return Signal(signal_enum);
|
return Signal(signal_enum);
|
||||||
|
|
|
@ -38,7 +38,7 @@ fn base2_str_to_byte(word: &[u8]) -> Result<u8, BinaryParserErrTypes> {
|
||||||
|
|
||||||
for (idx, chr) in word.iter().rev().enumerate() {
|
for (idx, chr) in word.iter().rev().enumerate() {
|
||||||
match chr {
|
match chr {
|
||||||
b'1' => val = bit_lut[idx] | val,
|
b'1' => val |= bit_lut[idx],
|
||||||
b'0' => {}
|
b'0' => {}
|
||||||
b'x' | b'X' => return Err(BinaryParserErrTypes::XValue),
|
b'x' | b'X' => return Err(BinaryParserErrTypes::XValue),
|
||||||
b'z' | b'Z' => return Err(BinaryParserErrTypes::ZValue),
|
b'z' | b'Z' => return Err(BinaryParserErrTypes::ZValue),
|
||||||
|
@ -73,13 +73,13 @@ pub(super) fn binary_str_to_vec_u8(binary_str: &str) -> Result<Vec<u8>, BinaryPa
|
||||||
if head_idx < 8 {
|
if head_idx < 8 {
|
||||||
head_idx = 0
|
head_idx = 0
|
||||||
} else {
|
} else {
|
||||||
head_idx = head_idx - 8;
|
head_idx -= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if tail_idx < 8 {
|
if tail_idx < 8 {
|
||||||
tail_idx = 0
|
tail_idx = 0
|
||||||
} else {
|
} else {
|
||||||
tail_idx = tail_idx - 8;
|
tail_idx -= 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(vec_u8)
|
Ok(vec_u8)
|
||||||
|
|
|
@ -64,7 +64,7 @@ pub const GOOD_DATE_FILES : [&str; 24] = [
|
||||||
"./test-vcd-files/verilator/vlt_dump.vcd",
|
"./test-vcd-files/verilator/vlt_dump.vcd",
|
||||||
"./test-vcd-files/xilinx_isim/test.vcd",
|
"./test-vcd-files/xilinx_isim/test.vcd",
|
||||||
"./test-vcd-files/xilinx_isim/test1.vcd",
|
"./test-vcd-files/xilinx_isim/test1.vcd",
|
||||||
"./test-vcd-files/xilinx_isim/test2x2_regex22_string1.vcd"
|
"./test-vcd-files/xilinx_isim/test2x2_regex22_string1.vcd",
|
||||||
];
|
];
|
||||||
|
|
||||||
pub const BAD_DATE_FILES: [&str; 6] = [
|
pub const BAD_DATE_FILES: [&str; 6] = [
|
||||||
|
|
Loading…
Reference in a new issue