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    pub fn rename_nets<F: Fn(usize) -> Identifier>(&self, f: F) -> Result<(), Error> {
1674        let mut i: usize = 0;
1675        for nr in self.objects() {
1676            if nr.is_an_input() {
1677                continue;
1678            }
1679            for mut net in nr.nets_mut() {
1680                net.set_identifier(f(i));
1681                i += 1;
1682            }
1683        }
1684
1685        for nr in self.objects() {
1686            if nr.is_an_input() {
1687                continue;
1688            }
1689
1690            nr.set_instance_name(f(i));
1691            i += 1;
1692        }
1693
1694        self.verify()
1695    }
1696
1697    /// Cleans unused nodes from the netlist, returning `Ok(true)` if the netlist changed.
1698    pub fn clean_once(&self) -> Result<bool, Error> {
1699        let mut dead_objs = HashSet::new();
1700        {
1701            let fan_out = self.get_analysis::<FanOutTable<I>>()?;
1702            for obj in self.objects() {
1703                let mut is_dead = true;
1704                for net in obj.nets() {
1705                    // This should account for outputs
1706                    if fan_out.net_has_uses(&net) {
1707                        is_dead = false;
1708                        break;
1709                    }
1710                }
1711                if is_dead && !obj.is_an_input() {
1712                    dead_objs.insert(obj.unwrap().borrow().index);
1713                }
1714            }
1715        }
1716
1717        if dead_objs.is_empty() {
1718            return Ok(false);
1719        }
1720
1721        let old_objects = self.objects.take();
1722
1723        // Check no dangling references will be created before mutating
1724        for i in dead_objs.iter() {
1725            let rc = &old_objects[*i];
1726            if Rc::strong_count(rc) > 1 {
1727                self.objects.replace(old_objects.clone());
1728                return Err(Error::DanglingReference(
1729                    rc.borrow().get().get_nets().to_vec(),
1730                ));
1731            }
1732        }
1733
1734        let mut remap: HashMap<usize, usize> = HashMap::new();
1735        for (old_index, obj) in old_objects.into_iter().enumerate() {
1736            if dead_objs.contains(&old_index) {
1737                continue;
1738            }
1739
1740            let new_index = self.objects.borrow().len();
1741            remap.insert(old_index, new_index);
1742            obj.borrow_mut().index = new_index;
1743            self.objects.borrow_mut().push(obj);
1744        }
1745
1746        for obj in self.objects.borrow().iter() {
1747            for operand in obj.borrow_mut().inds_mut() {
1748                let root = operand.root();
1749                let root = *remap.get(&root).unwrap_or(&root);
1750                *operand = operand.remap(root);
1751            }
1752        }
1753
1754        let pairs: Vec<_> = self.outputs.take().into_iter().collect();
1755        for (operand, net) in pairs {
1756            let root = operand.root();
1757            let root = *remap.get(&root).unwrap_or(&root);
1758            let new_operand = operand.remap(root);
1759            self.outputs.borrow_mut().insert(new_operand, net);
1760        }
1761
1762        Ok(true)
1763    }
1764
1765    /// Greedly removes unused nodes from the netlist, until it stops changing.
1766    /// Returns true if the netlist was changed.
1767    pub fn clean(&self) -> Result<bool, Error> {
1768        if !self.clean_once()? {
1769            Ok(false)
1770        } else {
1771            let mut changed = true;
1772            while changed {
1773                changed = self.clean_once()?;
1774            }
1775            Ok(true)
1776        }
1777    }
1778
1779    /// Returns `true` if all the nets are uniquely named
1780    fn nets_unique(&self) -> Result<(), Error> {
1781        let mut nets = HashSet::new();
1782        for net in self.into_iter() {
1783            if !nets.insert(net.clone().take_identifier()) {
1784                return Err(Error::NonuniqueNets(vec![net]));
1785            }
1786        }
1787        Ok(())
1788    }
1789
1790    /// Returns `true` if all the nets are uniquely named
1791    fn insts_unique(&self) -> Result<(), Error> {
1792        let mut insts = HashSet::new();
1793        for inst in self.objects() {
1794            if let Some(name) = inst.get_instance_name()
1795                && !insts.insert(name.clone())
1796            {
1797                return Err(Error::NonuniqueInsts(vec![name]));
1798            }
1799        }
1800        Ok(())
1801    }
1802
1803    /// Verifies that a netlist is well-formed.
1804    pub fn verify(&self) -> Result<(), Error> {
1805        if self.outputs.borrow().is_empty() {
1806            return Err(Error::NoOutputs);
1807        }
1808
1809        self.nets_unique()?;
1810
1811        self.insts_unique()?;
1812
1813        Ok(())
1814    }
1815}
1816
1817/// Represent a driven net alongside its connection to an input port
1818#[derive(Debug, Clone)]
1819pub struct Connection<I: Instantiable> {
1820    driver: DrivenNet<I>,
1821    input: InputPort<I>,
1822}
1823
1824impl<I> Connection<I>
1825where
1826    I: Instantiable,
1827{
1828    fn new(driver: DrivenNet<I>, input: InputPort<I>) -> Self {
1829        Self { driver, input }
1830    }
1831
1832    /// Return the driver of the connection
1833    pub fn src(&self) -> DrivenNet<I> {
1834        self.driver.clone()
1835    }
1836
1837    /// Return the net along the connection
1838    pub fn net(&self) -> Net {
1839        self.driver.as_net().clone()
1840    }
1841
1842    /// Returns the input port of the connection
1843    pub fn target(&self) -> InputPort<I> {
1844        self.input.clone()
1845    }
1846}
1847
1848impl<I> std::fmt::Display for Connection<I>
1849where
1850    I: Instantiable,
1851{
1852    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1853        self.net().fmt(f)
1854    }
1855}
1856
1857/// A collection of iterators for the netlist
1858pub mod iter {
1859
1860    use super::{
1861        Connection, DrivenNet, InputPort, Instantiable, Net, NetRef, Netlist, Operand, WeakIndex,
1862    };
1863    use std::collections::{HashMap, HashSet};
1864    /// An iterator over the nets in a netlist
1865    pub struct NetIterator<'a, I: Instantiable> {
1866        netlist: &'a Netlist<I>,
1867        index: usize,
1868        subindex: usize,
1869    }
1870
1871    impl<'a, I> NetIterator<'a, I>
1872    where
1873        I: Instantiable,
1874    {
1875        /// Creates a new iterator for the netlist
1876        pub fn new(netlist: &'a Netlist<I>) -> Self {
1877            Self {
1878                netlist,
1879                index: 0,
1880                subindex: 0,
1881            }
1882        }
1883    }
1884
1885    impl<I> Iterator for NetIterator<'_, I>
1886    where
1887        I: Instantiable,
1888    {
1889        type Item = Net;
1890
1891        fn next(&mut self) -> Option<Self::Item> {
1892            while self.index < self.netlist.objects.borrow().len() {
1893                let objects = self.netlist.objects.borrow();
1894                let object = objects[self.index].borrow();
1895                if self.subindex < object.get().get_nets().len() {
1896                    let net = object.get().get_nets()[self.subindex].clone();
1897                    self.subindex += 1;
1898                    return Some(net);
1899                }
1900                self.subindex = 0;
1901                self.index += 1;
1902            }
1903            None
1904        }
1905    }
1906
1907    /// An iterator over the objects in a netlist
1908    pub struct ObjectIterator<'a, I: Instantiable> {
1909        netlist: &'a Netlist<I>,
1910        index: usize,
1911    }
1912
1913    impl<'a, I> ObjectIterator<'a, I>
1914    where
1915        I: Instantiable,
1916    {
1917        /// Creates a new  object iterator for the netlist
1918        pub fn new(netlist: &'a Netlist<I>) -> Self {
1919            Self { netlist, index: 0 }
1920        }
1921    }
1922
1923    impl<I> Iterator for ObjectIterator<'_, I>
1924    where
1925        I: Instantiable,
1926    {
1927        type Item = NetRef<I>;
1928
1929        fn next(&mut self) -> Option<Self::Item> {
1930            if self.index < self.netlist.objects.borrow().len() {
1931                let objects = self.netlist.objects.borrow();
1932                let object = &objects[self.index];
1933                self.index += 1;
1934                return Some(NetRef::wrap(object.clone()));
1935            }
1936            None
1937        }
1938    }
1939
1940    /// An iterator over the connections in a netlist
1941    pub struct ConnectionIterator<'a, I: Instantiable> {
1942        netlist: &'a Netlist<I>,
1943        index: usize,
1944        subindex: usize,
1945    }
1946
1947    impl<'a, I> ConnectionIterator<'a, I>
1948    where
1949        I: Instantiable,
1950    {
1951        /// Create a new connection iterator for the netlist
1952        pub fn new(netlist: &'a Netlist<I>) -> Self {
1953            Self {
1954                netlist,
1955                index: 0,
1956                subindex: 0,
1957            }
1958        }
1959    }
1960
1961    impl<I> Iterator for ConnectionIterator<'_, I>
1962    where
1963        I: Instantiable,
1964    {
1965        type Item = super::Connection<I>;
1966
1967        fn next(&mut self) -> Option<Self::Item> {
1968            while self.index < self.netlist.objects.borrow().len() {
1969                let objects = self.netlist.objects.borrow();
1970                let object = objects[self.index].borrow();
1971                let noperands = object.operands.len();
1972                while self.subindex < noperands {
1973                    if let Some(operand) = &object.operands[self.subindex] {
1974                        let driver = match operand {
1975                            Operand::DirectIndex(idx) => {
1976                                DrivenNet::new(0, NetRef::wrap(objects[*idx].clone()))
1977                            }
1978                            Operand::CellIndex(idx, j) => {
1979                                DrivenNet::new(*j, NetRef::wrap(objects[*idx].clone()))
1980                            }
1981                        };
1982                        let input = InputPort::new(
1983                            self.subindex,
1984                            NetRef::wrap(objects[self.index].clone()),
1985                        );
1986                        self.subindex += 1;
1987                        return Some(Connection::new(driver, input));
1988                    }
1989                    self.subindex += 1;
1990                }
1991                self.subindex = 0;
1992                self.index += 1;
1993            }
1994            None
1995        }
1996    }
1997
1998    /// A stack that can check contains in roughly O(1) time.
1999    #[derive(Clone)]
2000    struct Walk<T: std::hash::Hash + PartialEq + Eq + Clone> {
2001        stack: Vec<T>,
2002        counter: HashMap<T, usize>,
2003    }
2004
2005    impl<T> Walk<T>
2006    where
2007        T: std::hash::Hash + PartialEq + Eq + Clone,
2008    {
2009        /// Create a new, empty Stack.
2010        fn new() -> Self {
2011            Self {
2012                stack: Vec::new(),
2013                counter: HashMap::new(),
2014            }
2015        }
2016
2017        /// Inserts an element into the stack
2018        fn push(&mut self, item: T) {
2019            self.stack.push(item.clone());
2020            *self.counter.entry(item).or_insert(0) += 1;
2021        }
2022
2023        /// Returns true if the stack shows a cycle
2024        fn contains_cycle(&self) -> bool {
2025            self.counter.values().any(|&count| count > 1)
2026        }
2027
2028        /// Returns a reference to the last element in the stack
2029        fn last(&self) -> Option<&T> {
2030            self.stack.last()
2031        }
2032    }
2033
2034    /// A depth-first iterator over the circuit nodes in a netlist
2035    /// # Examples
2036    ///
2037    /// ```
2038    /// use safety_net::iter::DFSIterator;
2039    /// use safety_net::GateNetlist;
2040    ///
2041    /// let netlist = GateNetlist::new("example".to_string());
2042    /// netlist.insert_input("input1".into());
2043    /// let mut nodes = Vec::new();
2044    /// let mut dfs = DFSIterator::new(&netlist, netlist.last().unwrap());
2045    /// while let Some(n) = dfs.next() {
2046    ///     if dfs.check_cycles() {
2047    ///         panic!("Cycle detected in the netlist");
2048    ///     }
2049    ///     nodes.push(n);
2050    /// }
2051    /// ```
2052    pub struct DFSIterator<'a, I: Instantiable> {
2053        netlist: &'a Netlist<I>,
2054        stacks: Vec<Walk<NetRef<I>>>,
2055        visited: HashSet<usize>,
2056        cycles: bool,
2057    }
2058
2059    impl<'a, I> DFSIterator<'a, I>
2060    where
2061        I: Instantiable,
2062    {
2063        /// Create a new DFS iterator for the netlist starting at `from`.
2064        pub fn new(netlist: &'a Netlist<I>, from: NetRef<I>) -> Self {
2065            let mut s = Walk::new();
2066            s.push(from);
2067            Self {
2068                netlist,
2069                stacks: vec![s],
2070                visited: HashSet::new(),
2071                cycles: false,
2072            }
2073        }
2074    }
2075
2076    impl<I> DFSIterator<'_, I>
2077    where
2078        I: Instantiable,
2079    {
2080        /// Check if the DFS traversal has encountered a cycle yet.
2081        pub fn check_cycles(&self) -> bool {
2082            self.cycles
2083        }
2084
2085        /// Consumes the iterator to detect cycles in the netlist.
2086        pub fn detect_cycles(mut self) -> bool {
2087            if self.cycles {
2088                return true;
2089            }
2090
2091            while let Some(_) = self.next() {
2092                if self.cycles {
2093                    return true;
2094                }
2095            }
2096
2097            self.cycles
2098        }
2099    }
2100
2101    impl<I> Iterator for DFSIterator<'_, I>
2102    where
2103        I: Instantiable,
2104    {
2105        type Item = NetRef<I>;
2106
2107        fn next(&mut self) -> Option<Self::Item> {
2108            if let Some(walk) = self.stacks.pop() {
2109                let item = walk.last().cloned();
2110                let uw = item.clone().unwrap().unwrap();
2111                let index = uw.borrow().get_index();
2112                if self.visited.insert(index) {
2113                    let operands = &uw.borrow().operands;
2114                    for operand in operands.iter().flatten() {
2115                        let mut new_walk = walk.clone();
2116                        new_walk.push(NetRef::wrap(self.netlist.index_weak(&operand.root())));
2117                        if !new_walk.contains_cycle() {
2118                            self.stacks.push(new_walk);
2119                        } else {
2120                            self.cycles = true;
2121                        }
2122                    }
2123                    return item;
2124                }
2125
2126                return self.next();
2127            }
2128
2129            None
2130        }
2131    }
2132}
2133
2134impl<'a, I> IntoIterator for &'a Netlist<I>
2135where
2136    I: Instantiable,
2137{
2138    type Item = Net;
2139    type IntoIter = iter::NetIterator<'a, I>;
2140
2141    fn into_iter(self) -> Self::IntoIter {
2142        iter::NetIterator::new(self)
2143    }
2144}
2145
2146/// Filter invariants of [Instantiable] in a netlist. Use it like you would `matches!`.
2147/// Example: ```filter_nodes!(netlist, Gate::AND(_));```
2148#[macro_export]
2149macro_rules! filter_nodes {
2150    ($netlist:ident, $pattern:pat $(if $guard:expr)? $(,)?) => {
2151        $netlist.matches(|f| match f {
2152            $pattern $(if $guard)? => true,
2153            _ => false
2154        })
2155    };
2156}
2157
2158impl<I> Netlist<I>
2159where
2160    I: Instantiable,
2161{
2162    /// Returns an iterator over the circuit nodes in the netlist.
2163    pub fn objects(&self) -> impl Iterator<Item = NetRef<I>> {
2164        iter::ObjectIterator::new(self)
2165    }
2166
2167    /// Returns an iterator over the circuit nodes that match the instance type.
2168    pub fn matches<F>(&self, filter: F) -> impl Iterator<Item = NetRef<I>>
2169    where
2170        F: Fn(&I) -> bool,
2171    {
2172        self.objects().filter(move |f| {
2173            if let Some(inst_type) = f.get_instance_type() {
2174                filter(&inst_type)
2175            } else {
2176                false
2177            }
2178        })
2179    }
2180
2181    /// Returns an iterator to principal inputs in the netlist as references.
2182    pub fn inputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
2183        self.objects()
2184            .filter(|n| n.is_an_input())
2185            .map(|n| DrivenNet::new(0, n))
2186    }
2187
2188    /// Returns an iterator to circuit nodes that drive an output in the netlist.
2189    pub fn outputs(&self) -> Vec<(DrivenNet<I>, Net)> {
2190        self.outputs
2191            .borrow()
2192            .iter()
2193            .flat_map(|(k, nets)| {
2194                nets.iter().map(|n| {
2195                    (
2196                        DrivenNet::new(k.secondary(), NetRef::wrap(self.index_weak(&k.root()))),
2197                        n.clone(),
2198                    )
2199                })
2200            })
2201            .collect()
2202    }
2203
2204    /// Returns an iterator over the wire connections in the netlist.
2205    pub fn connections(&self) -> impl Iterator<Item = Connection<I>> {
2206        iter::ConnectionIterator::new(self)
2207    }
2208
2209    /// Returns a depth-first search iterator over the nodes in the netlist.
2210    pub fn dfs(&self, from: NetRef<I>) -> impl Iterator<Item = NetRef<I>> {
2211        iter::DFSIterator::new(self, from)
2212    }
2213
2214    #[cfg(feature = "serde")]
2215    /// Serializes the netlist to a writer.
2216    pub fn serialize(self, writer: impl std::io::Write) -> Result<(), serde_json::Error>
2217    where
2218        I: ::serde::Serialize,
2219    {
2220        serde::netlist_serialize(self, writer)
2221    }
2222}
2223
2224impl<I> std::fmt::Display for Netlist<I>
2225where
2226    I: Instantiable,
2227{
2228    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2229        // Borrow everything first
2230        let objects = self.objects.borrow();
2231        let outputs = self.outputs.borrow();
2232
2233        writeln!(f, "module {} (", self.get_name())?;
2234
2235        // Print inputs and outputs
2236        let level = 2;
2237        let indent = " ".repeat(level);
2238        for oref in objects.iter() {
2239            let owned = oref.borrow();
2240            let obj = owned.get();
2241            if let Object::Input(net) = obj {
2242                writeln!(f, "{}{},", indent, net.get_identifier().emit_name())?;
2243            }
2244        }
2245
2246        // Flatten the outputs to collect all (operand, net) pairs
2247        let all_outputs: Vec<_> = outputs.iter().flat_map(|(_, nets)| nets.iter()).collect();
2248        for (i, net) in all_outputs.iter().enumerate() {
2249            if i == all_outputs.len() - 1 {
2250                writeln!(f, "{}{}", indent, net.get_identifier().emit_name())?;
2251            } else {
2252                writeln!(f, "{}{},", indent, net.get_identifier().emit_name())?;
2253            }
2254        }
2255        writeln!(f, ");")?;
2256
2257        // Make wire decls
2258        let mut already_decl = HashSet::new();
2259        for oref in objects.iter() {
2260            let owned = oref.borrow();
2261            let obj = owned.get();
2262            if let Object::Input(net) = obj {
2263                writeln!(f, "{}input {};", indent, net.get_identifier().emit_name())?;
2264                writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2265                already_decl.insert(net.clone());
2266            }
2267        }
2268        for nets in outputs.values() {
2269            for net in nets {
2270                if !already_decl.contains(net) {
2271                    writeln!(f, "{}output {};", indent, net.get_identifier().emit_name())?;
2272                    writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2273                    already_decl.insert(net.clone());
2274                }
2275            }
2276        }
2277        for oref in objects.iter() {
2278            let owned = oref.borrow();
2279            let obj = owned.get();
2280            if let Object::Instance(nets, _, inst_type) = obj
2281                && inst_type.get_constant().is_none()
2282            {
2283                for net in nets.iter() {
2284                    if !already_decl.contains(net) {
2285                        writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2286                        already_decl.insert(net.clone());
2287                    }
2288                }
2289            }
2290        }
2291
2292        for oref in objects.iter() {
2293            let owned = oref.borrow();
2294            let obj = owned.get();
2295
2296            // Skip emitting constants as their uses will be hard-wired
2297            if let Some(inst_type) = obj.get_instance_type()
2298                && inst_type.get_constant().is_some()
2299            {
2300                continue;
2301            }
2302
2303            if let Object::Instance(nets, inst_name, inst_type) = obj {
2304                for (k, v) in owned.attributes.iter() {
2305                    if let Some(value) = v {
2306                        writeln!(f, "{indent}(* {k} = \"{value}\" *)")?;
2307                    } else {
2308                        writeln!(f, "{indent}(* {k} *)")?;
2309                    }
2310                }
2311
2312                write!(f, "{}{} ", indent, inst_type.get_name())?;
2313                if inst_type.is_parameterized() {
2314                    writeln!(f, "#(")?;
2315                    let level = 4;
2316                    let indent = " ".repeat(level);
2317                    let params: Vec<_> = inst_type.parameters().collect();
2318                    for (i, (k, v)) in params.iter().enumerate() {
2319                        if i == params.len() - 1 {
2320                            writeln!(f, "{indent}.{k}({v})")?;
2321                        } else {
2322                            writeln!(f, "{indent}.{k}({v}),")?;
2323                        }
2324                    }
2325                    let level = 2;
2326                    let indent = " ".repeat(level);
2327                    write!(f, "{indent}) ")?;
2328                }
2329                writeln!(f, "{} (", inst_name.emit_name())?;
2330                let level = 4;
2331                let indent = " ".repeat(level);
2332                for (idx, port) in inst_type.get_input_ports().into_iter().enumerate() {
2333                    let port_name = port.get_identifier().emit_name();
2334                    if let Some(operand) = owned.operands[idx].as_ref() {
2335                        let operand_net = match operand {
2336                            Operand::DirectIndex(idx) => objects[*idx].borrow().as_net().clone(),
2337                            Operand::CellIndex(idx, j) => {
2338                                objects[*idx].borrow().get_net(*j).clone()
2339                            }
2340                        };
2341
2342                        let operand_str = if let Some(inst_type) =
2343                            objects[operand.root()].borrow().get().get_instance_type()
2344                            && let Some(logic) = inst_type.get_constant()
2345                        {
2346                            logic.to_string()
2347                        } else {
2348                            operand_net.get_identifier().emit_name()
2349                        };
2350
2351                        writeln!(f, "{}.{}({}),", indent, port_name, operand_str)?;
2352                    }
2353                }
2354
2355                for (idx, net) in nets.iter().enumerate() {
2356                    let port_name = inst_type.get_output_port(idx).get_identifier().emit_name();
2357                    if idx == nets.len() - 1 {
2358                        writeln!(
2359                            f,
2360                            "{}.{}({})",
2361                            indent,
2362                            port_name,
2363                            net.get_identifier().emit_name()
2364                        )?;
2365                    } else {
2366                        writeln!(
2367                            f,
2368                            "{}.{}({}),",
2369                            indent,
2370                            port_name,
2371                            net.get_identifier().emit_name()
2372                        )?;
2373                    }
2374                }
2375
2376                let level = 2;
2377                let indent = " ".repeat(level);
2378                writeln!(f, "{indent});")?;
2379            }
2380        }
2381
2382        for (driver, nets) in outputs.iter() {
2383            for net in nets {
2384                let driver_net = match driver {
2385                    Operand::DirectIndex(idx) => self.index_weak(idx).borrow().as_net().clone(),
2386                    Operand::CellIndex(idx, j) => self.index_weak(idx).borrow().get_net(*j).clone(),
2387                };
2388
2389                let driver_str = if let Some(inst_type) = self
2390                    .index_weak(&driver.root())
2391                    .borrow()
2392                    .get()
2393                    .get_instance_type()
2394                    && let Some(logic) = inst_type.get_constant()
2395                {
2396                    logic.to_string()
2397                } else {
2398                    driver_net.get_identifier().emit_name()
2399                };
2400
2401                if net.get_identifier() != driver_net.get_identifier() {
2402                    writeln!(
2403                        f,
2404                        "{}assign {} = {};",
2405                        indent,
2406                        net.get_identifier().emit_name(),
2407                        driver_str
2408                    )?;
2409                }
2410            }
2411        }
2412
2413        writeln!(f, "endmodule")
2414    }
2415}
2416
2417/// A type alias for a netlist of gates
2418pub type GateNetlist = Netlist<Gate>;
2419/// A type alias to Gate circuit nodes
2420pub type GateRef = NetRef<Gate>;
2421
2422#[cfg(test)]
2423mod tests {
2424    use super::*;
2425    #[test]
2426    fn test_delete_netlist() {
2427        let netlist = Netlist::new("simple_example".to_string());
2428
2429        // Add the the two inputs
2430        let input1 = netlist.insert_input("input1".into());
2431        let input2 = netlist.insert_input("input2".into());
2432
2433        // Instantiate an AND gate
2434        let instance = netlist
2435            .insert_gate(
2436                Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
2437                "my_and".into(),
2438                &[input1.clone(), input2.clone()],
2439            )
2440            .unwrap();
2441
2442        // Make this AND gate an output
2443        let instance = instance.expose_as_output().unwrap();
2444        instance.delete_uses().unwrap();
2445        // Cannot clean a netlist that is in a invalid state
2446        assert!(netlist.clean().is_err());
2447        input1.expose_with_name("an_output".into());
2448        assert!(netlist.clean().is_ok());
2449    }
2450
2451    #[test]
2452    #[should_panic(expected = "Attempted to create a gate with a sliced identifier")]
2453    fn gate_w_slice_panics() {
2454        Gate::new_logical("AND[1]".into(), vec!["A".into(), "B".into()], "Y".into());
2455    }
2456
2457    #[test]
2458    fn gates_dont_have_params() {
2459        // The baseline implementation of gates do not have parameters.
2460        let gate = Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into());
2461        assert!(!gate.has_parameter(&"id".into()));
2462        assert!(gate.get_parameter(&"id".into()).is_none());
2463        assert_eq!(*gate.get_gate_name(), "AND".into());
2464    }
2465
2466    #[test]
2467    fn operand_conversions() {
2468        let operand = Operand::CellIndex(3, 2);
2469        assert_eq!(operand.to_string(), "3.2");
2470        let parsed = "3.2".parse::<Operand>();
2471        assert!(parsed.is_ok());
2472        let parsed = parsed.unwrap();
2473        assert_eq!(operand, parsed);
2474    }
2475
2476    #[test]
2477    #[should_panic(expected = "out of bounds for netref")]
2478    fn test_bad_output() {
2479        let netlist = GateNetlist::new("min_module".to_string());
2480        let a = netlist.insert_input("a".into());
2481        DrivenNet::new(1, a.unwrap());
2482    }
2483}
2484#[cfg(feature = "serde")]
2485/// Serde support for netlists
2486pub mod serde {
2487    use super::{Netlist, Operand, OwnedObject, WeakIndex};
2488    use crate::{
2489        attribute::{AttributeKey, AttributeValue},
2490        circuit::{Instantiable, Net, Object},
2491    };
2492    use serde::{Deserialize, Serialize, de::DeserializeOwned};
2493    use std::cell::RefCell;
2494    use std::{
2495        collections::{BTreeSet, HashMap},
2496        rc::Rc,
2497    };
2498
2499    #[derive(Debug, Serialize, Deserialize)]
2500    struct SerdeObject<I>
2501    where
2502        I: Instantiable + Serialize,
2503    {
2504        /// The object that is owned by the netlist
2505        object: Object<I>,
2506        /// The list of operands for the object
2507        operands: Vec<Option<Operand>>,
2508        /// A collection of attributes for the object
2509        attributes: HashMap<AttributeKey, AttributeValue>,
2510    }
2511
2512    impl<I, O> From<OwnedObject<I, O>> for SerdeObject<I>
2513    where
2514        I: Instantiable + Serialize,
2515        O: WeakIndex<usize, Output = OwnedObject<I, O>>,
2516    {
2517        fn from(value: OwnedObject<I, O>) -> Self {
2518            SerdeObject {
2519                object: value.object,
2520                operands: value.operands,
2521                attributes: value.attributes,
2522            }
2523        }
2524    }
2525
2526    impl<I> SerdeObject<I>
2527    where
2528        I: Instantiable + Serialize,
2529    {
2530        fn into_owned_object<O>(self, owner: &Rc<O>, index: usize) -> OwnedObject<I, O>
2531        where
2532            O: WeakIndex<usize, Output = OwnedObject<I, O>>,
2533        {
2534            OwnedObject {
2535                object: self.object,
2536                owner: Rc::downgrade(owner),
2537                operands: self.operands,
2538                attributes: self.attributes,
2539                index,
2540            }
2541        }
2542    }
2543
2544    #[derive(Debug, Serialize, Deserialize)]
2545    struct SerdeNetlist<I>
2546    where
2547        I: Instantiable + Serialize,
2548    {
2549        /// The name of the netlist
2550        name: String,
2551        /// The list of objects in the netlist, such as inputs, modules, and primitives
2552        objects: Vec<SerdeObject<I>>,
2553        /// The list of operands that point to objects which are outputs.
2554        /// Indices must be a string if we want to support JSON.
2555        /// Each operand can map to multiple nets, supporting output aliases.
2556        outputs: HashMap<String, BTreeSet<Net>>,
2557    }
2558
2559    impl<I> From<Netlist<I>> for SerdeNetlist<I>
2560    where
2561        I: Instantiable + Serialize,
2562    {
2563        fn from(value: Netlist<I>) -> Self {
2564            SerdeNetlist {
2565                name: value.name.into_inner(),
2566                objects: value
2567                    .objects
2568                    .into_inner()
2569                    .into_iter()
2570                    .map(|o| {
2571                        Rc::try_unwrap(o)
2572                            .ok()
2573                            .expect("Cannot serialize with live references")
2574                            .into_inner()
2575                            .into()
2576                    })
2577                    .collect(),
2578                outputs: value
2579                    .outputs
2580                    .into_inner()
2581                    .into_iter()
2582                    // Indices must be a string if we want to support JSON.
2583                    .map(|(o, nets)| (o.to_string(), nets.into_iter().collect()))
2584                    .collect(),
2585            }
2586        }
2587    }
2588
2589    impl<I> SerdeNetlist<I>
2590    where
2591        I: Instantiable + Serialize,
2592    {
2593        /// Convert the serialized netlist back into a reference-counted netlist.
2594        fn into_netlist(self) -> Rc<Netlist<I>> {
2595            let netlist = Netlist::new(self.name);
2596            let outputs: HashMap<Operand, BTreeSet<Net>> = self
2597                .outputs
2598                .into_iter()
2599                .map(|(k, v)| {
2600                    let operand = k.parse::<Operand>().expect("Invalid index");
2601                    (operand, v.into_iter().collect())
2602                })
2603                .collect();
2604            let objects = self
2605                .objects
2606                .into_iter()
2607                .enumerate()
2608                .map(|(i, o)| {
2609                    let owned_object = o.into_owned_object(&netlist, i);
2610                    Rc::new(RefCell::new(owned_object))
2611                })
2612                .collect::<Vec<_>>();
2613            {
2614                let mut objs_mut = netlist.objects.borrow_mut();
2615                *objs_mut = objects;
2616                let mut outputs_mut = netlist.outputs.borrow_mut();
2617                *outputs_mut = outputs;
2618            }
2619            netlist
2620        }
2621    }
2622
2623    /// Serialize the netlist into the writer.
2624    pub fn netlist_serialize<I: Instantiable + Serialize>(
2625        netlist: Netlist<I>,
2626        writer: impl std::io::Write,
2627    ) -> Result<(), serde_json::Error> {
2628        let sobj: SerdeNetlist<I> = netlist.into();
2629        serde_json::to_writer_pretty(writer, &sobj)
2630    }
2631
2632    /// Deserialize a netlist from the reader.
2633    pub fn netlist_deserialize<I: Instantiable + Serialize + DeserializeOwned>(
2634        reader: impl std::io::Read,
2635    ) -> Result<Rc<Netlist<I>>, serde_json::Error> {
2636        let sobj: SerdeNetlist<I> = serde_json::from_reader(reader)?;
2637        Ok(sobj.into_netlist())
2638    }
2639}