safety_net/
netlist.rs

1/*!
2
3  API for a netlist data structure.
4
5*/
6
7use crate::{
8    attribute::{Attribute, AttributeKey, AttributeValue, Parameter},
9    circuit::{Identifier, Instantiable, Net, Object},
10    error::Error,
11    graph::{Analysis, FanOutTable},
12    logic::Logic,
13};
14use std::{
15    cell::{Ref, RefCell, RefMut},
16    collections::{BTreeSet, HashMap, HashSet},
17    num::ParseIntError,
18    rc::{Rc, Weak},
19};
20
21/// A trait for indexing into a collection of objects weakly.
22trait WeakIndex<Idx: ?Sized> {
23    /// The output data type which will be referred to weakly
24    type Output: ?Sized;
25    /// Indexes the collection weakly by the given index.
26    fn index_weak(&self, index: &Idx) -> Rc<RefCell<Self::Output>>;
27}
28
29/// A primitive gate in a digital circuit, such as AND, OR, NOT, etc.
30/// VDD and GND are reserved to represent logic one and zero, respectively.
31#[derive(Debug, Clone)]
32#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
33pub struct Gate {
34    /// The name of the primitive
35    name: Identifier,
36    /// Input ports, order matters
37    inputs: Vec<Net>,
38    /// Output ports, order matters
39    outputs: Vec<Net>,
40}
41
42impl Instantiable for Gate {
43    fn get_name(&self) -> &Identifier {
44        &self.name
45    }
46
47    fn get_input_ports(&self) -> impl IntoIterator<Item = &Net> {
48        &self.inputs
49    }
50
51    fn get_output_ports(&self) -> impl IntoIterator<Item = &Net> {
52        &self.outputs
53    }
54
55    fn has_parameter(&self, _id: &Identifier) -> bool {
56        false
57    }
58
59    fn get_parameter(&self, _id: &Identifier) -> Option<Parameter> {
60        None
61    }
62
63    fn set_parameter(&mut self, _id: &Identifier, _val: Parameter) -> Option<Parameter> {
64        None
65    }
66
67    fn parameters(&self) -> impl Iterator<Item = (Identifier, Parameter)> {
68        std::iter::empty()
69    }
70
71    fn from_constant(val: Logic) -> Option<Self> {
72        match val {
73            Logic::True => Some(Gate::new_logical("VDD".into(), vec![], "Y".into())),
74            Logic::False => Some(Gate::new_logical("GND".into(), vec![], "Y".into())),
75            _ => None,
76        }
77    }
78
79    fn get_constant(&self) -> Option<Logic> {
80        match self.name.to_string().as_str() {
81            "VDD" => Some(Logic::True),
82            "GND" => Some(Logic::False),
83            _ => None,
84        }
85    }
86
87    fn is_seq(&self) -> bool {
88        false
89    }
90}
91
92impl Gate {
93    /// Creates a new gate primitive with four-state logic types
94    pub fn new_logical(name: Identifier, inputs: Vec<Identifier>, output: Identifier) -> Self {
95        if name.is_sliced() {
96            panic!("Attempted to create a gate with a sliced identifier: {name}");
97        }
98
99        let outputs = vec![Net::new_logic(output)];
100        let inputs = inputs.into_iter().map(Net::new_logic).collect::<Vec<_>>();
101        Self {
102            name,
103            inputs,
104            outputs,
105        }
106    }
107
108    /// Creates a new gate primitive with four-state logic types with multiple outputs
109    pub fn new_logical_multi(
110        name: Identifier,
111        inputs: Vec<Identifier>,
112        outputs: Vec<Identifier>,
113    ) -> Self {
114        if name.is_sliced() {
115            panic!("Attempted to create a gate with a sliced identifier: {name}");
116        }
117
118        let outputs = outputs.into_iter().map(Net::new_logic).collect::<Vec<_>>();
119        let inputs = inputs.into_iter().map(Net::new_logic).collect::<Vec<_>>();
120        Self {
121            name,
122            inputs,
123            outputs,
124        }
125    }
126
127    /// Returns the single output port of the gate
128    pub fn get_single_output_port(&self) -> &Net {
129        if self.outputs.len() > 1 {
130            panic!("Attempted to grab output port of a multi-output gate");
131        }
132        self.outputs
133            .first()
134            .expect("Gate is missing an output port")
135    }
136
137    /// Set the type of cell by name
138    pub fn set_gate_name(&mut self, new_name: Identifier) {
139        self.name = new_name;
140    }
141
142    /// Returns the name of the gate primitive
143    pub fn get_gate_name(&self) -> &Identifier {
144        &self.name
145    }
146}
147
148/// An operand to an [Instantiable]
149#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
150#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
151enum Operand {
152    /// An index into the list of objects
153    DirectIndex(usize),
154    /// An index into the list of objects, with an extra index on the cell/primitive
155    CellIndex(usize, usize),
156}
157
158impl Operand {
159    /// Remap the node index of the operand to `x`.
160    fn remap(self, x: usize) -> Self {
161        match self {
162            Operand::DirectIndex(_idx) => Operand::DirectIndex(x),
163            Operand::CellIndex(_idx, j) => Operand::CellIndex(x, j),
164        }
165    }
166
167    /// Returns the circuit node index
168    fn root(&self) -> usize {
169        match self {
170            Operand::DirectIndex(idx) => *idx,
171            Operand::CellIndex(idx, _) => *idx,
172        }
173    }
174
175    /// Returns the secondary index (the cell index)
176    fn secondary(&self) -> usize {
177        match self {
178            Operand::DirectIndex(_) => 0,
179            Operand::CellIndex(_, j) => *j,
180        }
181    }
182}
183
184impl std::fmt::Display for Operand {
185    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
186        match self {
187            Operand::DirectIndex(idx) => write!(f, "{idx}"),
188            Operand::CellIndex(idx, j) => write!(f, "{idx}.{j}"),
189        }
190    }
191}
192
193impl std::str::FromStr for Operand {
194    type Err = ParseIntError;
195
196    fn from_str(s: &str) -> Result<Self, Self::Err> {
197        match s.split_once('.') {
198            Some((idx, j)) => {
199                let idx = idx.parse::<usize>()?;
200                let j = j.parse::<usize>()?;
201                Ok(Operand::CellIndex(idx, j))
202            }
203            None => {
204                let idx = s.parse::<usize>()?;
205                Ok(Operand::DirectIndex(idx))
206            }
207        }
208    }
209}
210
211/// An object that has a reference to its owning netlist/module
212#[derive(Debug)]
213struct OwnedObject<I, O>
214where
215    I: Instantiable,
216    O: WeakIndex<usize, Output = Self>,
217{
218    /// The object that is owned by the netlist
219    object: Object<I>,
220    /// The weak reference to the owner netlist/module
221    owner: Weak<O>,
222    /// The list of operands for the object
223    operands: Vec<Option<Operand>>,
224    /// A collection of attributes for the object
225    attributes: HashMap<AttributeKey, AttributeValue>,
226    /// The index of the object within the netlist/module
227    index: usize,
228}
229
230impl<I, O> OwnedObject<I, O>
231where
232    I: Instantiable,
233    O: WeakIndex<usize, Output = Self>,
234{
235    /// Get an iterator to mutate the operand indices
236    fn inds_mut(&mut self) -> impl Iterator<Item = &mut Operand> {
237        self.operands
238            .iter_mut()
239            .filter_map(|operand| operand.as_mut())
240    }
241
242    /// Get the driver to input `index`
243    fn get_driver(&self, index: usize) -> Option<Rc<RefCell<Self>>> {
244        self.operands[index].as_ref().map(|operand| {
245            self.owner
246                .upgrade()
247                .expect("Object is unlinked from netlist")
248                .index_weak(&operand.root())
249        })
250    }
251
252    /// Iterator to driving objects
253    fn drivers(&self) -> impl Iterator<Item = Option<Rc<RefCell<Self>>>> {
254        self.operands.iter().map(|operand| {
255            operand.as_ref().map(|operand| {
256                self.owner
257                    .upgrade()
258                    .expect("Object is unlinked from netlist")
259                    .index_weak(&operand.root())
260            })
261        })
262    }
263
264    /// Iterator to driving nets
265    fn driver_nets(&self) -> impl Iterator<Item = Option<Net>> {
266        self.operands.iter().map(|operand| {
267            operand.as_ref().map(|operand| match operand {
268                Operand::DirectIndex(idx) => self
269                    .owner
270                    .upgrade()
271                    .expect("Object is unlinked from netlist")
272                    .index_weak(idx)
273                    .borrow()
274                    .as_net()
275                    .clone(),
276                Operand::CellIndex(idx, j) => self
277                    .owner
278                    .upgrade()
279                    .expect("Object is unlinked from netlist")
280                    .index_weak(idx)
281                    .borrow()
282                    .get_net(*j)
283                    .clone(),
284            })
285        })
286    }
287
288    /// Get the underlying object
289    fn get(&self) -> &Object<I> {
290        &self.object
291    }
292
293    /// Get the underlying object mutably
294    fn get_mut(&mut self) -> &mut Object<I> {
295        &mut self.object
296    }
297
298    /// Get the index of `self` relative to the owning module
299    fn get_index(&self) -> usize {
300        self.index
301    }
302
303    /// Get the net that is driven by this object
304    fn as_net(&self) -> &Net {
305        match &self.object {
306            Object::Input(net) => net,
307            Object::Instance(nets, _, _) => {
308                if nets.len() > 1 {
309                    panic!("Attempt to grab the net of a multi-output instance");
310                } else {
311                    nets.first().expect("Instance is missing a net to drive")
312                }
313            }
314        }
315    }
316
317    /// Get the net that is driven by this object
318    fn as_net_mut(&mut self) -> &mut Net {
319        match &mut self.object {
320            Object::Input(net) => net,
321            Object::Instance(nets, _, _) => {
322                if nets.len() > 1 {
323                    panic!("Attempt to grab the net of a multi-output instance");
324                } else {
325                    nets.first_mut()
326                        .expect("Instance is missing a net to drive")
327                }
328            }
329        }
330    }
331
332    /// Get the net that is driven by this object at position `idx`
333    fn get_net(&self, idx: usize) -> &Net {
334        match &self.object {
335            Object::Input(net) => {
336                if idx != 0 {
337                    panic!("Nonzero index on an input object");
338                }
339                net
340            }
341            Object::Instance(nets, _, _) => &nets[idx],
342        }
343    }
344
345    /// Get a mutable reference to the net that is driven by this object at position `idx`
346    fn get_net_mut(&mut self, idx: usize) -> &mut Net {
347        match &mut self.object {
348            Object::Input(net) => {
349                if idx != 0 {
350                    panic!("Nonzero index on an input object");
351                }
352                net
353            }
354            Object::Instance(nets, _, _) => &mut nets[idx],
355        }
356    }
357
358    /// Check if this object drives a specific net
359    fn find_net(&self, net: &Net) -> Option<usize> {
360        match &self.object {
361            Object::Input(input_net) => {
362                if input_net == net {
363                    Some(0)
364                } else {
365                    None
366                }
367            }
368            Object::Instance(nets, _, _) => nets.iter().position(|n| n == net),
369        }
370    }
371
372    /// Attempt to find a mutable reference to a net within this object
373    fn find_net_mut(&mut self, net: &Net) -> Option<&mut Net> {
374        match &mut self.object {
375            Object::Input(input_net) => {
376                if input_net == net {
377                    Some(input_net)
378                } else {
379                    None
380                }
381            }
382            Object::Instance(nets, _, _) => nets.iter_mut().find(|n| *n == net),
383        }
384    }
385
386    /// Get driving net using the weak reference
387    ///
388    /// # Panics
389    ///
390    /// Panics if the reference to the netlist is lost.
391    fn get_driver_net(&self, index: usize) -> Option<Net> {
392        let operand = &self.operands[index];
393        match operand {
394            Some(op) => match op {
395                Operand::DirectIndex(idx) => self
396                    .owner
397                    .upgrade()
398                    .expect("Object is unlinked from netlist")
399                    .index_weak(idx)
400                    .borrow()
401                    .as_net()
402                    .clone()
403                    .into(),
404                Operand::CellIndex(idx, j) => self
405                    .owner
406                    .upgrade()
407                    .expect("Object is unlinked from netlist")
408                    .index_weak(idx)
409                    .borrow()
410                    .get_net(*j)
411                    .clone()
412                    .into(),
413            },
414            None => None,
415        }
416    }
417
418    fn clear_attribute(&mut self, k: &AttributeKey) -> Option<AttributeValue> {
419        self.attributes.remove(k)
420    }
421
422    fn set_attribute(&mut self, k: AttributeKey) {
423        self.attributes.insert(k, None);
424    }
425
426    fn insert_attribute(&mut self, k: AttributeKey, v: String) -> Option<AttributeValue> {
427        self.attributes.insert(k, Some(v))
428    }
429
430    fn attributes(&self) -> impl Iterator<Item = Attribute> {
431        Attribute::from_pairs(self.attributes.clone().into_iter())
432    }
433}
434
435/// This type exposes the interior mutability of elements in a netlist.
436type NetRefT<I> = Rc<RefCell<OwnedObject<I, Netlist<I>>>>;
437
438/// Provides an idiomatic interface
439/// to the interior mutability of the netlist
440#[derive(Clone)]
441pub struct NetRef<I>
442where
443    I: Instantiable,
444{
445    netref: NetRefT<I>,
446}
447
448impl<I> std::fmt::Debug for NetRef<I>
449where
450    I: Instantiable,
451{
452    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
453        let b = self.netref.borrow();
454        let o = b.get();
455        let i = b.index;
456        let owner = &b.owner;
457        match owner.upgrade() {
458            Some(owner) => {
459                let n = owner.get_name();
460                write!(f, "{{ owner: \"{n}\", index: {i}, val: \"{o}\" }}")
461            }
462            None => write!(f, "{{ owner: None, index: {i}, val: \"{o}\" }}"),
463        }
464    }
465}
466
467impl<I> PartialEq for NetRef<I>
468where
469    I: Instantiable,
470{
471    fn eq(&self, other: &Self) -> bool {
472        Rc::ptr_eq(&self.netref, &other.netref)
473    }
474}
475
476impl<I> Eq for NetRef<I> where I: Instantiable {}
477
478impl<I> Ord for NetRef<I>
479where
480    I: Instantiable,
481{
482    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
483        Rc::as_ptr(&self.netref).cmp(&Rc::as_ptr(&other.netref))
484    }
485}
486
487impl<I> PartialOrd for NetRef<I>
488where
489    I: Instantiable,
490{
491    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
492        Some(self.cmp(other))
493    }
494}
495
496impl<I> std::hash::Hash for NetRef<I>
497where
498    I: Instantiable,
499{
500    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
501        Rc::as_ptr(&self.netref).hash(state);
502    }
503}
504
505impl<I> NetRef<I>
506where
507    I: Instantiable,
508{
509    /// Creates a new [NetRef] from a [NetRefT]
510    fn wrap(netref: NetRefT<I>) -> Self {
511        Self { netref }
512    }
513
514    /// Returns the underlying [NetRefT]
515    fn unwrap(self) -> NetRefT<I> {
516        self.netref
517    }
518
519    /// Returns a borrow to the [Net] at this circuit node.
520    ///
521    /// # Panics
522    ///
523    /// Panics if the circuit node has multiple outputs.
524    pub fn as_net(&self) -> Ref<'_, Net> {
525        Ref::map(self.netref.borrow(), |f| f.as_net())
526    }
527
528    /// Returns a mutable borrow to the [Net] at this circuit node.
529    ///
530    /// # Panics
531    ///
532    /// Panics if the circuit node has multiple outputs.
533    pub fn as_net_mut(&self) -> RefMut<'_, Net> {
534        RefMut::map(self.netref.borrow_mut(), |f| f.as_net_mut())
535    }
536
537    /// Returns a borrow to the output [Net] as position `idx`
538    pub fn get_net(&self, idx: usize) -> Ref<'_, Net> {
539        Ref::map(self.netref.borrow(), |f| f.get_net(idx))
540    }
541
542    /// Returns a mutable borrow to the output [Net] as position `idx`
543    pub fn get_net_mut(&self, idx: usize) -> RefMut<'_, Net> {
544        RefMut::map(self.netref.borrow_mut(), |f| f.get_net_mut(idx))
545    }
546
547    /// Returns a borrow to the output [Net] as position `idx`
548    pub fn get_output(&self, idx: usize) -> DrivenNet<I> {
549        DrivenNet::new(idx, self.clone())
550    }
551
552    /// Returns a borrow to the output connected to port `id`
553    pub fn find_output(&self, id: &Identifier) -> Option<DrivenNet<I>> {
554        let ind = self.get_instance_type()?.find_output(id)?;
555        Some(self.get_output(ind))
556    }
557
558    /// Returns an abstraction around the input connection
559    pub fn get_input(&self, idx: usize) -> InputPort<I> {
560        if self.is_an_input() {
561            panic!("Principal inputs do not have inputs");
562        }
563        InputPort::new(idx, self.clone())
564    }
565
566    /// Returns a borrow to the input port with name `id`
567    pub fn find_input(&self, id: &Identifier) -> Option<InputPort<I>> {
568        let ind = self.get_instance_type()?.find_input(id)?;
569        Some(self.get_input(ind))
570    }
571
572    /// Returns the name of the net at this circuit node.
573    ///
574    /// # Panics
575    ///
576    /// Panics if the circuit node has multiple outputs.
577    pub fn get_identifier(&self) -> Identifier {
578        self.as_net().get_identifier().clone()
579    }
580
581    /// Changes the identifier of the net at this circuit node.
582    ///
583    /// # Panics
584    ///
585    /// Panics if the circuit node has multiple outputs.
586    pub fn set_identifier(&self, identifier: Identifier) {
587        self.as_net_mut().set_identifier(identifier)
588    }
589
590    /// Returns `true` if this circuit node is a principal input
591    pub fn is_an_input(&self) -> bool {
592        matches!(self.netref.borrow().get(), Object::Input(_))
593    }
594
595    /// Returns a reference to the object at this node.
596    pub fn get_obj(&self) -> Ref<'_, Object<I>> {
597        Ref::map(self.netref.borrow(), |f| f.get())
598    }
599
600    /// Returns the [Instantiable] type of the instance, if this circuit node is an instance
601    pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
602        Ref::filter_map(self.netref.borrow(), |f| f.get().get_instance_type()).ok()
603    }
604
605    /// Returns the [Instantiable] type of the instance, if this circuit node is an instance
606    pub fn get_instance_type_mut(&self) -> Option<RefMut<'_, I>> {
607        RefMut::filter_map(self.netref.borrow_mut(), |f| {
608            f.get_mut().get_instance_type_mut()
609        })
610        .ok()
611    }
612
613    /// Returns a copy of the name of the instance, if the circuit node is a instance.
614    pub fn get_instance_name(&self) -> Option<Identifier> {
615        match self.netref.borrow().get() {
616            Object::Instance(_, inst_name, _) => Some(inst_name.clone()),
617            _ => None,
618        }
619    }
620
621    /// Updates the name of the instance, if the circuit node is an instance.
622    ///
623    /// # Panics
624    ///
625    /// Panics if the circuit node is a principal input.
626    pub fn set_instance_name(&self, name: Identifier) {
627        match self.netref.borrow_mut().get_mut() {
628            Object::Instance(_, inst_name, _) => *inst_name = name,
629            _ => panic!("Attempted to set instance name on a non-instance object"),
630        }
631    }
632
633    /// Exposes this circuit node as a top-level output in the netlist.
634    /// Returns an error if the circuit node is a principal input.
635    ///
636    /// # Panics
637    ///
638    /// Panics if cell is a multi-output circuit node.
639    /// Panics if the reference to the netlist is lost.
640    pub fn expose_as_output(self) -> Result<Self, Error> {
641        let netlist = self
642            .netref
643            .borrow()
644            .owner
645            .upgrade()
646            .expect("NetRef is unlinked from netlist");
647        netlist.expose_net(self.clone().into())?;
648        Ok(self)
649    }
650
651    /// Exposes this circuit node as a top-level output in the netlist with a specific port name.
652    /// Multiple calls to this method can be used to create multiple output aliases for the same net.
653    ///
654    /// # Panics
655    ///
656    /// Panics if the cell is a multi-output circuit node.
657    /// Panics if the reference to the netlist is lost.
658    pub fn expose_with_name(self, name: Identifier) -> Self {
659        let netlist = self
660            .netref
661            .borrow()
662            .owner
663            .upgrade()
664            .expect("NetRef is unlinked from netlist");
665        netlist.expose_net_with_name(self.clone().into(), name);
666        self
667    }
668
669    /// Exposes the `net` driven by this circuit node as a top-level output.
670    /// Errors if `net` is not driven by this circuit node.
671    ///
672    /// # Panics
673    /// Panics if the reference to the netlist is lost.
674    pub fn expose_net(&self, net: &Net) -> Result<(), Error> {
675        let netlist = self
676            .netref
677            .borrow()
678            .owner
679            .upgrade()
680            .expect("NetRef is unlinked from netlist");
681        let net_index = self
682            .netref
683            .borrow()
684            .find_net(net)
685            .ok_or(Error::NetNotFound(net.clone()))?;
686        let dr = DrivenNet::new(net_index, self.clone());
687        netlist.expose_net(dr)?;
688        Ok(())
689    }
690
691    /// Removes a specific output alias by its name from this circuit node.
692    /// Returns true if the output was removed, false if it didn't exist.
693    ///
694    /// # Panics
695    ///
696    /// Panics if cell is a multi-output circuit node.
697    /// Panics if the reference to the netlist is lost.
698    pub fn remove_output(&self, net_name: &Identifier) -> bool {
699        let netlist = self
700            .netref
701            .borrow()
702            .owner
703            .upgrade()
704            .expect("NetRef is unlinked from netlist");
705        netlist.remove_output(&self.into(), net_name)
706    }
707
708    /// Removes all output aliases for this circuit node.
709    /// Returns the number of outputs that were removed.
710    ///
711    /// # Panics
712    ///
713    /// Panics if cell is a multi-output circuit node.
714    /// Panics if the reference to the netlist is lost.
715    pub fn remove_all_outputs(&self) -> usize {
716        let netlist = self
717            .netref
718            .borrow()
719            .owner
720            .upgrade()
721            .expect("NetRef is unlinked from netlist");
722        netlist.remove_outputs(&self.into())
723    }
724
725    /// Returns the circuit node that drives the `index`th input
726    pub fn get_driver(&self, index: usize) -> Option<Self> {
727        self.netref.borrow().get_driver(index).map(NetRef::wrap)
728    }
729
730    /// Returns the net that drives the `index`th input
731    ///
732    /// # Panics
733    ///
734    /// Panics if the reference to the netlist is lost.
735    pub fn get_driver_net(&self, index: usize) -> Option<Net> {
736        self.netref.borrow().get_driver_net(index)
737    }
738
739    /// Returns a request to mutably borrow the operand net
740    /// This requires another borrow in the form of [MutBorrowReq]
741    ///
742    /// # Panics
743    ///
744    /// Panics if the reference to the netlist is lost.
745    pub fn req_driver_net(&self, index: usize) -> Option<MutBorrowReq<I>> {
746        let net = self.get_driver_net(index)?;
747        let operand = self.get_driver(index).unwrap();
748        Some(MutBorrowReq::new(operand, net))
749    }
750
751    /// Returns the number of input ports for this circuit node.
752    pub fn get_num_input_ports(&self) -> usize {
753        if let Some(inst_type) = self.get_instance_type() {
754            inst_type.get_input_ports().into_iter().count()
755        } else {
756            0
757        }
758    }
759
760    /// Returns `true` if this circuit node has all its input ports connected.
761    pub fn is_fully_connected(&self) -> bool {
762        assert_eq!(
763            self.netref.borrow().operands.len(),
764            self.get_num_input_ports()
765        );
766        self.netref.borrow().operands.iter().all(|o| o.is_some())
767    }
768
769    /// Returns an iterator to the driving circuit nodes.
770    pub fn drivers(&self) -> impl Iterator<Item = Option<Self>> {
771        let drivers: Vec<Option<Self>> = self
772            .netref
773            .borrow()
774            .drivers()
775            .map(|o| o.map(NetRef::wrap))
776            .collect();
777        drivers.into_iter()
778    }
779
780    /// Returns an interator to the driving nets.
781    pub fn driver_nets(&self) -> impl Iterator<Item = Option<Net>> {
782        let vec: Vec<Option<Net>> = self.netref.borrow().driver_nets().collect();
783        vec.into_iter()
784    }
785
786    /// Returns an iterator to the output nets of this circuit node.
787    #[allow(clippy::unnecessary_to_owned)]
788    pub fn nets(&self) -> impl Iterator<Item = Net> {
789        self.netref.borrow().get().get_nets().to_vec().into_iter()
790    }
791
792    /// Returns an iterator to the output nets of this circuit node, along with port information.
793    pub fn inputs(&self) -> impl Iterator<Item = InputPort<I>> {
794        let len = self.netref.borrow().operands.len();
795        (0..len).map(move |i| InputPort::new(i, self.clone()))
796    }
797
798    /// Returns an iterator to the output nets of this circuit node, along with port information.
799    pub fn outputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
800        let len = self.netref.borrow().get().get_nets().len();
801        (0..len).map(move |i| DrivenNet::new(i, self.clone()))
802    }
803
804    /// Returns an iterator to mutate the output nets of this circuit node.
805    pub fn nets_mut(&self) -> impl Iterator<Item = RefMut<'_, Net>> {
806        let nnets = self.netref.borrow().get().get_nets().len();
807        (0..nnets).map(|i| self.get_net_mut(i))
808    }
809
810    /// Returns `true` if this circuit node drives the given net.
811    pub fn drives_net(&self, net: &Net) -> bool {
812        self.netref.borrow().find_net(net).is_some()
813    }
814
815    /// Returns `true` if this circuit node drives a top-level output.
816    ///
817    /// # Panics
818    /// Panics if the weak reference to the netlist is lost.
819    pub fn drives_a_top_output(&self) -> bool {
820        let netlist = self
821            .netref
822            .borrow()
823            .owner
824            .upgrade()
825            .expect("NetRef is unlinked from netlist");
826        netlist.drives_an_output(self.clone())
827    }
828
829    /// Attempts to find a mutable reference to `net` within this circuit node.
830    pub fn find_net_mut(&self, net: &Net) -> Option<RefMut<'_, Net>> {
831        RefMut::filter_map(self.netref.borrow_mut(), |f| f.find_net_mut(net)).ok()
832    }
833
834    /// Returns `true` if this circuit node has multiple outputs/nets.
835    pub fn is_multi_output(&self) -> bool {
836        self.netref.borrow().get().get_nets().len() > 1
837    }
838
839    /// Deletes the uses of this circuit node from the netlist.
840    ///
841    /// # Panics
842    ///
843    /// Panics if the reference to the netlist is lost.
844    pub fn delete_uses(self) -> Result<Object<I>, Error> {
845        let netlist = self
846            .netref
847            .borrow()
848            .owner
849            .upgrade()
850            .expect("NetRef is unlinked from netlist");
851        netlist.delete_net_uses(self)
852    }
853
854    /// Replaces the uses of this circuit node in the netlist with another circuit node.
855    ///
856    /// # Panics
857    ///
858    /// Panics if either `self` is a multi-output circuit node.
859    /// Panics if the weak reference to the netlist is lost.
860    pub fn replace_uses_with(self, other: &DrivenNet<I>) -> Result<Object<I>, Error> {
861        let netlist = self
862            .netref
863            .borrow()
864            .owner
865            .upgrade()
866            .expect("NetRef is unlinked from netlist");
867        netlist.replace_net_uses(self.into(), other)
868    }
869
870    /// Clears the attribute with the given key on this circuit node.
871    pub fn clear_attribute(&self, k: &AttributeKey) -> Option<AttributeValue> {
872        self.netref.borrow_mut().clear_attribute(k)
873    }
874
875    /// Set an attribute without a value
876    pub fn set_attribute(&self, k: AttributeKey) {
877        self.netref.borrow_mut().set_attribute(k);
878    }
879
880    /// Insert an attribute on this node with a value
881    pub fn insert_attribute(&self, k: AttributeKey, v: String) -> Option<AttributeValue> {
882        self.netref.borrow_mut().insert_attribute(k, v)
883    }
884
885    /// Returns an iterator to the attributes at this circuit node
886    pub fn attributes(&self) -> impl Iterator<Item = Attribute> {
887        let v: Vec<_> = self.netref.borrow().attributes().collect();
888        v.into_iter()
889    }
890}
891
892impl<I> std::fmt::Display for NetRef<I>
893where
894    I: Instantiable,
895{
896    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
897        self.netref.borrow().object.fmt(f)
898    }
899}
900
901impl<I> From<NetRef<I>> for DrivenNet<I>
902where
903    I: Instantiable,
904{
905    fn from(val: NetRef<I>) -> Self {
906        if val.is_multi_output() {
907            panic!("Cannot convert a multi-output netref to an output port");
908        }
909        DrivenNet::new(0, val)
910    }
911}
912
913impl<I> From<&NetRef<I>> for DrivenNet<I>
914where
915    I: Instantiable,
916{
917    fn from(val: &NetRef<I>) -> Self {
918        if val.is_multi_output() {
919            panic!("Cannot convert a multi-output netref to an output port");
920        }
921        DrivenNet::new(0, val.clone())
922    }
923}
924
925/// Facilitates mutable borrows to driver nets
926pub struct MutBorrowReq<I: Instantiable> {
927    from: NetRef<I>,
928    ind: Net,
929}
930
931impl<I> MutBorrowReq<I>
932where
933    I: Instantiable,
934{
935    /// Creates a new mutable borrow request
936    fn new(from: NetRef<I>, ind: Net) -> Self {
937        Self { from, ind }
938    }
939
940    /// Mutably borrows the requested net from the circuit node
941    pub fn borrow_mut(&self) -> RefMut<'_, Net> {
942        self.from.find_net_mut(&self.ind).unwrap()
943    }
944
945    /// Returns `true` if the circuit node is an input
946    pub fn is_an_input(&self) -> bool {
947        self.from.is_an_input()
948    }
949
950    /// Attempts to borrow the net mutably if the condition `f` is satisfied.
951    pub fn borrow_mut_if(&self, f: impl Fn(&NetRef<I>) -> bool) -> Option<RefMut<'_, Net>> {
952        if f(&self.from) {
953            Some(self.borrow_mut())
954        } else {
955            None
956        }
957    }
958}
959
960/// A netlist data structure
961#[derive(Debug)]
962pub struct Netlist<I>
963where
964    I: Instantiable,
965{
966    /// The name of the netlist
967    name: RefCell<String>,
968    /// The list of objects in the netlist, such as inputs, modules, and primitives
969    objects: RefCell<Vec<NetRefT<I>>>,
970    /// Each operand can map to multiple nets, supporting output aliases.
971    outputs: RefCell<HashMap<Operand, BTreeSet<Net>>>,
972}
973
974/// Represent the input port of a primitive
975#[derive(Debug, Clone)]
976pub struct InputPort<I: Instantiable> {
977    pos: usize,
978    netref: NetRef<I>,
979}
980
981impl<I> InputPort<I>
982where
983    I: Instantiable,
984{
985    fn new(pos: usize, netref: NetRef<I>) -> Self {
986        if pos >= netref.clone().unwrap().borrow().operands.len() {
987            panic!(
988                "Position {} out of bounds for netref with {} input nets",
989                pos,
990                netref.unwrap().borrow().get().get_nets().len()
991            );
992        }
993        Self { pos, netref }
994    }
995
996    /// Returns the net that is driving this input port
997    pub fn get_driver(&self) -> Option<DrivenNet<I>> {
998        if self.netref.is_an_input() {
999            panic!("Input port is not driven by a primitive");
1000        }
1001        if let Some(prev_operand) = self.netref.clone().unwrap().borrow().operands[self.pos] {
1002            let netlist = self
1003                .netref
1004                .clone()
1005                .unwrap()
1006                .borrow()
1007                .owner
1008                .upgrade()
1009                .expect("Input port is unlinked from netlist");
1010            let driver_nr = netlist.index_weak(&prev_operand.root());
1011            let nr = NetRef::wrap(driver_nr);
1012            let pos = prev_operand.secondary();
1013            Some(DrivenNet::new(pos, nr))
1014        } else {
1015            None
1016        }
1017    }
1018
1019    /// Disconnects an input port and returns the previous [DrivenNet] if it was connected.
1020    pub fn disconnect(&self) -> Option<DrivenNet<I>> {
1021        let val = self.get_driver();
1022        self.netref.clone().unwrap().borrow_mut().operands[self.pos] = None;
1023        val
1024    }
1025
1026    /// Get the input port associated with this connection
1027    pub fn get_port(&self) -> Net {
1028        if self.netref.is_an_input() {
1029            panic!("Net is not driven by a primitive");
1030        }
1031        self.netref
1032            .get_instance_type()
1033            .unwrap()
1034            .get_input_port(self.pos)
1035            .clone()
1036    }
1037
1038    /// Connects this input port to a driven net.
1039    pub fn connect(self, output: DrivenNet<I>) {
1040        output.connect(self);
1041    }
1042
1043    /// Return the underlying circuit node
1044    pub fn unwrap(self) -> NetRef<I> {
1045        self.netref
1046    }
1047
1048    /// Returns the index associated with this input port
1049    pub fn get_input_num(&self) -> usize {
1050        self.pos
1051    }
1052}
1053
1054impl<I> std::fmt::Display for InputPort<I>
1055where
1056    I: Instantiable,
1057{
1058    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1059        self.get_port().fmt(f)
1060    }
1061}
1062
1063/// Represent a net that is being driven by a [Instantiable]
1064#[derive(Debug, Clone)]
1065pub struct DrivenNet<I: Instantiable> {
1066    pos: usize,
1067    netref: NetRef<I>,
1068}
1069
1070impl<I> DrivenNet<I>
1071where
1072    I: Instantiable,
1073{
1074    fn new(pos: usize, netref: NetRef<I>) -> Self {
1075        if pos >= netref.clone().unwrap().borrow().get().get_nets().len() {
1076            panic!(
1077                "Position {} out of bounds for netref with {} outputted nets",
1078                pos,
1079                netref.unwrap().borrow().get().get_nets().len()
1080            );
1081        }
1082        Self { pos, netref }
1083    }
1084
1085    /// Returns the index that can address this net in the netlist.
1086    fn get_operand(&self) -> Operand {
1087        if self.netref.is_multi_output() {
1088            Operand::CellIndex(self.netref.clone().unwrap().borrow().get_index(), self.pos)
1089        } else {
1090            Operand::DirectIndex(self.netref.clone().unwrap().borrow().get_index())
1091        }
1092    }
1093
1094    /// Borrow the net being driven
1095    pub fn as_net(&self) -> Ref<'_, Net> {
1096        self.netref.get_net(self.pos)
1097    }
1098
1099    /// Get a mutable reference to the net being driven
1100    pub fn as_net_mut(&self) -> RefMut<'_, Net> {
1101        self.netref.get_net_mut(self.pos)
1102    }
1103
1104    /// Returns `true` if this net is a principal input
1105    pub fn is_an_input(&self) -> bool {
1106        self.netref.is_an_input()
1107    }
1108
1109    /// Get the output port associated with this connection
1110    pub fn get_port(&self) -> Net {
1111        if self.netref.is_an_input() {
1112            panic!("Net is not driven by a primitive");
1113        }
1114        self.netref
1115            .get_instance_type()
1116            .unwrap()
1117            .get_output_port(self.pos)
1118            .clone()
1119    }
1120
1121    /// Connects the net driven by this output port to the given input port.
1122    pub fn connect(&self, input: InputPort<I>) {
1123        let operand = self.get_operand();
1124        let index = input.netref.unwrap().borrow().get_index();
1125        let netlist = self
1126            .netref
1127            .clone()
1128            .unwrap()
1129            .borrow()
1130            .owner
1131            .upgrade()
1132            .expect("Output port is unlinked from netlist");
1133        let obj = netlist.index_weak(&index);
1134        obj.borrow_mut().operands[input.pos] = Some(operand);
1135    }
1136
1137    /// Returns `true` if this net is a top-level output in the netlist.
1138    pub fn is_top_level_output(&self) -> bool {
1139        let netlist = self
1140            .netref
1141            .clone()
1142            .unwrap()
1143            .borrow()
1144            .owner
1145            .upgrade()
1146            .expect("DrivenNet is unlinked from netlist");
1147        let outputs = netlist.outputs.borrow();
1148        outputs.contains_key(&self.get_operand())
1149    }
1150
1151    /// Return the underlying circuit node
1152    pub fn unwrap(self) -> NetRef<I> {
1153        self.netref
1154    }
1155
1156    /// Returns a copy of the identifier of the net being driven.
1157    pub fn get_identifier(&self) -> Identifier {
1158        self.as_net().get_identifier().clone()
1159    }
1160
1161    /// Exposes this driven net as a top-level output with a specific port name.
1162    /// Multiple calls to this method can be used to create multiple output aliases for the same net.
1163    ///
1164    /// # Panics
1165    ///
1166    /// Panics if the weak reference to the netlist is dead.
1167    pub fn expose_with_name(self, name: Identifier) -> Self {
1168        let netlist = self
1169            .netref
1170            .clone()
1171            .unwrap()
1172            .borrow()
1173            .owner
1174            .upgrade()
1175            .expect("DrivenNet is unlinked from netlist");
1176        netlist.expose_net_with_name(self.clone(), name);
1177        self
1178    }
1179
1180    /// Removes a specific output alias by its name from this driven net.
1181    /// Returns true if the output was removed, false if it didn't exist.
1182    ///
1183    /// # Panics
1184    ///
1185    /// Panics if the reference to the netlist is lost.
1186    pub fn remove_output(&self, net_name: &Identifier) -> bool {
1187        let netlist = self
1188            .netref
1189            .clone()
1190            .unwrap()
1191            .borrow()
1192            .owner
1193            .upgrade()
1194            .expect("DrivenNet is unlinked from netlist");
1195        netlist.remove_output(self, net_name)
1196    }
1197
1198    /// Removes all output aliases for this driven net.
1199    /// Returns the number of outputs that were removed.
1200    ///
1201    /// # Panics
1202    ///
1203    /// Panics if the reference to the netlist is lost.
1204    pub fn remove_all_outputs(&self) -> usize {
1205        let netlist = self
1206            .netref
1207            .clone()
1208            .unwrap()
1209            .borrow()
1210            .owner
1211            .upgrade()
1212            .expect("DrivenNet is unlinked from netlist");
1213        netlist.remove_outputs(self)
1214    }
1215
1216    /// Returns the output position, if the net is the output of a gate.
1217    pub fn get_output_index(&self) -> Option<usize> {
1218        if self.netref.is_an_input() {
1219            None
1220        } else {
1221            Some(self.pos)
1222        }
1223    }
1224
1225    /// Returns the [Instantiable] type driving this net, if it has a driver.
1226    pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
1227        self.netref.get_instance_type()
1228    }
1229}
1230
1231impl<I> std::fmt::Display for DrivenNet<I>
1232where
1233    I: Instantiable,
1234{
1235    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1236        self.as_net().fmt(f)
1237    }
1238}
1239
1240impl<I> PartialEq for DrivenNet<I>
1241where
1242    I: Instantiable,
1243{
1244    fn eq(&self, other: &Self) -> bool {
1245        self.netref == other.netref && self.pos == other.pos
1246    }
1247}
1248
1249impl<I> Eq for DrivenNet<I> where I: Instantiable {}
1250
1251impl<I> std::hash::Hash for DrivenNet<I>
1252where
1253    I: Instantiable,
1254{
1255    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1256        self.netref.hash(state);
1257        self.pos.hash(state);
1258    }
1259}
1260
1261impl<I> Ord for DrivenNet<I>
1262where
1263    I: Instantiable,
1264{
1265    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
1266        match self.netref.cmp(&other.netref) {
1267            std::cmp::Ordering::Equal => self.pos.cmp(&other.pos),
1268            ord => ord,
1269        }
1270    }
1271}
1272
1273impl<I> PartialOrd for DrivenNet<I>
1274where
1275    I: Instantiable,
1276{
1277    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1278        Some(self.cmp(other))
1279    }
1280}
1281
1282impl<I> WeakIndex<usize> for Netlist<I>
1283where
1284    I: Instantiable,
1285{
1286    type Output = OwnedObject<I, Self>;
1287
1288    fn index_weak(&self, index: &usize) -> Rc<RefCell<Self::Output>> {
1289        self.objects.borrow()[*index].clone()
1290    }
1291}
1292
1293impl<I> Netlist<I>
1294where
1295    I: Instantiable,
1296{
1297    /// Creates a new netlist with the given name
1298    pub fn new(name: String) -> Rc<Self> {
1299        Rc::new(Self {
1300            name: RefCell::new(name),
1301            objects: RefCell::new(Vec::new()),
1302            outputs: RefCell::new(HashMap::new()),
1303        })
1304    }
1305
1306    /// Attempts to reclaim the netlist, returning [Some] if successful.
1307    pub fn reclaim(self: Rc<Self>) -> Option<Self> {
1308        Rc::try_unwrap(self).ok()
1309    }
1310
1311    /// Creates a deep clone of the netlist.
1312    pub fn deep_clone(self: &Rc<Self>) -> Rc<Self> {
1313        let dc = Rc::new(Self {
1314            name: self.name.clone(),
1315            objects: RefCell::new(Vec::new()),
1316            outputs: self.outputs.clone(),
1317        });
1318
1319        let objects_linked: Vec<NetRefT<I>> = self
1320            .objects
1321            .borrow()
1322            .iter()
1323            .map(|obj| {
1324                Rc::new(RefCell::new(OwnedObject {
1325                    object: obj.borrow().object.clone(),
1326                    owner: Rc::downgrade(&dc),
1327                    operands: obj.borrow().operands.clone(),
1328                    attributes: obj.borrow().attributes.clone(),
1329                    index: obj.borrow().index,
1330                }))
1331            })
1332            .collect();
1333
1334        *dc.objects.borrow_mut() = objects_linked;
1335
1336        dc
1337    }
1338
1339    /// Use interior mutability to add an object to the netlist. Returns a mutable reference to the created object.
1340    ///
1341    /// # Panics
1342    /// If any of the `operands` do not belong to this netlist.
1343    fn insert_object(
1344        self: &Rc<Self>,
1345        object: Object<I>,
1346        operands: &[DrivenNet<I>],
1347    ) -> Result<NetRef<I>, Error> {
1348        for operand in operands {
1349            self.belongs(&operand.clone().unwrap());
1350        }
1351        let index = self.objects.borrow().len();
1352        let weak = Rc::downgrade(self);
1353        let operands = operands
1354            .iter()
1355            .map(|net| Some(net.get_operand()))
1356            .collect::<Vec<_>>();
1357        let owned_object = Rc::new(RefCell::new(OwnedObject {
1358            object,
1359            owner: weak,
1360            operands,
1361            attributes: HashMap::new(),
1362            index,
1363        }));
1364        self.objects.borrow_mut().push(owned_object.clone());
1365        Ok(NetRef::wrap(owned_object))
1366    }
1367
1368    /// Inserts an input net to the netlist
1369    pub fn insert_input(self: &Rc<Self>, net: Net) -> DrivenNet<I> {
1370        let obj = Object::Input(net);
1371        self.insert_object(obj, &[]).unwrap().into()
1372    }
1373
1374    /// Inserts a four-state logic input port to the netlist
1375    pub fn insert_input_escaped_logic_bus(
1376        self: &Rc<Self>,
1377        net: String,
1378        bw: usize,
1379    ) -> Vec<DrivenNet<I>> {
1380        Net::new_escaped_logic_bus(net, bw)
1381            .into_iter()
1382            .map(|n| self.insert_input(n))
1383            .collect()
1384    }
1385
1386    /// Inserts a gate to the netlist
1387    pub fn insert_gate(
1388        self: &Rc<Self>,
1389        inst_type: I,
1390        inst_name: Identifier,
1391        operands: &[DrivenNet<I>],
1392    ) -> Result<NetRef<I>, Error> {
1393        let nets = inst_type
1394            .get_output_ports()
1395            .into_iter()
1396            .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1397            .collect::<Vec<_>>();
1398        let input_count = inst_type.get_input_ports().into_iter().count();
1399        if operands.len() != input_count {
1400            return Err(Error::ArgumentMismatch(input_count, operands.len()));
1401        }
1402        let obj = Object::Instance(nets, inst_name, inst_type);
1403        self.insert_object(obj, operands)
1404    }
1405
1406    /// Use interior mutability to add an object to the netlist. Returns a mutable reference to the created object.
1407    pub fn insert_gate_disconnected(
1408        self: &Rc<Self>,
1409        inst_type: I,
1410        inst_name: Identifier,
1411    ) -> NetRef<I> {
1412        let nets = inst_type
1413            .get_output_ports()
1414            .into_iter()
1415            .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1416            .collect::<Vec<_>>();
1417        let object = Object::Instance(nets, inst_name, inst_type);
1418        let index = self.objects.borrow().len();
1419        let weak = Rc::downgrade(self);
1420        let input_count = object
1421            .get_instance_type()
1422            .unwrap()
1423            .get_input_ports()
1424            .into_iter()
1425            .count();
1426        let operands = vec![None; input_count];
1427        let owned_object = Rc::new(RefCell::new(OwnedObject {
1428            object,
1429            owner: weak,
1430            operands,
1431            attributes: HashMap::new(),
1432            index,
1433        }));
1434        self.objects.borrow_mut().push(owned_object.clone());
1435        NetRef::wrap(owned_object)
1436    }
1437
1438    /// Inserts a constant [Logic] value to the netlist
1439    pub fn insert_constant(
1440        self: &Rc<Self>,
1441        value: Logic,
1442        inst_name: Identifier,
1443    ) -> Result<DrivenNet<I>, Error> {
1444        let obj = I::from_constant(value).ok_or(Error::InstantiableError(format!(
1445            "Instantiable type does not support constant value {}",
1446            value
1447        )))?;
1448        Ok(self.insert_gate_disconnected(obj, inst_name).into())
1449    }
1450
1451    /// # Panics
1452    ///
1453    /// Panics if `netref` definitely does not belong to this netlist.
1454    fn belongs(&self, netref: &NetRef<I>) {
1455        if let Some(nl) = netref.netref.borrow().owner.upgrade() {
1456            if self.objects.borrow().len() != nl.objects.borrow().len() {
1457                panic!("NetRef does not belong to this netlist");
1458            }
1459
1460            if let Some(p) = self.objects.borrow().first()
1461                && let Some(np) = nl.objects.borrow().first()
1462                && !Rc::ptr_eq(p, np)
1463            {
1464                panic!("NetRef does not belong to this netlist");
1465            }
1466        }
1467
1468        if netref.netref.borrow().index >= self.objects.borrow().len() {
1469            panic!("NetRef does not belong to this netlist");
1470        }
1471    }
1472
1473    /// Returns the driving node at input position `index` for `netref`
1474    ///
1475    /// # Panics
1476    ///
1477    /// Panics if `index` is out of bounds
1478    /// The `netref` does not belong to this netlist
1479    pub fn get_driver(&self, netref: NetRef<I>, index: usize) -> Option<NetRef<I>> {
1480        self.belongs(&netref);
1481        let op = netref.unwrap().borrow().operands[index]?;
1482        Some(NetRef::wrap(self.index_weak(&op.root()).clone()))
1483    }
1484
1485    /// Set an added object as a top-level output with a specific name.
1486    /// Multiple calls with different names for the same net will create multiple aliases.
1487    ///
1488    /// # Panics
1489    /// The `net` does not belong to this netlist
1490    pub fn expose_net_with_name(&self, net: DrivenNet<I>, name: Identifier) -> DrivenNet<I> {
1491        self.belongs(&net.clone().unwrap());
1492        let mut outputs = self.outputs.borrow_mut();
1493        let named_net = net.as_net().with_name(name);
1494        outputs
1495            .entry(net.get_operand())
1496            .or_default()
1497            .insert(named_net);
1498        net
1499    }
1500
1501    /// Sets the current net as a top-level output using the current name of the net
1502    ///
1503    /// # Panics
1504    /// The `net` does not belong to this netlist
1505    pub fn expose_net(&self, net: DrivenNet<I>) -> Result<DrivenNet<I>, Error> {
1506        self.belongs(&net.clone().unwrap());
1507        if net.is_an_input() {
1508            return Err(Error::InputNeedsAlias(net.as_net().clone()));
1509        }
1510        let mut outputs = self.outputs.borrow_mut();
1511        outputs
1512            .entry(net.get_operand())
1513            .or_default()
1514            .insert(net.as_net().clone());
1515        Ok(net)
1516    }
1517
1518    /// Removes a specific output alias by its operand and net name.
1519    /// Returns true if the output was removed, false if it didn't exist.
1520    ///
1521    /// # Panics
1522    /// The `operand` does not belong to this netlist
1523    pub fn remove_output(&self, operand: &DrivenNet<I>, net_name: &Identifier) -> bool {
1524        self.belongs(&operand.clone().unwrap());
1525        let mut outputs = self.outputs.borrow_mut();
1526        if let Some(nets) = outputs.get_mut(&operand.get_operand()) {
1527            // Create a net with just the identifier to match for removal
1528            let net_to_remove = Net::new(net_name.clone(), crate::circuit::DataType::logic());
1529            if nets.remove(&net_to_remove) {
1530                // If the set is now empty, remove the operand entirely
1531                if nets.is_empty() {
1532                    outputs.remove(&operand.get_operand());
1533                }
1534                return true;
1535            }
1536        }
1537        false
1538    }
1539
1540    /// Removes all output aliases for a specific operand.
1541    /// Returns the number of outputs that were removed.
1542    pub fn remove_outputs(&self, operand: &DrivenNet<I>) -> usize {
1543        //let mut outputs = self.outputs.borrow_mut();
1544        self.outputs
1545            .borrow_mut()
1546            .remove(&operand.get_operand())
1547            .map(|nets| nets.len())
1548            .unwrap_or(0)
1549    }
1550
1551    /// Removes all outputs from the netlist.
1552    pub fn clear_outputs(&self) {
1553        self.outputs.borrow_mut().clear();
1554    }
1555
1556    /// Unlink a circuit node from the rest of the netlist. Return the object that was being stored.
1557    ///
1558    /// # Panics
1559    /// The `netref` does not belong to this netlist
1560    pub fn delete_net_uses(&self, netref: NetRef<I>) -> Result<Object<I>, Error> {
1561        self.belongs(&netref);
1562        let unwrapped = netref.clone().unwrap();
1563        if Rc::strong_count(&unwrapped) > 3 {
1564            return Err(Error::DanglingReference(netref.nets().collect()));
1565        }
1566        let old_index = unwrapped.borrow().get_index();
1567        let objects = self.objects.borrow();
1568        for oref in objects.iter() {
1569            let operands = &mut oref.borrow_mut().operands;
1570            for operand in operands.iter_mut() {
1571                if let Some(op) = operand {
1572                    match op {
1573                        Operand::DirectIndex(idx) | Operand::CellIndex(idx, _)
1574                            if *idx == old_index =>
1575                        {
1576                            *operand = None;
1577                        }
1578                        _ => (),
1579                    }
1580                }
1581            }
1582        }
1583
1584        let outputs: Vec<Operand> = self
1585            .outputs
1586            .borrow()
1587            .keys()
1588            .filter(|operand| match operand {
1589                Operand::DirectIndex(idx) | Operand::CellIndex(idx, _) => *idx == old_index,
1590            })
1591            .cloned()
1592            .collect();
1593
1594        for operand in outputs {
1595            self.outputs.borrow_mut().remove(&operand);
1596        }
1597
1598        Ok(netref.unwrap().borrow().get().clone())
1599    }
1600
1601    /// Replaces the uses of a circuit node with another circuit node. The [Object] stored at `of` is returned.
1602    ///
1603    /// # Panics
1604    /// `of` or `with` do not belong to this netlist
1605    pub fn replace_net_uses(
1606        &self,
1607        of: DrivenNet<I>,
1608        with: &DrivenNet<I>,
1609    ) -> Result<Object<I>, Error> {
1610        {
1611            self.belongs(&of.clone().unwrap());
1612            self.belongs(&with.clone().unwrap());
1613        }
1614        let unwrapped = of.clone().unwrap().unwrap();
1615        let i = of.get_output_index();
1616        let k = with.get_output_index();
1617
1618        if of.clone().unwrap() == with.clone().unwrap() {
1619            if i == k {
1620                return Ok(of.unwrap().unwrap().borrow().get().clone());
1621            }
1622
1623            if Rc::strong_count(&unwrapped) > 4 {
1624                return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1625            }
1626        } else if Rc::strong_count(&unwrapped) > 3 {
1627            return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1628        }
1629
1630        let old_index = of.get_operand();
1631
1632        if let Some(nets) = self.outputs.borrow().get(&old_index)
1633            && nets.contains(&*of.as_net())
1634        {
1635            return Err(Error::NonuniqueNets(nets.iter().cloned().collect()));
1636        }
1637
1638        let new_index = with.get_operand();
1639        let objects = self.objects.borrow();
1640        for oref in objects.iter() {
1641            let operands = &mut oref.borrow_mut().operands;
1642            for operand in operands.iter_mut() {
1643                if let Some(op) = operand
1644                    && *op == old_index
1645                {
1646                    *operand = Some(new_index);
1647                }
1648            }
1649        }
1650
1651        // Move all the old outputs to the new key
1652        let outs = self.outputs.borrow_mut().remove(&old_index);
1653        if let Some(outs) = outs {
1654            self.outputs
1655                .borrow_mut()
1656                .entry(new_index)
1657                .or_default()
1658                .extend(outs);
1659        }
1660
1661        Ok(of.unwrap().unwrap().borrow().get().clone())
1662    }
1663}
1664
1665impl<I> Netlist<I>
1666where
1667    I: Instantiable,
1668{
1669    /// Returns the name of the netlist module
1670    pub fn get_name(&self) -> Ref<'_, String> {
1671        self.name.borrow()
1672    }
1673
1674    /// Sets the name of the netlist module
1675    /// # Panics
1676    ///
1677    /// Panics if the module name cannot be borrowed mutably.
1678    pub fn set_name(&self, name: String) {
1679        *self.name.borrow_mut() = name;
1680    }
1681
1682    /// Iterates over the input ports of the netlist.
1683    pub fn get_input_ports(&self) -> impl Iterator<Item = Net> {
1684        self.objects().filter_map(|oref| {
1685            if oref.is_an_input() {
1686                Some(oref.as_net().clone())
1687            } else {
1688                None
1689            }
1690        })
1691    }
1692
1693    /// Returns a list of output nets
1694    pub fn get_output_ports(&self) -> Vec<Net> {
1695        self.outputs
1696            .borrow()
1697            .values()
1698            .flat_map(|nets| nets.iter().cloned())
1699            .collect()
1700    }
1701
1702    /// Constructs an analysis of the netlist.
1703    pub fn get_analysis<'a, A: Analysis<'a, I>>(&'a self) -> Result<A, Error> {
1704        A::build(self)
1705    }
1706
1707    /// Finds the first circuit node that drives the `net`. This operation is O(n).
1708    /// This should be unique provided the netlist is well-formed.
1709    pub fn find_net(&self, net: &Net) -> Option<DrivenNet<I>> {
1710        for obj in self.objects() {
1711            for o in obj.outputs() {
1712                if *o.as_net() == *net {
1713                    return Some(o);
1714                }
1715            }
1716        }
1717        None
1718    }
1719
1720    /// Returns a `NetRef` to the first circuit node
1721    pub fn first(&self) -> Option<NetRef<I>> {
1722        self.objects
1723            .borrow()
1724            .first()
1725            .map(|nr| NetRef::wrap(nr.clone()))
1726    }
1727
1728    /// Returns a `NetRef` to the last circuit node
1729    pub fn last(&self) -> Option<NetRef<I>> {
1730        self.objects
1731            .borrow()
1732            .last()
1733            .map(|nr| NetRef::wrap(nr.clone()))
1734    }
1735
1736    /// Returns the number of objects in the netlist (instances + inputs)
1737    pub fn len(&self) -> usize {
1738        self.objects.borrow().len()
1739    }
1740
1741    /// Returns `true` if the netlist contains no objects.
1742    pub fn is_empty(&self) -> bool {
1743        self.objects.borrow().is_empty()
1744    }
1745
1746    /// Returns `true` if an output of `netref` which is driving a module output.
1747    ///
1748    /// # Panics
1749    /// The `netref` does not belong to this netlist
1750    pub fn drives_an_output(&self, netref: NetRef<I>) -> bool {
1751        self.belongs(&netref);
1752        let my_index = netref.unwrap().borrow().get_index();
1753        for key in self.outputs.borrow().keys() {
1754            if key.root() == my_index {
1755                return true;
1756            }
1757        }
1758        false
1759    }
1760
1761    /// Rename nets and instances in the netlist using the provided *injective* function.
1762    /// Returns an error if the function is not injective.
1763    /// # Examples
1764    ///
1765    /// ```
1766    /// use safety_net::format_id;
1767    /// use safety_net::{Gate, GateNetlist};
1768    ///
1769    /// let netlist = GateNetlist::new("example".to_string());
1770    /// let inv = Gate::new_logical("INV".into(), vec!["A".into()], "Y".into());
1771    /// let foo = netlist.insert_input("foo".into());
1772    /// let nr = netlist.insert_gate(inv, "bar".into(), &[foo]).unwrap();
1773    /// nr.expose_with_name("baz".into());
1774    /// netlist.rename_nets(|id, i| format_id!("{}_{}", id, i) ).unwrap();
1775    /// // "bar_Y" -> "bar_Y_0"
1776    /// // "bar" -> "bar_1"
1777    /// ```
1778    pub fn rename_nets<F: Fn(&Identifier, usize) -> Identifier>(&self, f: F) -> Result<(), Error> {
1779        let mut i: usize = 0;
1780        for nr in self.objects() {
1781            if nr.is_an_input() {
1782                continue;
1783            }
1784            for mut net in nr.nets_mut() {
1785                let rename = f(net.get_identifier(), i);
1786                net.set_identifier(rename);
1787                i += 1;
1788            }
1789        }
1790
1791        for nr in self.objects() {
1792            if nr.is_an_input() {
1793                continue;
1794            }
1795
1796            let rename = f(&nr.get_instance_name().unwrap(), i);
1797            nr.set_instance_name(rename);
1798            i += 1;
1799        }
1800
1801        self.verify()
1802    }
1803
1804    /// Retains the [DrivenNet]s in `set`, given they are used. Otherwise, they are cleaned and returned in a `Ok(vec)`.
1805    pub fn retain_once(&self, set: &mut HashSet<DrivenNet<I>>) -> Result<Vec<Object<I>>, Error> {
1806        let mut dead_objs = HashSet::new();
1807        {
1808            let fan_out = self.get_analysis::<FanOutTable<I>>()?;
1809            for obj in self.objects() {
1810                let mut is_dead = true;
1811                for net in obj.outputs() {
1812                    // This should account for outputs
1813                    if fan_out.net_has_uses(&net.as_net()) {
1814                        is_dead = false;
1815                    } else {
1816                        set.remove(&net);
1817                    }
1818                }
1819                if is_dead && !obj.is_an_input() {
1820                    dead_objs.insert(obj.unwrap().borrow().index);
1821                }
1822            }
1823        }
1824
1825        if dead_objs.is_empty() {
1826            return Ok(vec![]);
1827        }
1828
1829        let old_objects = self.objects.take();
1830
1831        // Check no dangling references will be created before mutating
1832        for i in dead_objs.iter() {
1833            let rc = &old_objects[*i];
1834            if Rc::strong_count(rc) > 1 {
1835                self.objects.replace(old_objects.clone());
1836                return Err(Error::DanglingReference(
1837                    rc.borrow().get().get_nets().to_vec(),
1838                ));
1839            }
1840        }
1841
1842        let mut removed = Vec::new();
1843        let mut remap: HashMap<usize, usize> = HashMap::new();
1844        for (old_index, obj) in old_objects.into_iter().enumerate() {
1845            if dead_objs.contains(&old_index) {
1846                removed.push(obj.borrow().get().clone());
1847                continue;
1848            }
1849
1850            let new_index = self.objects.borrow().len();
1851            remap.insert(old_index, new_index);
1852            obj.borrow_mut().index = new_index;
1853            self.objects.borrow_mut().push(obj);
1854        }
1855
1856        for obj in self.objects.borrow().iter() {
1857            for operand in obj.borrow_mut().inds_mut() {
1858                let root = operand.root();
1859                let root = *remap.get(&root).unwrap_or(&root);
1860                *operand = operand.remap(root);
1861            }
1862        }
1863
1864        let pairs: Vec<_> = self.outputs.take().into_iter().collect();
1865        for (operand, net) in pairs {
1866            let root = operand.root();
1867            let root = *remap.get(&root).unwrap_or(&root);
1868            let new_operand = operand.remap(root);
1869            self.outputs.borrow_mut().insert(new_operand, net);
1870        }
1871
1872        Ok(removed)
1873    }
1874
1875    /// Removes unused nodes from the netlist, until it stops changing.
1876    /// Returns `Ok(vec)` of the removed objects.
1877    pub fn clean(&self) -> Result<Vec<Object<I>>, Error> {
1878        let mut removed = Vec::new();
1879        let mut r = self.retain_once(&mut HashSet::new())?;
1880        while !r.is_empty() {
1881            removed.extend(r);
1882            r = self.retain_once(&mut HashSet::new())?;
1883        }
1884        Ok(removed)
1885    }
1886
1887    /// Retains the [DrivenNet]s in `set`, given they are used. Otherwise, they are cleaned and returned in a `Ok(vec)`.
1888    pub fn retain(&self, set: &mut HashSet<DrivenNet<I>>) -> Result<Vec<Object<I>>, Error> {
1889        let mut removed = Vec::new();
1890        let mut r = self.retain_once(set)?;
1891        while !r.is_empty() {
1892            removed.extend(r);
1893            r = self.retain_once(set)?;
1894        }
1895        Ok(removed)
1896    }
1897
1898    /// Returns `true` if all the nets/insts are uniquely named
1899    fn nets_insts_unique(&self) -> Result<(), Error> {
1900        let mut nets = HashSet::new();
1901        for net in self {
1902            if !nets.insert(net.clone().take_identifier()) {
1903                return Err(Error::NonuniqueNets(vec![net]));
1904            }
1905        }
1906        for inst in self.objects() {
1907            if let Some(name) = inst.get_instance_name()
1908                && !nets.insert(name.clone())
1909            {
1910                return Err(Error::NonuniqueInsts(vec![name]));
1911            }
1912        }
1913        Ok(())
1914    }
1915
1916    /// Verifies that a netlist is well-formed.
1917    pub fn verify(&self) -> Result<(), Error> {
1918        if self.outputs.borrow().is_empty() {
1919            return Err(Error::NoOutputs);
1920        }
1921
1922        self.nets_insts_unique()?;
1923
1924        Ok(())
1925    }
1926}
1927
1928/// Represent a driven net alongside its connection to an input port
1929#[derive(Debug, Clone)]
1930pub struct Connection<I: Instantiable> {
1931    driver: DrivenNet<I>,
1932    input: InputPort<I>,
1933}
1934
1935impl<I> Connection<I>
1936where
1937    I: Instantiable,
1938{
1939    fn new(driver: DrivenNet<I>, input: InputPort<I>) -> Self {
1940        Self { driver, input }
1941    }
1942
1943    /// Return the driver of the connection
1944    pub fn src(&self) -> DrivenNet<I> {
1945        self.driver.clone()
1946    }
1947
1948    /// Return the net along the connection
1949    pub fn net(&self) -> Net {
1950        self.driver.as_net().clone()
1951    }
1952
1953    /// Returns the input port of the connection
1954    pub fn target(&self) -> InputPort<I> {
1955        self.input.clone()
1956    }
1957}
1958
1959impl<I> std::fmt::Display for Connection<I>
1960where
1961    I: Instantiable,
1962{
1963    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1964        self.net().fmt(f)
1965    }
1966}
1967
1968/// A collection of iterators for the netlist
1969pub mod iter {
1970
1971    use super::{
1972        Connection, DrivenNet, InputPort, Instantiable, Net, NetRef, Netlist, Operand, WeakIndex,
1973    };
1974    use std::collections::{HashMap, HashSet};
1975    /// An iterator over the nets in a netlist
1976    pub struct NetIterator<'a, I: Instantiable> {
1977        netlist: &'a Netlist<I>,
1978        index: usize,
1979        subindex: usize,
1980    }
1981
1982    impl<'a, I> NetIterator<'a, I>
1983    where
1984        I: Instantiable,
1985    {
1986        /// Creates a new iterator for the netlist
1987        pub fn new(netlist: &'a Netlist<I>) -> Self {
1988            Self {
1989                netlist,
1990                index: 0,
1991                subindex: 0,
1992            }
1993        }
1994    }
1995
1996    impl<I> Iterator for NetIterator<'_, I>
1997    where
1998        I: Instantiable,
1999    {
2000        type Item = Net;
2001
2002        fn next(&mut self) -> Option<Self::Item> {
2003            while self.index < self.netlist.objects.borrow().len() {
2004                let objects = self.netlist.objects.borrow();
2005                let object = objects[self.index].borrow();
2006                if self.subindex < object.get().get_nets().len() {
2007                    let net = object.get().get_nets()[self.subindex].clone();
2008                    self.subindex += 1;
2009                    return Some(net);
2010                }
2011                self.subindex = 0;
2012                self.index += 1;
2013            }
2014            None
2015        }
2016    }
2017
2018    /// An iterator over the objects in a netlist
2019    pub struct ObjectIterator<'a, I: Instantiable> {
2020        netlist: &'a Netlist<I>,
2021        index: usize,
2022    }
2023
2024    impl<'a, I> ObjectIterator<'a, I>
2025    where
2026        I: Instantiable,
2027    {
2028        /// Creates a new  object iterator for the netlist
2029        pub fn new(netlist: &'a Netlist<I>) -> Self {
2030            Self { netlist, index: 0 }
2031        }
2032    }
2033
2034    impl<I> Iterator for ObjectIterator<'_, I>
2035    where
2036        I: Instantiable,
2037    {
2038        type Item = NetRef<I>;
2039
2040        fn next(&mut self) -> Option<Self::Item> {
2041            if self.index < self.netlist.objects.borrow().len() {
2042                let objects = self.netlist.objects.borrow();
2043                let object = &objects[self.index];
2044                self.index += 1;
2045                return Some(NetRef::wrap(object.clone()));
2046            }
2047            None
2048        }
2049    }
2050
2051    /// An iterator over the connections in a netlist
2052    pub struct ConnectionIterator<'a, I: Instantiable> {
2053        netlist: &'a Netlist<I>,
2054        index: usize,
2055        subindex: usize,
2056    }
2057
2058    impl<'a, I> ConnectionIterator<'a, I>
2059    where
2060        I: Instantiable,
2061    {
2062        /// Create a new connection iterator for the netlist
2063        pub fn new(netlist: &'a Netlist<I>) -> Self {
2064            Self {
2065                netlist,
2066                index: 0,
2067                subindex: 0,
2068            }
2069        }
2070    }
2071
2072    impl<I> Iterator for ConnectionIterator<'_, I>
2073    where
2074        I: Instantiable,
2075    {
2076        type Item = super::Connection<I>;
2077
2078        fn next(&mut self) -> Option<Self::Item> {
2079            while self.index < self.netlist.objects.borrow().len() {
2080                let objects = self.netlist.objects.borrow();
2081                let object = objects[self.index].borrow();
2082                let noperands = object.operands.len();
2083                while self.subindex < noperands {
2084                    if let Some(operand) = &object.operands[self.subindex] {
2085                        let driver = match operand {
2086                            Operand::DirectIndex(idx) => {
2087                                DrivenNet::new(0, NetRef::wrap(objects[*idx].clone()))
2088                            }
2089                            Operand::CellIndex(idx, j) => {
2090                                DrivenNet::new(*j, NetRef::wrap(objects[*idx].clone()))
2091                            }
2092                        };
2093                        let input = InputPort::new(
2094                            self.subindex,
2095                            NetRef::wrap(objects[self.index].clone()),
2096                        );
2097                        self.subindex += 1;
2098                        return Some(Connection::new(driver, input));
2099                    }
2100                    self.subindex += 1;
2101                }
2102                self.subindex = 0;
2103                self.index += 1;
2104            }
2105            None
2106        }
2107    }
2108
2109    /// A stack that can check contains in roughly O(1) time.
2110    #[derive(Clone)]
2111    struct Walk<T: std::hash::Hash + PartialEq + Eq + Clone> {
2112        stack: Vec<T>,
2113        counter: HashMap<T, usize>,
2114    }
2115
2116    impl<T> Walk<T>
2117    where
2118        T: std::hash::Hash + PartialEq + Eq + Clone,
2119    {
2120        /// Create a new, empty Stack.
2121        fn new() -> Self {
2122            Self {
2123                stack: Vec::new(),
2124                counter: HashMap::new(),
2125            }
2126        }
2127
2128        /// Inserts an element into the stack
2129        fn push(&mut self, item: T) {
2130            self.stack.push(item.clone());
2131            *self.counter.entry(item).or_insert(0) += 1;
2132        }
2133
2134        /// Returns true if the stack shows a cycle
2135        fn contains_cycle(&self) -> bool {
2136            self.counter.values().any(|&count| count > 1)
2137        }
2138
2139        /// Returns true if the stack contains a cycle to the root node
2140        fn root_cycle(&self) -> bool {
2141            if self.stack.is_empty() {
2142                return false;
2143            }
2144            self.counter[&self.stack[0]] > 1
2145        }
2146
2147        /// Returns a reference to the last element in the stack
2148        fn last(&self) -> Option<&T> {
2149            self.stack.last()
2150        }
2151    }
2152
2153    /// A depth-first iterator over the circuit nodes in a netlist
2154    /// # Examples
2155    ///
2156    /// ```
2157    /// use safety_net::iter::DFSIterator;
2158    /// use safety_net::GateNetlist;
2159    ///
2160    /// let netlist = GateNetlist::new("example".to_string());
2161    /// netlist.insert_input("input1".into());
2162    /// let mut nodes = Vec::new();
2163    /// let mut dfs = DFSIterator::new(&netlist, netlist.last().unwrap());
2164    /// while let Some(n) = dfs.next() {
2165    ///     if dfs.check_cycles() {
2166    ///         panic!("Cycle detected in the netlist");
2167    ///     }
2168    ///     nodes.push(n);
2169    /// }
2170    /// ```
2171    pub struct DFSIterator<'a, I: Instantiable> {
2172        dfs: NetDFSIterator<'a, I>,
2173    }
2174
2175    impl<'a, I> DFSIterator<'a, I>
2176    where
2177        I: Instantiable,
2178    {
2179        /// Create a new DFS iterator for the netlist starting at `from`.
2180        pub fn new(netlist: &'a Netlist<I>, from: NetRef<I>) -> Self {
2181            Self {
2182                dfs: NetDFSIterator::new(netlist, DrivenNet::new(0, from)),
2183            }
2184        }
2185    }
2186
2187    impl<I> DFSIterator<'_, I>
2188    where
2189        I: Instantiable,
2190    {
2191        /// Check if the DFS traversal has encountered a cycle yet.
2192        pub fn check_cycles(&self) -> bool {
2193            self.dfs.check_cycles()
2194        }
2195
2196        /// Consumes the iterator to detect cycles in the netlist.
2197        pub fn detect_cycles(self) -> bool {
2198            self.dfs.detect_cycles()
2199        }
2200
2201        /// Check if the DFS traversal has encountered the root `from`` again.
2202        pub fn check_self_loop(&self) -> bool {
2203            self.dfs.check_self_loop()
2204        }
2205
2206        /// Consumes the iterator to detect if the DFS traversal will encounter the root `from` again.
2207        pub fn detect_self_loop(self) -> bool {
2208            self.dfs.detect_self_loop()
2209        }
2210    }
2211
2212    impl<I> Iterator for DFSIterator<'_, I>
2213    where
2214        I: Instantiable,
2215    {
2216        type Item = NetRef<I>;
2217
2218        fn next(&mut self) -> Option<Self::Item> {
2219            self.dfs.next().map(|d| d.unwrap())
2220        }
2221    }
2222
2223    type TermFn<I> = Box<dyn Fn(&DrivenNet<I>) -> bool + 'static>;
2224
2225    /// Depth-first iterator that works like DFSIterator but iterates over DrivenNet
2226    pub struct NetDFSIterator<'a, I: Instantiable> {
2227        netlist: &'a Netlist<I>,
2228        stacks: Vec<Walk<DrivenNet<I>>>,
2229        visited: HashSet<usize>,
2230        any_cycle: bool,
2231        root_cycle: bool,
2232        terminate: TermFn<I>,
2233    }
2234
2235    impl<'a, I> NetDFSIterator<'a, I>
2236    where
2237        I: Instantiable,
2238    {
2239        /// Create a new DFS DrivenNet iterator for the netlist starting at `from`, ignoring all dependencies beyond the `terminate` condition.
2240        /// Terminators themselves *are* included in the iteration.
2241        pub fn new_filtered<F: Fn(&DrivenNet<I>) -> bool + 'static>(
2242            netlist: &'a Netlist<I>,
2243            from: DrivenNet<I>,
2244            terminate: F,
2245        ) -> Self {
2246            let mut s = Walk::new();
2247            s.push(from);
2248            Self {
2249                netlist,
2250                stacks: vec![s],
2251                visited: HashSet::new(),
2252                any_cycle: false,
2253                root_cycle: false,
2254                terminate: Box::new(terminate),
2255            }
2256        }
2257
2258        /// Create a new DFS DrivenNet iterator for the netlist starting at `from`.
2259        pub fn new(netlist: &'a Netlist<I>, from: DrivenNet<I>) -> Self {
2260            Self::new_filtered(netlist, from, |_| false)
2261        }
2262    }
2263
2264    impl<I> NetDFSIterator<'_, I>
2265    where
2266        I: Instantiable,
2267    {
2268        /// Check if the DFS traversal has encountered a cycle yet.
2269        pub fn check_cycles(&self) -> bool {
2270            self.any_cycle
2271        }
2272
2273        /// Consumes the iterator to detect cycles in the netlist.
2274        pub fn detect_cycles(mut self) -> bool {
2275            if self.any_cycle {
2276                return true;
2277            }
2278
2279            while let Some(_) = self.next() {
2280                if self.any_cycle {
2281                    return true;
2282                }
2283            }
2284
2285            self.any_cycle
2286        }
2287
2288        /// Check if the DFS traversal has encountered the root `from` again.
2289        pub fn check_self_loop(&self) -> bool {
2290            self.root_cycle
2291        }
2292
2293        /// Consumes the iterator to detect if the DFS traversal will encounter the root `from` again.
2294        pub fn detect_self_loop(mut self) -> bool {
2295            if self.root_cycle {
2296                return true;
2297            }
2298
2299            while let Some(_) = self.next() {
2300                if self.root_cycle {
2301                    return true;
2302                }
2303            }
2304
2305            self.root_cycle
2306        }
2307    }
2308
2309    impl<I> Iterator for NetDFSIterator<'_, I>
2310    where
2311        I: Instantiable,
2312    {
2313        type Item = DrivenNet<I>;
2314
2315        fn next(&mut self) -> Option<Self::Item> {
2316            if let Some(walk) = self.stacks.pop() {
2317                self.any_cycle |= walk.contains_cycle();
2318                self.root_cycle |= walk.root_cycle();
2319                let item = walk.last().cloned();
2320                let uw = item.clone().unwrap().unwrap().unwrap();
2321                let index = uw.borrow().get_index();
2322                if self.visited.insert(index) {
2323                    if !(self.terminate)(item.as_ref().unwrap()) {
2324                        let operands = &uw.borrow().operands;
2325                        for operand in operands.iter().flatten() {
2326                            let mut new_walk = walk.clone();
2327                            new_walk.push(DrivenNet::new(
2328                                operand.secondary(),
2329                                NetRef::wrap(self.netlist.index_weak(&operand.root())),
2330                            ));
2331                            self.stacks.push(new_walk);
2332                        }
2333                    }
2334                    return item;
2335                }
2336
2337                return self.next();
2338            }
2339
2340            None
2341        }
2342    }
2343}
2344
2345impl<'a, I> IntoIterator for &'a Netlist<I>
2346where
2347    I: Instantiable,
2348{
2349    type Item = Net;
2350    type IntoIter = iter::NetIterator<'a, I>;
2351
2352    fn into_iter(self) -> Self::IntoIter {
2353        iter::NetIterator::new(self)
2354    }
2355}
2356
2357/// Filter invariants of [Instantiable] in a netlist. Use it like you would `matches!`.
2358/// Example: ```filter_nodes!(netlist, Gate::AND(_));```
2359#[macro_export]
2360macro_rules! filter_nodes {
2361    ($netlist:ident, $pattern:pat $(if $guard:expr)? $(,)?) => {
2362        $netlist.matches(|f| match f {
2363            $pattern $(if $guard)? => true,
2364            _ => false
2365        })
2366    };
2367}
2368
2369impl<I> Netlist<I>
2370where
2371    I: Instantiable,
2372{
2373    /// Returns an iterator over the circuit nodes in the netlist.
2374    pub fn objects(&self) -> impl Iterator<Item = NetRef<I>> {
2375        iter::ObjectIterator::new(self)
2376    }
2377
2378    /// Returns an iterator over the circuit nodes that match the instance type.
2379    pub fn matches<F>(&self, filter: F) -> impl Iterator<Item = NetRef<I>>
2380    where
2381        F: Fn(&I) -> bool,
2382    {
2383        self.objects().filter(move |f| {
2384            if let Some(inst_type) = f.get_instance_type() {
2385                filter(&inst_type)
2386            } else {
2387                false
2388            }
2389        })
2390    }
2391
2392    /// Returns an iterator to principal inputs in the netlist as references.
2393    pub fn inputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
2394        self.objects()
2395            .filter(|n| n.is_an_input())
2396            .map(|n| DrivenNet::new(0, n))
2397    }
2398
2399    /// Returns an iterator to circuit nodes that drive an output in the netlist.
2400    pub fn outputs(&self) -> Vec<(DrivenNet<I>, Net)> {
2401        self.outputs
2402            .borrow()
2403            .iter()
2404            .flat_map(|(k, nets)| {
2405                nets.iter().map(|n| {
2406                    (
2407                        DrivenNet::new(k.secondary(), NetRef::wrap(self.index_weak(&k.root()))),
2408                        n.clone(),
2409                    )
2410                })
2411            })
2412            .collect()
2413    }
2414
2415    /// Returns an iterator over the wire connections in the netlist.
2416    pub fn connections(&self) -> impl Iterator<Item = Connection<I>> {
2417        iter::ConnectionIterator::new(self)
2418    }
2419
2420    /// Returns a depth-first search iterator over the nodes in the netlist.
2421    ///
2422    /// # Panics
2423    /// `from` does not belong to this netlist
2424    pub fn node_dfs(&self, from: NetRef<I>) -> impl Iterator<Item = NetRef<I>> {
2425        self.belongs(&from);
2426        iter::DFSIterator::new(self, from)
2427    }
2428
2429    /// Returns a depth-first search iterator over the nodes in the netlist, with the nodes in DrivenNet form.
2430    ///
2431    /// # Panics
2432    /// `from` does not belong to this netlist
2433    pub fn net_dfs(&self, from: DrivenNet<I>) -> impl Iterator<Item = DrivenNet<I>> {
2434        self.belongs(&from.clone().unwrap());
2435        iter::NetDFSIterator::new(self, from)
2436    }
2437
2438    #[cfg(feature = "serde")]
2439    /// Serializes the netlist to a writer.
2440    pub fn serialize(self, writer: impl std::io::Write) -> Result<(), serde_json::Error>
2441    where
2442        I: ::serde::Serialize,
2443    {
2444        serde::netlist_serialize(self, writer)
2445    }
2446
2447    #[cfg(feature = "graph")]
2448    /// Converts the current configuration of the netlist to a graphviz string
2449    pub fn dot_string(&self) -> Result<String, Error> {
2450        use super::graph::MultiDiGraph;
2451        let analysis = self.get_analysis::<MultiDiGraph<_>>()?;
2452        let graph = analysis.get_graph();
2453        let dot = petgraph::dot::Dot::with_config(graph, &[]);
2454        Ok(dot.to_string())
2455    }
2456
2457    #[cfg(feature = "graph")]
2458    /// Dumps the current netlist to <module_name>.dot in the current working directory.
2459    pub fn dump_dot(&self) -> std::io::Result<()> {
2460        use super::graph::MultiDiGraph;
2461        use std::io::Write;
2462        let mut dir = std::env::current_dir()?;
2463        let mod_name = format!("{}.dot", self.get_name());
2464        dir.push(mod_name);
2465        let mut file = std::fs::File::create(dir)?;
2466        if let Err(e) = self.verify() {
2467            write!(file, "Netlist verification failed: {e}")
2468        } else {
2469            let analysis = self.get_analysis::<MultiDiGraph<_>>().unwrap();
2470            let graph = analysis.get_graph();
2471            let dot = petgraph::dot::Dot::with_config(graph, &[]);
2472            write!(file, "{dot}")
2473        }
2474    }
2475}
2476
2477impl<I> std::fmt::Display for Netlist<I>
2478where
2479    I: Instantiable,
2480{
2481    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2482        // Borrow everything first
2483        let objects = self.objects.borrow();
2484        let outputs = self.outputs.borrow();
2485
2486        writeln!(f, "module {} (", self.get_name())?;
2487
2488        // Print inputs and outputs
2489        let level = 2;
2490        let indent = " ".repeat(level);
2491        for oref in objects.iter() {
2492            let owned = oref.borrow();
2493            let obj = owned.get();
2494            if let Object::Input(net) = obj {
2495                writeln!(f, "{}{},", indent, net.get_identifier().emit_name())?;
2496            }
2497        }
2498
2499        // Flatten the outputs to collect all (operand, net) pairs
2500        let all_outputs: Vec<_> = outputs.iter().flat_map(|(_, nets)| nets.iter()).collect();
2501        for (i, net) in all_outputs.iter().enumerate() {
2502            if i == all_outputs.len() - 1 {
2503                writeln!(f, "{}{}", indent, net.get_identifier().emit_name())?;
2504            } else {
2505                writeln!(f, "{}{},", indent, net.get_identifier().emit_name())?;
2506            }
2507        }
2508        writeln!(f, ");")?;
2509
2510        // Make wire decls
2511        let mut already_decl = HashSet::new();
2512        for oref in objects.iter() {
2513            let owned = oref.borrow();
2514            let obj = owned.get();
2515            if let Object::Input(net) = obj {
2516                writeln!(f, "{}input {};", indent, net.get_identifier().emit_name())?;
2517                writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2518                already_decl.insert(net.clone());
2519            }
2520        }
2521        for nets in outputs.values() {
2522            for net in nets {
2523                if !already_decl.contains(net) {
2524                    writeln!(f, "{}output {};", indent, net.get_identifier().emit_name())?;
2525                    writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2526                    already_decl.insert(net.clone());
2527                }
2528            }
2529        }
2530        for oref in objects.iter() {
2531            let owned = oref.borrow();
2532            let obj = owned.get();
2533            if let Object::Instance(nets, _, inst_type) = obj
2534                && inst_type.get_constant().is_none()
2535            {
2536                for net in nets.iter() {
2537                    if !already_decl.contains(net) {
2538                        writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2539                        already_decl.insert(net.clone());
2540                    }
2541                }
2542            }
2543        }
2544
2545        for oref in objects.iter() {
2546            let owned = oref.borrow();
2547            let obj = owned.get();
2548
2549            // Skip emitting constants as their uses will be hard-wired
2550            if let Some(inst_type) = obj.get_instance_type()
2551                && inst_type.get_constant().is_some()
2552            {
2553                continue;
2554            }
2555
2556            if let Object::Instance(nets, inst_name, inst_type) = obj {
2557                for (k, v) in owned.attributes.iter() {
2558                    if let Some(value) = v {
2559                        writeln!(f, "{indent}(* {k} = \"{value}\" *)")?;
2560                    } else {
2561                        writeln!(f, "{indent}(* {k} *)")?;
2562                    }
2563                }
2564
2565                write!(f, "{}{} ", indent, inst_type.get_name())?;
2566                if inst_type.is_parameterized() {
2567                    writeln!(f, "#(")?;
2568                    let level = 4;
2569                    let indent = " ".repeat(level);
2570                    let params: Vec<_> = inst_type.parameters().collect();
2571                    for (i, (k, v)) in params.iter().enumerate() {
2572                        if i == params.len() - 1 {
2573                            writeln!(f, "{indent}.{k}({v})")?;
2574                        } else {
2575                            writeln!(f, "{indent}.{k}({v}),")?;
2576                        }
2577                    }
2578                    let level = 2;
2579                    let indent = " ".repeat(level);
2580                    write!(f, "{indent}) ")?;
2581                }
2582                writeln!(f, "{} (", inst_name.emit_name())?;
2583                let level = 4;
2584                let indent = " ".repeat(level);
2585                for (idx, port) in inst_type.get_input_ports().into_iter().enumerate() {
2586                    let port_name = port.get_identifier().emit_name();
2587                    if let Some(operand) = owned.operands[idx].as_ref() {
2588                        let operand_net = match operand {
2589                            Operand::DirectIndex(idx) => objects[*idx].borrow().as_net().clone(),
2590                            Operand::CellIndex(idx, j) => {
2591                                objects[*idx].borrow().get_net(*j).clone()
2592                            }
2593                        };
2594
2595                        let operand_str = if let Some(inst_type) =
2596                            objects[operand.root()].borrow().get().get_instance_type()
2597                            && let Some(logic) = inst_type.get_constant()
2598                        {
2599                            logic.to_string()
2600                        } else {
2601                            operand_net.get_identifier().emit_name()
2602                        };
2603
2604                        writeln!(f, "{}.{}({}),", indent, port_name, operand_str)?;
2605                    }
2606                }
2607
2608                for (idx, net) in nets.iter().enumerate() {
2609                    let port_name = inst_type.get_output_port(idx).get_identifier().emit_name();
2610                    if idx == nets.len() - 1 {
2611                        writeln!(
2612                            f,
2613                            "{}.{}({})",
2614                            indent,
2615                            port_name,
2616                            net.get_identifier().emit_name()
2617                        )?;
2618                    } else {
2619                        writeln!(
2620                            f,
2621                            "{}.{}({}),",
2622                            indent,
2623                            port_name,
2624                            net.get_identifier().emit_name()
2625                        )?;
2626                    }
2627                }
2628
2629                let level = 2;
2630                let indent = " ".repeat(level);
2631                writeln!(f, "{indent});")?;
2632            }
2633        }
2634
2635        for (driver, nets) in outputs.iter() {
2636            for net in nets {
2637                let driver_net = match driver {
2638                    Operand::DirectIndex(idx) => self.index_weak(idx).borrow().as_net().clone(),
2639                    Operand::CellIndex(idx, j) => self.index_weak(idx).borrow().get_net(*j).clone(),
2640                };
2641
2642                let driver_str = if let Some(inst_type) = self
2643                    .index_weak(&driver.root())
2644                    .borrow()
2645                    .get()
2646                    .get_instance_type()
2647                    && let Some(logic) = inst_type.get_constant()
2648                {
2649                    logic.to_string()
2650                } else {
2651                    driver_net.get_identifier().emit_name()
2652                };
2653
2654                if net.get_identifier() != driver_net.get_identifier() {
2655                    writeln!(
2656                        f,
2657                        "{}assign {} = {};",
2658                        indent,
2659                        net.get_identifier().emit_name(),
2660                        driver_str
2661                    )?;
2662                }
2663            }
2664        }
2665
2666        writeln!(f, "endmodule")
2667    }
2668}
2669
2670/// A type alias for a netlist of gates
2671pub type GateNetlist = Netlist<Gate>;
2672/// A type alias to Gate circuit nodes
2673pub type GateRef = NetRef<Gate>;
2674
2675#[cfg(test)]
2676mod tests {
2677    use super::iter::{DFSIterator, NetDFSIterator};
2678    use super::*;
2679    #[test]
2680    fn test_delete_netlist() {
2681        let netlist = Netlist::new("simple_example".to_string());
2682
2683        // Add the the two inputs
2684        let input1 = netlist.insert_input("input1".into());
2685        let input2 = netlist.insert_input("input2".into());
2686
2687        // Instantiate an AND gate
2688        let instance = netlist
2689            .insert_gate(
2690                Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
2691                "my_and".into(),
2692                &[input1.clone(), input2.clone()],
2693            )
2694            .unwrap();
2695
2696        // Make this AND gate an output
2697        let instance = instance.expose_as_output().unwrap();
2698        instance.delete_uses().unwrap();
2699        // We can still clean this mostly empty netlist
2700        assert!(netlist.clean().is_ok());
2701        input1.expose_with_name("an_output".into());
2702        assert!(netlist.clean().is_ok());
2703    }
2704
2705    #[test]
2706    #[should_panic(expected = "Attempted to create a gate with a sliced identifier")]
2707    fn gate_w_slice_panics() {
2708        Gate::new_logical("AND[1]".into(), vec!["A".into(), "B".into()], "Y".into());
2709    }
2710
2711    #[test]
2712    fn gates_dont_have_params() {
2713        // The baseline implementation of gates do not have parameters.
2714        let gate = Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into());
2715        assert!(!gate.has_parameter(&"id".into()));
2716        assert!(gate.get_parameter(&"id".into()).is_none());
2717        assert_eq!(*gate.get_gate_name(), "AND".into());
2718    }
2719
2720    #[test]
2721    fn operand_conversions() {
2722        let operand = Operand::CellIndex(3, 2);
2723        assert_eq!(operand.to_string(), "3.2");
2724        let parsed = "3.2".parse::<Operand>();
2725        assert!(parsed.is_ok());
2726        let parsed = parsed.unwrap();
2727        assert_eq!(operand, parsed);
2728    }
2729
2730    #[test]
2731    #[should_panic(expected = "out of bounds for netref")]
2732    fn test_bad_output() {
2733        let netlist = GateNetlist::new("min_module".to_string());
2734        let a = netlist.insert_input("a".into());
2735        DrivenNet::new(1, a.unwrap());
2736    }
2737
2738    #[test]
2739    fn test_netdfsiterator() {
2740        let netlist = Netlist::new("dfs_netlist".to_string());
2741
2742        // inputs
2743        let a = netlist.insert_input("a".into());
2744        let b = netlist.insert_input("b".into());
2745        let c = netlist.insert_input("c".into());
2746        let d = netlist.insert_input("d".into());
2747        let e = netlist.insert_input("e".into());
2748
2749        // gates
2750        let n1 = netlist
2751            .insert_gate(
2752                Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into()),
2753                "n1".into(),
2754                &[a.clone(), b.clone()],
2755            )
2756            .unwrap()
2757            .get_output(0);
2758        let n2 = netlist
2759            .insert_gate(
2760                Gate::new_logical("NOR".into(), vec!["A".into(), "B".into()], "Y".into()),
2761                "n2".into(),
2762                &[d.clone(), e.clone()],
2763            )
2764            .unwrap()
2765            .get_output(0);
2766        let n3 = netlist
2767            .insert_gate(
2768                Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
2769                "n3".into(),
2770                &[n1.clone(), c.clone()],
2771            )
2772            .unwrap()
2773            .get_output(0);
2774        let n4 = netlist
2775            .insert_gate(
2776                Gate::new_logical("NAND".into(), vec!["A".into(), "B".into()], "Y".into()),
2777                "n4".into(),
2778                &[n3.clone(), n2.clone()],
2779            )
2780            .unwrap()
2781            .get_output(0);
2782        n4.clone().expose_with_name("y".into());
2783
2784        // test DFSIterator
2785        let mut dfs = NetDFSIterator::new(&netlist, n4.clone());
2786        assert_eq!(dfs.next(), Some(n4));
2787        assert_eq!(dfs.next(), Some(n2));
2788        assert_eq!(dfs.next(), Some(e));
2789        assert_eq!(dfs.next(), Some(d));
2790        assert_eq!(dfs.next(), Some(n3));
2791        assert_eq!(dfs.next(), Some(c));
2792        assert_eq!(dfs.next(), Some(n1));
2793        assert_eq!(dfs.next(), Some(b));
2794        assert_eq!(dfs.next(), Some(a));
2795        assert_eq!(dfs.next(), None);
2796    }
2797
2798    #[test]
2799    fn test_dfs_cycles() {
2800        let netlist = Netlist::new("dfs_cycles".to_string());
2801
2802        // inputs
2803        let a = netlist.insert_input("a".into());
2804
2805        // gates
2806        let and = netlist.insert_gate_disconnected(
2807            Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
2808            "and".into(),
2809        );
2810
2811        // connect and form cycle
2812        a.connect(and.get_input(0));
2813        and.get_output(0).connect(and.get_input(1));
2814
2815        // test dfs iterators
2816        let dfs = DFSIterator::new(&netlist, and.clone());
2817        let driven_dfs = NetDFSIterator::new(&netlist, and.get_output(0));
2818
2819        assert!(dfs.detect_cycles());
2820        assert!(driven_dfs.detect_cycles());
2821    }
2822
2823    #[test]
2824    fn test_netdfsiterator_with_boundary() {
2825        let netlist = Netlist::new("dfs_netlist".to_string());
2826
2827        // inputs
2828        let a = netlist.insert_input("a".into());
2829        let b = netlist.insert_input("b".into());
2830        let c = netlist.insert_input("c".into());
2831        let d = netlist.insert_input("d".into());
2832        let e = netlist.insert_input("e".into());
2833
2834        // gates
2835        let n1 = netlist
2836            .insert_gate(
2837                Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into()),
2838                "n1".into(),
2839                &[a.clone(), b.clone()],
2840            )
2841            .unwrap()
2842            .get_output(0);
2843        let n2 = netlist
2844            .insert_gate(
2845                Gate::new_logical("NOR".into(), vec!["A".into(), "B".into()], "Y".into()),
2846                "n2".into(),
2847                &[d.clone(), e.clone()],
2848            )
2849            .unwrap()
2850            .get_output(0);
2851        let n3 = netlist
2852            .insert_gate(
2853                Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
2854                "n3".into(),
2855                &[n1.clone(), c.clone()],
2856            )
2857            .unwrap()
2858            .get_output(0);
2859        let n4 = netlist
2860            .insert_gate(
2861                Gate::new_logical("NAND".into(), vec!["A".into(), "B".into()], "Y".into()),
2862                "n4".into(),
2863                &[n3.clone(), n2.clone()],
2864            )
2865            .unwrap()
2866            .get_output(0);
2867
2868        // Stop DFS expansion at n3 to emulate a traversal boundary.
2869        let n3_boundary = n3.clone();
2870        let mut dfs =
2871            NetDFSIterator::new_filtered(&netlist, n4.clone(), move |n| *n == n3_boundary);
2872        assert_eq!(dfs.next(), Some(n4));
2873        assert_eq!(dfs.next(), Some(n2));
2874        assert_eq!(dfs.next(), Some(e));
2875        assert_eq!(dfs.next(), Some(d));
2876        assert_eq!(dfs.next(), Some(n3));
2877        assert_eq!(dfs.next(), None);
2878    }
2879}
2880#[cfg(feature = "serde")]
2881/// Serde support for netlists
2882pub mod serde {
2883    use super::{Netlist, Operand, OwnedObject, WeakIndex};
2884    use crate::{
2885        attribute::{AttributeKey, AttributeValue},
2886        circuit::{Instantiable, Net, Object},
2887    };
2888    use serde::{Deserialize, Serialize, de::DeserializeOwned};
2889    use std::cell::RefCell;
2890    use std::{
2891        collections::{BTreeSet, HashMap},
2892        rc::Rc,
2893    };
2894
2895    #[derive(Debug, Serialize, Deserialize)]
2896    struct SerdeObject<I>
2897    where
2898        I: Instantiable + Serialize,
2899    {
2900        /// The object that is owned by the netlist
2901        object: Object<I>,
2902        /// The list of operands for the object
2903        operands: Vec<Option<Operand>>,
2904        /// A collection of attributes for the object
2905        attributes: HashMap<AttributeKey, AttributeValue>,
2906    }
2907
2908    impl<I, O> From<OwnedObject<I, O>> for SerdeObject<I>
2909    where
2910        I: Instantiable + Serialize,
2911        O: WeakIndex<usize, Output = OwnedObject<I, O>>,
2912    {
2913        fn from(value: OwnedObject<I, O>) -> Self {
2914            SerdeObject {
2915                object: value.object,
2916                operands: value.operands,
2917                attributes: value.attributes,
2918            }
2919        }
2920    }
2921
2922    impl<I> SerdeObject<I>
2923    where
2924        I: Instantiable + Serialize,
2925    {
2926        fn into_owned_object<O>(self, owner: &Rc<O>, index: usize) -> OwnedObject<I, O>
2927        where
2928            O: WeakIndex<usize, Output = OwnedObject<I, O>>,
2929        {
2930            OwnedObject {
2931                object: self.object,
2932                owner: Rc::downgrade(owner),
2933                operands: self.operands,
2934                attributes: self.attributes,
2935                index,
2936            }
2937        }
2938    }
2939
2940    #[derive(Debug, Serialize, Deserialize)]
2941    struct SerdeNetlist<I>
2942    where
2943        I: Instantiable + Serialize,
2944    {
2945        /// The name of the netlist
2946        name: String,
2947        /// The list of objects in the netlist, such as inputs, modules, and primitives
2948        objects: Vec<SerdeObject<I>>,
2949        /// The list of operands that point to objects which are outputs.
2950        /// Indices must be a string if we want to support JSON.
2951        /// Each operand can map to multiple nets, supporting output aliases.
2952        outputs: HashMap<String, BTreeSet<Net>>,
2953    }
2954
2955    impl<I> From<Netlist<I>> for SerdeNetlist<I>
2956    where
2957        I: Instantiable + Serialize,
2958    {
2959        fn from(value: Netlist<I>) -> Self {
2960            SerdeNetlist {
2961                name: value.name.into_inner(),
2962                objects: value
2963                    .objects
2964                    .into_inner()
2965                    .into_iter()
2966                    .map(|o| {
2967                        Rc::try_unwrap(o)
2968                            .ok()
2969                            .expect("Cannot serialize with live references")
2970                            .into_inner()
2971                            .into()
2972                    })
2973                    .collect(),
2974                outputs: value
2975                    .outputs
2976                    .into_inner()
2977                    .into_iter()
2978                    // Indices must be a string if we want to support JSON.
2979                    .map(|(o, nets)| (o.to_string(), nets.into_iter().collect()))
2980                    .collect(),
2981            }
2982        }
2983    }
2984
2985    impl<I> SerdeNetlist<I>
2986    where
2987        I: Instantiable + Serialize,
2988    {
2989        /// Convert the serialized netlist back into a reference-counted netlist.
2990        fn into_netlist(self) -> Rc<Netlist<I>> {
2991            let netlist = Netlist::new(self.name);
2992            let outputs: HashMap<Operand, BTreeSet<Net>> = self
2993                .outputs
2994                .into_iter()
2995                .map(|(k, v)| {
2996                    let operand = k.parse::<Operand>().expect("Invalid index");
2997                    (operand, v.into_iter().collect())
2998                })
2999                .collect();
3000            let objects = self
3001                .objects
3002                .into_iter()
3003                .enumerate()
3004                .map(|(i, o)| {
3005                    let owned_object = o.into_owned_object(&netlist, i);
3006                    Rc::new(RefCell::new(owned_object))
3007                })
3008                .collect::<Vec<_>>();
3009            {
3010                let mut objs_mut = netlist.objects.borrow_mut();
3011                *objs_mut = objects;
3012                let mut outputs_mut = netlist.outputs.borrow_mut();
3013                *outputs_mut = outputs;
3014            }
3015            netlist
3016        }
3017    }
3018
3019    /// Serialize the netlist into the writer.
3020    pub fn netlist_serialize<I: Instantiable + Serialize>(
3021        netlist: Netlist<I>,
3022        writer: impl std::io::Write,
3023    ) -> Result<(), serde_json::Error> {
3024        let sobj: SerdeNetlist<I> = netlist.into();
3025        serde_json::to_writer_pretty(writer, &sobj)
3026    }
3027
3028    /// Deserialize a netlist from the reader.
3029    pub fn netlist_deserialize<I: Instantiable + Serialize + DeserializeOwned>(
3030        reader: impl std::io::Read,
3031    ) -> Result<Rc<Netlist<I>>, serde_json::Error> {
3032        let sobj: SerdeNetlist<I> = serde_json::from_reader(reader)?;
3033        Ok(sobj.into_netlist())
3034    }
3035}