commit bf4e793ea348651243bc78194f52e48ea3ccb933 Author: Yehowshua Immanuel Date: Thu Apr 14 00:50:37 2022 -0400 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..494728b --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "VCDViewer" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +num = "0.4" +clap = { version = "3.1.8", features = ["derive"] } diff --git a/README.md b/README.md new file mode 100644 index 0000000..8235c1f --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +# The Beginnings of a high-performance, low memory footprint VCD Viewer in Rust for massive multi-GB waveforms + +## Features + - very fast + - loads 200MB of VCD waveform per second on an 8 core 2017 desktop CPU with NVMe storage + - consumes roughly between 10 - 50MB of memory per GB of waveform + - elegant/pretty UI + - can be easily ported to work in browser via webassembly + - allows high-performance custom Rust plugins to manipulate and + generate new waveforms live + +## Running + +Make sure you have a test vcd file to get you started. You can grab +a large VCD file from +[here](https://drive.google.com/file/d/1pfm2qo2l8fGTHHJ8TLrg1vSGaV_TUbp2/view?usp=sharing). + +The first build of the program may take some time. + +``cargo run --release -- path/to/vcd/file`` + +## TODO + - [x] Test positions with seeking + - [x] vcd should be argument + - [x] structure to store stream position against timestamp as string + - [x] structure to store stream position against timestamp as BigInt + +### April 14 + - [ ] store timestamps to struct + - [ ] Get file loading status + - [ ] Get all signal scopes + +### April 15 + - [ ] Re-factor to support hooks in the initial file ingest + - [ ] Modularize + +### April 15 + - [ ] Build tree per signal. + - [ ] Each signal also comes with a value change buffer to + avoid frequent disk readouts. + +# VCD Spec Questions +- [ ] I'm pretty sure that only one statement per line is allowed. \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..5423c94 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,60 @@ +use std::io::prelude::*; +use std::io; +use std::fs::File; + +use num::*; +use clap::Parser; + +#[derive(Parser)] +struct Cli { + /// The path to the file to read + #[clap(parse(from_os_str))] + path: std::path::PathBuf, +} + +struct Timestamp{ + file_offset: u64, + timestamp: BigInt +} + +fn main() -> std::io::Result<()> { + let args = Cli::parse(); + + let file = File::open(&args.path)?; + let mut reader = io::BufReader::new(file); + + let mut buffer = String::new(); + let mut timestamp_offsets = Vec::new(); + let mut timestamps = Vec::new(); + + while { + let bytes_read = reader.read_line(&mut buffer).unwrap(); + bytes_read > 0 + } { + if &buffer[0..1] == "#" { + let pos = reader.stream_position().unwrap(); + timestamp_offsets.push(pos); + + let timestamp = { + let len = buffer.len(); + let str_val = &buffer[1..(len - 1)].as_bytes(); + BigInt::parse_bytes(str_val, 10).unwrap() + }; + timestamps.push(timestamp); + } + buffer.clear() + } + + let index = 4; + let timestamp_offset = timestamp_offsets.get(index).unwrap(); + let timestamp = timestamps.get(index).unwrap(); + dbg!((timestamp_offset, timestamp)); + + // seek to where we found the first timestamp and read + // out the next line + reader.seek(io::SeekFrom::Start(*timestamp_offset)); + reader.read_line(&mut buffer); + dbg!(buffer); + + Ok(()) +}