///|
pub struct SignalStats {
changes : Int
first_time : Int64?
last_time : Int64?
rising_edges : Int
falling_edges : Int
unknown_values : Int
} derive(Debug)
///|
pub fn stats(trace : Trace, signal_id : String) -> SignalStats {
let mut changes = 0
let mut rising = 0
let mut falling = 0
let mut unknown = 0
let mut first : Int64? = None
let mut last : Int64? = None
let mut previous : Char? = None
for change in trace.changes {
if change.id != signal_id {
continue
}
changes += 1
if first is None {
first = Some(change.time)
}
last = Some(change.time)
match change.value {
Scalar(value) => {
if value == 'x' || value == 'X' || value == 'z' || value == 'Z' {
unknown += 1
}
match previous {
Some('0') if value == '1' => rising += 1
Some('1') if value == '0' => falling += 1
_ => ()
}
previous = Some(value)
}
_ => ()
}
}
{
changes,
first_time: first,
last_time: last,
rising_edges: rising,
falling_edges: falling,
unknown_values: unknown,
}
}
///|
pub fn all_stats(trace : Trace) -> Array[(String, SignalStats)] {
trace.signals.map(fn(signal) { (signal.id, stats(trace, signal.id)) })
}
///|
pub fn duty_cycle(trace : Trace, signal_id : String) -> Double? {
let mut high : Int64 = 0L
let mut start : Int64? = None
let mut previous : Char? = None
for change in trace.changes {
if change.id != signal_id {
continue
}
match previous {
Some('1') =>
match start {
Some(t) => high += change.time - t
None => ()
}
_ => ()
}
match change.value {
Scalar('1') => start = Some(change.time)
Scalar(_) => start = None
_ => start = None
}
match change.value {
Scalar(c) => previous = Some(c)
_ => previous = None
}
}
if trace.end_time <= 0L {
None
} else {
Some(high.to_double() / trace.end_time.to_double())
}
}