Initial SystemVerilog/fst2vcd support
This commit is contained in:
parent
de897a5010
commit
909cca2508
|
@ -73,7 +73,7 @@ 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.query_string_val_on_tmln(&time, &vcd).unwrap();
|
let val = state_signal.query_val_on_tmln(&time, &vcd).unwrap();
|
||||||
println!("Signal `{name}` has value `{val}` at time `{time}`");
|
println!("Signal `{name}` has value `{val}` at time `{time}`");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
mod vcd;
|
mod vcd;
|
||||||
pub use vcd::parse::parse_vcd;
|
pub use vcd::parse::parse_vcd;
|
||||||
pub use vcd::signal::{Signal, SignalType, SignalValue, SignalErrors};
|
pub use vcd::signal::{Signal, SignalErrors, SignalType, SignalValue};
|
||||||
pub use vcd::types::{Metadata, Timescale, Version};
|
pub use vcd::types::{Metadata, Timescale, Version};
|
||||||
pub use vcd::types::{ScopeIdx, SignalIdx, VCD};
|
pub use vcd::types::{ScopeIdx, SignalIdx, VCD};
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,16 @@ pub(super) fn parse_var<R: std::io::Read>(
|
||||||
"wand",
|
"wand",
|
||||||
"wire",
|
"wire",
|
||||||
"wor",
|
"wor",
|
||||||
|
"int",
|
||||||
|
"int_s",
|
||||||
|
"shortint",
|
||||||
|
"int_l",
|
||||||
|
"longint",
|
||||||
|
"char",
|
||||||
|
"byte",
|
||||||
|
"logic",
|
||||||
|
"bit",
|
||||||
|
"shortreal",
|
||||||
];
|
];
|
||||||
|
|
||||||
// $var parameter 3 a IDLE $end
|
// $var parameter 3 a IDLE $end
|
||||||
|
@ -66,6 +76,15 @@ pub(super) fn parse_var<R: std::io::Read>(
|
||||||
"wand" => Ok(SignalType::WAnd),
|
"wand" => Ok(SignalType::WAnd),
|
||||||
"wire" => Ok(SignalType::Wire),
|
"wire" => Ok(SignalType::Wire),
|
||||||
"wor" => Ok(SignalType::WOr),
|
"wor" => Ok(SignalType::WOr),
|
||||||
|
"int" => Ok(SignalType::SVInt),
|
||||||
|
"int_s" => Ok(SignalType::SVShortInt),
|
||||||
|
"shortint" => Ok(SignalType::SVShortInt),
|
||||||
|
"int_l" => Ok(SignalType::SVLongInt),
|
||||||
|
"longint" => Ok(SignalType::SVLongInt),
|
||||||
|
"logic" => Ok(SignalType::SVLogic),
|
||||||
|
"shortreal" => Ok(SignalType::SVShortReal),
|
||||||
|
"byte" => Ok(SignalType::SVChar),
|
||||||
|
"char" => Ok(SignalType::SVChar),
|
||||||
_ => {
|
_ => {
|
||||||
let err = format!(
|
let err = format!(
|
||||||
"Error near {}:{} \
|
"Error near {}:{} \
|
||||||
|
@ -84,38 +103,19 @@ pub(super) fn parse_var<R: std::io::Read>(
|
||||||
|
|
||||||
// $var parameter 3 a IDLE $end
|
// $var parameter 3 a IDLE $end
|
||||||
// ^ - num_bits
|
// ^ - num_bits
|
||||||
let num_bits = match var_type {
|
let num_bits = {
|
||||||
SignalType::Event
|
let num_bits = word
|
||||||
| SignalType::Integer
|
.parse::<usize>()
|
||||||
| SignalType::Parameter
|
.unwrap_or_else(|_| panic!("{}", parse_err));
|
||||||
| SignalType::Reg
|
let num_bits = u32::try_from(num_bits).map_err(|_| {
|
||||||
| SignalType::Supply0
|
format!(
|
||||||
| SignalType::Supply1
|
"Error near {}:{} while parsing vcd file at {cursor:?}. \
|
||||||
| SignalType::Tri
|
|
||||||
| SignalType::TriAnd
|
|
||||||
| SignalType::TriOr
|
|
||||||
| SignalType::TriReg
|
|
||||||
| SignalType::Tri0
|
|
||||||
| SignalType::Tri1
|
|
||||||
| SignalType::Time
|
|
||||||
| SignalType::WAnd
|
|
||||||
| SignalType::Wire
|
|
||||||
| SignalType::WOr => {
|
|
||||||
let num_bits = word
|
|
||||||
.parse::<usize>()
|
|
||||||
.unwrap_or_else(|_| panic!("{}", parse_err));
|
|
||||||
let num_bits = u32::try_from(num_bits).map_err(|_| {
|
|
||||||
format!(
|
|
||||||
"Error near {}:{} while parsing vcd file at {cursor:?}. \
|
|
||||||
This signal has {num_bits} > 2^32 - 1 bits.",
|
This signal has {num_bits} > 2^32 - 1 bits.",
|
||||||
file!(),
|
file!(),
|
||||||
line!()
|
line!()
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
Some(num_bits)
|
Some(num_bits)
|
||||||
}
|
|
||||||
// for strings, reals, and realtimes we don't really care what the number of bits is
|
|
||||||
_ => None,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// $var parameter 3 a IDLE $end
|
// $var parameter 3 a IDLE $end
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -32,6 +34,13 @@ pub enum SignalType {
|
||||||
WAnd,
|
WAnd,
|
||||||
Wire,
|
Wire,
|
||||||
WOr,
|
WOr,
|
||||||
|
SVLogic,
|
||||||
|
SVInt,
|
||||||
|
SVShortInt,
|
||||||
|
SVLongInt,
|
||||||
|
SVChar,
|
||||||
|
SVBit,
|
||||||
|
SVShortReal,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
|
@ -40,11 +49,26 @@ pub enum SignalValue {
|
||||||
String(String),
|
String(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for SignalValue {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
SignalValue::BigUint(num) => { write!(f, "BigUnit: {num}") }
|
||||||
|
SignalValue::String(val) => {write!(f, "String: {val}")}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct QueryResult<T> {
|
pub struct QueryResult<T> {
|
||||||
pub current: Option<(TimeStamp, T)>,
|
pub current: Option<(TimeStamp, T)>,
|
||||||
pub next: Option<TimeStamp>,
|
pub next: Option<TimeStamp>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for QueryResult<SignalValue> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "(current: {:?}, next: {:?})", self.current, self.next)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Signal<'a>(pub(super) &'a SignalEnum);
|
pub struct Signal<'a>(pub(super) &'a SignalEnum);
|
||||||
|
|
||||||
impl<'a> Signal<'a> {
|
impl<'a> Signal<'a> {
|
||||||
|
@ -465,7 +489,7 @@ impl SignalEnum {
|
||||||
if lsb_indxs_of_string_tmstmp_vals_on_tmln.is_empty() {
|
if lsb_indxs_of_string_tmstmp_vals_on_tmln.is_empty() {
|
||||||
return Ok(QueryResult {
|
return Ok(QueryResult {
|
||||||
current: None,
|
current: None,
|
||||||
next: None
|
next: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -610,7 +634,7 @@ impl SignalEnum {
|
||||||
if lsb_indxs_of_num_tmstmp_vals_on_tmln.is_empty() {
|
if lsb_indxs_of_num_tmstmp_vals_on_tmln.is_empty() {
|
||||||
return Ok(QueryResult {
|
return Ok(QueryResult {
|
||||||
current: None,
|
current: None,
|
||||||
next: None
|
next: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,9 @@
|
||||||
|
|
||||||
// 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; 31] = [
|
pub const FILES: [&str; 32] = [
|
||||||
"./tests/vcd-files/aldec/SPI_Write.vcd",
|
"./tests/vcd-files/aldec/SPI_Write.vcd",
|
||||||
|
"./tests/vcd-files/fst2vcd/logic.vcd",
|
||||||
"./tests/vcd-files/ghdl/alu.vcd",
|
"./tests/vcd-files/ghdl/alu.vcd",
|
||||||
"./tests/vcd-files/ghdl/idea.vcd",
|
"./tests/vcd-files/ghdl/idea.vcd",
|
||||||
"./tests/vcd-files/ghdl/pcpu.vcd",
|
"./tests/vcd-files/ghdl/pcpu.vcd",
|
||||||
|
|
Loading…
Reference in a new issue