sane import and export behaviors
This commit is contained in:
parent
d343b6f5ff
commit
9f18b166a5
|
@ -5,9 +5,7 @@
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
|
||||||
use fastwave_backend::*;
|
use fastwave_backend::parse_vcd;
|
||||||
|
|
||||||
use num::{BigUint};
|
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
struct Cli {
|
struct Cli {
|
||||||
|
@ -23,7 +21,7 @@ fn main() -> std::io::Result<()> {
|
||||||
|
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
let file = File::open(&args.path)?;
|
let file = File::open(&args.path)?;
|
||||||
let vcd = 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);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::*;
|
use fastwave_backend::{ScopeIdx, VCD, parse_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!(" |");}
|
||||||
|
|
|
@ -2,7 +2,11 @@
|
||||||
// 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.
|
||||||
|
|
||||||
mod vcd;
|
mod vcd;
|
||||||
pub use 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};
|
||||||
|
|
||||||
pub use num::BigUint;
|
pub use num::BigUint;
|
||||||
|
|
18
src/vcd.rs
18
src/vcd.rs
|
@ -2,17 +2,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.
|
||||||
|
|
||||||
mod reader;
|
mod reader;
|
||||||
use reader::*;
|
pub(crate) mod types;
|
||||||
|
pub(crate) mod parse;
|
||||||
mod types;
|
pub(crate) mod signal;
|
||||||
pub use types::*;
|
mod utilities;
|
||||||
|
|
||||||
mod parse;
|
|
||||||
pub use parse::*;
|
|
||||||
|
|
||||||
mod signal;
|
|
||||||
pub use signal::*;
|
|
||||||
|
|
||||||
mod utilities;
|
|
||||||
use utilities::*;
|
|
|
@ -2,38 +2,26 @@
|
||||||
// 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 num::BigUint;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
mod combinator_atoms;
|
mod combinator_atoms;
|
||||||
use combinator_atoms::*;
|
|
||||||
|
|
||||||
mod types;
|
mod types;
|
||||||
use types::*;
|
|
||||||
|
|
||||||
mod metadata;
|
mod metadata;
|
||||||
use metadata::*;
|
|
||||||
|
|
||||||
mod scopes;
|
mod scopes;
|
||||||
use scopes::*;
|
|
||||||
|
|
||||||
mod events;
|
mod events;
|
||||||
use events::*;
|
|
||||||
|
|
||||||
pub fn parse_vcd(file: File) -> Result<VCD, String> {
|
|
||||||
let mut word_gen = WordReader::new(file);
|
|
||||||
|
|
||||||
let header = parse_metadata(&mut word_gen)?;
|
pub fn parse_vcd(file: File) -> Result<super::types::VCD, String> {
|
||||||
|
let mut word_gen = super::reader::WordReader::new(file);
|
||||||
|
|
||||||
|
let header = metadata::parse_metadata(&mut word_gen)?;
|
||||||
|
|
||||||
// later, we'll need to map parsed ascii symbols to their
|
// later, we'll need to map parsed ascii symbols to their
|
||||||
// respective signal indexes
|
// respective signal indexes
|
||||||
let mut signal_map = std::collections::HashMap::new();
|
let mut signal_map = std::collections::HashMap::new();
|
||||||
|
|
||||||
// after we parse metadata, we form the VCD object
|
// after we parse metadata, we form the VCD object
|
||||||
let mut vcd = VCD {
|
let mut vcd = super::types::VCD {
|
||||||
metadata: header,
|
metadata: header,
|
||||||
tmstmps_encoded_as_u8s: vec![],
|
tmstmps_encoded_as_u8s: vec![],
|
||||||
all_signals: vec![],
|
all_signals: vec![],
|
||||||
|
@ -41,8 +29,8 @@ pub fn parse_vcd(file: File) -> Result<VCD, String> {
|
||||||
root_scopes: vec![],
|
root_scopes: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
parse_scopes(&mut word_gen, &mut vcd, &mut signal_map)?;
|
scopes::parse_scopes(&mut word_gen, &mut vcd, &mut signal_map)?;
|
||||||
parse_events(&mut word_gen, &mut vcd, &mut signal_map)?;
|
events::parse_events(&mut word_gen, &mut vcd, &mut signal_map)?;
|
||||||
|
|
||||||
Ok(vcd)
|
Ok(vcd)
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
// 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::reader::{next_word, WordReader};
|
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 {
|
||||||
|
|
|
@ -3,7 +3,14 @@
|
||||||
// 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::*;
|
use std::collections::HashMap;
|
||||||
|
use num::BigUint;
|
||||||
|
|
||||||
|
use super::super::utilities::{BinaryParserErrTypes, binary_str_to_vec_u8};
|
||||||
|
use super::super::signal::{SignalEnum, LsbIdxOfTmstmpValOnTmln};
|
||||||
|
use super::super::reader::{WordReader, Cursor, Line, Word, next_word};
|
||||||
|
use super::super::types::{SignalIdx, VCD};
|
||||||
|
|
||||||
|
|
||||||
pub(super) fn parse_events<'a>(
|
pub(super) fn parse_events<'a>(
|
||||||
word_reader: &mut WordReader,
|
word_reader: &mut WordReader,
|
||||||
|
|
|
@ -2,10 +2,14 @@
|
||||||
// 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 chrono::prelude::*;
|
use chrono::prelude::{DateTime, Utc, TimeZone};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use super::*;
|
use super::super::reader::{Cursor, WordReader, next_word};
|
||||||
|
use super::super::types::{Timescale, Version, Metadata};
|
||||||
|
|
||||||
|
use super::combinator_atoms::{take_until, take_while, digit, tag};
|
||||||
|
use super::types::{ParseResult};
|
||||||
|
|
||||||
pub(super) fn parse_date(
|
pub(super) fn parse_date(
|
||||||
word_and_ctx1: (&str, &Cursor),
|
word_and_ctx1: (&str, &Cursor),
|
||||||
|
|
|
@ -5,7 +5,15 @@
|
||||||
|
|
||||||
/// 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 super::*;
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use super::super::reader::{WordReader, next_word, curr_word};
|
||||||
|
use super::super::types::{VCD, Scope, ScopeIdx, SignalIdx};
|
||||||
|
use super::super::signal::{SigType, SignalEnum};
|
||||||
|
|
||||||
|
use super::combinator_atoms::{tag, ident};
|
||||||
|
use super::types::{ParseResult};
|
||||||
|
|
||||||
pub(super) fn parse_var<'a>(
|
pub(super) fn parse_var<'a>(
|
||||||
word_reader: &mut WordReader,
|
word_reader: &mut WordReader,
|
||||||
|
@ -322,7 +330,7 @@ pub(super) fn parse_scopes<'a>(
|
||||||
signal_map: &mut HashMap<String, SignalIdx>,
|
signal_map: &mut HashMap<String, SignalIdx>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
// get the current word
|
// get the current word
|
||||||
let (word, cursor) = curr_word!(word_reader)?;
|
let (word, _) = curr_word!(word_reader)?;
|
||||||
|
|
||||||
// we may have orphaned vars that occur before the first scope
|
// we may have orphaned vars that occur before the first scope
|
||||||
if word == "$var" {
|
if word == "$var" {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::prelude::*;
|
use std::io::BufRead;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
use crate::VCD;
|
|
||||||
|
|
||||||
// Copyright (C) 2022 Yehowshua Immanuel
|
// Copyright (C) 2022 Yehowshua Immanuel
|
||||||
// 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::{ScopeIdx, SignalIdx};
|
use super::types::{ScopeIdx, SignalIdx};
|
||||||
|
use super::types;
|
||||||
use num::{BigUint};
|
use num::{BigUint};
|
||||||
|
|
||||||
// Index to the least significant byte of a timestamp
|
// Index to the least significant byte of a timestamp
|
||||||
|
@ -41,7 +40,7 @@ impl<'a> Signal<'a> {
|
||||||
&self,
|
&self,
|
||||||
desired_time: &BigUint,
|
desired_time: &BigUint,
|
||||||
tmstmps_encoded_as_u8s: &Vec<u8>,
|
tmstmps_encoded_as_u8s: &Vec<u8>,
|
||||||
vcd: &VCD,
|
vcd: &types::VCD,
|
||||||
) -> Result<String, SignalErrors> {
|
) -> Result<String, SignalErrors> {
|
||||||
let Signal(signal_enum) = &self;
|
let Signal(signal_enum) = &self;
|
||||||
signal_enum.query_string_val_on_tmln(desired_time, tmstmps_encoded_as_u8s, &vcd.all_signals)
|
signal_enum.query_string_val_on_tmln(desired_time, tmstmps_encoded_as_u8s, &vcd.all_signals)
|
||||||
|
@ -50,7 +49,7 @@ impl<'a> Signal<'a> {
|
||||||
&self,
|
&self,
|
||||||
desired_time: &BigUint,
|
desired_time: &BigUint,
|
||||||
tmstmps_encoded_as_u8s: &Vec<u8>,
|
tmstmps_encoded_as_u8s: &Vec<u8>,
|
||||||
vcd: &VCD,
|
vcd: &types::VCD,
|
||||||
) -> Result<BigUint, SignalErrors> {
|
) -> Result<BigUint, SignalErrors> {
|
||||||
let Signal(signal_enum) = &self;
|
let Signal(signal_enum) = &self;
|
||||||
signal_enum.query_num_val_on_tmln(desired_time, tmstmps_encoded_as_u8s, &vcd.all_signals)
|
signal_enum.query_num_val_on_tmln(desired_time, tmstmps_encoded_as_u8s, &vcd.all_signals)
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
use crate::Signal;
|
// use crate::Signal;
|
||||||
|
|
||||||
// Copyright (C) 2022 Yehowshua Immanuel
|
// Copyright (C) 2022 Yehowshua Immanuel
|
||||||
// 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::SignalEnum;
|
use chrono::prelude::{DateTime, Utc};
|
||||||
use chrono::prelude::*;
|
use super::signal::{Signal, SignalEnum};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct Version(pub String);
|
pub struct Version(pub String);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) enum Timescale {
|
pub enum Timescale {
|
||||||
Fs,
|
Fs,
|
||||||
Ps,
|
Ps,
|
||||||
Ns,
|
Ns,
|
||||||
|
@ -22,10 +22,10 @@ pub(super) enum Timescale {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct Metadata {
|
pub struct Metadata {
|
||||||
pub(super) date: Option<DateTime<Utc>>,
|
pub date: Option<DateTime<Utc>>,
|
||||||
pub(super) version: Option<Version>,
|
pub version: Option<Version>,
|
||||||
pub(super) timescale: (Option<u32>, Timescale),
|
pub timescale: (Option<u32>, Timescale),
|
||||||
}
|
}
|
||||||
|
|
||||||
// We do a lot of arena allocation in this codebase.
|
// We do a lot of arena allocation in this codebase.
|
||||||
|
@ -48,7 +48,7 @@ pub(super) struct Scope {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct VCD {
|
pub struct VCD {
|
||||||
pub(super) metadata: Metadata,
|
pub metadata: Metadata,
|
||||||
// Since we only need to store values when there is an actual change
|
// Since we only need to store values when there is an actual change
|
||||||
// in the timeline, we keep a vector that stores the time at which an
|
// in the timeline, we keep a vector that stores the time at which an
|
||||||
// event occurs. Time t is always stored/encoded as the minimum length sequence
|
// event occurs. Time t is always stored/encoded as the minimum length sequence
|
||||||
|
@ -100,7 +100,7 @@ impl VCD {
|
||||||
// dereference signal if Signal::Alias, or keep idx if Signal::Data
|
// dereference signal if Signal::Alias, or keep idx if Signal::Data
|
||||||
let signal_idx = match signal {
|
let signal_idx = match signal {
|
||||||
SignalEnum::Data { self_idx, .. } => *self_idx,
|
SignalEnum::Data { self_idx, .. } => *self_idx,
|
||||||
SignalEnum::Alias { name, signal_alias } => *signal_alias,
|
SignalEnum::Alias {signal_alias, .. } => *signal_alias,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Should now point to Signal::Data variant, or else there's an error
|
// Should now point to Signal::Data variant, or else there's an error
|
||||||
|
@ -119,7 +119,7 @@ impl VCD {
|
||||||
pub fn get_signal<'a>(&'a self, idx: SignalIdx) -> Signal<'a> {
|
pub fn get_signal<'a>(&'a self, idx: SignalIdx) -> Signal<'a> {
|
||||||
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);
|
||||||
}
|
}
|
||||||
// Takes a signal_idx as input and returns the corresponding signal if the
|
// Takes a signal_idx as input and returns the corresponding signal if the
|
||||||
// corresponding signal is of the Signal::Data variant, else the function the
|
// corresponding signal is of the Signal::Data variant, else the function the
|
||||||
|
|
Loading…
Reference in a new issue