1use rustdv_gpi as gpi;
4
5#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
8pub struct SimDuration {
9 pub steps: u64,
10}
11
12impl SimDuration {
13 pub fn steps(steps: u64) -> SimDuration {
14 SimDuration { steps }
15 }
16
17 fn from_pow10(n: u64, exp: i32) -> SimDuration {
18 let prec = gpi::time_precision();
19 if exp >= prec {
20 let factor = 10u64.pow((exp - prec) as u32);
21 SimDuration { steps: n * factor }
22 } else {
23 let div = 10u64.pow((prec - exp) as u32);
24 assert!(
25 n % div == 0,
26 "duration {n}e{exp} is below simulator precision 1e{prec}"
27 );
28 SimDuration { steps: n / div }
29 }
30 }
31
32 pub fn fs(n: u64) -> SimDuration {
33 Self::from_pow10(n, -15)
34 }
35 pub fn ps(n: u64) -> SimDuration {
36 Self::from_pow10(n, -12)
37 }
38 pub fn ns(n: u64) -> SimDuration {
39 Self::from_pow10(n, -9)
40 }
41 pub fn us(n: u64) -> SimDuration {
42 Self::from_pow10(n, -6)
43 }
44 pub fn ms(n: u64) -> SimDuration {
45 Self::from_pow10(n, -3)
46 }
47 pub fn sec(n: u64) -> SimDuration {
48 Self::from_pow10(n, 0)
49 }
50
51 pub fn from_unit(n: u64, unit: &str) -> SimDuration {
53 match unit {
54 "fs" => Self::fs(n),
55 "ps" => Self::ps(n),
56 "ns" => Self::ns(n),
57 "us" => Self::us(n),
58 "ms" => Self::ms(n),
59 "s" | "sec" => Self::sec(n),
60 "step" | "steps" => Self::steps(n),
61 _ => panic!("unknown time unit '{unit}'"),
62 }
63 }
64}
65
66pub fn sim_time_steps() -> u64 {
68 gpi::sim_time_steps()
69}
70
71pub fn sim_time_ns() -> f64 {
73 let prec = gpi::time_precision();
74 let steps = gpi::sim_time_steps() as f64;
75 steps * 10f64.powi(prec + 9)
76}