ordered search now working

This commit is contained in:
Yehowshua Immanuel 2022-09-02 15:05:33 -04:00
parent 223d36c1a6
commit aeb796c46b
4 changed files with 103 additions and 38 deletions

View file

@ -39,6 +39,20 @@ pub fn parse_vcd(file: File) -> Result<VCD, String> {
parse_scopes(&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)
}

View file

@ -1,3 +1,5 @@
use num::Zero;
use super::*;
pub(super) fn parse_events<'a>(
@ -7,6 +9,7 @@ pub(super) fn parse_events<'a>(
) -> Result<(), String> {
let mut curr_tmstmp_lsb_idx = 0u32;
let mut curr_tmstmp_len_u8 = 0u8;
let mut curr_time = BigUint::zero();
loop {
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:?}"
)
})?;
curr_time = value.clone();
let mut value = value.to_bytes_le();
// TODO : u32 helps with less memory, but should ideally likely be
// configurable.
@ -45,16 +49,15 @@ pub(super) fn parse_events<'a>(
line!()
)
})?;
vcd.tmstmps_encoded_as_u8s.append(&mut value);
curr_tmstmp_lsb_idx =
u32::try_from(vcd.tmstmps_encoded_as_u8s.len()).map_err(|_| {
format!(
"Error near {}:{}. Failed to convert from usize to u8.",
"Error near {}:{}. Failed to convert from usize to u32.",
file!(),
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
@ -111,10 +114,6 @@ pub(super) fn parse_events<'a>(
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 {
Signal::Data {
name,
@ -172,6 +171,19 @@ pub(super) fn parse_events<'a>(
string_vals.push(value_string);
Ok(())
} 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 =
u8::try_from(value_u8.len()).map_err(|_| {
format!(
@ -182,22 +194,12 @@ pub(super) fn parse_events<'a>(
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 {
nums_encoded_as_fixed_width_le_u8.push(0u8);
curr_num_bytes += 1;
}
byte_len_of_num_tmstmp_vals_on_tmln.push(curr_tmstmp_len_u8);
Ok(())
}
}
@ -231,6 +233,7 @@ pub(super) fn parse_events<'a>(
sig_type,
ref mut signal_error,
num_bits,
num_bytes,
nums_encoded_as_fixed_width_le_u8,
lsb_indxs_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)?;
}
};
nums_encoded_as_fixed_width_le_u8.push(0u8);
// 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!())
})?;
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(())
}
Signal::Alias { .. } => {
@ -306,6 +324,7 @@ pub(super) fn parse_events<'a>(
sig_type,
ref mut signal_error,
num_bits,
num_bytes,
nums_encoded_as_fixed_width_le_u8,
lsb_indxs_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)?;
}
};
nums_encoded_as_fixed_width_le_u8.push(1u8);
// 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!())
})?;
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(())
}
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" => {
let val = word.to_string();
// lokup signal idx
@ -385,6 +419,7 @@ pub(super) fn parse_events<'a>(
num_bits,
string_vals,
byte_len_of_num_tmstmp_vals_on_tmln,
byte_len_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)?;
}
};
string_vals.push(val);
// record timestamp at which this event occurs
lsb_indxs_of_string_tmstmp_vals_on_tmln
.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(())
}
Signal::Alias { .. } => {

View file

@ -122,8 +122,8 @@ pub(super) fn parse_var<'a>(
string_vals: vec![],
lsb_indxs_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![],
lsb_indxs_of_string_tmstmp_vals_on_tmln: vec![],
scope_parent: parent_scope_idx,
};
(signal, signal_idx)

View file

@ -58,8 +58,8 @@ pub(super) enum Signal {
// a particular timestamp is composed of.
lsb_indxs_of_num_tmstmp_vals_on_tmln: Vec<LsbIdxOfTmstmpValOnTmln>,
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>,
lsb_indxs_of_string_tmstmp_vals_on_tmln: Vec<LsbIdxOfTmstmpValOnTmln>,
scope_parent: ScopeIdx,
},
Alias {
@ -76,9 +76,12 @@ pub(super) enum SignalErrors {
},
EmptyTimeline,
TimelineNotMultiple,
OrderingFailure,
OrderingFailure {
lhs_time: BigUint,
mid_time: BigUint,
rhs_time: BigUint,
},
PointsToAlias,
NoNumBits,
NoNumBytes,
Other(String),
}
@ -100,9 +103,9 @@ impl Signal {
})?;
Ok(bytes_required)
}
pub fn lookup_time_and_val(
pub(super) fn lookup_time_and_val(
&self,
idx: usize,
event_idx: usize,
tmstmps_encoded_as_u8s: &Vec<u8>,
) -> Result<(TimeStamp, SignalValNum), SignalErrors> {
let (
@ -127,25 +130,26 @@ impl Signal {
}?;
// 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;
// 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 = BigUint::from_bytes_le(timestamp);
// get signal value
let bytes_per_value = num_bytes.ok_or_else(|| SignalErrors::NoNumBytes)?;
let bytes_per_value = bytes_per_value as usize;
let start_idx = idx * bytes_per_value;
let end_idx = (idx + 1) * bytes_per_value;
let start_idx = event_idx * 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 = BigUint::from_bytes_le(signal_val);
Ok((timestamp, signal_val))
}
pub(super) fn query_num_val_on_tmln(
pub fn query_num_val_on_tmln(
&self,
desired_time: BigUint,
tmstmps_encoded_as_u8s: &Vec<u8>,
@ -199,9 +203,13 @@ impl Signal {
line!()
))
})?;
if lsb_indxs_of_num_tmstmp_vals_on_tmln.len()
!= (nums_encoded_as_fixed_width_le_u8.len() * bytes_required as usize)
if nums_encoded_as_fixed_width_le_u8.len()
!= (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);
}
@ -252,12 +260,16 @@ impl Signal {
let (left_time, left_val) =
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_right = desired_time < right_time;
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);