reda_sp/model/sources/
pulse.rs

1use derive_builder::Builder;
2use reda_unit::{u, Time, Voltage};
3
4#[derive(Debug, Clone, Builder)]
5pub struct PulseVoltage {
6    pub v0: Voltage,      // 初始电压 Vo
7    pub v1: Voltage,      // 峰值电压 V1
8    pub delay: Time,      // Td 初始延迟
9    pub rise: Time,       // Tr 上升时间
10    pub fall: Time,       // Tf 下降时间
11    pub width: Time,      // Tw 脉宽
12    pub period: Time,     // To 周期
13}
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                // In rise
40                self.v0 + delta_v * (t / self.rise)
41            }
42            t if t < (self.rise + self.width) => {
43                // high
44                self.v1
45            }
46            t if t < (self.rise + self.width + self.fall) => {
47                // In fall
48                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}