Signal query #5
|
@ -39,6 +39,20 @@ pub fn parse_vcd(file: File) -> Result<VCD, String> {
|
||||||
|
|
||||||
parse_scopes(&mut word_gen, &mut vcd, &mut signal_map)?;
|
parse_scopes(&mut word_gen, &mut vcd, &mut signal_map)?;
|
||||||
parse_events(&mut word_gen, &mut vcd, &mut signal_map)?;
|
parse_events(&mut word_gen, &mut vcd, &mut signal_map)?;
|
||||||
|
let signal = vcd.try_dereference_alias(signal_map.get("Q").unwrap())?;
|
||||||
|
let name = match signal {
|
||||||
|
Signal::Data { name, .. } => name,
|
||||||
|
_ => "ERROR",
|
||||||
|
};
|
||||||
|
let val = signal
|
||||||
|
.query_num_val_on_tmln(
|
||||||
|
BigUint::from(4687u32),
|
||||||
|
&vcd.tmstmps_encoded_as_u8s,
|
||||||
|
&vcd.all_signals,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
dbg!(format!("{val:#X}"));
|
||||||
|
dbg!(name);
|
||||||
|
|
||||||
Ok(vcd)
|
Ok(vcd)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use num::Zero;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub(super) fn parse_events<'a>(
|
pub(super) fn parse_events<'a>(
|
||||||
|
@ -7,6 +9,7 @@ pub(super) fn parse_events<'a>(
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let mut curr_tmstmp_lsb_idx = 0u32;
|
let mut curr_tmstmp_lsb_idx = 0u32;
|
||||||
let mut curr_tmstmp_len_u8 = 0u8;
|
let mut curr_tmstmp_len_u8 = 0u8;
|
||||||
|
let mut curr_time = BigUint::zero();
|
||||||
loop {
|
loop {
|
||||||
let next_word = word_reader.next_word();
|
let next_word = word_reader.next_word();
|
||||||
|
|
||||||
|
@ -35,6 +38,7 @@ pub(super) fn parse_events<'a>(
|
||||||
"Error near {f}:{l}. Failed to parse {value} as BigInt at {cursor:?}"
|
"Error near {f}:{l}. Failed to parse {value} as BigInt at {cursor:?}"
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
curr_time = value.clone();
|
||||||
let mut value = value.to_bytes_le();
|
let mut value = value.to_bytes_le();
|
||||||
// TODO : u32 helps with less memory, but should ideally likely be
|
// TODO : u32 helps with less memory, but should ideally likely be
|
||||||
// configurable.
|
// configurable.
|
||||||
|
@ -45,16 +49,15 @@ pub(super) fn parse_events<'a>(
|
||||||
line!()
|
line!()
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
vcd.tmstmps_encoded_as_u8s.append(&mut value);
|
|
||||||
curr_tmstmp_lsb_idx =
|
curr_tmstmp_lsb_idx =
|
||||||
u32::try_from(vcd.tmstmps_encoded_as_u8s.len()).map_err(|_| {
|
u32::try_from(vcd.tmstmps_encoded_as_u8s.len()).map_err(|_| {
|
||||||
format!(
|
format!(
|
||||||
"Error near {}:{}. Failed to convert from usize to u8.",
|
"Error near {}:{}. Failed to convert from usize to u32.",
|
||||||
file!(),
|
file!(),
|
||||||
line!()
|
line!()
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
// curr_tmstmp_lsb_idx = vcd.tmstmps_encoded_as_u8s.len();
|
vcd.tmstmps_encoded_as_u8s.append(&mut value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle the case of an n bit signal whose value must be parsed
|
// handle the case of an n bit signal whose value must be parsed
|
||||||
|
@ -111,10 +114,6 @@ pub(super) fn parse_events<'a>(
|
||||||
|
|
||||||
let signal = vcd.try_dereference_alias_mut(signal_idx)?;
|
let signal = vcd.try_dereference_alias_mut(signal_idx)?;
|
||||||
|
|
||||||
// we may have to dereference a signal if it's pointing at an alias
|
|
||||||
// let signal = &vcd.all_signals[*signal_idx];
|
|
||||||
// let signal = signal.try_dereference_alias_mut(&vcd.all_signals)?;
|
|
||||||
|
|
||||||
match signal {
|
match signal {
|
||||||
Signal::Data {
|
Signal::Data {
|
||||||
name,
|
name,
|
||||||
|
@ -172,6 +171,19 @@ pub(super) fn parse_events<'a>(
|
||||||
string_vals.push(value_string);
|
string_vals.push(value_string);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
// timestamp stuff
|
||||||
|
lsb_indxs_of_num_tmstmp_vals_on_tmln
|
||||||
|
.push(LsbIdxOfTmstmpValOnTmln(curr_tmstmp_lsb_idx));
|
||||||
|
byte_len_of_num_tmstmp_vals_on_tmln.push(curr_tmstmp_len_u8);
|
||||||
|
|
||||||
|
// value stuff
|
||||||
|
// 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 bytes_required = num_bytes.ok_or_else(|| {
|
||||||
|
format!("Error near {}:{}. num_bytes empty.", file!(), line!())
|
||||||
|
})?;
|
||||||
let mut curr_num_bytes =
|
let mut curr_num_bytes =
|
||||||
u8::try_from(value_u8.len()).map_err(|_| {
|
u8::try_from(value_u8.len()).map_err(|_| {
|
||||||
format!(
|
format!(
|
||||||
|
@ -182,22 +194,12 @@ pub(super) fn parse_events<'a>(
|
||||||
line!()
|
line!()
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
lsb_indxs_of_num_tmstmp_vals_on_tmln
|
|
||||||
.push(LsbIdxOfTmstmpValOnTmln(curr_tmstmp_lsb_idx));
|
|
||||||
|
|
||||||
// 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 bytes_required = num_bytes.ok_or_else(|| {
|
|
||||||
format!("Error near {}:{}. num_bytes empty.", file!(), line!())
|
|
||||||
})?;
|
|
||||||
|
|
||||||
|
nums_encoded_as_fixed_width_le_u8.append(&mut value_u8);
|
||||||
while curr_num_bytes < bytes_required {
|
while curr_num_bytes < bytes_required {
|
||||||
nums_encoded_as_fixed_width_le_u8.push(0u8);
|
nums_encoded_as_fixed_width_le_u8.push(0u8);
|
||||||
curr_num_bytes += 1;
|
curr_num_bytes += 1;
|
||||||
}
|
}
|
||||||
byte_len_of_num_tmstmp_vals_on_tmln.push(curr_tmstmp_len_u8);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -231,6 +233,7 @@ pub(super) fn parse_events<'a>(
|
||||||
sig_type,
|
sig_type,
|
||||||
ref mut signal_error,
|
ref mut signal_error,
|
||||||
num_bits,
|
num_bits,
|
||||||
|
num_bytes,
|
||||||
nums_encoded_as_fixed_width_le_u8,
|
nums_encoded_as_fixed_width_le_u8,
|
||||||
lsb_indxs_of_num_tmstmp_vals_on_tmln,
|
lsb_indxs_of_num_tmstmp_vals_on_tmln,
|
||||||
byte_len_of_num_tmstmp_vals_on_tmln,
|
byte_len_of_num_tmstmp_vals_on_tmln,
|
||||||
|
@ -271,10 +274,25 @@ pub(super) fn parse_events<'a>(
|
||||||
Err(msg)?;
|
Err(msg)?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
nums_encoded_as_fixed_width_le_u8.push(0u8);
|
// timestamp stuff
|
||||||
lsb_indxs_of_num_tmstmp_vals_on_tmln
|
lsb_indxs_of_num_tmstmp_vals_on_tmln
|
||||||
.push(LsbIdxOfTmstmpValOnTmln(curr_tmstmp_lsb_idx));
|
.push(LsbIdxOfTmstmpValOnTmln(curr_tmstmp_lsb_idx));
|
||||||
byte_len_of_num_tmstmp_vals_on_tmln.push(curr_tmstmp_len_u8);
|
byte_len_of_num_tmstmp_vals_on_tmln.push(curr_tmstmp_len_u8);
|
||||||
|
|
||||||
|
// value stuff
|
||||||
|
// 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 bytes_required = num_bytes.ok_or_else(|| {
|
||||||
|
format!("Error near {}:{}. num_bytes empty.", file!(), line!())
|
||||||
|
})?;
|
||||||
|
nums_encoded_as_fixed_width_le_u8.push(0u8);
|
||||||
|
let mut curr_num_bytes = 1;
|
||||||
|
while curr_num_bytes < bytes_required {
|
||||||
|
nums_encoded_as_fixed_width_le_u8.push(0u8);
|
||||||
|
curr_num_bytes += 1;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Signal::Alias { .. } => {
|
Signal::Alias { .. } => {
|
||||||
|
@ -306,6 +324,7 @@ pub(super) fn parse_events<'a>(
|
||||||
sig_type,
|
sig_type,
|
||||||
ref mut signal_error,
|
ref mut signal_error,
|
||||||
num_bits,
|
num_bits,
|
||||||
|
num_bytes,
|
||||||
nums_encoded_as_fixed_width_le_u8,
|
nums_encoded_as_fixed_width_le_u8,
|
||||||
lsb_indxs_of_num_tmstmp_vals_on_tmln,
|
lsb_indxs_of_num_tmstmp_vals_on_tmln,
|
||||||
byte_len_of_num_tmstmp_vals_on_tmln,
|
byte_len_of_num_tmstmp_vals_on_tmln,
|
||||||
|
@ -346,10 +365,25 @@ pub(super) fn parse_events<'a>(
|
||||||
Err(msg)?;
|
Err(msg)?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
nums_encoded_as_fixed_width_le_u8.push(1u8);
|
// timestamp stuff
|
||||||
lsb_indxs_of_num_tmstmp_vals_on_tmln
|
lsb_indxs_of_num_tmstmp_vals_on_tmln
|
||||||
.push(LsbIdxOfTmstmpValOnTmln(curr_tmstmp_lsb_idx));
|
.push(LsbIdxOfTmstmpValOnTmln(curr_tmstmp_lsb_idx));
|
||||||
byte_len_of_num_tmstmp_vals_on_tmln.push(curr_tmstmp_len_u8);
|
byte_len_of_num_tmstmp_vals_on_tmln.push(curr_tmstmp_len_u8);
|
||||||
|
|
||||||
|
// value stuff
|
||||||
|
// 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 bytes_required = num_bytes.ok_or_else(|| {
|
||||||
|
format!("Error near {}:{}. num_bytes empty.", file!(), line!())
|
||||||
|
})?;
|
||||||
|
nums_encoded_as_fixed_width_le_u8.push(1u8);
|
||||||
|
let mut curr_num_bytes = 1;
|
||||||
|
while curr_num_bytes < bytes_required {
|
||||||
|
nums_encoded_as_fixed_width_le_u8.push(0u8);
|
||||||
|
curr_num_bytes += 1;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Signal::Alias { .. } => {
|
Signal::Alias { .. } => {
|
||||||
|
@ -362,7 +396,7 @@ pub(super) fn parse_events<'a>(
|
||||||
}?;
|
}?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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();
|
||||||
// lokup signal idx
|
// lokup signal idx
|
||||||
|
@ -385,6 +419,7 @@ pub(super) fn parse_events<'a>(
|
||||||
num_bits,
|
num_bits,
|
||||||
string_vals,
|
string_vals,
|
||||||
byte_len_of_num_tmstmp_vals_on_tmln,
|
byte_len_of_num_tmstmp_vals_on_tmln,
|
||||||
|
byte_len_of_string_tmstmp_vals_on_tmln,
|
||||||
lsb_indxs_of_string_tmstmp_vals_on_tmln,
|
lsb_indxs_of_string_tmstmp_vals_on_tmln,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
|
@ -423,10 +458,14 @@ pub(super) fn parse_events<'a>(
|
||||||
Err(msg)?;
|
Err(msg)?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
string_vals.push(val);
|
|
||||||
|
// record timestamp at which this event occurs
|
||||||
lsb_indxs_of_string_tmstmp_vals_on_tmln
|
lsb_indxs_of_string_tmstmp_vals_on_tmln
|
||||||
.push(LsbIdxOfTmstmpValOnTmln(curr_tmstmp_lsb_idx));
|
.push(LsbIdxOfTmstmpValOnTmln(curr_tmstmp_lsb_idx));
|
||||||
byte_len_of_num_tmstmp_vals_on_tmln.push(curr_tmstmp_len_u8);
|
byte_len_of_string_tmstmp_vals_on_tmln.push(curr_tmstmp_len_u8);
|
||||||
|
|
||||||
|
// record value
|
||||||
|
string_vals.push(val);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Signal::Alias { .. } => {
|
Signal::Alias { .. } => {
|
||||||
|
|
|
@ -122,8 +122,8 @@ pub(super) fn parse_var<'a>(
|
||||||
string_vals: vec![],
|
string_vals: vec![],
|
||||||
lsb_indxs_of_num_tmstmp_vals_on_tmln: vec![],
|
lsb_indxs_of_num_tmstmp_vals_on_tmln: vec![],
|
||||||
byte_len_of_num_tmstmp_vals_on_tmln: vec![],
|
byte_len_of_num_tmstmp_vals_on_tmln: vec![],
|
||||||
lsb_indxs_of_string_tmstmp_vals_on_tmln: vec![],
|
|
||||||
byte_len_of_string_tmstmp_vals_on_tmln: vec![],
|
byte_len_of_string_tmstmp_vals_on_tmln: vec![],
|
||||||
|
lsb_indxs_of_string_tmstmp_vals_on_tmln: vec![],
|
||||||
scope_parent: parent_scope_idx,
|
scope_parent: parent_scope_idx,
|
||||||
};
|
};
|
||||||
(signal, signal_idx)
|
(signal, signal_idx)
|
||||||
|
|
|
@ -58,8 +58,8 @@ pub(super) enum Signal {
|
||||||
// a particular timestamp is composed of.
|
// a particular timestamp is composed of.
|
||||||
lsb_indxs_of_num_tmstmp_vals_on_tmln: Vec<LsbIdxOfTmstmpValOnTmln>,
|
lsb_indxs_of_num_tmstmp_vals_on_tmln: Vec<LsbIdxOfTmstmpValOnTmln>,
|
||||||
byte_len_of_num_tmstmp_vals_on_tmln: Vec<u8>,
|
byte_len_of_num_tmstmp_vals_on_tmln: Vec<u8>,
|
||||||
lsb_indxs_of_string_tmstmp_vals_on_tmln: Vec<LsbIdxOfTmstmpValOnTmln>,
|
|
||||||
byte_len_of_string_tmstmp_vals_on_tmln: Vec<u8>,
|
byte_len_of_string_tmstmp_vals_on_tmln: Vec<u8>,
|
||||||
|
lsb_indxs_of_string_tmstmp_vals_on_tmln: Vec<LsbIdxOfTmstmpValOnTmln>,
|
||||||
scope_parent: ScopeIdx,
|
scope_parent: ScopeIdx,
|
||||||
},
|
},
|
||||||
Alias {
|
Alias {
|
||||||
|
@ -76,9 +76,12 @@ pub(super) enum SignalErrors {
|
||||||
},
|
},
|
||||||
EmptyTimeline,
|
EmptyTimeline,
|
||||||
TimelineNotMultiple,
|
TimelineNotMultiple,
|
||||||
OrderingFailure,
|
OrderingFailure {
|
||||||
|
lhs_time: BigUint,
|
||||||
|
mid_time: BigUint,
|
||||||
|
rhs_time: BigUint,
|
||||||
|
},
|
||||||
PointsToAlias,
|
PointsToAlias,
|
||||||
NoNumBits,
|
|
||||||
NoNumBytes,
|
NoNumBytes,
|
||||||
Other(String),
|
Other(String),
|
||||||
}
|
}
|
||||||
|
@ -100,9 +103,9 @@ impl Signal {
|
||||||
})?;
|
})?;
|
||||||
Ok(bytes_required)
|
Ok(bytes_required)
|
||||||
}
|
}
|
||||||
pub fn lookup_time_and_val(
|
pub(super) fn lookup_time_and_val(
|
||||||
&self,
|
&self,
|
||||||
idx: usize,
|
event_idx: usize,
|
||||||
tmstmps_encoded_as_u8s: &Vec<u8>,
|
tmstmps_encoded_as_u8s: &Vec<u8>,
|
||||||
) -> Result<(TimeStamp, SignalValNum), SignalErrors> {
|
) -> Result<(TimeStamp, SignalValNum), SignalErrors> {
|
||||||
let (
|
let (
|
||||||
|
@ -127,25 +130,26 @@ impl Signal {
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
// get index
|
// get index
|
||||||
let LsbIdxOfTmstmpValOnTmln(timestamp_idx) = lsb_indxs_of_num_tmstmp_vals_on_tmln[idx];
|
let LsbIdxOfTmstmpValOnTmln(timestamp_idx) =
|
||||||
|
lsb_indxs_of_num_tmstmp_vals_on_tmln[event_idx];
|
||||||
let timestamp_idx = timestamp_idx as usize;
|
let timestamp_idx = timestamp_idx as usize;
|
||||||
|
|
||||||
// form timestamp
|
// form timestamp
|
||||||
let byte_len = byte_len_of_num_tmstmp_vals_on_tmln[timestamp_idx] as usize;
|
let byte_len = byte_len_of_num_tmstmp_vals_on_tmln[event_idx] as usize;
|
||||||
let timestamp = &tmstmps_encoded_as_u8s[timestamp_idx..(timestamp_idx + byte_len)];
|
let timestamp = &tmstmps_encoded_as_u8s[timestamp_idx..(timestamp_idx + byte_len)];
|
||||||
let timestamp = BigUint::from_bytes_le(timestamp);
|
let timestamp = BigUint::from_bytes_le(timestamp);
|
||||||
|
|
||||||
// get signal value
|
// get signal value
|
||||||
let bytes_per_value = num_bytes.ok_or_else(|| SignalErrors::NoNumBytes)?;
|
let bytes_per_value = num_bytes.ok_or_else(|| SignalErrors::NoNumBytes)?;
|
||||||
let bytes_per_value = bytes_per_value as usize;
|
let bytes_per_value = bytes_per_value as usize;
|
||||||
let start_idx = idx * bytes_per_value;
|
let start_idx = event_idx * bytes_per_value;
|
||||||
let end_idx = (idx + 1) * bytes_per_value;
|
let end_idx = (event_idx + 1) * bytes_per_value;
|
||||||
let signal_val = &nums_encoded_as_fixed_width_le_u8[start_idx..end_idx];
|
let signal_val = &nums_encoded_as_fixed_width_le_u8[start_idx..end_idx];
|
||||||
let signal_val = BigUint::from_bytes_le(signal_val);
|
let signal_val = BigUint::from_bytes_le(signal_val);
|
||||||
|
|
||||||
Ok((timestamp, signal_val))
|
Ok((timestamp, signal_val))
|
||||||
}
|
}
|
||||||
pub(super) fn query_num_val_on_tmln(
|
pub fn query_num_val_on_tmln(
|
||||||
&self,
|
&self,
|
||||||
desired_time: BigUint,
|
desired_time: BigUint,
|
||||||
tmstmps_encoded_as_u8s: &Vec<u8>,
|
tmstmps_encoded_as_u8s: &Vec<u8>,
|
||||||
|
@ -199,9 +203,13 @@ impl Signal {
|
||||||
line!()
|
line!()
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
if lsb_indxs_of_num_tmstmp_vals_on_tmln.len()
|
if nums_encoded_as_fixed_width_le_u8.len()
|
||||||
!= (nums_encoded_as_fixed_width_le_u8.len() * bytes_required as usize)
|
!= (lsb_indxs_of_num_tmstmp_vals_on_tmln.len() * (bytes_required as usize))
|
||||||
{
|
{
|
||||||
|
dbg!((
|
||||||
|
nums_encoded_as_fixed_width_le_u8.len(),
|
||||||
|
(lsb_indxs_of_num_tmstmp_vals_on_tmln.len() * (bytes_required as usize))
|
||||||
|
));
|
||||||
return Err(SignalErrors::TimelineNotMultiple);
|
return Err(SignalErrors::TimelineNotMultiple);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,12 +260,16 @@ impl Signal {
|
||||||
|
|
||||||
let (left_time, left_val) =
|
let (left_time, left_val) =
|
||||||
self.lookup_time_and_val(lower_idx - 1, tmstmps_encoded_as_u8s)?;
|
self.lookup_time_and_val(lower_idx - 1, tmstmps_encoded_as_u8s)?;
|
||||||
let (right_time, _) = self.lookup_time_and_val(lower_idx - 1, tmstmps_encoded_as_u8s)?;
|
let (right_time, _) = self.lookup_time_and_val(lower_idx, tmstmps_encoded_as_u8s)?;
|
||||||
|
|
||||||
let ordered_left = left_time < desired_time;
|
let ordered_left = left_time < desired_time;
|
||||||
let ordered_right = desired_time < right_time;
|
let ordered_right = desired_time < right_time;
|
||||||
if !(ordered_left && ordered_right) {
|
if !(ordered_left && ordered_right) {
|
||||||
return Err(SignalErrors::OrderingFailure);
|
return Err(SignalErrors::OrderingFailure {
|
||||||
|
lhs_time: left_time,
|
||||||
|
mid_time: desired_time,
|
||||||
|
rhs_time: right_time,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(left_val);
|
return Ok(left_val);
|
||||||
|
|
Loading…
Reference in a new issue