notable restructuring

This commit is contained in:
Yehowshua Immanuel 2022-09-09 02:59:33 -04:00
parent 4c1af97760
commit 320b0d348d
43 changed files with 154 additions and 142 deletions

View file

@ -53,7 +53,11 @@ various EDA tools. If you want a larger VCD file, grab one from
The first build of the program may take some time. The first build of the program may take some time.
``cargo run --release test-vcd-files/aldec/SPI_Write.vcd`` ``cargo run --release --example parse_vcd tests/vcd-files/aldec/SPI_Write.vcd``
You can also run the vcd1 or vcd2 example with:
- cargo run --release --example vcd1
- cargo run --release --example vcd2
You can run all the tests with ``cargo test`` You can run all the tests with ``cargo test``
@ -62,7 +66,7 @@ You may wish to test the parser on a malformed VCD just to make
sure that the parser gives useful/sane errors. sure that the parser gives useful/sane errors.
Here's a command to test on a malformed VCD: Here's a command to test on a malformed VCD:
`cargo run --release test-vcd-files/VCD_file_with_errors.vcd` ``cargo run --release --example parse_vcd tests/vcd-files/VCD_file_with_errors.vcd``
# TODO # TODO

29
examples/parse_vcd.rs Normal file
View file

@ -0,0 +1,29 @@
use clap::Parser;
use std::fs::File;
use fastwave::*;
use num::{BigUint};
#[derive(Parser)]
struct Cli {
/// The path to the file to read
#[clap(parse(from_os_str))]
path: std::path::PathBuf,
}
fn main() -> std::io::Result<()> {
let args = Cli::parse();
use std::time::Instant;
let now = Instant::now();
let file = File::open(&args.path)?;
let vcd = parse_vcd(file).unwrap();
let elapsed = now.elapsed();
println!("Parsed VCD file {} : {:.2?}", &args.path.as_os_str().to_str().unwrap(), elapsed);
Ok(())
}

34
examples/vcd1.rs Normal file
View file

@ -0,0 +1,34 @@
use clap::Parser;
use std::fs::File;
use fastwave::*;
use num::{BigUint};
fn main() -> std::io::Result<()> {
use std::time::Instant;
let now = Instant::now();
let file_path = "tests/vcd-files/icarus/CPU.vcd";
let file = File::open(file_path).unwrap();
let vcd = parse_vcd(file).unwrap();
let elapsed = now.elapsed();
println!("Parsed VCD file {} : {:.2?}", file_path, elapsed);
// testbench -> CPU -> rs2_data[31:0] @ 4687s
let rs2_data_signal = &vcd.all_signals[51];
let name = rs2_data_signal.name();
let time = BigUint::from(4687u32);
let val = rs2_data_signal
.query_num_val_on_tmln(
&time,
&vcd.tmstmps_encoded_as_u8s,
&vcd.all_signals,
)
.unwrap();
println!("Signal `{name}` has value `{val}` at time `{time}`");
Ok(())
}

34
examples/vcd2.rs Normal file
View file

@ -0,0 +1,34 @@
use clap::Parser;
use std::fs::File;
use fastwave::*;
use num::{BigUint};
fn main() -> std::io::Result<()> {
use std::time::Instant;
let now = Instant::now();
let file_path = "tests/vcd-files/amaranth/up_counter.vcd";
let file = File::open(file_path)?;
let vcd = parse_vcd(file).unwrap();
let elapsed = now.elapsed();
println!("Parsed VCD file {} : {:.2?}", file_path, elapsed);
let state_signal = &vcd.all_signals[4];
let name = state_signal.name();
let time = BigUint::from(57760000u32);
let val = state_signal
.query_string_val_on_tmln(
&time,
&vcd.tmstmps_encoded_as_u8s,
&vcd.all_signals,
)
.unwrap();
println!("Signal `{name}` has value `{val}` at time `{time}`");
Ok(())
}

View file

@ -1 +1,2 @@
pub mod vcd; mod vcd;
pub use vcd::*;

View file

