1use crate::netlist::prelude::*;
7use crate::traits::NetlistBase;
8
9use super::hierarchy_reference_access::*;
10
11pub trait NetlistReferenceAccess: NetlistBase {
13 fn pin_ref(&self, pin: &Self::PinId) -> PinRef<'_, Self> {
15 PinRef {
16 base: self,
17 id: pin.clone(),
18 }
19 }
20
21 fn pin_instance_ref(&self, id: &Self::PinInstId) -> PinInstRef<'_, Self> {
23 PinInstRef {
24 base: self,
25 id: id.clone(),
26 }
27 }
28
29 fn net_ref(&self, net: &Self::NetId) -> NetRef<'_, Self> {
31 NetRef {
32 base: self,
33 id: net.clone(),
34 }
35 }
36
37 fn terminal_ref(&self, t: &TerminalId<Self>) -> TerminalRef<Self> {
39 match t {
40 TerminalId::PinId(p) => TerminalRef::Pin(self.pin_ref(p)),
41 TerminalId::PinInstId(p) => TerminalRef::PinInst(self.pin_instance_ref(p)),
42 }
43 }
44}
45
46impl<T: NetlistBase> NetlistReferenceAccess for T {}
47
48impl<'a, N: NetlistBase> CellRef<'a, N> {
49 pub fn each_pin_id(&self) -> impl Iterator<Item = N::PinId> + '_ {
51 self.base.each_pin(&self.id)
52 }
53
54 pub fn each_pin(&self) -> impl Iterator<Item = PinRef<'a, N>> + '_ {
56 self.base.each_pin(&self.id).map(move |id| PinRef {
57 base: self.base,
58 id,
59 })
60 }
61
62 pub fn each_input_pin(&self) -> impl Iterator<Item = PinRef<'a, N>> + '_ {
64 self.each_pin().filter(|p| p.direction().is_input())
65 }
66
67 pub fn each_output_pin(&self) -> impl Iterator<Item = PinRef<'a, N>> + '_ {
69 self.each_pin().filter(|p| p.direction().is_output())
70 }
71
72 pub fn pin_by_name(&self, name: &str) -> Option<PinRef<'a, N>> {
74 self.base.pin_by_name(&self.id, name).map(|id| PinRef {
75 base: self.base,
76 id,
77 })
78 }
79
80 pub fn each_net(&self) -> impl Iterator<Item = NetRef<'a, N>> + '_ {
82 self.base.each_internal_net(&self.id).map(move |id| NetRef {
83 base: self.base,
84 id,
85 })
86 }
87
88 pub fn num_internal_nets(&self) -> usize {
90 self.base.num_internal_nets(&self.id)
91 }
92
93 pub fn net_by_name(&self, name: &str) -> Option<NetRef<'a, N>> {
95 self.base.net_by_name(&self.id, name).map(|id| NetRef {
96 base: self.base,
97 id,
98 })
99 }
100}
101
102impl<'a, N: NetlistBase> CellInstRef<'a, N> {
103 pub fn each_pin_instance_id(&self) -> impl Iterator<Item = N::PinInstId> + '_ {
105 self.base.each_pin_instance(&self.id)
106 }
107
108 pub fn each_pin_instance(&self) -> impl Iterator<Item = PinInstRef<'a, N>> + '_ {
110 self.base
111 .each_pin_instance(&self.id)
112 .map(move |id| PinInstRef {
113 base: self.base,
114 id,
115 })
116 }
117
118 pub fn each_net(&self) -> impl Iterator<Item = NetRef<'a, N>> + '_ {
120 self.base.each_external_net(&self.id).map(move |id| NetRef {
121 base: self.base,
122 id,
123 })
124 }
125
126 pub fn pin_instance(&self, pin: &N::PinId) -> PinInstRef<'a, N> {
128 self.base.pin_ref(pin).instance(&self.id())
129 }
130
131 pub fn pin_instance_by_name(&self, name: &str) -> Option<PinInstRef<'a, N>> {
133 let pin_id = self.base.pin_by_name(&self.template().id(), name);
134 pin_id.map(|p| self.pin_instance(&p))
135 }
136}
137
138pub struct NetRef<'a, N: NetlistBase + ?Sized> {
141 pub(super) base: &'a N,
143 pub(super) id: N::NetId,
145}
146
147impl<'a, N: NetlistBase> Eq for NetRef<'a, N> {}
148impl<'a, N: NetlistBase> PartialEq for NetRef<'a, N> {
149 fn eq(&self, other: &Self) -> bool {
150 self.id == other.id && std::ptr::eq(self.base, other.base)
151 }
152}
153
154impl<'a, N: NetlistBase> NetRef<'a, N> {
155 pub fn id(&self) -> N::NetId {
157 self.id.clone()
158 }
159
160 pub fn name(&self) -> Option<N::NameType> {
162 self.base.net_name(&self.id)
163 }
164
165 pub fn parent(&self) -> CellRef<'a, N> {
167 CellRef {
168 base: self.base,
169 id: self.base.parent_cell_of_net(&self.id),
170 }
171 }
172
173 pub fn each_pin(&self) -> impl Iterator<Item = PinRef<'a, N>> + '_ {
175 self.base.each_pin_of_net(&self.id).map(move |id| PinRef {
176 base: self.base,
177 id,
178 })
179 }
180
181 pub fn each_pin_instance(&self) -> impl Iterator<Item = PinInstRef<'a, N>> + '_ {
183 self.base
184 .each_pin_instance_of_net(&self.id)
185 .map(move |id| PinInstRef {
186 base: self.base,
187 id,
188 })
189 }
190
191 pub fn each_terminal(&self) -> impl Iterator<Item = TerminalRef<'a, N>> + '_ {
193 let pins = self.each_pin().map(|p| p.into());
194 let pin_insts = self.each_pin_instance().map(|p| p.into());
195 pins.chain(pin_insts)
196 }
197
198 pub fn each_driver(&self) -> impl Iterator<Item = TerminalRef<'a, N>> + '_ {
202 self.each_terminal().filter(|t| match t {
203 TerminalRef::Pin(p) => p.direction().is_input(),
204 TerminalRef::PinInst(p) => p.pin().direction().is_output(),
205 })
206 }
207
208 pub fn each_sink(&self) -> impl Iterator<Item = TerminalRef<'a, N>> + '_ {
212 self.each_terminal().filter(|t| match t {
213 TerminalRef::Pin(p) => p.direction().is_output(),
214 TerminalRef::PinInst(p) => p.pin().direction().is_input(),
215 })
216 }
217
218 pub fn qname(&self, separator: &str) -> String {
220 format!(
221 "{}{}{}",
222 self.parent().name(),
223 separator,
224 self.name()
225 .unwrap_or_else(|| "<unnamed>".to_string().into())
226 )
227 }
228
229 pub fn num_pins(&self) -> usize {
231 self.base.num_net_pins(&self.id)
232 }
233
234 pub fn num_pin_instances(&self) -> usize {
236 self.base.num_net_pin_instances(&self.id)
237 }
238
239 pub fn num_terminals(&self) -> usize {
241 self.base.num_net_terminals(&self.id)
242 }
243}
244
245pub struct PinRef<'a, N: NetlistBase + ?Sized> {
248 pub(super) base: &'a N,
250 pub(super) id: N::PinId,
252}
253
254impl<'a, N: NetlistBase> Eq for PinRef<'a, N> {}
255impl<'a, N: NetlistBase> PartialEq for PinRef<'a, N> {
256 fn eq(&self, other: &Self) -> bool {
257 self.id == other.id && std::ptr::eq(self.base, other.base)
258 }
259}
260
261impl<'a, N: NetlistBase + ?Sized> Clone for PinRef<'a, N> {
262 fn clone(&self) -> Self {
263 Self {
264 base: self.base,
265 id: self.id.clone(),
266 }
267 }
268}
269
270impl<'a, N: NetlistBase> PinRef<'a, N> {
271 pub fn base(&self) -> &'_ N {
273 self.base
274 }
275
276 pub fn id(&self) -> N::PinId {
278 self.id.clone()
279 }
280
281 pub fn terminal_id(&self) -> TerminalId<N> {
283 TerminalId::PinId(self.id())
284 }
285
286 pub fn name(&self) -> N::NameType {
288 self.base.pin_name(&self.id)
289 }
290
291 pub fn direction(&self) -> Direction {
293 self.base.pin_direction(&self.id)
294 }
295
296 pub fn net(&self) -> Option<NetRef<'a, N>> {
298 self.base.net_of_pin(&self.id).map(|id| NetRef {
299 base: self.base,
300 id,
301 })
302 }
303
304 pub fn cell(&self) -> CellRef<'a, N> {
306 CellRef {
307 base: self.base,
308 id: self.base.parent_cell_of_pin(&self.id),
309 }
310 }
311
312 pub fn instance(&self, cell_inst: &N::CellInstId) -> PinInstRef<'a, N> {
314 PinInstRef {
315 base: self.base,
316 id: self.base.pin_instance(cell_inst, &self.id),
317 }
318 }
319
320 pub fn into_terminal(self) -> TerminalRef<'a, N> {
322 self.into()
323 }
324
325 pub fn qname(&self, separator: &str) -> String {
328 format!("{}{}{}", self.cell().name(), separator, self.name())
329 }
330}
331
332pub struct PinInstRef<'a, N: NetlistBase + ?Sized> {
335 pub(super) base: &'a N,
337 pub(super) id: N::PinInstId,
339}
340
341impl<'a, N: NetlistBase> Eq for PinInstRef<'a, N> {}
342impl<'a, N: NetlistBase> PartialEq for PinInstRef<'a, N> {
343 fn eq(&self, other: &Self) -> bool {
344 self.id == other.id && std::ptr::eq(self.base, other.base)
345 }
346}
347
348impl<'a, N: NetlistBase + ?Sized> Clone for PinInstRef<'a, N> {
349 fn clone(&self) -> Self {
350 Self {
351 base: self.base,
352 id: self.id.clone(),
353 }
354 }
355}
356
357impl<'a, N: NetlistBase> PinInstRef<'a, N> {
358 pub fn id(&self) -> N::PinInstId {
360 self.id.clone()
361 }
362
363 pub fn base(&self) -> &'_ N {
365 self.base
366 }
367
368 pub fn terminal_id(&self) -> TerminalId<N> {
370 TerminalId::PinInstId(self.id())
371 }
372
373 pub fn pin(&self) -> PinRef<'a, N> {
375 PinRef {
376 base: self.base,
377 id: self.base.template_pin(&self.id),
378 }
379 }
380
381 pub fn cell_instance(&self) -> CellInstRef<'a, N> {
383 CellInstRef {
384 base: self.base,
385 id: self.base.parent_of_pin_instance(&self.id),
386 }
387 }
388
389 pub fn net(&self) -> Option<NetRef<'a, N>> {
391 self.base.net_of_pin_instance(&self.id).map(|id| NetRef {
392 base: self.base,
393 id,
394 })
395 }
396
397 pub fn into_terminal(self) -> TerminalRef<'a, N> {
399 self.into()
400 }
401
402 pub fn qname(&self, separator: &str) -> String {
406 format!(
407 "{}{}{}{}{}",
408 self.pin().cell().name(),
409 separator,
410 self.cell_instance()
411 .name()
412 .unwrap_or_else(|| "<unnamed>".to_string().into()),
413 separator,
414 self.pin().name()
415 )
416 }
417}
418
419pub enum TerminalRef<'a, N: NetlistBase + ?Sized> {
421 Pin(PinRef<'a, N>),
423 PinInst(PinInstRef<'a, N>),
425}
426
427impl<'a, N: NetlistBase + ?Sized> Clone for TerminalRef<'a, N> {
428 fn clone(&self) -> Self {
429 match self {
430 TerminalRef::Pin(p) => TerminalRef::Pin(p.clone()),
431 TerminalRef::PinInst(p) => TerminalRef::PinInst(p.clone()),
432 }
433 }
434}
435
436impl<'a, N: NetlistBase> PartialEq for TerminalRef<'a, N> {
437 fn eq(&self, other: &Self) -> bool {
438 self.id() == other.id()
439 }
440}
441
442impl<'a, N: NetlistBase> From<PinRef<'a, N>> for TerminalRef<'a, N> {
443 fn from(p: PinRef<'a, N>) -> Self {
444 Self::Pin(p)
445 }
446}
447
448impl<'a, N: NetlistBase> From<PinInstRef<'a, N>> for TerminalRef<'a, N> {
449 fn from(p: PinInstRef<'a, N>) -> Self {
450 Self::PinInst(p)
451 }
452}
453
454impl<'a, N: NetlistBase> From<TerminalRef<'a, N>> for TerminalId<N> {
455 fn from(t: TerminalRef<'a, N>) -> Self {
456 match t {
457 TerminalRef::Pin(p) => TerminalId::PinId(p.id),
458 TerminalRef::PinInst(p) => TerminalId::PinInstId(p.id),
459 }
460 }
461}
462
463impl<'a, N: NetlistBase> TerminalRef<'a, N> {
464 pub fn id(&self) -> TerminalId<N> {
466 (*self).clone().into()
467 }
468
469 pub fn base(&self) -> &'_ N {
471 match self {
472 TerminalRef::Pin(p) => p.base(),
473 TerminalRef::PinInst(p) => p.base(),
474 }
475 }
476
477 pub fn net(&self) -> Option<NetRef<'a, N>> {
479 match self {
480 TerminalRef::Pin(p) => p.net(),
481 TerminalRef::PinInst(p) => p.net(),
482 }
483 }
484
485 pub fn pin_name(&self) -> N::NameType {
487 match self {
488 TerminalRef::Pin(p) => p.name(),
489 TerminalRef::PinInst(p) => p.pin().name(),
490 }
491 }
492
493 pub fn parent(&self) -> CellRef<N> {
497 match self {
498 TerminalRef::Pin(p) => p.cell(),
499 TerminalRef::PinInst(p) => p.cell_instance().parent(),
500 }
501 }
502
503 pub fn qname(&self, separator: &str) -> String {
508 match self {
509 TerminalRef::Pin(p) => p.qname(separator),
510 TerminalRef::PinInst(p) => p.qname(separator),
511 }
512 }
513}