Skip to main content

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
1049impl<I> std::fmt::Display for InputPort<I>
1050where
1051    I: Instantiable,
1052{
1053    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1054        self.get_port().fmt(f)
1055    }
1056}
1057
1058/// Represent a net that is being driven by a [Instantiable]
1059#[derive(Debug, Clone)]
1060pub struct DrivenNet<I: Instantiable> {
1061    pos: usize,
1062    netref: NetRef<I>,
1063}
1064
1065impl<I> DrivenNet<I>
1066where
1067    I: Instantiable,
1068{
1069    fn new(pos: usize, netref: NetRef<I>) -> Self {
1070        if pos >= netref.clone().unwrap().borrow().get().get_nets().len() {
1071            panic!(
1072                "Position {} out of bounds for netref with {} outputted nets",
1073                pos,
1074                netref.unwrap().borrow().get().get_nets().len()
1075            );
1076        }
1077        Self { pos, netref }
1078    }
1079
1080    /// Returns the index that can address this net in the netlist.
1081    fn get_operand(&self) -> Operand {
1082        if self.netref.is_multi_output() {
1083            Operand::CellIndex(self.netref.clone().unwrap().borrow().get_index(), self.pos)
1084        } else {
1085            Operand::DirectIndex(self.netref.clone().unwrap().borrow().get_index())
1086        }
1087    }
1088
1089    /// Borrow the net being driven
1090    pub fn as_net(&self) -> Ref<'_, Net> {
1091        self.netref.get_net(self.pos)
1092    }
1093
1094    /// Get a mutable reference to the net being driven
1095    pub fn as_net_mut(&self) -> RefMut<'_, Net> {
1096        self.netref.get_net_mut(self.pos)
1097    }
1098
1099    /// Returns `true` if this net is a principal input
1100    pub fn is_an_input(&self) -> bool {
1101        self.netref.is_an_input()
1102    }
1103
1104    /// Get the output port associated with this connection
1105    pub fn get_port(&self) -> Net {
1106        if self.netref.is_an_input() {
1107            panic!("Net is not driven by a primitive");
1108        }
1109        self.netref
1110            .get_instance_type()
1111            .unwrap()
1112            .get_output_port(self.pos)
1113            .clone()
1114    }
1115
1116    /// Connects the net driven by this output port to the given input port.
1117    pub fn connect(&self, input: InputPort<I>) {
1118        let operand = self.get_operand();
1119        let index = input.netref.unwrap().borrow().get_index();
1120        let netlist = self
1121            .netref
1122            .clone()
1123            .unwrap()
1124            .borrow()
1125            .owner
1126            .upgrade()
1127            .expect("Output port is unlinked from netlist");
1128        let obj = netlist.index_weak(&index);
1129        obj.borrow_mut().operands[input.pos] = Some(operand);
1130    }
1131
1132    /// Returns `true` if this net is a top-level output in the netlist.
1133    pub fn is_top_level_output(&self) -> bool {
1134        let netlist = self
1135            .netref
1136            .clone()
1137            .unwrap()
1138            .borrow()
1139            .owner
1140            .upgrade()
1141            .expect("DrivenNet is unlinked from netlist");
1142        let outputs = netlist.outputs.borrow();
1143        outputs.contains_key(&self.get_operand())
1144    }
1145
1146    /// Return the underlying circuit node
1147    pub fn unwrap(self) -> NetRef<I> {
1148        self.netref
1149    }
1150
1151    /// Returns a copy of the identifier of the net being driven.
1152    pub fn get_identifier(&self) -> Identifier {
1153        self.as_net().get_identifier().clone()
1154    }
1155
1156    /// Exposes this driven net as a top-level output with a specific port name.
1157    /// Multiple calls to this method can be used to create multiple output aliases for the same net.
1158    ///
1159    /// # Panics
1160    ///
1161    /// Panics if the weak reference to the netlist is dead.
1162    pub fn expose_with_name(self, name: Identifier) -> Self {
1163        let netlist = self
1164            .netref
1165            .clone()
1166            .unwrap()
1167            .borrow()
1168            .owner
1169            .upgrade()
1170            .expect("DrivenNet is unlinked from netlist");
1171        netlist.expose_net_with_name(self.clone(), name);
1172        self
1173    }
1174
1175    /// Removes a specific output alias by its name from this driven net.
1176    /// Returns true if the output was removed, false if it didn't exist.
1177    ///
1178    /// # Panics
1179    ///
1180    /// Panics if the reference to the netlist is lost.
1181    pub fn remove_output(&self, net_name: &Identifier) -> bool {
1182        let netlist = self
1183            .netref
1184            .clone()
1185            .unwrap()
1186            .borrow()
1187            .owner
1188            .upgrade()
1189            .expect("DrivenNet is unlinked from netlist");
1190        netlist.remove_output(self, net_name)
1191    }
1192
1193    /// Removes all output aliases for this driven net.
1194    /// Returns the number of outputs that were removed.
1195    ///
1196    /// # Panics
1197    ///
1198    /// Panics if the reference to the netlist is lost.
1199    pub fn remove_all_outputs(&self) -> usize {
1200        let netlist = self
1201            .netref
1202            .clone()
1203            .unwrap()
1204            .borrow()
1205            .owner
1206            .upgrade()
1207            .expect("DrivenNet is unlinked from netlist");
1208        netlist.remove_outputs(self)
1209    }
1210
1211    /// Returns the output position, if the net is the output of a gate.
1212    pub fn get_output_index(&self) -> Option<usize> {
1213        if self.netref.is_an_input() {
1214            None
1215        } else {
1216            Some(self.pos)
1217        }
1218    }
1219
1220    /// Returns the [Instantiable] type driving this net, if it has a driver.
1221    pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
1222        self.netref.get_instance_type()
1223    }
1224}
1225
1226impl<I> std::fmt::Display for DrivenNet<I>
1227where
1228    I: Instantiable,
1229{
1230    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1231        self.as_net().fmt(f)
1232    }
1233}
1234
1235impl<I> PartialEq for DrivenNet<I>
1236where
1237    I: Instantiable,
1238{
1239    fn eq(&self, other: &Self) -> bool {
1240        self.netref == other.netref && self.pos == other.pos
1241    }
1242}
1243
1244impl<I> Eq for DrivenNet<I> where I: Instantiable {}
1245
1246impl<I> std::hash::Hash for DrivenNet<I>
1247where
1248    I: Instantiable,
1249{
1250    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1251        self.netref.hash(state);
1252        self.pos.hash(state);
1253    }
1254}
1255
1256impl<I> Ord for DrivenNet<I>
1257where
1258    I: Instantiable,
1259{
1260    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
1261        match self.netref.cmp(&other.netref) {
1262            std::cmp::Ordering::Equal => self.pos.cmp(&other.pos),
1263            ord => ord,
1264        }
1265    }
1266}
1267
1268impl<I> PartialOrd for DrivenNet<I>
1269where
1270    I: Instantiable,
1271{
1272    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1273        Some(self.cmp(other))
1274    }
1275}
1276
1277impl<I> WeakIndex<usize> for Netlist<I>
1278where
1279    I: Instantiable,
1280{
1281    type Output = OwnedObject<I, Self>;
1282
1283    fn index_weak(&self, index: &usize) -> Rc<RefCell<Self::Output>> {
1284        self.objects.borrow()[*index].clone()
1285    }
1286}
1287
1288impl<I> Netlist<I>
1289where
1290    I: Instantiable,
1291{
1292    /// Creates a new netlist with the given name
1293    pub fn new(name: String) -> Rc<Self> {
1294        Rc::new(Self {
1295            name: RefCell::new(name),
1296            objects: RefCell::new(Vec::new()),
1297            outputs: RefCell::new(HashMap::new()),
1298        })
1299    }
1300
1301    /// Attempts to reclaim the netlist, returning [Some] if successful.
1302    pub fn reclaim(self: Rc<Self>) -> Option<Self> {
1303        Rc::try_unwrap(self).ok()
1304    }
1305
1306    /// Use interior mutability to add an object to the netlist. Returns a mutable reference to the created object.
1307    fn insert_object(
1308        self: &Rc<Self>,
1309        object: Object<I>,
1310        operands: &[DrivenNet<I>],
1311    ) -> Result<NetRef<I>, Error> {
1312        let index = self.objects.borrow().len();
1313        let weak = Rc::downgrade(self);
1314        let operands = operands
1315            .iter()
1316            .map(|net| Some(net.get_operand()))
1317            .collect::<Vec<_>>();
1318        let owned_object = Rc::new(RefCell::new(OwnedObject {
1319            object,
1320            owner: weak,
1321            operands,
1322            attributes: HashMap::new(),
1323            index,
1324        }));
1325        self.objects.borrow_mut().push(owned_object.clone());
1326        Ok(NetRef::wrap(owned_object))
1327    }
1328
1329    /// Inserts an input net to the netlist
1330    pub fn insert_input(self: &Rc<Self>, net: Net) -> DrivenNet<I> {
1331        let obj = Object::Input(net);
1332        self.insert_object(obj, &[]).unwrap().into()
1333    }
1334
1335    /// Inserts a four-state logic input port to the netlist
1336    pub fn insert_input_escaped_logic_bus(
1337        self: &Rc<Self>,
1338        net: String,
1339        bw: usize,
1340    ) -> Vec<DrivenNet<I>> {
1341        Net::new_escaped_logic_bus(net, bw)
1342            .into_iter()
1343            .map(|n| self.insert_input(n))
1344            .collect()
1345    }
1346
1347    /// Inserts a gate to the netlist
1348    pub fn insert_gate(
1349        self: &Rc<Self>,
1350        inst_type: I,
1351        inst_name: Identifier,
1352        operands: &[DrivenNet<I>],
1353    ) -> Result<NetRef<I>, Error> {
1354        let nets = inst_type
1355            .get_output_ports()
1356            .into_iter()
1357            .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1358            .collect::<Vec<_>>();
1359        let input_count = inst_type.get_input_ports().into_iter().count();
1360        if operands.len() != input_count {
1361            return Err(Error::ArgumentMismatch(input_count, operands.len()));
1362        }
1363        let obj = Object::Instance(nets, inst_name, inst_type);
1364        self.insert_object(obj, operands)
1365    }
1366
1367    /// Use interior mutability to add an object to the netlist. Returns a mutable reference to the created object.
1368    pub fn insert_gate_disconnected(
1369        self: &Rc<Self>,
1370        inst_type: I,
1371        inst_name: Identifier,
1372    ) -> NetRef<I> {
1373        let nets = inst_type
1374            .get_output_ports()
1375            .into_iter()
1376            .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1377            .collect::<Vec<_>>();
1378        let object = Object::Instance(nets, inst_name, inst_type);
1379        let index = self.objects.borrow().len();
1380        let weak = Rc::downgrade(self);
1381        let input_count = object
1382            .get_instance_type()
1383            .unwrap()
1384            .get_input_ports()
1385            .into_iter()
1386            .count();
1387        let operands = vec![None; input_count];
1388        let owned_object = Rc::new(RefCell::new(OwnedObject {
1389            object,
1390            owner: weak,
1391            operands,
1392            attributes: HashMap::new(),
1393            index,
1394        }));
1395        self.objects.borrow_mut().push(owned_object.clone());
1396        NetRef::wrap(owned_object)
1397    }
1398
1399    /// Inserts a constant [Logic] value to the netlist
1400    pub fn insert_constant(
1401        self: &Rc<Self>,
1402        value: Logic,
1403        inst_name: Identifier,
1404    ) -> Result<DrivenNet<I>, Error> {
1405        let obj = I::from_constant(value).ok_or(Error::InstantiableError(format!(
1406            "Instantiable type does not support constant value {}",
1407            value
1408        )))?;
1409        Ok(self.insert_gate_disconnected(obj, inst_name).into())
1410    }
1411
1412    /// Returns the driving node at input position `index` for `netref`
1413    ///
1414    /// # Panics
1415    ///
1416    /// Panics if `index` is out of bounds
1417    pub fn get_driver(&self, netref: NetRef<I>, index: usize) -> Option<NetRef<I>> {
1418        let op = netref.unwrap().borrow().operands[index]?;
1419        Some(NetRef::wrap(self.index_weak(&op.root()).clone()))
1420    }
1421
1422    /// Set an added object as a top-level output with a specific name.
1423    /// Multiple calls with different names for the same net will create multiple aliases.
1424    pub fn expose_net_with_name(&self, net: DrivenNet<I>, name: Identifier) -> DrivenNet<I> {
1425        let mut outputs = self.outputs.borrow_mut();
1426        let named_net = net.as_net().with_name(name);
1427        outputs
1428            .entry(net.get_operand())
1429            .or_default()
1430            .insert(named_net);
1431        net
1432    }
1433
1434    /// Sets the current net as a top-level output using the current name of the net
1435    pub fn expose_net(&self, net: DrivenNet<I>) -> Result<DrivenNet<I>, Error> {
1436        if net.is_an_input() {
1437            return Err(Error::InputNeedsAlias(net.as_net().clone()));
1438        }
1439        let mut outputs = self.outputs.borrow_mut();
1440        outputs
1441            .entry(net.get_operand())
1442            .or_default()
1443            .insert(net.as_net().clone());
1444        Ok(net)
1445    }
1446
1447    /// Removes a specific output alias by its operand and net name.
1448    /// Returns true if the output was removed, false if it didn't exist.
1449    pub fn remove_output(&self, operand: &DrivenNet<I>, net_name: &Identifier) -> bool {
1450        let mut outputs = self.outputs.borrow_mut();
1451        if let Some(nets) = outputs.get_mut(&operand.get_operand()) {
1452            // Create a net with just the identifier to match for removal
1453            let net_to_remove = Net::new(net_name.clone(), crate::circuit::DataType::logic());
1454            if nets.remove(&net_to_remove) {
1455                // If the set is now empty, remove the operand entirely
1456                if nets.is_empty() {
1457                    outputs.remove(&operand.get_operand());
1458                }
1459                return true;
1460            }
1461        }
1462        false
1463    }
1464
1465    /// Removes all output aliases for a specific operand.
1466    /// Returns the number of outputs that were removed.
1467    pub fn remove_outputs(&self, operand: &DrivenNet<I>) -> usize {
1468        //let mut outputs = self.outputs.borrow_mut();
1469        self.outputs
1470            .borrow_mut()
1471            .remove(&operand.get_operand())
1472            .map(|nets| nets.len())
1473            .unwrap_or(0)
1474    }
1475
1476    /// Removes all outputs from the netlist.
1477    pub fn clear_outputs(&self) {
1478        self.outputs.borrow_mut().clear();
1479    }
1480
1481    /// Unlink a circuit node from the rest of the netlist. Return the object that was being stored.
1482    pub fn delete_net_uses(&self, netref: NetRef<I>) -> Result<Object<I>, Error> {
1483        let unwrapped = netref.clone().unwrap();
1484        if Rc::strong_count(&unwrapped) > 3 {
1485            return Err(Error::DanglingReference(netref.nets().collect()));
1486        }
1487        let old_index = unwrapped.borrow().get_index();
1488        let objects = self.objects.borrow();
1489        for oref in objects.iter() {
1490            let operands = &mut oref.borrow_mut().operands;
1491            for operand in operands.iter_mut() {
1492                if let Some(op) = operand {
1493                    match op {
1494                        Operand::DirectIndex(idx) | Operand::CellIndex(idx, _)
1495                            if *idx == old_index =>
1496                        {
1497                            *operand = None;
1498                        }
1499                        _ => (),
1500                    }
1501                }
1502            }
1503        }
1504
1505        let outputs: Vec<Operand> = self
1506            .outputs
1507            .borrow()
1508            .keys()
1509            .filter(|operand| match operand {
1510                Operand::DirectIndex(idx) | Operand::CellIndex(idx, _) => *idx == old_index,
1511            })
1512            .cloned()
1513            .collect();
1514
1515        for operand in outputs {
1516            self.outputs.borrow_mut().remove(&operand);
1517        }
1518
1519        Ok(netref.unwrap().borrow().get().clone())
1520    }
1521
1522    /// Replaces the uses of a circuit node with another circuit node. The [Object] stored at `of` is returned.
1523    pub fn replace_net_uses(
1524        &self,
1525        of: DrivenNet<I>,
1526        with: &DrivenNet<I>,
1527    ) -> Result<Object<I>, Error> {
1528        let unwrapped = of.clone().unwrap().unwrap();
1529        let i = of.get_output_index();
1530        let k = with.get_output_index();
1531
1532        if of.clone().unwrap() == with.clone().unwrap() {
1533            if i == k {
1534                return Ok(of.unwrap().unwrap().borrow().get().clone());
1535            }
1536
1537            if Rc::strong_count(&unwrapped) > 4 {
1538                return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1539            }
1540        } else if Rc::strong_count(&unwrapped) > 3 {
1541            return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1542        }
1543
1544        let old_index = of.get_operand();
1545
1546        if let Some(nets) = self.outputs.borrow().get(&old_index)
1547            && nets.contains(&*of.as_net())
1548        {
1549            return Err(Error::NonuniqueNets(nets.iter().cloned().collect()));
1550        }
1551
1552        let new_index = with.get_operand();
1553        let objects = self.objects.borrow();
1554        for oref in objects.iter() {
1555            let operands = &mut oref.borrow_mut().operands;
1556            for operand in operands.iter_mut() {
1557                if let Some(op) = operand
1558                    && *op == old_index
1559                {
1560                    *operand = Some(new_index);
1561                }
1562            }
1563        }
1564
1565        // Move all the old outputs to the new key
1566        let outs = self.outputs.borrow_mut().remove(&old_index);
1567        if let Some(outs) = outs {
1568            self.outputs
1569                .borrow_mut()
1570                .entry(new_index)
1571                .or_default()
1572                .extend(outs);
1573        }
1574
1575        Ok(of.unwrap().unwrap().borrow().get().clone())
1576    }
1577}
1578
1579impl<I> Netlist<I>
1580where
1581    I: Instantiable,
1582{
1583    /// Returns the name of the netlist module
1584    pub fn get_name(&self) -> Ref<'_, String> {
1585        self.name.borrow()
1586    }
1587
1588    /// Sets the name of the netlist module
1589    /// # Panics
1590    ///
1591    /// Panics if the module name cannot be borrowed mutably.
1592    pub fn set_name(&self, name: String) {
1593        *self.name.borrow_mut() = name;
1594    }
1595
1596    /// Iterates over the input ports of the netlist.
1597    pub fn get_input_ports(&self) -> impl Iterator<Item = Net> {
1598        self.objects().filter_map(|oref| {
1599            if oref.is_an_input() {
1600                Some(oref.as_net().clone())
1601            } else {
1602                None
1603            }
1604        })
1605    }
1606
1607    /// Returns a list of output nets
1608    pub fn get_output_ports(&self) -> Vec<Net> {
1609        self.outputs
1610            .borrow()
1611            .values()
1612            .flat_map(|nets| nets.iter().cloned())
1613            .collect()
1614    }
1615
1616    /// Constructs an analysis of the netlist.
1617    pub fn get_analysis<'a, A: Analysis<'a, I>>(&'a self) -> Result<A, Error> {
1618        A::build(self)
1619    }
1620
1621    /// Finds the first circuit node that drives the `net`. This operation is O(n).
1622    /// This should be unique provided the netlist is well-formed.
1623    pub fn find_net(&self, net: &Net) -> Option<DrivenNet<I>> {
1624        for obj in self.objects() {
1625            for o in obj.outputs() {
1626                if *o.as_net() == *net {
1627                    return Some(o);
1628                }
1629            }
1630        }
1631        None
1632    }
1633
1634    /// Returns a `NetRef` to the first circuit node
1635    pub fn first(&self) -> Option<NetRef<I>> {
1636        self.objects
1637            .borrow()
1638            .first()
1639            .map(|nr| NetRef::wrap(nr.clone()))
1640    }
1641
1642    /// Returns a `NetRef` to the last circuit node
1643    pub fn last(&self) -> Option<NetRef<I>> {
1644        self.objects
1645            .borrow()
1646            .last()
1647            .map(|nr| NetRef::wrap(nr.clone()))
1648    }
1649
1650    /// Returns the number of objects in the netlist (instances + inputs)
1651    pub fn len(&self) -> usize {
1652        self.objects.borrow().len()
1653    }
1654
1655    /// Returns `true` if the netlist contains no objects.
1656    pub fn is_empty(&self) -> bool {
1657        self.objects.borrow().is_empty()
1658    }
1659
1660    /// Returns `true` if an output of `netref` which is driving a module output.
1661    pub fn drives_an_output(&self, netref: NetRef<I>) -> bool {
1662        let my_index = netref.unwrap().borrow().get_index();
1663        for key in self.outputs.borrow().keys() {
1664            if key.root() == my_index {
1665                return true;
1666            }
1667        }
1668        false
1669    }
1670
1671    /// Rename nets and instances in the netlist using the provided *injective* function.
1672    /// Returns an error if the function is not injective.
1673    /// # Examples
1674    ///
1675    /// ```
1676    /// use safety_net::format_id;
1677    /// use safety_net::{Gate, GateNetlist};
1678    ///
1679    /// let netlist = GateNetlist::new("example".to_string());
1680    /// let inv = Gate::new_logical("INV".into(), vec!["A".into()], "Y".into());
1681    /// let foo = netlist.insert_input("foo".into());
1682    /// let nr = netlist.insert_gate(inv, "bar".into(), &[foo]).unwrap();
1683    /// nr.expose_with_name("baz".into());
1684    /// netlist.rename_nets(|id, i| format_id!("{}_{}", id, i) ).unwrap();
1685    /// // "bar_Y" -> "bar_Y_0"
1686    /// // "bar" -> "bar_1"
1687    /// ```
1688    pub fn rename_nets<F: Fn(&Identifier, usize) -> Identifier>(&self, f: F) -> Result<(), Error> {
1689        let mut i: usize = 0;
1690        for nr in self.objects() {
1691            if nr.is_an_input() {
1692                continue;
1693            }
1694            for mut net in nr.nets_mut() {
1695                let rename = f(net.get_identifier(), i);
1696                net.set_identifier(rename);
1697                i += 1;
1698            }
1699        }
1700
1701        for nr in self.objects() {
1702            if nr.is_an_input() {
1703                continue;
1704            }
1705
1706            let rename = f(&nr.get_instance_name().unwrap(), i);
1707            nr.set_instance_name(rename);
1708            i += 1;
1709        }
1710
1711        self.verify()
1712    }
1713
1714    /// Cleans unused nodes from the netlist, returning `Ok(vec)` of the removed objects.
1715    pub fn clean_once(&self) -> Result<Vec<Object<I>>, Error> {
1716        let mut dead_objs = HashSet::new();
1717        {
1718            let fan_out = self.get_analysis::<FanOutTable<I>>()?;
1719            for obj in self.objects() {
1720                let mut is_dead = true;
1721                for net in obj.nets() {
1722                    // This should account for outputs
1723                    if fan_out.net_has_uses(&net) {
1724                        is_dead = false;
1725                        break;
1726                    }
1727                }
1728                if is_dead && !obj.is_an_input() {
1729                    dead_objs.insert(obj.unwrap().borrow().index);
1730                }
1731            }
1732        }
1733
1734        if dead_objs.is_empty() {
1735            return Ok(vec![]);
1736        }
1737
1738        let old_objects = self.objects.take();
1739
1740        // Check no dangling references will be created before mutating
1741        for i in dead_objs.iter() {
1742            let rc = &old_objects[*i];
1743            if Rc::strong_count(rc) > 1 {
1744                self.objects.replace(old_objects.clone());
1745                return Err(Error::DanglingReference(
1746                    rc.borrow().get().get_nets().to_vec(),
1747                ));
1748            }
1749        }
1750
1751        let mut removed = Vec::new();
1752        let mut remap: HashMap<usize, usize> = HashMap::new();
1753        for (old_index, obj) in old_objects.into_iter().enumerate() {
1754            if dead_objs.contains(&old_index) {
1755                removed.push(obj.borrow().get().clone());
1756                continue;
1757            }
1758
1759            let new_index = self.objects.borrow().len();
1760            remap.insert(old_index, new_index);
1761            obj.borrow_mut().index = new_index;
1762            self.objects.borrow_mut().push(obj);
1763        }
1764
1765        for obj in self.objects.borrow().iter() {
1766            for operand in obj.borrow_mut().inds_mut() {
1767                let root = operand.root();
1768                let root = *remap.get(&root).unwrap_or(&root);
1769                *operand = operand.remap(root);
1770            }
1771        }
1772
1773        let pairs: Vec<_> = self.outputs.take().into_iter().collect();
1774        for (operand, net) in pairs {
1775            let root = operand.root();
1776            let root = *remap.get(&root).unwrap_or(&root);
1777            let new_operand = operand.remap(root);
1778            self.outputs.borrow_mut().insert(new_operand, net);
1779        }
1780
1781        Ok(removed)
1782    }
1783
1784    /// Greedly removes unused nodes from the netlist, until it stops changing.
1785    /// Returns `Ok(vec)` of the removed objects.
1786    pub fn clean(&self) -> Result<Vec<Object<I>>, Error> {
1787        let mut removed = Vec::new();
1788        let mut r = self.clean_once()?;
1789        while !r.is_empty() {
1790            removed.extend(r);
1791            r = self.clean_once()?;
1792        }
1793        Ok(removed)
1794    }
1795
1796    /// Returns `true` if all the nets are uniquely named
1797    fn nets_unique(&self) -> Result<(), Error> {
1798        let mut nets = HashSet::new();
1799        for net in self.into_iter() {
1800            if !nets.insert(net.clone().take_identifier()) {
1801                return Err(Error::NonuniqueNets(vec![net]));
1802            }
1803        }
1804        Ok(())
1805    }
1806
1807    /// Returns `true` if all the nets are uniquely named
1808    fn insts_unique(&self) -> Result<(), Error> {
1809        let mut insts = HashSet::new();
1810        for inst in self.objects() {
1811            if let Some(name) = inst.get_instance_name()
1812                && !insts.insert(name.clone())
1813            {
1814                return Err(Error::NonuniqueInsts(vec![name]));
1815            }
1816        }
1817        Ok(())
1818    }
1819
1820    /// Verifies that a netlist is well-formed.
1821    pub fn verify(&self) -> Result<(), Error> {
1822        if self.outputs.borrow().is_empty() {
1823            return Err(Error::NoOutputs);
1824        }
1825
1826        self.nets_unique()?;
1827
1828        self.insts_unique()?;
1829
1830        Ok(())
1831    }
1832}
1833
1834/// Represent a driven net alongside its connection to an input port
1835#[derive(Debug, Clone)]
1836pub struct Connection<I: Instantiable> {
1837    driver: DrivenNet<I>,
1838    input: InputPort<I>,
1839}
1840
1841impl<I> Connection<I>
1842where
1843    I: Instantiable,
1844{
1845    fn new(driver: DrivenNet<I>, input: InputPort<I>) -> Self {
1846        Self { driver, input }
1847    }
1848
1849    /// Return the driver of the connection
1850    pub fn src(&self) -> DrivenNet<I> {
1851        self.driver.clone()
1852    }
1853
1854    /// Return the net along the connection
1855    pub fn net(&self) -> Net {
1856        self.driver.as_net().clone()
1857    }
1858
1859    /// Returns the input port of the connection
1860    pub fn target(&self) -> InputPort<I> {
1861        self.input.clone()
1862    }
1863}
1864
1865impl<I> std::fmt::Display for Connection<I>
1866where
1867    I: Instantiable,
1868{
1869    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1870        self.net().fmt(f)
1871    }
1872}
1873
1874/// A collection of iterators for the netlist
1875pub mod iter {
1876
1877    use super::{
1878        Connection, DrivenNet, InputPort, Instantiable, Net, NetRef, Netlist, Operand, WeakIndex,
1879    };
1880    use std::collections::{HashMap, HashSet};
1881    /// An iterator over the nets in a netlist
1882    pub struct NetIterator<'a, I: Instantiable> {
1883        netlist: &'a Netlist<I>,
1884        index: usize,
1885        subindex: usize,
1886    }
1887
1888    impl<'a, I> NetIterator<'a, I>
1889    where
1890        I: Instantiable,
1891    {
1892        /// Creates a new iterator for the netlist
1893        pub fn new(netlist: &'a Netlist<I>) -> Self {
1894            Self {
1895                netlist,
1896                index: 0,
1897                subindex: 0,
1898            }
1899        }
1900    }
1901
1902    impl<I> Iterator for NetIterator<'_, I>
1903    where
1904        I: Instantiable,
1905    {
1906        type Item = Net;
1907
1908        fn next(&mut self) -> Option<Self::Item> {
1909            while self.index < self.netlist.objects.borrow().len() {
1910                let objects = self.netlist.objects.borrow();
1911                let object = objects[self.index].borrow();
1912                if self.subindex < object.get().get_nets().len() {
1913                    let net = object.get().get_nets()[self.subindex].clone();
1914                    self.subindex += 1;
1915                    return Some(net);
1916                }
1917                self.subindex = 0;
1918                self.index += 1;
1919            }
1920            None
1921        }
1922    }
1923
1924    /// An iterator over the objects in a netlist
1925    pub struct ObjectIterator<'a, I: Instantiable> {
1926        netlist: &'a Netlist<I>,
1927        index: usize,
1928    }
1929
1930    impl<'a, I> ObjectIterator<'a, I>
1931    where
1932        I: Instantiable,
1933    {
1934        /// Creates a new  object iterator for the netlist
1935        pub fn new(netlist: &'a Netlist<I>) -> Self {
1936            Self { netlist, index: 0 }
1937        }
1938    }
1939
1940    impl<I> Iterator for ObjectIterator<'_, I>
1941    where
1942        I: Instantiable,
1943    {
1944        type Item = NetRef<I>;
1945
1946        fn next(&mut self) -> Option<Self::Item> {
1947            if self.index < self.netlist.objects.borrow().len() {
1948                let objects = self.netlist.objects.borrow();
1949                let object = &objects[self.index];
1950                self.index += 1;
1951                return Some(NetRef::wrap(object.clone()));
1952            }
1953            None
1954        }
1955    }
1956
1957    /// An iterator over the connections in a netlist
1958    pub struct ConnectionIterator<'a, I: Instantiable> {
1959        netlist: &'a Netlist<I>,
1960        index: usize,
1961        subindex: usize,
1962    }
1963
1964    impl<'a, I> ConnectionIterator<'a, I>
1965    where
1966        I: Instantiable,
1967    {
1968        /// Create a new connection iterator for the netlist
1969        pub fn new(netlist: &'a Netlist<I>) -> Self {
1970            Self {
1971                netlist,
1972                index: 0,
1973                subindex: 0,
1974            }
1975        }
1976    }
1977
1978    impl<I> Iterator for ConnectionIterator<'_, I>
1979    where
1980        I: Instantiable,
1981    {
1982        type Item = super::Connection<I>;
1983
1984        fn next(&mut self) -> Option<Self::Item> {
1985            while self.index < self.netlist.objects.borrow().len() {
1986                let objects = self.netlist.objects.borrow();
1987                let object = objects[self.index].borrow();
1988                let noperands = object.operands.len();
1989                while self.subindex < noperands {
1990                    if let Some(operand) = &object.operands[self.subindex] {
1991                        let driver = match operand {
1992                            Operand::DirectIndex(idx) => {
1993                                DrivenNet::new(0, NetRef::wrap(objects[*idx].clone()))
1994                            }
1995                            Operand::CellIndex(idx, j) => {
1996                                DrivenNet::new(*j, NetRef::wrap(objects[*idx].clone()))
1997                            }
1998                        };
1999                        let input = InputPort::new(
2000                            self.subindex,
2001                            NetRef::wrap(objects[self.index].clone()),
2002                        );
2003                        self.subindex += 1;
2004                        return Some(Connection::new(driver, input));
2005                    }
2006                    self.subindex += 1;
2007                }
2008                self.subindex = 0;
2009                self.index += 1;
2010            }
2011            None
2012        }
2013    }
2014
2015    /// A stack that can check contains in roughly O(1) time.
2016    #[derive(Clone)]
2017    struct Walk<T: std::hash::Hash + PartialEq + Eq + Clone> {
2018        stack: Vec<T>,
2019        counter: HashMap<T, usize>,
2020    }
2021
2022    impl<T> Walk<T>
2023    where
2024        T: std::hash::Hash + PartialEq + Eq + Clone,
2025    {
2026        /// Create a new, empty Stack.
2027        fn new() -> Self {
2028            Self {
2029                stack: Vec::new(),
2030                counter: HashMap::new(),
2031            }
2032        }
2033
2034        /// Inserts an element into the stack
2035        fn push(&mut self, item: T) {
2036            self.stack.push(item.clone());
2037            *self.counter.entry(item).or_insert(0) += 1;
2038        }
2039
2040        /// Returns true if the stack shows a cycle
2041        fn contains_cycle(&self) -> bool {
2042            self.counter.values().any(|&count| count > 1)
2043        }
2044
2045        /// Returns a reference to the last element in the stack
2046        fn last(&self) -> Option<&T> {
2047            self.stack.last()
2048        }
2049    }
2050
2051    /// A depth-first iterator over the circuit nodes in a netlist
2052    /// # Examples
2053    ///
2054    /// ```
2055    /// use safety_net::iter::DFSIterator;
2056    /// use safety_net::GateNetlist;
2057    ///
2058    /// let netlist = GateNetlist::new("example".to_string());
2059    /// netlist.insert_input("input1".into());
2060    /// let mut nodes = Vec::new();
2061    /// let mut dfs = DFSIterator::new(&netlist, netlist.last().unwrap());
2062    /// while let Some(n) = dfs.next() {
2063    ///     if dfs.check_cycles() {
2064    ///         panic!("Cycle detected in the netlist");
2065    ///     }
2066    ///     nodes.push(n);
2067    /// }
2068    /// ```
2069    pub struct DFSIterator<'a, I: Instantiable> {
2070        netlist: &'a Netlist<I>,
2071        stacks: Vec<Walk<NetRef<I>>>,
2072        visited: HashSet<usize>,
2073        cycles: bool,
2074    }
2075
2076    impl<'a, I> DFSIterator<'a, I>
2077    where
2078        I: Instantiable,
2079    {
2080        /// Create a new DFS iterator for the netlist starting at `from`.
2081        pub fn new(netlist: &'a Netlist<I>, from: NetRef<I>) -> Self {
2082            let mut s = Walk::new();
2083            s.push(from);
2084            Self {
2085                netlist,
2086                stacks: vec![s],
2087                visited: HashSet::new(),
2088                cycles: false,
2089            }
2090        }
2091    }
2092
2093    impl<I> DFSIterator<'_, I>
2094    where
2095        I: Instantiable,
2096    {
2097        /// Check if the DFS traversal has encountered a cycle yet.
2098        pub fn check_cycles(&self) -> bool {
2099            self.cycles
2100        }
2101
2102        /// Consumes the iterator to detect cycles in the netlist.
2103        pub fn detect_cycles(mut self) -> bool {
2104            if self.cycles {
2105                return true;
2106            }
2107
2108            while let Some(_) = self.next() {
2109                if self.cycles {
2110                    return true;
2111                }
2112            }
2113
2114            self.cycles
2115        }
2116    }
2117
2118    impl<I> Iterator for DFSIterator<'_, I>
2119    where
2120        I: Instantiable,
2121    {
2122        type Item = NetRef<I>;
2123
2124        fn next(&mut self) -> Option<Self::Item> {
2125            if let Some(walk) = self.stacks.pop() {
2126                if walk.contains_cycle() {
2127                    self.cycles = true;
2128                }
2129                let item = walk.last().cloned();
2130                let uw = item.clone().unwrap().unwrap();
2131                let index = uw.borrow().get_index();
2132                if self.visited.insert(index) {
2133                    let operands = &uw.borrow().operands;
2134                    for operand in operands.iter().flatten() {
2135                        let mut new_walk = walk.clone();
2136                        new_walk.push(NetRef::wrap(self.netlist.index_weak(&operand.root())));
2137                        self.stacks.push(new_walk);
2138                    }
2139                    return item;
2140                }
2141
2142                return self.next();
2143            }
2144
2145            None
2146        }
2147    }
2148}
2149
2150impl<'a, I> IntoIterator for &'a Netlist<I>
2151where
2152    I: Instantiable,
2153{
2154    type Item = Net;
2155    type IntoIter = iter::NetIterator<'a, I>;
2156
2157    fn into_iter(self) -> Self::IntoIter {
2158        iter::NetIterator::new(self)
2159    }
2160}
2161
2162/// Filter invariants of [Instantiable] in a netlist. Use it like you would `matches!`.
2163/// Example: ```filter_nodes!(netlist, Gate::AND(_));```
2164#[macro_export]
2165macro_rules! filter_nodes {
2166    ($netlist:ident, $pattern:pat $(if $guard:expr)? $(,)?) => {
2167        $netlist.matches(|f| match f {
2168            $pattern $(if $guard)? => true,
2169            _ => false
2170        })
2171    };
2172}
2173
2174impl<I> Netlist<I>
2175where
2176    I: Instantiable,
2177{
2178    /// Returns an iterator over the circuit nodes in the netlist.
2179    pub fn objects(&self) -> impl Iterator<Item = NetRef<I>> {
2180        iter::ObjectIterator::new(self)
2181    }
2182
2183    /// Returns an iterator over the circuit nodes that match the instance type.
2184    pub fn matches<F>(&self, filter: F) -> impl Iterator<Item = NetRef<I>>
2185    where
2186        F: Fn(&I) -> bool,
2187    {
2188        self.objects().filter(move |f| {
2189            if let Some(inst_type) = f.get_instance_type() {
2190                filter(&inst_type)
2191            } else {
2192                false
2193            }
2194        })
2195    }
2196
2197    /// Returns an iterator to principal inputs in the netlist as references.
2198    pub fn inputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
2199        self.objects()
2200            .filter(|n| n.is_an_input())
2201            .map(|n| DrivenNet::new(0, n))
2202    }
2203
2204    /// Returns an iterator to circuit nodes that drive an output in the netlist.
2205    pub fn outputs(&self) -> Vec<(DrivenNet<I>, Net)> {
2206        self.outputs
2207            .borrow()
2208            .iter()
2209            .flat_map(|(k, nets)| {
2210                nets.iter().map(|n| {
2211                    (
2212                        DrivenNet::new(k.secondary(), NetRef::wrap(self.index_weak(&k.root()))),
2213                        n.clone(),
2214                    )
2215                })
2216            })
2217            .collect()
2218    }
2219
2220    /// Returns an iterator over the wire connections in the netlist.
2221    pub fn connections(&self) -> impl Iterator<Item = Connection<I>> {
2222        iter::ConnectionIterator::new(self)
2223    }
2224
2225    /// Returns a depth-first search iterator over the nodes in the netlist.
2226    pub fn dfs(&self, from: NetRef<I>) -> impl Iterator<Item = NetRef<I>> {
2227        iter::DFSIterator::new(self, from)
2228    }
2229
2230    #[cfg(feature = "serde")]
2231    /// Serializes the netlist to a writer.
2232    pub fn serialize(self, writer: impl std::io::Write) -> Result<(), serde_json::Error>
2233    where
2234        I: ::serde::Serialize,
2235    {
2236        serde::netlist_serialize(self, writer)
2237    }
2238}
2239
2240impl<I> std::fmt::Display for Netlist<I>
2241where
2242    I: Instantiable,
2243{
2244    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2245        // Borrow everything first
2246        let objects = self.objects.borrow();
2247        let outputs = self.outputs.borrow();
2248
2249        writeln!(f, "module {} (", self.get_name())?;
2250
2251        // Print inputs and outputs
2252        let level = 2;
2253        let indent = " ".repeat(level);
2254        for oref in objects.iter() {
2255            let owned = oref.borrow();
2256            let obj = owned.get();
2257            if let Object::Input(net) = obj {
2258                writeln!(f, "{}{},", indent, net.get_identifier().emit_name())?;
2259            }
2260        }
2261
2262        // Flatten the outputs to collect all (operand, net) pairs
2263        let all_outputs: Vec<_> = outputs.iter().flat_map(|(_, nets)| nets.iter()).collect();
2264        for (i, net) in all_outputs.iter().enumerate() {
2265            if i == all_outputs.len() - 1 {
2266                writeln!(f, "{}{}", indent, net.get_identifier().emit_name())?;
2267            } else {
2268                writeln!(f, "{}{},", indent, net.get_identifier().emit_name())?;
2269            }
2270        }
2271        writeln!(f, ");")?;
2272
2273        // Make wire decls
2274        let mut already_decl = HashSet::new();
2275        for oref in objects.iter() {
2276            let owned = oref.borrow();
2277            let obj = owned.get();
2278            if let Object::Input(net) = obj {
2279                writeln!(f, "{}input {};", indent, net.get_identifier().emit_name())?;
2280                writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2281                already_decl.insert(net.clone());
2282            }
2283        }
2284        for nets in outputs.values() {
2285            for net in nets {
2286                if !already_decl.contains(net) {
2287                    writeln!(f, "{}output {};", indent, net.get_identifier().emit_name())?;
2288                    writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2289                    already_decl.insert(net.clone());
2290                }
2291            }
2292        }
2293        for oref in objects.iter() {
2294            let owned = oref.borrow();
2295            let obj = owned.get();
2296            if let Object::Instance(nets, _, inst_type) = obj
2297                && inst_type.get_constant().is_none()
2298            {
2299                for net in nets.iter() {
2300                    if !already_decl.contains(net) {
2301                        writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2302                        already_decl.insert(net.clone());
2303                    }
2304                }
2305            }
2306        }
2307
2308        for oref in objects.iter() {
2309            let owned = oref.borrow();
2310            let obj = owned.get();
2311
2312            // Skip emitting constants as their uses will be hard-wired
2313            if let Some(inst_type) = obj.get_instance_type()
2314                && inst_type.get_constant().is_some()
2315            {
2316                continue;
2317            }
2318
2319            if let Object::Instance(nets, inst_name, inst_type) = obj {
2320                for (k, v) in owned.attributes.iter() {
2321                    if let Some(value) = v {
2322                        writeln!(f, "{indent}(* {k} = \"{value}\" *)")?;
2323                    } else {
2324                        writeln!(f, "{indent}(* {k} *)")?;
2325                    }
2326                }
2327
2328                write!(f, "{}{} ", indent, inst_type.get_name())?;
2329                if inst_type.is_parameterized() {
2330                    writeln!(f, "#(")?;
2331                    let level = 4;
2332                    let indent = " ".repeat(level);
2333                    let params: Vec<_> = inst_type.parameters().collect();
2334                    for (i, (k, v)) in params.iter().enumerate() {
2335                        if i == params.len() - 1 {
2336                            writeln!(f, "{indent}.{k}({v})")?;
2337                        } else {
2338                            writeln!(f, "{indent}.{k}({v}),")?;
2339                        }
2340                    }
2341                    let level = 2;
2342                    let indent = " ".repeat(level);
2343                    write!(f, "{indent}) ")?;
2344                }
2345                writeln!(f, "{} (", inst_name.emit_name())?;
2346                let level = 4;
2347                let indent = " ".repeat(level);
2348                for (idx, port) in inst_type.get_input_ports().into_iter().enumerate() {
2349                    let port_name = port.get_identifier().emit_name();
2350                    if let Some(operand) = owned.operands[idx].as_ref() {
2351                        let operand_net = match operand {
2352                            Operand::DirectIndex(idx) => objects[*idx].borrow().as_net().clone(),
2353                            Operand::CellIndex(idx, j) => {
2354                                objects[*idx].borrow().get_net(*j).clone()
2355                            }
2356                        };
2357
2358                        let operand_str = if let Some(inst_type) =
2359                            objects[operand.root()].borrow().get().get_instance_type()
2360                            && let Some(logic) = inst_type.get_constant()
2361                        {
2362                            logic.to_string()
2363                        } else {
2364                            operand_net.get_identifier().emit_name()
2365                        };
2366
2367                        writeln!(f, "{}.{}({}),", indent, port_name, operand_str)?;
2368                    }
2369                }
2370
2371                for (idx, net) in nets.iter().enumerate() {
2372                    let port_name = inst_type.get_output_port(idx).get_identifier().emit_name();
2373                    if idx == nets.len() - 1 {
2374                        writeln!(
2375                            f,
2376                            "{}.{}({})",
2377                            indent,
2378                            port_name,
2379                            net.get_identifier().emit_name()
2380                        )?;
2381                    } else {
2382                        writeln!(
2383                            f,
2384                            "{}.{}({}),",
2385                            indent,
2386                            port_name,
2387                            net.get_identifier().emit_name()
2388                        )?;
2389                    }
2390                }
2391
2392                let level = 2;
2393                let indent = " ".repeat(level);
2394                writeln!(f, "{indent});")?;
2395            }
2396        }
2397
2398        for (driver, nets) in outputs.iter() {
2399            for net in nets {
2400                let driver_net = match driver {
2401                    Operand::DirectIndex(idx) => self.index_weak(idx).borrow().as_net().clone(),
2402                    Operand::CellIndex(idx, j) => self.index_weak(idx).borrow().get_net(*j).clone(),
2403                };
2404
2405                let driver_str = if let Some(inst_type) = self
2406                    .index_weak(&driver.root())
2407                    .borrow()
2408                    .get()
2409                    .get_instance_type()
2410                    && let Some(logic) = inst_type.get_constant()
2411                {
2412                    logic.to_string()
2413                } else {
2414                    driver_net.get_identifier().emit_name()
2415                };
2416
2417                if net.get_identifier() != driver_net.get_identifier() {
2418                    writeln!(
2419                        f,
2420                        "{}assign {} = {};",
2421                        indent,
2422                        net.get_identifier().emit_name(),
2423                        driver_str
2424                    )?;
2425                }
2426            }
2427        }
2428
2429        writeln!(f, "endmodule")
2430    }
2431}
2432
2433/// A type alias for a netlist of gates
2434pub type GateNetlist = Netlist<Gate>;
2435/// A type alias to Gate circuit nodes
2436pub type GateRef = NetRef<Gate>;
2437
2438#[cfg(test)]
2439mod tests {
2440    use super::*;
2441    #[test]
2442    fn test_delete_netlist() {
2443        let netlist = Netlist::new("simple_example".to_string());
2444
2445        // Add the the two inputs
2446        let input1 = netlist.insert_input("input1".into());
2447        let input2 = netlist.insert_input("input2".into());
2448
2449        // Instantiate an AND gate
2450        let instance = netlist
2451            .insert_gate(
2452                Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
2453                "my_and".into(),
2454                &[input1.clone(), input2.clone()],
2455            )
2456            .unwrap();
2457
2458        // Make this AND gate an output
2459        let instance = instance.expose_as_output().unwrap();
2460        instance.delete_uses().unwrap();
2461        // Cannot clean a netlist that is in a invalid state
2462        assert!(netlist.clean().is_err());
2463        input1.expose_with_name("an_output".into());
2464        assert!(netlist.clean().is_ok());
2465    }
2466
2467    #[test]
2468    #[should_panic(expected = "Attempted to create a gate with a sliced identifier")]
2469    fn gate_w_slice_panics() {
2470        Gate::new_logical("AND[1]".into(), vec!["A".into(), "B".into()], "Y".into());
2471    }
2472
2473    #[test]
2474    fn gates_dont_have_params() {
2475        // The baseline implementation of gates do not have parameters.
2476        let gate = Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into());
2477        assert!(!gate.has_parameter(&"id".into()));
2478        assert!(gate.get_parameter(&"id".into()).is_none());
2479        assert_eq!(*gate.get_gate_name(), "AND".into());
2480    }
2481
2482    #[test]
2483    fn operand_conversions() {
2484        let operand = Operand::CellIndex(3, 2);
2485        assert_eq!(operand.to_string(), "3.2");
2486        let parsed = "3.2".parse::<Operand>();
2487        assert!(parsed.is_ok());
2488        let parsed = parsed.unwrap();
2489        assert_eq!(operand, parsed);
2490    }
2491
2492    #[test]
2493    #[should_panic(expected = "out of bounds for netref")]
2494    fn test_bad_output() {
2495        let netlist = GateNetlist::new("min_module".to_string());
2496        let a = netlist.insert_input("a".into());
2497        DrivenNet::new(1, a.unwrap());
2498    }
2499}
2500#[cfg(feature = "serde")]
2501/// Serde support for netlists
2502pub mod serde {
2503    use super::{Netlist, Operand, OwnedObject, WeakIndex};
2504    use crate::{
2505        attribute::{AttributeKey, AttributeValue},
2506        circuit::{Instantiable, Net, Object},
2507    };
2508    use serde::{Deserialize, Serialize, de::DeserializeOwned};
2509    use std::cell::RefCell;
2510    use std::{
2511        collections::{BTreeSet, HashMap},
2512        rc::Rc,
2513    };
2514
2515    #[derive(Debug, Serialize, Deserialize)]
2516    struct SerdeObject<I>
2517    where
2518        I: Instantiable + Serialize,
2519    {
2520        /// The object that is owned by the netlist
2521        object: Object<I>,
2522        /// The list of operands for the object
2523        operands: Vec<Option<Operand>>,
2524        /// A collection of attributes for the object
2525        attributes: HashMap<AttributeKey, AttributeValue>,
2526    }
2527
2528    impl<I, O> From<OwnedObject<I, O>> for SerdeObject<I>
2529    where
2530        I: Instantiable + Serialize,
2531        O: WeakIndex<usize, Output = OwnedObject<I, O>>,
2532    {
2533        fn from(value: OwnedObject<I, O>) -> Self {
2534            SerdeObject {
2535                object: value.object,
2536                operands: value.operands,
2537                attributes: value.attributes,
2538            }
2539        }
2540    }
2541
2542    impl<I> SerdeObject<I>
2543    where
2544        I: Instantiable + Serialize,
2545    {
2546        fn into_owned_object<O>(self, owner: &Rc<O>, index: usize) -> OwnedObject<I, O>
2547        where
2548            O: WeakIndex<usize, Output = OwnedObject<I, O>>,
2549        {
2550            OwnedObject {
2551                object: self.object,
2552                owner: Rc::downgrade(owner),
2553                operands: self.operands,
2554                attributes: self.attributes,
2555                index,
2556            }
2557        }
2558    }
2559
2560    #[derive(Debug, Serialize, Deserialize)]
2561    struct SerdeNetlist<I>
2562    where
2563        I: Instantiable + Serialize,
2564    {
2565        /// The name of the netlist
2566        name: String,
2567        /// The list of objects in the netlist, such as inputs, modules, and primitives
2568        objects: Vec<SerdeObject<I>>,
2569        /// The list of operands that point to objects which are outputs.
2570        /// Indices must be a string if we want to support JSON.
2571        /// Each operand can map to multiple nets, supporting output aliases.
2572        outputs: HashMap<String, BTreeSet<Net>>,
2573    }
2574
2575    impl<I> From<Netlist<I>> for SerdeNetlist<I>
2576    where
2577        I: Instantiable + Serialize,
2578    {
2579        fn from(value: Netlist<I>) -> Self {
2580            SerdeNetlist {
2581                name: value.name.into_inner(),
2582                objects: value
2583                    .objects
2584                    .into_inner()
2585                    .into_iter()
2586                    .map(|o| {
2587                        Rc::try_unwrap(o)
2588                            .ok()
2589                            .expect("Cannot serialize with live references")
2590                            .into_inner()
2591                            .into()
2592                    })
2593                    .collect(),
2594                outputs: value
2595                    .outputs
2596                    .into_inner()
2597                    .into_iter()
2598                    // Indices must be a string if we want to support JSON.
2599                    .map(|(o, nets)| (o.to_string(), nets.into_iter().collect()))
2600                    .collect(),
2601            }
2602        }
2603    }
2604
2605    impl<I> SerdeNetlist<I>
2606    where
2607        I: Instantiable + Serialize,
2608    {
2609        /// Convert the serialized netlist back into a reference-counted netlist.
2610        fn into_netlist(self) -> Rc<Netlist<I>> {
2611            let netlist = Netlist::new(self.name);
2612            let outputs: HashMap<Operand, BTreeSet<Net>> = self
2613                .outputs
2614                .into_iter()
2615                .map(|(k, v)| {
2616                    let operand = k.parse::<Operand>().expect("Invalid index");
2617                    (operand, v.into_iter().collect())
2618                })
2619                .collect();
2620            let objects = self
2621                .objects
2622                .into_iter()
2623                .enumerate()
2624                .map(|(i, o)| {
2625                    let owned_object = o.into_owned_object(&netlist, i);
2626                    Rc::new(RefCell::new(owned_object))
2627                })
2628                .collect::<Vec<_>>();
2629            {
2630                let mut objs_mut = netlist.objects.borrow_mut();
2631                *objs_mut = objects;
2632                let mut outputs_mut = netlist.outputs.borrow_mut();
2633                *outputs_mut = outputs;
2634            }
2635            netlist
2636        }
2637    }
2638
2639    /// Serialize the netlist into the writer.
2640    pub fn netlist_serialize<I: Instantiable + Serialize>(
2641        netlist: Netlist<I>,
2642        writer: impl std::io::Write,
2643    ) -> Result<(), serde_json::Error> {
2644        let sobj: SerdeNetlist<I> = netlist.into();
2645        serde_json::to_writer_pretty(writer, &sobj)
2646    }
2647
2648    /// Deserialize a netlist from the reader.
2649    pub fn netlist_deserialize<I: Instantiable + Serialize + DeserializeOwned>(
2650        reader: impl std::io::Read,
2651    ) -> Result<Rc<Netlist<I>>, serde_json::Error> {
2652        let sobj: SerdeNetlist<I> = serde_json::from_reader(reader)?;
2653        Ok(sobj.into_netlist())
2654    }
2655}