@ -1,66 +0,0 @@
use clap::Parser;
use std::fs::File;
pub mod test;
pub mod vcd;
use vcd::*;
use num::{BigUint};
#[derive(Parser)]
struct Cli {
/// The path to the file to read
#[clap(parse(from_os_str))]
path: std::path::PathBuf,
}
fn main() -> std::io::Result<()> {
let args = Cli::parse();
use std::time::Instant;
let now = Instant::now();
let file = File::open(&args.path)?;
let vcd = parse_vcd(file).unwrap();
let elapsed = now.elapsed();
println!("Parsed VCD file {} : {:.2?}", &args.path.as_os_str().to_str().unwrap(), elapsed);
// the following is really only for test-vcd-files/icarus/CPU.vcd
// at the moment
if args.path.as_os_str().to_str().unwrap() == "test-vcd-files/icarus/CPU.vcd" {
let rs2_data_signal = &vcd.all_signals[51];
let name = rs2_data_signal.name();
// query testbench -> CPU -> rs2_data[31:0] @ 4687s
let time = BigUint::from(4687u32);
let val = rs2_data_signal
.query_num_val_on_tmln(
&time,
&vcd.tmstmps_encoded_as_u8s,
&vcd.all_signals,
)
.unwrap();
println!("Signal `{name}` has value `{val}` at time `{time}`");
// also need to test testbench -> CPU -> ID_EX_RD[4:0]
}
// this is to help with testing stringed enums
if args.path.as_os_str().to_str().unwrap() == "test-vcd-files/amaranth/up_counter.vcd" {
let state_signal = &vcd.all_signals[4];
let name = state_signal.name();
let time = BigUint::from(57760000u32);
let val = state_signal
.query_string_val_on_tmln(
&time,
&vcd.tmstmps_encoded_as_u8s,
&vcd.all_signals,
)
.unwrap();
println!("Signal `{name}` has value `{val}` at time `{time}`");
}
Ok(())
}

View file

@ -1,2 +0,0 @@
mod files;
pub use files::*;

View file

@ -41,44 +41,4 @@ pub fn parse_vcd(file: File) -> Result<VCD, String> {
parse_events(&mut word_gen, &mut vcd, &mut signal_map)?; parse_events(&mut word_gen, &mut vcd, &mut signal_map)?;
Ok(vcd) Ok(vcd)
} }
#[cfg(test)]
mod tests {
use super::*;
use crate::test;
use std::fs::File;
#[test]
fn headers() {
// TODO: eventually, once all dates pass, merge the following
// two loops
// testing dates
for file in test::GOOD_DATE_FILES {
let metadata = parse_metadata(&mut WordReader::new(File::open(file).unwrap()));
assert!(metadata.is_ok());
assert!(metadata.unwrap().date.is_some());
}
for file in test::FILES {
let metadata = parse_metadata(&mut WordReader::new(File::open(file).unwrap()));
assert!(metadata.is_ok());
let (scalar, _timescale) = metadata.unwrap().timescale;
assert!(scalar.is_some());
}
}
#[test]
fn scopes() {
// see if we can parse all signal trees successfully
for file_name in test::FILES {
let file = File::open(file_name).unwrap();
let vcd = parse_vcd(file);
if !vcd.is_ok() {
dbg!(file_name);
vcd.unwrap();
}
}
}
}

View file

