handle case of signal events with bitwidths shorter than nominal signal length
This commit is contained in:
parent
d70a09e255
commit
b685bf8be7
184
src/vcd/parse.rs
184
src/vcd/parse.rs
|
@ -273,12 +273,12 @@ fn parse_events<'a>(
|
||||||
// Also account for the error case of a bitwidth of `None`
|
// Also account for the error case of a bitwidth of `None`
|
||||||
match num_bits {
|
match num_bits {
|
||||||
Some(ref num_bits) => {
|
Some(ref num_bits) => {
|
||||||
if *num_bits > observed_num_bits {
|
if observed_num_bits > *num_bits {
|
||||||
let (f, l) = (file!(), line!());
|
let (f, l) = (file!(), line!());
|
||||||
let msg = format!("\
|
let msg = format!("\
|
||||||
Error near {f}:{l}. The bitwidth for signal {name} \
|
Error near {f}:{l}. The bitwidth for signal {name} \
|
||||||
of sig_type {sig_type:?} is expected to be `1` not \
|
of sig_type {sig_type:?} is expected to be `{num_bits}` not \
|
||||||
`{num_bits}`. \
|
`{observed_num_bits}`. \
|
||||||
This error occurred while parsing the vcd file at \
|
This error occurred while parsing the vcd file at \
|
||||||
{cursor:?}");
|
{cursor:?}");
|
||||||
*signal_error = Some(msg);
|
*signal_error = Some(msg);
|
||||||
|
@ -309,7 +309,31 @@ fn parse_events<'a>(
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
u8_timeline_markers.push(timeline_idx);
|
u8_timeline_markers.push(timeline_idx);
|
||||||
|
|
||||||
|
let mut curr_num_bytes = value_u8.len();
|
||||||
u8_timeline.append(&mut value_u8);
|
u8_timeline.append(&mut value_u8);
|
||||||
|
|
||||||
|
// we may need to zero extend values
|
||||||
|
// so that we end up storing all values
|
||||||
|
// of a particular signal in a consistent
|
||||||
|
// amount of bytes
|
||||||
|
let num_bits = num_bits.unwrap();
|
||||||
|
let bytes_required = (num_bits / 8) +
|
||||||
|
if (num_bits % 8) > 0 {1} else {0};
|
||||||
|
|
||||||
|
while curr_num_bytes < bytes_required {
|
||||||
|
// useful for debugging
|
||||||
|
// let err = format!("Error at {cursor:?}.\
|
||||||
|
// num_bits = {num_bits}, \
|
||||||
|
// observed_bits = {observed_num_bits}, \
|
||||||
|
// curr_num_bytes = {curr_num_bytes}, \
|
||||||
|
// bytes_required = {bytes_required} \
|
||||||
|
// for signal {name}");
|
||||||
|
// Err(err)?;
|
||||||
|
|
||||||
|
u8_timeline.push(0u8);
|
||||||
|
curr_num_bytes += 1;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,6 +426,83 @@ fn parse_events<'a>(
|
||||||
}?;
|
}?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"1" => {
|
||||||
|
// lokup signal idx
|
||||||
|
let hash = &word[1..];
|
||||||
|
let (f, l )= (file!(), line!());
|
||||||
|
let Signal_Idx(ref signal_idx) = signal_map.get(hash).ok_or(
|
||||||
|
format!("Error near {f}:{l}. Failed to lookup signal {hash} at {cursor:?}"))?;
|
||||||
|
|
||||||
|
// account for fact that signal idx could be an alias, so there
|
||||||
|
// could be one step of indirection
|
||||||
|
let signal_idx =
|
||||||
|
{
|
||||||
|
let signal = vcd.all_signals.get(*signal_idx).unwrap();
|
||||||
|
match signal {
|
||||||
|
Signal::Data {..} => {*signal_idx}
|
||||||
|
Signal::Alias {name, signal_alias} => {
|
||||||
|
let Signal_Idx(ref signal_idx) = signal_alias;
|
||||||
|
signal_idx.clone()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// after handling potential indirection, go ahead and update the timeline
|
||||||
|
// of the signal signal_idx references
|
||||||
|
let signal = vcd.all_signals.get_mut(signal_idx).unwrap();
|
||||||
|
match signal {
|
||||||
|
Signal::Data {name, sig_type, ref mut signal_error, num_bits,
|
||||||
|
self_idx, u8_timeline, u8_timeline_markers, scope_parent, ..} => {
|
||||||
|
|
||||||
|
// if this is a bad signal, go ahead and skip it
|
||||||
|
if signal_error.is_some() {continue;}
|
||||||
|
|
||||||
|
// Get bitwidth and verify that it is 1.
|
||||||
|
// Also account for the error case of a bitwidth of `None`
|
||||||
|
match num_bits {
|
||||||
|
Some(ref num_bits) => {
|
||||||
|
if *num_bits != 1 {
|
||||||
|
let (f, l) = (file!(), line!());
|
||||||
|
let msg = format!("\
|
||||||
|
Error near {f}:{l}. The bitwidth for signal {name} \
|
||||||
|
of sig_type {sig_type:?} is expected to be `1` not \
|
||||||
|
`{num_bits}`. \
|
||||||
|
This error occurred while parsing the vcd file at \
|
||||||
|
{cursor:?}");
|
||||||
|
*signal_error = Some(msg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let (f, l) = (file!(), line!());
|
||||||
|
let msg = format!("\
|
||||||
|
Error near {f}:{l}. The bitwidth for signal {name} \
|
||||||
|
must be specified for a signal of type {sig_type:?}. \
|
||||||
|
This error occurred while parsing the vcd file at \
|
||||||
|
{cursor:?}");
|
||||||
|
Err(msg)?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let (f, l )= (file!(), line!());
|
||||||
|
let timeline_idx = u32::try_from(vcd.timeline.len()).map_err(
|
||||||
|
|e| format!("Error near {f}:{l}. Failed to convert from usize to u32."))?;
|
||||||
|
let timeline_idx = TimelineIdx(timeline_idx);
|
||||||
|
|
||||||
|
u8_timeline_markers.push(timeline_idx);
|
||||||
|
u8_timeline.push(1u8);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Signal::Alias {..} => {
|
||||||
|
let (f, l )= (file!(), line!());
|
||||||
|
let msg = format!(
|
||||||
|
"Error near {f}:{l}, a signal alias should not point to a signal alias.\n\
|
||||||
|
This error occurred while parsing vcd file at {cursor:?}");
|
||||||
|
Err(msg)
|
||||||
|
}
|
||||||
|
}?;
|
||||||
|
}
|
||||||
// other one bit cases
|
// other one bit cases
|
||||||
"x" | "X" | "z" | "Z" | "u" | "U" => {
|
"x" | "X" | "z" | "Z" | "u" | "U" => {
|
||||||
let val = word.to_string();
|
let val = word.to_string();
|
||||||
|
@ -482,83 +583,6 @@ fn parse_events<'a>(
|
||||||
}
|
}
|
||||||
}?;
|
}?;
|
||||||
}
|
}
|
||||||
"1" => {
|
|
||||||
// lokup signal idx
|
|
||||||
let hash = &word[1..];
|
|
||||||
let (f, l )= (file!(), line!());
|
|
||||||
let Signal_Idx(ref signal_idx) = signal_map.get(hash).ok_or(
|
|
||||||
format!("Error near {f}:{l}. Failed to lookup signal {hash} at {cursor:?}"))?;
|
|
||||||
|
|
||||||
// account for fact that signal idx could be an alias, so there
|
|
||||||
// could be one step of indirection
|
|
||||||
let signal_idx =
|
|
||||||
{
|
|
||||||
let signal = vcd.all_signals.get(*signal_idx).unwrap();
|
|
||||||
match signal {
|
|
||||||
Signal::Data {..} => {*signal_idx}
|
|
||||||
Signal::Alias {name, signal_alias} => {
|
|
||||||
let Signal_Idx(ref signal_idx) = signal_alias;
|
|
||||||
signal_idx.clone()
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// after handling potential indirection, go ahead and update the timeline
|
|
||||||
// of the signal signal_idx references
|
|
||||||
let signal = vcd.all_signals.get_mut(signal_idx).unwrap();
|
|
||||||
match signal {
|
|
||||||
Signal::Data {name, sig_type, ref mut signal_error, num_bits,
|
|
||||||
self_idx, u8_timeline, u8_timeline_markers, scope_parent, ..} => {
|
|
||||||
|
|
||||||
// if this is a bad signal, go ahead and skip it
|
|
||||||
if signal_error.is_some() {continue;}
|
|
||||||
|
|
||||||
// Get bitwidth and verify that it is 1.
|
|
||||||
// Also account for the error case of a bitwidth of `None`
|
|
||||||
match num_bits {
|
|
||||||
Some(ref num_bits) => {
|
|
||||||
if *num_bits != 1 {
|
|
||||||
let (f, l) = (file!(), line!());
|
|
||||||
let msg = format!("\
|
|
||||||
Error near {f}:{l}. The bitwidth for signal {name} \
|
|
||||||
of sig_type {sig_type:?} is expected to be `1` not \
|
|
||||||
`{num_bits}`. \
|
|
||||||
This error occurred while parsing the vcd file at \
|
|
||||||
{cursor:?}");
|
|
||||||
*signal_error = Some(msg);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let (f, l) = (file!(), line!());
|
|
||||||
let msg = format!("\
|
|
||||||
Error near {f}:{l}. The bitwidth for signal {name} \
|
|
||||||
must be specified for a signal of type {sig_type:?}. \
|
|
||||||
This error occurred while parsing the vcd file at \
|
|
||||||
{cursor:?}");
|
|
||||||
Err(msg)?;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let (f, l )= (file!(), line!());
|
|
||||||
let timeline_idx = u32::try_from(vcd.timeline.len()).map_err(
|
|
||||||
|e| format!("Error near {f}:{l}. Failed to convert from usize to u32."))?;
|
|
||||||
let timeline_idx = TimelineIdx(timeline_idx);
|
|
||||||
|
|
||||||
u8_timeline_markers.push(timeline_idx);
|
|
||||||
u8_timeline.push(1u8);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Signal::Alias {..} => {
|
|
||||||
let (f, l )= (file!(), line!());
|
|
||||||
let msg = format!(
|
|
||||||
"Error near {f}:{l}, a signal alias should not point to a signal alias.\n\
|
|
||||||
This error occurred while parsing vcd file at {cursor:?}");
|
|
||||||
Err(msg)
|
|
||||||
}
|
|
||||||
}?;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue