reda_sp/model/sources/
pulse.rs1use derive_builder::Builder;
2use reda_unit::{u, Time, Voltage};
3
4#[derive(Debug, Clone, Builder)]
5pub struct PulseVoltage {
6 pub v0: Voltage, pub v1: Voltage, pub delay: Time, pub rise: Time, pub fall: Time, pub width: Time, pub period: Time, }
14
15impl PulseVoltage {
16 pub fn clock(vdd: Voltage, period: Time, slew: Time) -> Self {
17 Self {
18 v0: u!(0 V),
19 v1: vdd,
20 delay: u!(0 s),
21 rise: slew,
22 fall: slew,
23 width: (period - 2. * slew) / 2.,
24 period
25 }
26 }
27
28 pub fn voltage_at(&self, time: Time) -> Voltage {
29 if time <= self.delay {
30 return self.v0;
31 }
32
33 let t_in_cycle = (time - self.delay) % self.period;
34
35 let delta_v = self.v1 - self.v0;
36 match t_in_cycle {
37 t if t.value() < 0.0 => self.v0,
38 t if t < self.rise => {
39 self.v0 + delta_v * (t / self.rise)
41 }
42 t if t < (self.rise + self.width) => {
43 self.v1
45 }
46 t if t < (self.rise + self.width + self.fall) => {
47 self.v1 - delta_v * ((t - self.rise - self.width) / self.fall)
49 }
50 _ => self.v0
51 }
52 }
53
54 pub fn to_spice(&self) -> String {
55 format!(
56 "PULSE({} {} {} {} {} {} {})",
57 self.v0,
58 self.v1,
59 self.delay,
60 self.rise,
61 self.fall,
62 self.width,
63 self.period
64 )
65 }
66}