@ -1,37 +1,37 @@
// TODO: we should eventually be able to only test on just // TODO: we should eventually be able to only test on just
// the files const // the files const
pub const FILES : [&str; 30] = [ pub const FILES : [&str; 30] = [
"./test-vcd-files/aldec/SPI_Write.vcd", "./tests/vcd-files/aldec/SPI_Write.vcd",
"./test-vcd-files/ghdl/alu.vcd", "./tests/vcd-files/ghdl/alu.vcd",
"./test-vcd-files/ghdl/idea.vcd", "./tests/vcd-files/ghdl/idea.vcd",
"./test-vcd-files/ghdl/pcpu.vcd", "./tests/vcd-files/ghdl/pcpu.vcd",
"./test-vcd-files/gtkwave-analyzer/perm_current.vcd", "./tests/vcd-files/gtkwave-analyzer/perm_current.vcd",
"./test-vcd-files/icarus/CPU.vcd", "./tests/vcd-files/icarus/CPU.vcd",
"./test-vcd-files/icarus/rv32_soc_TB.vcd", "./tests/vcd-files/icarus/rv32_soc_TB.vcd",
"./test-vcd-files/icarus/test1.vcd", "./tests/vcd-files/icarus/test1.vcd",
"./test-vcd-files/model-sim/CPU_Design.msim.vcd", "./tests/vcd-files/model-sim/CPU_Design.msim.vcd",
"./test-vcd-files/model-sim/clkdiv2n_tb.vcd", "./tests/vcd-files/model-sim/clkdiv2n_tb.vcd",
"./test-vcd-files/my-hdl/Simple_Memory.vcd", "./tests/vcd-files/my-hdl/Simple_Memory.vcd",
"./test-vcd-files/my-hdl/sigmoid_tb.vcd", "./tests/vcd-files/my-hdl/sigmoid_tb.vcd",
"./test-vcd-files/my-hdl/top.vcd", "./tests/vcd-files/my-hdl/top.vcd",
"./test-vcd-files/ncsim/ffdiv_32bit_tb.vcd", "./tests/vcd-files/ncsim/ffdiv_32bit_tb.vcd",
"./test-vcd-files/quartus/mipsHardware.vcd", "./tests/vcd-files/quartus/mipsHardware.vcd",
"./test-vcd-files/quartus/wave_registradores.vcd", "./tests/vcd-files/quartus/wave_registradores.vcd",
"./test-vcd-files/questa-sim/dump.vcd", "./tests/vcd-files/questa-sim/dump.vcd",
"./test-vcd-files/questa-sim/test.vcd", "./tests/vcd-files/questa-sim/test.vcd",
"./test-vcd-files/riviera-pro/dump.vcd", "./tests/vcd-files/riviera-pro/dump.vcd",
"./test-vcd-files/systemc/waveform.vcd", "./tests/vcd-files/systemc/waveform.vcd",
"./test-vcd-files/treadle/GCD.vcd", "./tests/vcd-files/treadle/GCD.vcd",
"./test-vcd-files/vcs/Apb_slave_uvm_new.vcd", "./tests/vcd-files/vcs/Apb_slave_uvm_new.vcd",
"./test-vcd-files/vcs/datapath_log.vcd", "./tests/vcd-files/vcs/datapath_log.vcd",
"./test-vcd-files/vcs/processor.vcd", "./tests/vcd-files/vcs/processor.vcd",
"./test-vcd-files/verilator/swerv1.vcd", "./tests/vcd-files/verilator/swerv1.vcd",
"./test-vcd-files/verilator/vlt_dump.vcd", "./tests/vcd-files/verilator/vlt_dump.vcd",
"./test-vcd-files/vivado/iladata.vcd", "./tests/vcd-files/vivado/iladata.vcd",
"./test-vcd-files/xilinx_isim/test.vcd", "./tests/vcd-files/xilinx_isim/test.vcd",
"./test-vcd-files/xilinx_isim/test1.vcd", "./tests/vcd-files/xilinx_isim/test1.vcd",
// TODO : add signal ignore list to handle bitwidth mismatches // TODO : add signal ignore list to handle bitwidth mismatches
"./test-vcd-files/xilinx_isim/test2x2_regex22_string1.vcd" "./tests/vcd-files/xilinx_isim/test2x2_regex22_string1.vcd"
]; ];
pub const GOOD_DATE_FILES : [&str; 24] = [ pub const GOOD_DATE_FILES : [&str; 24] = [

18
tests/integration_test.rs Normal file
View file

@ -0,0 +1,18 @@
use std::fs::File;
mod files;
use files::*;
#[test]
fn parse_all_VCDs() {
// see if we can parse all signal trees successfully
for file_name in FILES {
let file = File::open(file_name).unwrap();
let vcd = fastwave::parse_vcd(file);
if !vcd.is_ok() {
dbg!(file_name);
vcd.unwrap();
}
}
}