1use std::sync::Arc;
4
5use scir::{Library, NamedSliceOne, NetlistLibConversion, SliceOnePath};
6
7use crate::{
8 simulation::{
9 Analysis, Simulator,
10 data::{Save, SaveKey, Saved},
11 },
12 types::schematic::{NestedNode, RawNestedNode},
13};
14
15use super::{
16 Cell, ContextView, HasContextView, HasNestedView, InstancePath, NestedView, Schematic,
17 conv::{ConvertedNodePath, RawLib},
18 schema::Schema,
19};
20
21pub struct PexContext<S: Schema> {
23 lib: Arc<RawLib<S>>,
25 conv: Arc<NetlistLibConversion>,
26 path: InstancePath,
27}
28
29impl<S: Schema> Clone for PexContext<S> {
30 fn clone(&self) -> Self {
31 Self {
32 lib: self.lib.clone(),
33 conv: self.conv.clone(),
34 path: self.path.clone(),
35 }
36 }
37}
38
39pub trait StringPathSchema: Schema {
41 fn node_path(lib: &Library<Self>, conv: &NetlistLibConversion, path: &SliceOnePath) -> String;
43}
44
45impl<S: StringPathSchema> HasContextView<PexContext<S>> for NestedNode {
46 type ContextView = RawNestedNode;
47
48 fn context_view(&self, parent: &PexContext<S>) -> ContextView<Self, PexContext<S>> {
49 let n = self;
50 let path = parent.lib.convert_node_path(&n.path()).unwrap();
51 let path = match path {
52 ConvertedNodePath::Cell(path) => path,
53 ConvertedNodePath::Primitive {
54 instances, port, ..
55 } => SliceOnePath::new(instances.clone(), NamedSliceOne::new(port.clone())),
56 };
57 let path = parent.lib.scir.simplify_path(path);
58 RawNestedNode::new(
59 parent.path.clone(),
60 S::node_path(&parent.lib.scir, &parent.conv, &path),
61 )
62 }
63}
64
65pub struct PexData<T: Schematic> {
67 cell: Cell<Arc<T>>,
68 lib: Arc<RawLib<T::Schema>>,
69 conv: Arc<NetlistLibConversion>,
70}
71
72impl<T: Schematic> Clone for PexData<T> {
73 fn clone(&self) -> Self {
74 Self {
75 cell: self.cell.clone(),
76 lib: self.lib.clone(),
77 conv: self.conv.clone(),
78 }
79 }
80}
81
82impl<T: Schematic> PexData<T> {
83 pub fn new(
85 cell: Cell<Arc<T>>,
86 lib: Arc<RawLib<T::Schema>>,
87 conv: Arc<NetlistLibConversion>,
88 ) -> Self {
89 Self { cell, lib, conv }
90 }
91}
92
93pub struct NestedPexData<T: Schematic> {
95 cell: Cell<Arc<T>>,
96 ctx: PexContext<T::Schema>,
97}
98
99impl<T: Schematic> Clone for NestedPexData<T> {
100 fn clone(&self) -> Self {
101 Self {
102 cell: self.cell.clone(),
103 ctx: self.ctx.clone(),
104 }
105 }
106}
107
108impl<T: Schematic> NestedPexData<T>
109where
110 T::NestedData: HasContextView<PexContext<T::Schema>>,
111{
112 pub fn data(&self) -> ContextView<T::NestedData, PexContext<T::Schema>> {
114 self.cell.context_data(&self.ctx)
115 }
116}
117
118impl<T: Schematic> HasNestedView for PexData<T> {
119 type NestedView = NestedPexData<T>;
120 fn nested_view(&self, parent: &InstancePath) -> NestedView<Self> {
121 NestedPexData {
122 cell: self.cell.clone(),
123 ctx: PexContext {
124 lib: self.lib.clone(),
125 conv: self.conv.clone(),
126 path: parent.clone(),
127 },
128 }
129 }
130}
131
132impl<T: Schematic> HasNestedView for NestedPexData<T> {
133 type NestedView = NestedPexData<T>;
134 fn nested_view(&self, parent: &InstancePath) -> NestedView<Self> {
135 NestedPexData {
136 cell: self.cell.clone(),
137 ctx: PexContext {
138 lib: self.ctx.lib.clone(),
139 conv: self.ctx.conv.clone(),
140 path: self.ctx.path.prepend(parent),
141 },
142 }
143 }
144}
145
146impl<S: Simulator, A: Analysis, T: Schematic> Save<S, A> for NestedPexData<T>
147where
148 T::NestedData: HasContextView<PexContext<T::Schema>>,
149 ContextView<T::NestedData, PexContext<T::Schema>>: Save<S, A>,
150{
151 type SaveKey = SaveKey<ContextView<T::NestedData, PexContext<T::Schema>>, S, A>;
152 type Saved = Saved<ContextView<T::NestedData, PexContext<T::Schema>>, S, A>;
153
154 fn save(
155 &self,
156 ctx: &substrate::simulation::SimulationContext<S>,
157 opts: &mut <S as Simulator>::Options,
158 ) -> <Self as Save<S, A>>::SaveKey {
159 self.data().save(ctx, opts)
160 }
161
162 fn from_saved(
163 output: &<A as Analysis>::Output,
164 key: &<Self as Save<S, A>>::SaveKey,
165 ) -> <Self as Save<S, A>>::Saved {
166 <ContextView<T::NestedData, PexContext<T::Schema>> as Save<S, A>>::from_saved(output, key)
167 }
168}