Skip to content

Commit

Permalink
make icarus example work
Browse files Browse the repository at this point in the history
  • Loading branch information
ekiwi committed Nov 10, 2023
1 parent 468b4be commit 997d18a
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 21 deletions.
31 changes: 24 additions & 7 deletions src/hierarchy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Space efficient format for a wavedump hierarchy.

use bytesize::ByteSize;
use std::num::{NonZeroU16, NonZeroU32};
use std::num::{NonZeroU16, NonZeroU32, NonZeroU64};
use string_interner::Symbol;

#[derive(Debug, Clone, Copy, PartialEq)]
Expand Down Expand Up @@ -124,6 +124,7 @@ pub enum VarType {
Wire,
Reg,
Parameter,
Integer,
String,
Todo, // placeholder tpe
}
Expand All @@ -135,9 +136,25 @@ pub enum VarDirection {
}

#[derive(Debug, Clone, Copy)]
pub struct VarIndex {
pub msb: i32,
pub lsb: i32,
pub struct VarIndex(NonZeroU64);

impl VarIndex {
pub(crate) fn new(msb: i32, lsb: i32) -> Self {
assert!(msb >= lsb);
assert!((lsb as u32) < u32::MAX);
let value = ((msb as u64) << 32) | (lsb as u64);
Self(NonZeroU64::new(value + 1).unwrap())
}

pub fn msb(&self) -> i32 {
let value = self.0.get() - 1;
(value >> 32) as i32
}

pub fn lsb(&self) -> i32 {
let value = self.0.get() - 1;
(value & (u32::MAX as u64)) as i32
}
}

/// Signal identifier in the waveform (VCD, FST, etc.) file.
Expand Down Expand Up @@ -755,13 +772,13 @@ mod tests {
+ 1 // tpe
+ 1 // direction
+ 4 // length
+ 12 // bit index TODO: try to save some space here!
+ 8 // bit index
+ std::mem::size_of::<SignalRef>() // handle
+ std::mem::size_of::<ScopeRef>() // parent
+ std::mem::size_of::<HierarchyItemId>() // next
);
// currently this all comes out to 36 bytes (~= 4x 64-bit pointers)
assert_eq!(std::mem::size_of::<Var>(), 36);
// currently this all comes out to 32 bytes (~= 4x 64-bit pointers)
assert_eq!(std::mem::size_of::<Var>(), 32);

// Scope
assert_eq!(
Expand Down
5 changes: 3 additions & 2 deletions src/vcd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ fn parse_index(index: &[u8]) -> Option<VarIndex> {
let inner = &index[1..(index.len() - 1)];
let inner_str = std::str::from_utf8(inner).unwrap();
let bit = i32::from_str_radix(inner_str, 10).unwrap();
Some(VarIndex { msb: bit, lsb: bit })
Some(VarIndex::new(bit, bit))
}
Some(pos) => {
let msb_bytes = &index[1..pos];
Expand All @@ -138,7 +138,7 @@ fn parse_index(index: &[u8]) -> Option<VarIndex> {
let lsb_bytes = &index[(pos + 1)..(index.len() - 1)];
let lsb_str = std::str::from_utf8(lsb_bytes).unwrap();
let lsb = i32::from_str_radix(lsb_str, 10).unwrap();
Some(VarIndex { msb, lsb })
Some(VarIndex::new(msb, lsb))
}
}
}
Expand Down Expand Up @@ -167,6 +167,7 @@ fn convert_var_tpe(tpe: &[u8]) -> VarType {
b"wire" => VarType::Wire,
b"reg" => VarType::Reg,
b"parameter" => VarType::Parameter,
b"integer" => VarType::Integer,
b"string" => VarType::String,
_ => panic!("TODO: convert {}", String::from_utf8_lossy(tpe)),
}
Expand Down
15 changes: 8 additions & 7 deletions src/wavemem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,15 +682,16 @@ fn expand_special_vector_cases(value: &[u8], len: usize) -> Option<Vec<u8>> {
// zero, x or z extend
match value[0] {
b'1' | b'0' => {
let mut zero_extended = Vec::with_capacity(len);
zero_extended.resize(len - value.len(), b'0');
zero_extended.extend_from_slice(value);
Some(zero_extended)
let mut extended = Vec::with_capacity(len);
extended.resize(len - value.len(), b'0');
extended.extend_from_slice(value);
Some(extended)
}
b'x' | b'X' | b'z' | b'Z' => {
let mut repeated = Vec::with_capacity(len);
repeated.resize(len, value[0]);
Some(repeated)
let mut extended = Vec::with_capacity(len);
extended.resize(len - value.len(), value[0]);
extended.extend_from_slice(value);
Some(extended)
}
_ => None, // failed
}
Expand Down
25 changes: 20 additions & 5 deletions tests/diff_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ fn waveform_var_type_to_string(tpe: VarType) -> &'static str {
VarType::Wire => "wire",
VarType::Reg => "reg",
VarType::Parameter => "parameter",
VarType::Integer => "integer",
VarType::String => "string",
VarType::Todo => "todo",
}
Expand Down Expand Up @@ -117,12 +118,12 @@ fn diff_hierarchy_item(ref_item: &vcd::ScopeItem, our_item: HierarchyItem, our_h
match ref_var.index {
None => assert!(our_var.index().is_none()),
Some(vcd::ReferenceIndex::BitSelect(bit)) => {
assert_eq!(our_var.index().unwrap().msb, bit);
assert_eq!(our_var.index().unwrap().lsb, bit);
assert_eq!(our_var.index().unwrap().msb(), bit);
assert_eq!(our_var.index().unwrap().lsb(), bit);
}
Some(vcd::ReferenceIndex::Range(msb, lsb)) => {
assert_eq!(our_var.index().unwrap().msb, msb);
assert_eq!(our_var.index().unwrap().lsb, lsb);
assert_eq!(our_var.index().unwrap().msb(), msb);
assert_eq!(our_var.index().unwrap().lsb(), lsb);
}
}
}
Expand Down Expand Up @@ -172,7 +173,16 @@ fn diff_signals<R: BufRead>(ref_reader: &mut vcd::Parser<R>, our: &mut Waveform)
let prefix_len = our_value_str.len() - value.len();
// we are zero / x extending, so our string might be longer
let suffix: String = our_value_str.chars().skip(prefix_len).collect();
assert_eq!(suffix, value.to_string());
assert_eq!(
suffix,
value.to_string(),
"{} ({:?}) = {} @ {} ({})",
id,
signal_ref,
value,
current_time,
our_value_str
);
let is_x_extended = suffix.chars().next().unwrap() == 'x';
let is_z_extended = suffix.chars().next().unwrap() == 'z';
for c in our_value_str.chars().take(prefix_len) {
Expand Down Expand Up @@ -277,6 +287,11 @@ fn diff_gtkwave_perm_current() {
);
}

#[test]
fn diff_icarus_CPU() {
run_diff_test("inputs/icarus/CPU.vcd", "inputs/icarus/CPU.vcd.fst");
}

#[test]
fn diff_treadle_gcd() {
run_diff_test("inputs/treadle/GCD.vcd", "inputs/treadle/GCD.vcd.fst");
Expand Down

0 comments on commit 997d18a

Please sign in to comment.