1use std::ops::Deref;
4
5use codegen::impl_save_tuples;
6
7use crate::{
8 schematic::{HasNestedView, NestedInstance, NestedView, Schematic},
9 simulation::{Analysis, SimulationContext, Simulator},
10 types::{
11 ArrayBundle, HasBundleKind,
12 schematic::{IoTerminalBundle, NestedNode},
13 },
14};
15
16#[derive(Debug, Clone, Copy)]
18pub struct SaveOutput;
19
20#[derive(Debug, Clone, Copy)]
22pub struct SaveTime;
23
24#[derive(Debug, Clone, Copy)]
26pub struct SaveFreq;
27
28impl HasNestedView for SaveOutput {
29 type NestedView = SaveOutput;
30
31 fn nested_view(&self, _parent: &substrate::schematic::InstancePath) -> Self::NestedView {
32 *self
33 }
34}
35
36impl HasNestedView for SaveTime {
37 type NestedView = SaveTime;
38
39 fn nested_view(&self, _parent: &substrate::schematic::InstancePath) -> Self::NestedView {
40 *self
41 }
42}
43
44pub type SaveKey<T, S, A> = <T as Save<S, A>>::SaveKey;
46
47pub type Saved<T, S, A> = <T as Save<S, A>>::Saved;
49
50pub trait Save<S: Simulator, A: Analysis> {
52 type SaveKey;
56 type Saved;
58
59 fn save(
62 &self,
63 ctx: &SimulationContext<S>,
64 opts: &mut <S as Simulator>::Options,
65 ) -> <Self as Save<S, A>>::SaveKey;
66
67 fn from_saved(
69 output: &<A as Analysis>::Output,
70 key: &<Self as Save<S, A>>::SaveKey,
71 ) -> <Self as Save<S, A>>::Saved;
72}
73
74impl_save_tuples! {64, NestedNode}
75
76impl<T: Save<S, A>, S: Simulator, A: Analysis> Save<S, A> for Option<T> {
77 type SaveKey = Option<SaveKey<T, S, A>>;
78 type Saved = Option<Saved<T, S, A>>;
79
80 fn save(
81 &self,
82 ctx: &SimulationContext<S>,
83 opts: &mut <S as Simulator>::Options,
84 ) -> <Self as Save<S, A>>::SaveKey {
85 self.as_ref().map(|x| x.save(ctx, opts))
86 }
87
88 fn from_saved(
89 output: &<A as Analysis>::Output,
90 key: &<Self as Save<S, A>>::SaveKey,
91 ) -> <Self as Save<S, A>>::Saved {
92 key.as_ref().map(|k| T::from_saved(output, k))
93 }
94}
95
96impl<T: Save<S, A>, S: Simulator, A: Analysis> Save<S, A> for Vec<T> {
97 type SaveKey = Vec<SaveKey<T, S, A>>;
98 type Saved = Vec<Saved<T, S, A>>;
99
100 fn save(
101 &self,
102 ctx: &SimulationContext<S>,
103 opts: &mut <S as Simulator>::Options,
104 ) -> <Self as Save<S, A>>::SaveKey {
105 self.iter().map(|x| x.save(ctx, opts)).collect()
106 }
107
108 fn from_saved(
109 output: &<A as Analysis>::Output,
110 key: &<Self as Save<S, A>>::SaveKey,
111 ) -> <Self as Save<S, A>>::Saved {
112 key.iter().map(|k| T::from_saved(output, k)).collect()
113 }
114}
115
116impl<T: HasBundleKind + Save<S, A>, S: Simulator, A: Analysis> Save<S, A> for ArrayBundle<T> {
117 type SaveKey = Vec<SaveKey<T, S, A>>;
118 type Saved = Vec<Saved<T, S, A>>;
119
120 fn save(
121 &self,
122 ctx: &SimulationContext<S>,
123 opts: &mut <S as Simulator>::Options,
124 ) -> <Self as Save<S, A>>::SaveKey {
125 (0..self.num_elems())
126 .map(|i| self[i].save(ctx, opts))
127 .collect()
128 }
129
130 fn from_saved(
131 output: &<A as Analysis>::Output,
132 key: &<Self as Save<S, A>>::SaveKey,
133 ) -> <Self as Save<S, A>>::Saved {
134 <Vec<T>>::from_saved(output, key)
135 }
136}
137
138#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
142pub struct NestedInstanceOutput<D, I> {
143 data: D,
145 io: I,
147}
148
149impl<D, I> Deref for NestedInstanceOutput<D, I> {
150 type Target = D;
151 fn deref(&self) -> &Self::Target {
152 &self.data
153 }
154}
155
156impl<D, I> NestedInstanceOutput<D, I> {
157 pub fn io(&self) -> &I {
159 &self.io
160 }
161
162 pub fn data(&self) -> &D {
164 &self.data
165 }
166}
167
168impl<S: Simulator, A: Analysis> Save<S, A> for () {
169 type SaveKey = ();
170 type Saved = ();
171
172 fn save(
173 &self,
174 _ctx: &SimulationContext<S>,
175 _opts: &mut <S as Simulator>::Options,
176 ) -> <Self as Save<S, A>>::SaveKey {
177 }
178
179 fn from_saved(
180 _output: &<A as Analysis>::Output,
181 _key: &<Self as Save<S, A>>::SaveKey,
182 ) -> <Self as Save<S, A>>::Saved {
183 }
184}
185
186impl<T, S, A> Save<S, A> for NestedInstance<T>
187where
188 T: Schematic,
189 S: Simulator,
190 A: Analysis,
191 NestedView<T::NestedData>: Save<S, A>,
192 NestedView<IoTerminalBundle<T>>: Save<S, A>,
193{
194 type SaveKey = (
195 <NestedView<T::NestedData> as Save<S, A>>::SaveKey,
196 <NestedView<IoTerminalBundle<T>> as Save<S, A>>::SaveKey,
197 );
198 type Saved = NestedInstanceOutput<
199 <NestedView<T::NestedData> as Save<S, A>>::Saved,
200 <NestedView<IoTerminalBundle<T>> as Save<S, A>>::Saved,
201 >;
202
203 fn save(
204 &self,
205 ctx: &SimulationContext<S>,
206 opts: &mut <S as Simulator>::Options,
207 ) -> <Self as Save<S, A>>::SaveKey {
208 let data = self.data().save(ctx, opts);
209 let io = self.io().save(ctx, opts);
210 (data, io)
211 }
212
213 fn from_saved(
214 output: &<A as Analysis>::Output,
215 key: &<Self as Save<S, A>>::SaveKey,
216 ) -> <Self as Save<S, A>>::Saved {
217 NestedInstanceOutput {
218 data: <NestedView<T::NestedData> as Save<S, A>>::from_saved(output, &key.0),
219 io: <NestedView<IoTerminalBundle<T>> as Save<S, A>>::from_saved(output, &key.1),
220 }
221 }
222}