diff --git a/src/vcd/parse.rs b/src/vcd/parse.rs index e9a7b46..5302682 100644 --- a/src/vcd/parse.rs +++ b/src/vcd/parse.rs @@ -273,12 +273,12 @@ fn parse_events<'a>( // Also account for the error case of a bitwidth of `None` match num_bits { Some(ref num_bits) => { - if *num_bits > observed_num_bits { + if observed_num_bits > *num_bits { 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}`. \ + of sig_type {sig_type:?} is expected to be `{num_bits}` not \ + `{observed_num_bits}`. \ This error occurred while parsing the vcd file at \ {cursor:?}"); *signal_error = Some(msg); @@ -309,7 +309,31 @@ fn parse_events<'a>( } else { u8_timeline_markers.push(timeline_idx); + + let mut curr_num_bytes = value_u8.len(); 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(()) } } @@ -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 "x" | "X" | "z" | "Z" | "u" | "U" => { 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) - } - }?; - } _ => {} }