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::{BTreeMap, 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) -> &[Net] {
48        &self.inputs
49    }
50
51    fn get_output_ports(&self) -> &[Net] {
52        &self.outputs
53    }
54
55    fn get_parameter(&self, _id: &Identifier) -> Option<Parameter> {
56        None
57    }
58
59    fn set_parameter(&mut self, _id: &Identifier, _val: Parameter) -> Option<Parameter> {
60        panic!("Gate does not support parameters");
61    }
62
63    fn clear_parameter(&mut self, _id: &Identifier) -> Option<Parameter> {
64        None
65    }
66
67    fn parameters(&self) -> Vec<(Identifier, Parameter)> {
68        Vec::new()
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 Ord for Operand {
159    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
160        match (self, other) {
161            (Operand::DirectIndex(a), Operand::DirectIndex(b)) => a.cmp(b),
162            (Operand::CellIndex(a, b), Operand::CellIndex(c, d)) => (a, b).cmp(&(c, d)),
163            (Operand::DirectIndex(a), Operand::CellIndex(c, d)) => {
164                if a == c && *d == 0 {
165                    std::cmp::Ordering::Less
166                } else {
167                    (a, &0).cmp(&(c, d))
168                }
169            }
170            (Operand::CellIndex(a, b), Operand::DirectIndex(c)) => {
171                if a == c && *b == 0 {
172                    std::cmp::Ordering::Greater
173                } else {
174                    (a, b).cmp(&(c, &0))
175                }
176            }
177        }
178    }
179}
180
181impl PartialOrd for Operand {
182    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
183        Some(self.cmp(other))
184    }
185}
186
187impl Operand {
188    /// Remap the node index of the operand to `x`.
189    fn remap(self, x: usize) -> Self {
190        match self {
191            Operand::DirectIndex(_idx) => Operand::DirectIndex(x),
192            Operand::CellIndex(_idx, j) => Operand::CellIndex(x, j),
193        }
194    }
195
196    /// Returns the circuit node index
197    fn root(&self) -> usize {
198        match self {
199            Operand::DirectIndex(idx) => *idx,
200            Operand::CellIndex(idx, _) => *idx,
201        }
202    }
203
204    /// Returns the secondary index (the cell index)
205    fn secondary(&self) -> usize {
206        match self {
207            Operand::DirectIndex(_) => 0,
208            Operand::CellIndex(_, j) => *j,
209        }
210    }
211}
212
213impl std::fmt::Display for Operand {
214    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
215        match self {
216            Operand::DirectIndex(idx) => write!(f, "{idx}"),
217            Operand::CellIndex(idx, j) => write!(f, "{idx}.{j}"),
218        }
219    }
220}
221
222impl std::str::FromStr for Operand {
223    type Err = ParseIntError;
224
225    fn from_str(s: &str) -> Result<Self, Self::Err> {
226        match s.split_once('.') {
227            Some((idx, j)) => {
228                let idx = idx.parse::<usize>()?;
229                let j = j.parse::<usize>()?;
230                Ok(Operand::CellIndex(idx, j))
231            }
232            None => {
233                let idx = s.parse::<usize>()?;
234                Ok(Operand::DirectIndex(idx))
235            }
236        }
237    }
238}
239
240/// An object that has a reference to its owning netlist/module
241#[derive(Debug)]
242struct OwnedObject<I, O>
243where
244    I: Instantiable,
245    O: WeakIndex<usize, Output = Self>,
246{
247    /// The object that is owned by the netlist
248    object: Object<I>,
249    /// The weak reference to the owner netlist/module
250    owner: Weak<O>,
251    /// The list of operands for the object
252    operands: Vec<Option<Operand>>,
253    /// A collection of attributes for the object
254    attributes: BTreeMap<AttributeKey, AttributeValue>,
255    /// The index of the object within the netlist/module
256    index: usize,
257}
258
259impl<I, O> OwnedObject<I, O>
260where
261    I: Instantiable,
262    O: WeakIndex<usize, Output = Self>,
263{
264    /// Get an iterator to mutate the operand indices
265    fn inds_mut(&mut self) -> impl Iterator<Item = &mut Operand> {
266        self.operands
267            .iter_mut()
268            .filter_map(|operand| operand.as_mut())
269    }
270
271    /// Get the driver to input `index`
272    fn get_driver(&self, index: usize) -> Option<Rc<RefCell<Self>>> {
273        self.operands[index].as_ref().map(|operand| {
274            self.owner
275                .upgrade()
276                .expect("Object is unlinked from netlist")
277                .index_weak(&operand.root())
278        })
279    }
280
281    /// Iterator to driving objects
282    fn drivers(&self) -> impl Iterator<Item = Option<Rc<RefCell<Self>>>> {
283        self.operands.iter().map(|operand| {
284            operand.as_ref().map(|operand| {
285                self.owner
286                    .upgrade()
287                    .expect("Object is unlinked from netlist")
288                    .index_weak(&operand.root())
289            })
290        })
291    }
292
293    /// Iterator to driving nets
294    fn driver_nets(&self) -> impl Iterator<Item = Option<Net>> {
295        self.operands.iter().map(|operand| {
296            operand.as_ref().map(|operand| match operand {
297                Operand::DirectIndex(idx) => self
298                    .owner
299                    .upgrade()
300                    .expect("Object is unlinked from netlist")
301                    .index_weak(idx)
302                    .borrow()
303                    .as_net()
304                    .clone(),
305                Operand::CellIndex(idx, j) => self
306                    .owner
307                    .upgrade()
308                    .expect("Object is unlinked from netlist")
309                    .index_weak(idx)
310                    .borrow()
311                    .get_net(*j)
312                    .clone(),
313            })
314        })
315    }
316
317    /// Get the underlying object
318    fn get(&self) -> &Object<I> {
319        &self.object
320    }
321
322    /// Get the underlying object mutably
323    fn get_mut(&mut self) -> &mut Object<I> {
324        &mut self.object
325    }
326
327    /// Get the index of `self` relative to the owning module
328    fn get_index(&self) -> usize {
329        self.index
330    }
331
332    /// Get the net that is driven by this object
333    fn as_net(&self) -> &Net {
334        match &self.object {
335            Object::Input(net) => net,
336            Object::Instance(nets, _, _) => {
337                if nets.len() > 1 {
338                    panic!("Attempt to grab the net of a multi-output instance");
339                } else {
340                    nets.first().expect("Instance is missing a net to drive")
341                }
342            }
343        }
344    }
345
346    /// Get the net that is driven by this object
347    fn as_net_mut(&mut self) -> &mut Net {
348        match &mut self.object {
349            Object::Input(net) => net,
350            Object::Instance(nets, _, _) => {
351                if nets.len() > 1 {
352                    panic!("Attempt to grab the net of a multi-output instance");
353                } else {
354                    nets.first_mut()
355                        .expect("Instance is missing a net to drive")
356                }
357            }
358        }
359    }
360
361    /// Get the net that is driven by this object at position `idx`
362    fn get_net(&self, idx: usize) -> &Net {
363        match &self.object {
364            Object::Input(net) => {
365                if idx != 0 {
366                    panic!("Nonzero index on an input object");
367                }
368                net
369            }
370            Object::Instance(nets, _, _) => &nets[idx],
371        }
372    }
373
374    /// Get a mutable reference to the net that is driven by this object at position `idx`
375    fn get_net_mut(&mut self, idx: usize) -> &mut Net {
376        match &mut self.object {
377            Object::Input(net) => {
378                if idx != 0 {
379                    panic!("Nonzero index on an input object");
380                }
381                net
382            }
383            Object::Instance(nets, _, _) => &mut nets[idx],
384        }
385    }
386
387    /// Check if this object drives a specific net
388    fn find_net(&self, net: &Net) -> Option<usize> {
389        match &self.object {
390            Object::Input(input_net) => {
391                if input_net == net {
392                    Some(0)
393                } else {
394                    None
395                }
396            }
397            Object::Instance(nets, _, _) => nets.iter().position(|n| n == net),
398        }
399    }
400
401    /// Attempt to find a mutable reference to a net within this object
402    fn find_net_mut(&mut self, net: &Net) -> Option<&mut Net> {
403        match &mut self.object {
404            Object::Input(input_net) => {
405                if input_net == net {
406                    Some(input_net)
407                } else {
408                    None
409                }
410            }
411            Object::Instance(nets, _, _) => nets.iter_mut().find(|n| *n == net),
412        }
413    }
414
415    /// Get driving net using the weak reference
416    ///
417    /// # Panics
418    ///
419    /// Panics if the reference to the netlist is lost.
420    fn get_driver_net(&self, index: usize) -> Option<Net> {
421        let operand = &self.operands[index];
422        match operand {
423            Some(op) => match op {
424                Operand::DirectIndex(idx) => self
425                    .owner
426                    .upgrade()
427                    .expect("Object is unlinked from netlist")
428                    .index_weak(idx)
429                    .borrow()
430                    .as_net()
431                    .clone()
432                    .into(),
433                Operand::CellIndex(idx, j) => self
434                    .owner
435                    .upgrade()
436                    .expect("Object is unlinked from netlist")
437                    .index_weak(idx)
438                    .borrow()
439                    .get_net(*j)
440                    .clone()
441                    .into(),
442            },
443            None => None,
444        }
445    }
446
447    fn clear_attribute(&mut self, k: &AttributeKey) -> Option<AttributeValue> {
448        self.attributes.remove(k)
449    }
450
451    fn set_attribute(&mut self, k: AttributeKey) {
452        self.attributes.insert(k, None);
453    }
454
455    fn insert_attribute(&mut self, k: AttributeKey, v: Parameter) -> Option<AttributeValue> {
456        self.attributes.insert(k, Some(v))
457    }
458
459    fn attributes(&self) -> impl Iterator<Item = Attribute> {
460        Attribute::from_pairs(self.attributes.clone().into_iter())
461    }
462}
463
464/// This type exposes the interior mutability of elements in a netlist.
465type NetRefT<I> = Rc<RefCell<OwnedObject<I, Netlist<I>>>>;
466
467/// Provides an idiomatic interface
468/// to the interior mutability of the netlist
469#[derive(Clone)]
470pub struct NetRef<I>
471where
472    I: Instantiable,
473{
474    netref: NetRefT<I>,
475}
476
477impl<I> std::fmt::Debug for NetRef<I>
478where
479    I: Instantiable,
480{
481    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
482        let b = self.netref.borrow();
483        let o = b.get();
484        let i = b.index;
485        let owner = &b.owner;
486        match owner.upgrade() {
487            Some(owner) => {
488                let n = owner.get_name();
489                write!(f, "{{ owner: \"{n}\", index: {i}, val: \"{o}\" }}")
490            }
491            None => write!(f, "{{ owner: None, index: {i}, val: \"{o}\" }}"),
492        }
493    }
494}
495
496impl<I> PartialEq for NetRef<I>
497where
498    I: Instantiable,
499{
500    fn eq(&self, other: &Self) -> bool {
501        Rc::ptr_eq(&self.netref, &other.netref)
502    }
503}
504
505impl<I> Eq for NetRef<I> where I: Instantiable {}
506
507impl<I> Ord for NetRef<I>
508where
509    I: Instantiable,
510{
511    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
512        Rc::as_ptr(&self.netref).cmp(&Rc::as_ptr(&other.netref))
513    }
514}
515
516impl<I> PartialOrd for NetRef<I>
517where
518    I: Instantiable,
519{
520    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
521        Some(self.cmp(other))
522    }
523}
524
525impl<I> std::hash::Hash for NetRef<I>
526where
527    I: Instantiable,
528{
529    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
530        Rc::as_ptr(&self.netref).hash(state);
531    }
532}
533
534impl<I> NetRef<I>
535where
536    I: Instantiable,
537{
538    /// Creates a new [NetRef] from a [NetRefT]
539    fn wrap(netref: NetRefT<I>) -> Self {
540        Self { netref }
541    }
542
543    /// Returns the underlying [NetRefT]
544    fn unwrap(self) -> NetRefT<I> {
545        self.netref
546    }
547
548    /// Returns the upgraded owner or panics
549    fn owner(&self) -> Rc<Netlist<I>> {
550        self.netref
551            .borrow()
552            .owner
553            .upgrade()
554            .expect("NetRef is unlinked from netlist")
555    }
556
557    /// Returns a borrow to the [Net] at this circuit node.
558    ///
559    /// # Panics
560    ///
561    /// Panics if the circuit node has multiple outputs.
562    pub fn as_net(&self) -> Ref<'_, Net> {
563        Ref::map(self.netref.borrow(), |f| f.as_net())
564    }
565
566    /// Returns a mutable borrow to the [Net] at this circuit node.
567    ///
568    /// # Panics
569    ///
570    /// Panics if the circuit node has multiple outputs.
571    pub fn as_net_mut(&self) -> RefMut<'_, Net> {
572        RefMut::map(self.netref.borrow_mut(), |f| f.as_net_mut())
573    }
574
575    /// Returns a borrow to the output [Net] at position `idx`
576    pub fn get_net(&self, idx: usize) -> Ref<'_, Net> {
577        Ref::map(self.netref.borrow(), |f| f.get_net(idx))
578    }
579
580    /// Returns a mutable borrow to the output [Net] at position `idx`
581    pub fn get_net_mut(&self, idx: usize) -> RefMut<'_, Net> {
582        RefMut::map(self.netref.borrow_mut(), |f| f.get_net_mut(idx))
583    }
584
585    /// Returns a borrow to the output [Net] at position `idx`
586    ///
587    /// # Panics
588    ///
589    /// Panics if the index is out of bounds.
590    pub fn get_output(&self, idx: usize) -> DrivenNet<I> {
591        let len = self.netref.borrow().get().get_nets().len();
592        if idx >= len {
593            panic!("Output index {idx} is out of bounds for circuit node with {len} outputs");
594        }
595        DrivenNet::new(idx, self.clone())
596    }
597
598    /// Returns a borrow to the output connected to port `id`
599    pub fn find_output(&self, id: &Identifier) -> Option<DrivenNet<I>> {
600        let ind = self.get_instance_type()?.find_output(id)?;
601        Some(self.get_output(ind))
602    }
603
604    /// Returns an abstraction around the input connection
605    ///
606    /// # Panics
607    ///
608    /// Panics if the index is out of bounds
609    pub fn get_input(&self, idx: usize) -> InputPort<I> {
610        if self.is_an_input() {
611            panic!("Principal inputs do not have inputs");
612        }
613        let len = self.netref.borrow().operands.len();
614        if idx >= len {
615            panic!("Input index {idx} is out of bounds for circuit node with {len} inputs");
616        }
617        InputPort::new(idx, self.clone())
618    }
619
620    /// Returns a borrow to the input port with name `id`
621    pub fn find_input(&self, id: &Identifier) -> Option<InputPort<I>> {
622        let ind = self.get_instance_type()?.find_input(id)?;
623        Some(self.get_input(ind))
624    }
625
626    /// Returns the name of the net at this circuit node.
627    ///
628    /// # Panics
629    ///
630    /// Panics if the circuit node has multiple outputs.
631    pub fn get_identifier(&self) -> Identifier {
632        self.as_net().get_identifier().clone()
633    }
634
635    /// Changes the identifier of the net at this circuit node.
636    ///
637    /// # Panics
638    ///
639    /// Panics if the circuit node has multiple outputs.
640    pub fn set_identifier(&self, identifier: Identifier) {
641        self.as_net_mut().set_identifier(identifier)
642    }
643
644    /// Returns `true` if this circuit node is a principal input
645    pub fn is_an_input(&self) -> bool {
646        matches!(self.netref.borrow().get(), Object::Input(_))
647    }
648
649    /// Returns a reference to the object at this node.
650    pub fn get_obj(&self) -> Ref<'_, Object<I>> {
651        Ref::map(self.netref.borrow(), |f| f.get())
652    }
653
654    /// Returns the [Instantiable] type of the instance, if this circuit node is an instance
655    pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
656        Ref::filter_map(self.netref.borrow(), |f| f.get().get_instance_type()).ok()
657    }
658
659    /// Returns the [Instantiable] type of the instance, if this circuit node is an instance
660    pub fn get_instance_type_mut(&self) -> Option<RefMut<'_, I>> {
661        RefMut::filter_map(self.netref.borrow_mut(), |f| {
662            f.get_mut().get_instance_type_mut()
663        })
664        .ok()
665    }
666
667    /// Returns a copy of the name of the instance, if the circuit node is a instance.
668    pub fn get_instance_name(&self) -> Option<Identifier> {
669        match self.netref.borrow().get() {
670            Object::Instance(_, inst_name, _) => Some(inst_name.clone()),
671            _ => None,
672        }
673    }
674
675    /// Updates the name of the instance, if the circuit node is an instance.
676    ///
677    /// # Panics
678    ///
679    /// Panics if the circuit node is a principal input.
680    pub fn set_instance_name(&self, name: Identifier) {
681        match self.netref.borrow_mut().get_mut() {
682            Object::Instance(_, inst_name, _) => *inst_name = name,
683            _ => panic!("Attempted to set instance name on a non-instance object"),
684        }
685    }
686
687    /// Exposes this circuit node as a top-level output in the netlist.
688    /// Returns an error if the circuit node is a principal input.
689    ///
690    /// # Panics
691    ///
692    /// Panics if cell is a multi-output circuit node.
693    /// Panics if the reference to the netlist is lost.
694    pub fn expose_as_output(self) -> Result<Self, Error> {
695        let netlist = self.owner();
696        netlist.expose_net(self.clone().into())?;
697        Ok(self)
698    }
699
700    /// Exposes this circuit node as a top-level output in the netlist with a specific port name.
701    /// Multiple calls to this method can be used to create multiple output aliases for the same net.
702    ///
703    /// # Panics
704    ///
705    /// Panics if the cell is a multi-output circuit node.
706    /// Panics if the reference to the netlist is lost.
707    pub fn expose_with_name(self, name: Identifier) -> Self {
708        let netlist = self.owner();
709        netlist.expose_net_with_name(self.clone().into(), name);
710        self
711    }
712
713    /// Exposes the `net` driven by this circuit node as a top-level output.
714    /// Errors if `net` is not driven by this circuit node.
715    ///
716    /// # Panics
717    /// Panics if the reference to the netlist is lost.
718    pub fn expose_net(&self, net: &Net) -> Result<(), Error> {
719        let netlist = self.owner();
720        let net_index = self
721            .netref
722            .borrow()
723            .find_net(net)
724            .ok_or(Error::NetNotFound(net.clone()))?;
725        let dr = DrivenNet::new(net_index, self.clone());
726        netlist.expose_net(dr)?;
727        Ok(())
728    }
729
730    /// Removes a specific output alias by its name from this circuit node.
731    /// Returns true if the output was removed, false if it didn't exist.
732    ///
733    /// # Panics
734    ///
735    /// Panics if cell is a multi-output circuit node.
736    /// Panics if the reference to the netlist is lost.
737    pub fn remove_output(&self, net_name: &Identifier) -> bool {
738        let netlist = self.owner();
739        netlist.remove_output(&self.into(), net_name)
740    }
741
742    /// Removes all output aliases for this circuit node.
743    /// Returns the number of outputs that were removed.
744    ///
745    /// # Panics
746    ///
747    /// Panics if cell is a multi-output circuit node.
748    /// Panics if the reference to the netlist is lost.
749    pub fn remove_all_outputs(&self) -> usize {
750        let netlist = self.owner();
751        netlist.remove_outputs(&self.into())
752    }
753
754    /// Returns the circuit node that drives the `index`th input
755    pub fn get_driver(&self, index: usize) -> Option<Self> {
756        self.netref.borrow().get_driver(index).map(NetRef::wrap)
757    }
758
759    /// Returns the net that drives the `index`th input
760    ///
761    /// # Panics
762    ///
763    /// Panics if the reference to the netlist is lost.
764    pub fn get_driver_net(&self, index: usize) -> Option<Net> {
765        self.netref.borrow().get_driver_net(index)
766    }
767
768    /// Returns the number of input ports for this circuit node.
769    pub fn get_num_input_ports(&self) -> usize {
770        if let Some(inst_type) = self.get_instance_type() {
771            inst_type.get_input_ports().iter().count()
772        } else {
773            0
774        }
775    }
776
777    /// Returns `true` if this circuit node has all its input ports connected.
778    pub fn is_fully_connected(&self) -> bool {
779        assert_eq!(
780            self.netref.borrow().operands.len(),
781            self.get_num_input_ports()
782        );
783        self.netref.borrow().operands.iter().all(|o| o.is_some())
784    }
785
786    /// Returns an iterator to the driving circuit nodes.
787    pub fn drivers(&self) -> impl Iterator<Item = Option<Self>> {
788        let drivers: Vec<Option<Self>> = self
789            .netref
790            .borrow()
791            .drivers()
792            .map(|o| o.map(NetRef::wrap))
793            .collect();
794        drivers.into_iter()
795    }
796
797    /// Returns an interator to the driving nets.
798    pub fn driver_nets(&self) -> impl Iterator<Item = Option<Net>> {
799        let vec: Vec<Option<Net>> = self.netref.borrow().driver_nets().collect();
800        vec.into_iter()
801    }
802
803    /// Returns an iterator to the output nets of this circuit node.
804    #[allow(clippy::unnecessary_to_owned)]
805    pub fn nets(&self) -> impl Iterator<Item = Net> {
806        self.netref.borrow().get().get_nets().to_vec().into_iter()
807    }
808
809    /// Returns an iterator to the output nets of this circuit node, along with port information.
810    pub fn inputs(&self) -> impl Iterator<Item = InputPort<I>> {
811        let len = self.netref.borrow().operands.len();
812        (0..len).map(move |i| InputPort::new(i, self.clone()))
813    }
814
815    /// Returns an iterator to the output nets of this circuit node, along with port information.
816    pub fn outputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
817        let len = self.netref.borrow().get().get_nets().len();
818        (0..len).map(move |i| DrivenNet::new(i, self.clone()))
819    }
820
821    /// Returns an iterator to mutate the output nets of this circuit node.
822    pub fn nets_mut(&self) -> impl Iterator<Item = RefMut<'_, Net>> {
823        let nnets = self.netref.borrow().get().get_nets().len();
824        (0..nnets).map(|i| self.get_net_mut(i))
825    }
826
827    /// Returns `true` if this circuit node drives the given net.
828    pub fn drives_net(&self, net: &Net) -> bool {
829        self.netref.borrow().find_net(net).is_some()
830    }
831
832    /// Returns `true` if this circuit node drives a top-level output.
833    ///
834    /// # Panics
835    /// Panics if the weak reference to the netlist is lost.
836    pub fn drives_a_top_output(&self) -> bool {
837        let netlist = self.owner();
838        netlist.drives_an_output(self.clone())
839    }
840
841    /// Attempts to find a mutable reference to `net` within this circuit node.
842    pub fn find_net_mut(&self, net: &Net) -> Option<RefMut<'_, Net>> {
843        RefMut::filter_map(self.netref.borrow_mut(), |f| f.find_net_mut(net)).ok()
844    }
845
846    /// Returns `true` if this circuit node has multiple outputs/nets.
847    pub fn is_multi_output(&self) -> bool {
848        self.netref.borrow().get().get_nets().len() > 1
849    }
850
851    /// Deletes the uses of this circuit node from the netlist.
852    ///
853    /// # Panics
854    ///
855    /// Panics if the reference to the netlist is lost.
856    pub fn delete_uses(self) -> Result<Object<I>, Error> {
857        let netlist = self.owner();
858        netlist.delete_net_uses(self)
859    }
860
861    /// Replaces the uses of this circuit node in the netlist with another circuit node.
862    ///
863    /// # See also:
864    /// - [`NetMapper`](rewriter::NetMapper)
865    ///
866    /// # Panics
867    ///
868    /// Panics if either `self` is a multi-output circuit node.
869    /// Panics if the weak reference to the netlist is lost.
870    pub fn replace_uses_with(self, other: &DrivenNet<I>) -> Result<NetRef<I>, Error> {
871        let netlist = self.owner();
872        netlist
873            .replace_net_uses(self.into(), other)
874            .map(|d| d.unwrap())
875    }
876
877    /// Clears the attribute with the given key on this circuit node.
878    pub fn clear_attribute(&self, k: &AttributeKey) -> Option<AttributeValue> {
879        self.netref.borrow_mut().clear_attribute(k)
880    }
881
882    /// Set an attribute without a value
883    pub fn set_attribute(&self, k: AttributeKey) {
884        self.netref.borrow_mut().set_attribute(k);
885    }
886
887    /// Insert an attribute on this node with a value
888    pub fn insert_attribute(&self, k: AttributeKey, v: Parameter) -> Option<AttributeValue> {
889        self.netref.borrow_mut().insert_attribute(k, v)
890    }
891
892    /// Returns an iterator to the attributes at this circuit node
893    pub fn attributes(&self) -> impl Iterator<Item = Attribute> {
894        let v: Vec<_> = self.netref.borrow().attributes().collect();
895        v.into_iter()
896    }
897}
898
899impl<I> std::fmt::Display for NetRef<I>
900where
901    I: Instantiable,
902{
903    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
904        self.netref.borrow().object.fmt(f)
905    }
906}
907
908impl<I> From<NetRef<I>> for DrivenNet<I>
909where
910    I: Instantiable,
911{
912    fn from(val: NetRef<I>) -> Self {
913        if val.is_multi_output() {
914            panic!("Cannot convert a multi-output netref to an output port");
915        }
916        DrivenNet::new(0, val)
917    }
918}
919
920impl<I> From<&NetRef<I>> for DrivenNet<I>
921where
922    I: Instantiable,
923{
924    fn from(val: &NetRef<I>) -> Self {
925        if val.is_multi_output() {
926            panic!("Cannot convert a multi-output netref to an output port");
927        }
928        DrivenNet::new(0, val.clone())
929    }
930}
931
932/// A netlist data structure
933#[derive(Debug)]
934pub struct Netlist<I>
935where
936    I: Instantiable,
937{
938    /// The name of the netlist
939    name: RefCell<Identifier>,
940    /// The list of objects in the netlist, such as inputs, modules, and primitives
941    objects: RefCell<Vec<NetRefT<I>>>,
942    /// Each operand can map to multiple nets, supporting output aliases.
943    outputs: RefCell<BTreeMap<Operand, BTreeSet<Net>>>,
944}
945
946/// Represent the input port of a primitive
947#[derive(Debug, Clone)]
948pub struct InputPort<I: Instantiable> {
949    pos: usize,
950    netref: NetRef<I>,
951}
952
953impl<I> InputPort<I>
954where
955    I: Instantiable,
956{
957    fn new(pos: usize, netref: NetRef<I>) -> Self {
958        if pos >= netref.clone().unwrap().borrow().operands.len() {
959            panic!(
960                "Position {} out of bounds for netref with {} input nets",
961                pos,
962                netref.unwrap().borrow().get().get_nets().len()
963            );
964        }
965        Self { pos, netref }
966    }
967
968    /// Returns the net that is driving this input port
969    pub fn get_driver(&self) -> Option<DrivenNet<I>> {
970        if self.netref.is_an_input() {
971            panic!("Input port is not driven by a primitive");
972        }
973        if let Some(prev_operand) = self.netref.clone().unwrap().borrow().operands[self.pos] {
974            let netlist = self
975                .netref
976                .clone()
977                .unwrap()
978                .borrow()
979                .owner
980                .upgrade()
981                .expect("Input port is unlinked from netlist");
982            let driver_nr = netlist.index_weak(&prev_operand.root());
983            let nr = NetRef::wrap(driver_nr);
984            let pos = prev_operand.secondary();
985            Some(DrivenNet::new(pos, nr))
986        } else {
987            None
988        }
989    }
990
991    /// Disconnects an input port and returns the previous [DrivenNet] if it was connected.
992    pub fn disconnect(&self) -> Option<DrivenNet<I>> {
993        let val = self.get_driver();
994        self.netref.clone().unwrap().borrow_mut().operands[self.pos] = None;
995        val
996    }
997
998    /// Get the input port associated with this connection
999    pub fn get_port(&self) -> Net {
1000        if self.netref.is_an_input() {
1001            panic!("Net is not driven by a primitive");
1002        }
1003        self.netref
1004            .get_instance_type()
1005            .unwrap()
1006            .get_input_port(self.pos)
1007            .clone()
1008    }
1009
1010    /// Connects this input port to a driven net.
1011    pub fn connect(self, output: DrivenNet<I>) {
1012        output.connect(self);
1013    }
1014
1015    /// Return the underlying circuit node
1016    pub fn unwrap(self) -> NetRef<I> {
1017        self.netref
1018    }
1019
1020    /// Returns the index associated with this input port
1021    pub fn get_input_num(&self) -> usize {
1022        self.pos
1023    }
1024}
1025
1026impl<I> std::fmt::Display for InputPort<I>
1027where
1028    I: Instantiable,
1029{
1030    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1031        self.get_port().fmt(f)
1032    }
1033}
1034
1035/// Represent a net that is being driven by a [Instantiable]
1036#[derive(Debug, Clone)]
1037pub struct DrivenNet<I: Instantiable> {
1038    pos: usize,
1039    netref: NetRef<I>,
1040}
1041
1042impl<I> DrivenNet<I>
1043where
1044    I: Instantiable,
1045{
1046    fn new(pos: usize, netref: NetRef<I>) -> Self {
1047        if pos >= netref.clone().unwrap().borrow().get().get_nets().len() {
1048            panic!(
1049                "Position {} out of bounds for netref with {} outputted nets",
1050                pos,
1051                netref.unwrap().borrow().get().get_nets().len()
1052            );
1053        }
1054        Self { pos, netref }
1055    }
1056
1057    /// Returns the index that can address this net in the netlist.
1058    fn get_operand(&self) -> Operand {
1059        if self.netref.is_multi_output() {
1060            Operand::CellIndex(self.netref.clone().unwrap().borrow().get_index(), self.pos)
1061        } else {
1062            Operand::DirectIndex(self.netref.clone().unwrap().borrow().get_index())
1063        }
1064    }
1065
1066    /// Borrow the net being driven
1067    pub fn as_net(&self) -> Ref<'_, Net> {
1068        self.netref.get_net(self.pos)
1069    }
1070
1071    /// Get a mutable reference to the net being driven
1072    pub fn as_net_mut(&self) -> RefMut<'_, Net> {
1073        self.netref.get_net_mut(self.pos)
1074    }
1075
1076    /// Returns `true` if this net is a principal input
1077    pub fn is_an_input(&self) -> bool {
1078        self.netref.is_an_input()
1079    }
1080
1081    /// Get the output port associated with this connection
1082    pub fn get_port(&self) -> Net {
1083        if self.netref.is_an_input() {
1084            panic!("Net is not driven by a primitive");
1085        }
1086        self.netref
1087            .get_instance_type()
1088            .unwrap()
1089            .get_output_port(self.pos)
1090            .clone()
1091    }
1092
1093    /// Connects the net driven by this output port to the given input port.
1094    pub fn connect(&self, input: InputPort<I>) {
1095        let operand = self.get_operand();
1096        let index = input.netref.unwrap().borrow().get_index();
1097        let netlist = self
1098            .netref
1099            .clone()
1100            .unwrap()
1101            .borrow()
1102            .owner
1103            .upgrade()
1104            .expect("Output port is unlinked from netlist");
1105        let obj = netlist.index_weak(&index);
1106        obj.borrow_mut().operands[input.pos] = Some(operand);
1107    }
1108
1109    /// Returns `true` if this net is a top-level output in the netlist.
1110    pub fn is_top_level_output(&self) -> bool {
1111        let netlist = self
1112            .netref
1113            .clone()
1114            .unwrap()
1115            .borrow()
1116            .owner
1117            .upgrade()
1118            .expect("DrivenNet is unlinked from netlist");
1119        let outputs = netlist.outputs.borrow();
1120        outputs.contains_key(&self.get_operand())
1121    }
1122
1123    /// Return the underlying circuit node
1124    pub fn unwrap(self) -> NetRef<I> {
1125        self.netref
1126    }
1127
1128    /// Returns a copy of the identifier of the net being driven.
1129    pub fn get_identifier(&self) -> Identifier {
1130        self.as_net().get_identifier().clone()
1131    }
1132
1133    /// Exposes this driven net as a top-level output with a specific port name.
1134    /// Multiple calls to this method can be used to create multiple output aliases for the same net.
1135    ///
1136    /// # Panics
1137    ///
1138    /// Panics if the weak reference to the netlist is dead.
1139    pub fn expose_with_name(self, name: Identifier) -> Self {
1140        let netlist = self
1141            .netref
1142            .clone()
1143            .unwrap()
1144            .borrow()
1145            .owner
1146            .upgrade()
1147            .expect("DrivenNet is unlinked from netlist");
1148        netlist.expose_net_with_name(self.clone(), name);
1149        self
1150    }
1151
1152    /// Removes a specific output alias by its name from this driven net.
1153    /// Returns true if the output was removed, false if it didn't exist.
1154    ///
1155    /// # Panics
1156    ///
1157    /// Panics if the reference to the netlist is lost.
1158    pub fn remove_output(&self, net_name: &Identifier) -> bool {
1159        let netlist = self
1160            .netref
1161            .clone()
1162            .unwrap()
1163            .borrow()
1164            .owner
1165            .upgrade()
1166            .expect("DrivenNet is unlinked from netlist");
1167        netlist.remove_output(self, net_name)
1168    }
1169
1170    /// Removes all output aliases for this driven net.
1171    /// Returns the number of outputs that were removed.
1172    ///
1173    /// # Panics
1174    ///
1175    /// Panics if the reference to the netlist is lost.
1176    pub fn remove_all_outputs(&self) -> usize {
1177        let netlist = self
1178            .netref
1179            .clone()
1180            .unwrap()
1181            .borrow()
1182            .owner
1183            .upgrade()
1184            .expect("DrivenNet is unlinked from netlist");
1185        netlist.remove_outputs(self)
1186    }
1187
1188    /// Returns the output position, if the net is the output of a gate.
1189    pub fn get_output_index(&self) -> Option<usize> {
1190        if self.netref.is_an_input() {
1191            None
1192        } else {
1193            Some(self.pos)
1194        }
1195    }
1196
1197    /// Returns the [Instantiable] type driving this net, if it has a driver.
1198    pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
1199        self.netref.get_instance_type()
1200    }
1201}
1202
1203impl<I> std::fmt::Display for DrivenNet<I>
1204where
1205    I: Instantiable,
1206{
1207    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1208        self.as_net().fmt(f)
1209    }
1210}
1211
1212impl<I> PartialEq for DrivenNet<I>
1213where
1214    I: Instantiable,
1215{
1216    fn eq(&self, other: &Self) -> bool {
1217        self.netref == other.netref && self.pos == other.pos
1218    }
1219}
1220
1221impl<I> Eq for DrivenNet<I> where I: Instantiable {}
1222
1223impl<I> std::hash::Hash for DrivenNet<I>
1224where
1225    I: Instantiable,
1226{
1227    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1228        self.netref.hash(state);
1229        self.pos.hash(state);
1230    }
1231}
1232
1233impl<I> Ord for DrivenNet<I>
1234where
1235    I: Instantiable,
1236{
1237    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
1238        match self.netref.cmp(&other.netref) {
1239            std::cmp::Ordering::Equal => self.pos.cmp(&other.pos),
1240            ord => ord,
1241        }
1242    }
1243}
1244
1245impl<I> PartialOrd for DrivenNet<I>
1246where
1247    I: Instantiable,
1248{
1249    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1250        Some(self.cmp(other))
1251    }
1252}
1253
1254impl<I> WeakIndex<usize> for Netlist<I>
1255where
1256    I: Instantiable,
1257{
1258    type Output = OwnedObject<I, Self>;
1259
1260    fn index_weak(&self, index: &usize) -> Rc<RefCell<Self::Output>> {
1261        self.objects.borrow()[*index].clone()
1262    }
1263}
1264
1265impl<I> Netlist<I>
1266where
1267    I: Instantiable,
1268{
1269    /// Creates a new netlist with the given name
1270    pub fn new(name: Identifier) -> Rc<Self> {
1271        Rc::new(Self {
1272            name: RefCell::new(name),
1273            objects: RefCell::new(Vec::new()),
1274            outputs: RefCell::new(BTreeMap::new()),
1275        })
1276    }
1277
1278    /// Attempts to reclaim the netlist and unlink the nodes, returning [Some] if successful.
1279    pub fn try_unlink(self: Rc<Self>) -> Result<Self, Rc<Self>> {
1280        Rc::try_unwrap(self)
1281    }
1282
1283    /// Creates a deep clone of the netlist.
1284    pub fn deep_clone(&self) -> Rc<Self> {
1285        let dc = Rc::new(Self {
1286            name: self.name.clone(),
1287            objects: RefCell::new(Vec::new()),
1288            outputs: self.outputs.clone(),
1289        });
1290
1291        let objects_linked: Vec<NetRefT<I>> = self
1292            .objects
1293            .borrow()
1294            .iter()
1295            .map(|obj| {
1296                let b = obj.borrow();
1297                Rc::new(RefCell::new(OwnedObject {
1298                    object: b.object.clone(),
1299                    owner: Rc::downgrade(&dc),
1300                    operands: b.operands.clone(),
1301                    attributes: b.attributes.clone(),
1302                    index: b.index,
1303                }))
1304            })
1305            .collect();
1306
1307        *dc.objects.borrow_mut() = objects_linked;
1308
1309        dc
1310    }
1311
1312    /// Use interior mutability to add an object to the netlist. Returns a mutable reference to the created object.
1313    ///
1314    /// # Panics
1315    /// If any of the `operands` do not belong to this netlist.
1316    fn insert_object(
1317        self: &Rc<Self>,
1318        object: Object<I>,
1319        operands: &[DrivenNet<I>],
1320    ) -> Result<NetRef<I>, Error> {
1321        for operand in operands {
1322            self.belongs(&operand.clone().unwrap());
1323        }
1324        let index = self.objects.borrow().len();
1325        let weak = Rc::downgrade(self);
1326        let operands = operands
1327            .iter()
1328            .map(|net| Some(net.get_operand()))
1329            .collect::<Vec<_>>();
1330        let owned_object = Rc::new(RefCell::new(OwnedObject {
1331            object,
1332            owner: weak,
1333            operands,
1334            attributes: BTreeMap::new(),
1335            index,
1336        }));
1337        self.objects.borrow_mut().push(owned_object.clone());
1338        Ok(NetRef::wrap(owned_object))
1339    }
1340
1341    /// Inserts an input net to the netlist
1342    pub fn insert_input(self: &Rc<Self>, net: Net) -> DrivenNet<I> {
1343        let obj = Object::Input(net);
1344        self.insert_object(obj, &[]).unwrap().into()
1345    }
1346
1347    /// Inserts a four-state logic input port to the netlist
1348    pub fn insert_input_logic_bus(self: &Rc<Self>, net: String, bw: usize) -> Vec<DrivenNet<I>> {
1349        Net::new_logic_bus(net, bw)
1350            .into_iter()
1351            .map(|n| self.insert_input(n))
1352            .collect()
1353    }
1354
1355    /// Inserts a gate to the netlist
1356    pub fn insert_gate(
1357        self: &Rc<Self>,
1358        inst_type: I,
1359        inst_name: Identifier,
1360        operands: &[DrivenNet<I>],
1361    ) -> Result<NetRef<I>, Error> {
1362        let nets = inst_type
1363            .get_output_ports()
1364            .iter()
1365            .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1366            .collect::<Vec<_>>();
1367        let input_count = inst_type.get_input_ports().iter().count();
1368        if operands.len() != input_count {
1369            return Err(Error::ArgumentMismatch(input_count, operands.len()));
1370        }
1371        let obj = Object::Instance(nets, inst_name, inst_type);
1372        self.insert_object(obj, operands)
1373    }
1374
1375    /// Use interior mutability to add an object to the netlist. Returns a mutable reference to the created object.
1376    pub fn insert_gate_disconnected(
1377        self: &Rc<Self>,
1378        inst_type: I,
1379        inst_name: Identifier,
1380    ) -> NetRef<I> {
1381        let nets = inst_type
1382            .get_output_ports()
1383            .iter()
1384            .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1385            .collect::<Vec<_>>();
1386        let object = Object::Instance(nets, inst_name, inst_type);
1387        let index = self.objects.borrow().len();
1388        let weak = Rc::downgrade(self);
1389        let input_count = object
1390            .get_instance_type()
1391            .unwrap()
1392            .get_input_ports()
1393            .iter()
1394            .count();
1395        let operands = vec![None; input_count];
1396        let owned_object = Rc::new(RefCell::new(OwnedObject {
1397            object,
1398            owner: weak,
1399            operands,
1400            attributes: BTreeMap::new(),
1401            index,
1402        }));
1403        self.objects.borrow_mut().push(owned_object.clone());
1404        NetRef::wrap(owned_object)
1405    }
1406
1407    /// Inserts a constant [Logic] value to the netlist
1408    pub fn insert_constant(
1409        self: &Rc<Self>,
1410        value: Logic,
1411        inst_name: Identifier,
1412    ) -> Result<DrivenNet<I>, Error> {
1413        let obj = I::from_constant(value).ok_or(Error::InstantiableError(format!(
1414            "Instantiable type does not support constant value {}",
1415            value
1416        )))?;
1417        Ok(self.insert_gate_disconnected(obj, inst_name).into())
1418    }
1419
1420    /// # Panics
1421    ///
1422    /// Panics if `netref` definitely does not belong to this netlist.
1423    fn belongs(&self, netref: &NetRef<I>) {
1424        if let Some(nl) = netref.netref.borrow().owner.upgrade() {
1425            if self.objects.borrow().len() != nl.objects.borrow().len() {
1426                panic!("NetRef does not belong to this netlist");
1427            }
1428
1429            if let Some(p) = self.objects.borrow().first()
1430                && let Some(np) = nl.objects.borrow().first()
1431                && !Rc::ptr_eq(p, np)
1432            {
1433                panic!("NetRef does not belong to this netlist");
1434            }
1435        }
1436
1437        if netref.netref.borrow().index >= self.objects.borrow().len() {
1438            panic!("NetRef does not belong to this netlist");
1439        }
1440    }
1441
1442    /// Returns the driving node at input position `index` for `netref`
1443    ///
1444    /// # Panics
1445    ///
1446    /// Panics if `index` is out of bounds
1447    /// The `netref` does not belong to this netlist
1448    pub fn get_driver(&self, netref: NetRef<I>, index: usize) -> Option<DrivenNet<I>> {
1449        self.belongs(&netref);
1450        let op = netref.unwrap().borrow().operands[index]?;
1451        Some(DrivenNet::new(
1452            op.secondary(),
1453            NetRef::wrap(self.index_weak(&op.root()).clone()),
1454        ))
1455    }
1456
1457    /// Set an added object as a top-level output with a specific name.
1458    /// Multiple calls with different names for the same net will create multiple aliases.
1459    ///
1460    /// # Panics
1461    /// The `net` does not belong to this netlist
1462    pub fn expose_net_with_name(&self, net: DrivenNet<I>, name: Identifier) -> DrivenNet<I> {
1463        self.belongs(&net.clone().unwrap());
1464        let mut outputs = self.outputs.borrow_mut();
1465        let named_net = net.as_net().with_name(name);
1466        outputs
1467            .entry(net.get_operand())
1468            .or_default()
1469            .insert(named_net);
1470        net
1471    }
1472
1473    /// Sets the current net as a top-level output using the current name of the net
1474    ///
1475    /// # Panics
1476    /// The `net` does not belong to this netlist
1477    pub fn expose_net(&self, net: DrivenNet<I>) -> Result<DrivenNet<I>, Error> {
1478        self.belongs(&net.clone().unwrap());
1479        if net.is_an_input() {
1480            return Err(Error::InputNeedsAlias(net.as_net().clone()));
1481        }
1482        let mut outputs = self.outputs.borrow_mut();
1483        outputs
1484            .entry(net.get_operand())
1485            .or_default()
1486            .insert(net.as_net().clone());
1487        Ok(net)
1488    }
1489
1490    /// Removes a specific output alias by its operand and net name.
1491    /// Returns true if the output was removed, false if it didn't exist.
1492    ///
1493    /// # Panics
1494    /// The `operand` does not belong to this netlist
1495    pub fn remove_output(&self, operand: &DrivenNet<I>, net_name: &Identifier) -> bool {
1496        self.belongs(&operand.clone().unwrap());
1497        let mut outputs = self.outputs.borrow_mut();
1498        if let Some(nets) = outputs.get_mut(&operand.get_operand()) {
1499            // Create a net with just the identifier to match for removal
1500            let net_to_remove = Net::new(net_name.clone(), crate::circuit::DataType::logic());
1501            if nets.remove(&net_to_remove) {
1502                // If the set is now empty, remove the operand entirely
1503                if nets.is_empty() {
1504                    outputs.remove(&operand.get_operand());
1505                }
1506                return true;
1507            }
1508        }
1509        false
1510    }
1511
1512    /// Removes all output aliases for a specific operand.
1513    /// Returns the number of outputs that were removed.
1514    pub fn remove_outputs(&self, operand: &DrivenNet<I>) -> usize {
1515        //let mut outputs = self.outputs.borrow_mut();
1516        self.outputs
1517            .borrow_mut()
1518            .remove(&operand.get_operand())
1519            .map(|nets| nets.len())
1520            .unwrap_or(0)
1521    }
1522
1523    /// Removes all outputs from the netlist.
1524    pub fn clear_outputs(&self) {
1525        self.outputs.borrow_mut().clear();
1526    }
1527
1528    /// Clones `netref` into `self`.
1529    /// The operands of `netref` are remapped according to `map`.
1530    /// `prefix` is used to rename the instance name.
1531    /// **For operands that do not exist in the map, the cloned node is disconnected.**
1532    pub fn clone_into<O: Instantiable + Into<I>>(
1533        self: &Rc<Self>,
1534        netref: &NetRef<O>,
1535        prefix: Option<Identifier>,
1536        map: &mut HashMap<DrivenNet<O>, DrivenNet<I>>,
1537    ) -> NetRef<I> {
1538        let mut object = netref.get_obj().clone();
1539        let attributes = BTreeMap::from_iter(netref.attributes().map(|a| a.split()));
1540        if let Some(prefix) = &prefix
1541            && let Object::Instance(_, name, _) = &mut object
1542        {
1543            let update = prefix + name;
1544            *name = update;
1545        }
1546
1547        let mut object = match object {
1548            Object::Input(a) => Object::Input(a),
1549            Object::Instance(nets, name, inst_type) => {
1550                Object::Instance(nets, name, inst_type.into())
1551            }
1552        };
1553
1554        if let Some(prefix) = &prefix {
1555            for net in object.get_nets_mut() {
1556                let update = prefix + net.get_identifier();
1557                net.set_identifier(update);
1558            }
1559        }
1560
1561        let mapped: Vec<Option<DrivenNet<I>>> = netref
1562            .inputs()
1563            .map(|x| map.get(&x.get_driver()?).cloned())
1564            .collect();
1565
1566        let mut operands = Vec::new();
1567
1568        for operand in mapped {
1569            let op = match operand {
1570                None => None,
1571                Some(d) => {
1572                    let op = d.get_operand();
1573                    self.belongs(&d.unwrap());
1574                    Some(op)
1575                }
1576            };
1577            operands.push(op);
1578        }
1579
1580        let index = self.objects.borrow().len();
1581        let weak = Rc::downgrade(self);
1582        let owned_object = Rc::new(RefCell::new(OwnedObject {
1583            object,
1584            owner: weak,
1585            operands,
1586            attributes,
1587            index,
1588        }));
1589        self.objects.borrow_mut().push(owned_object.clone());
1590        let clone = NetRef::wrap(owned_object);
1591
1592        for (k, v) in netref.outputs().zip(clone.outputs()) {
1593            map.insert(k, v);
1594        }
1595
1596        clone
1597    }
1598
1599    /// Unlink a circuit node from the rest of the netlist. Return the object that was being stored.
1600    ///
1601    /// # Panics
1602    /// The `netref` does not belong to this netlist
1603    pub fn delete_net_uses(&self, netref: NetRef<I>) -> Result<Object<I>, Error> {
1604        self.belongs(&netref);
1605        let unwrapped = netref.clone().unwrap();
1606        if Rc::strong_count(&unwrapped) > 3 {
1607            return Err(Error::DanglingReference(netref.nets().collect()));
1608        }
1609        let old_index = unwrapped.borrow().get_index();
1610        let objects = self.objects.borrow();
1611        for oref in objects.iter() {
1612            let operands = &mut oref.borrow_mut().operands;
1613            for operand in operands.iter_mut() {
1614                if let Some(op) = operand {
1615                    match op {
1616                        Operand::DirectIndex(idx) | Operand::CellIndex(idx, _)
1617                            if *idx == old_index =>
1618                        {
1619                            *operand = None;
1620                        }
1621                        _ => (),
1622                    }
1623                }
1624            }
1625        }
1626
1627        let outputs: Vec<Operand> = self
1628            .outputs
1629            .borrow()
1630            .keys()
1631            .filter(|operand| match operand {
1632                Operand::DirectIndex(idx) | Operand::CellIndex(idx, _) => *idx == old_index,
1633            })
1634            .cloned()
1635            .collect();
1636
1637        for operand in outputs {
1638            self.outputs.borrow_mut().remove(&operand);
1639        }
1640
1641        Ok(netref.unwrap().borrow().get().clone())
1642    }
1643
1644    /// Replaces the uses of a circuit node with another circuit node. `of` is returned and unused.
1645    ///
1646    /// # See also:
1647    /// - [`NetMapper`](rewriter::NetMapper)
1648    ///
1649    /// # Panics
1650    /// `of` or `with` do not belong to this netlist
1651    pub fn replace_net_uses(
1652        &self,
1653        of: DrivenNet<I>,
1654        with: &DrivenNet<I>,
1655    ) -> Result<DrivenNet<I>, Error> {
1656        {
1657            self.belongs(&of.clone().unwrap());
1658            self.belongs(&with.clone().unwrap());
1659        }
1660        let unwrapped = of.clone().unwrap().unwrap();
1661        let i = of.get_output_index();
1662        let k = with.get_output_index();
1663
1664        if of.clone().unwrap() == with.clone().unwrap() {
1665            if i == k {
1666                return Ok(of);
1667            }
1668
1669            if Rc::strong_count(&unwrapped) > 4 {
1670                return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1671            }
1672        } else if Rc::strong_count(&unwrapped) > 3 {
1673            return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1674        }
1675
1676        let old_index = of.get_operand();
1677
1678        if let Some(nets) = self.outputs.borrow().get(&old_index)
1679            && nets.contains(&of.as_net())
1680        {
1681            if of.is_an_input() {
1682                return Err(Error::NonuniqueNets(nets.iter().cloned().collect()));
1683            } else {
1684                let id = of.as_net().get_identifier().clone() + "_replaced".into();
1685                of.as_net_mut().set_identifier(id);
1686            }
1687        }
1688
1689        let new_index = with.get_operand();
1690        let objects = self.objects.borrow();
1691        for oref in objects.iter() {
1692            let operands = &mut oref.borrow_mut().operands;
1693            for operand in operands.iter_mut() {
1694                if let Some(op) = operand
1695                    && *op == old_index
1696                {
1697                    *operand = Some(new_index);
1698                }
1699            }
1700        }
1701
1702        // Move all the old outputs to the new key
1703        let outs = self.outputs.borrow_mut().remove(&old_index);
1704        if let Some(outs) = outs {
1705            self.outputs
1706                .borrow_mut()
1707                .entry(new_index)
1708                .or_default()
1709                .extend(outs);
1710        }
1711
1712        Ok(of)
1713    }
1714}
1715
1716impl<I> Netlist<I>
1717where
1718    I: Instantiable,
1719{
1720    /// Returns the name of the netlist module
1721    pub fn get_name(&self) -> Ref<'_, Identifier> {
1722        self.name.borrow()
1723    }
1724
1725    /// Sets the name of the netlist module
1726    /// # Panics
1727    ///
1728    /// Panics if the module name cannot be borrowed mutably.
1729    pub fn set_name(&self, name: Identifier) {
1730        *self.name.borrow_mut() = name;
1731    }
1732
1733    /// Iterates over the input ports of the netlist.
1734    pub fn get_input_ports(&self) -> impl Iterator<Item = Net> {
1735        self.objects().filter_map(|oref| {
1736            if oref.is_an_input() {
1737                Some(oref.as_net().clone())
1738            } else {
1739                None
1740            }
1741        })
1742    }
1743
1744    /// Returns a list of output nets
1745    pub fn get_output_ports(&self) -> Vec<Net> {
1746        self.outputs
1747            .borrow()
1748            .values()
1749            .flat_map(|nets| nets.iter().cloned())
1750            .collect()
1751    }
1752
1753    /// Constructs an analysis of the netlist.
1754    pub fn get_analysis<'a, A: Analysis<'a, I>>(&'a self) -> Result<A, Error> {
1755        A::build(self)
1756    }
1757
1758    /// Finds the first circuit node that drives the `net`. This operation is O(n).
1759    /// This should be unique provided the netlist is well-formed.
1760    pub fn find_net(&self, net: &Net) -> Option<DrivenNet<I>> {
1761        for obj in self.objects() {
1762            for o in obj.outputs() {
1763                if *o.as_net() == *net {
1764                    return Some(o);
1765                }
1766            }
1767        }
1768        None
1769    }
1770
1771    /// Returns a `NetRef` to the first circuit node
1772    pub fn first(&self) -> Option<NetRef<I>> {
1773        self.objects
1774            .borrow()
1775            .first()
1776            .map(|nr| NetRef::wrap(nr.clone()))
1777    }
1778
1779    /// Returns a `NetRef` to the last circuit node
1780    pub fn last(&self) -> Option<NetRef<I>> {
1781        self.objects
1782            .borrow()
1783            .last()
1784            .map(|nr| NetRef::wrap(nr.clone()))
1785    }
1786
1787    /// Returns the number of objects in the netlist (instances + inputs)
1788    pub fn len(&self) -> usize {
1789        self.objects.borrow().len()
1790    }
1791
1792    /// Returns `true` if the netlist contains no objects.
1793    pub fn is_empty(&self) -> bool {
1794        self.objects.borrow().is_empty()
1795    }
1796
1797    /// Returns `true` if an output of `netref` which is driving a module output.
1798    ///
1799    /// # Panics
1800    /// The `netref` does not belong to this netlist
1801    pub fn drives_an_output(&self, netref: NetRef<I>) -> bool {
1802        self.belongs(&netref);
1803        let my_index = netref.unwrap().borrow().get_index();
1804        for key in self.outputs.borrow().keys() {
1805            if key.root() == my_index {
1806                return true;
1807            }
1808        }
1809        false
1810    }
1811
1812    /// Rename nets and instances in the netlist using the provided *injective* function.
1813    /// Returns an error if the function is not injective.
1814    /// # Examples
1815    ///
1816    /// ```
1817    /// use safety_net::format_id;
1818    /// use safety_net::{Gate, GateNetlist};
1819    ///
1820    /// let netlist = GateNetlist::new("example".into());
1821    /// let inv = Gate::new_logical("INV".into(), vec!["A".into()], "Y".into());
1822    /// let foo = netlist.insert_input("foo".into());
1823    /// let nr = netlist.insert_gate(inv, "bar".into(), &[foo]).unwrap();
1824    /// nr.expose_with_name("baz".into());
1825    /// netlist.rename_nets(|id, i| format_id!("{}_{}", id, i) ).unwrap();
1826    /// // "bar_Y" -> "bar_Y_0"
1827    /// // "bar" -> "bar_1"
1828    /// ```
1829    pub fn rename_nets<F: Fn(&Identifier, usize) -> Identifier>(&self, f: F) -> Result<(), Error> {
1830        let mut i: usize = 0;
1831        let mut set = HashSet::new();
1832        let mut vec = Vec::new();
1833        // Dry run
1834        for nr in self.objects() {
1835            if nr.is_an_input() {
1836                continue;
1837            }
1838            for net in nr.nets() {
1839                let id = net.get_identifier().clone();
1840                let rename = f(&id, i);
1841                if !set.insert(rename.clone()) {
1842                    return Err(Error::NonuniqueNets(vec![net]));
1843                }
1844                vec.push(rename);
1845                i += 1;
1846            }
1847        }
1848
1849        for nr in self.objects() {
1850            if nr.is_an_input() {
1851                continue;
1852            }
1853
1854            let id = nr.get_instance_name().unwrap();
1855            let rename = f(&id, i);
1856            if !set.insert(rename.clone()) {
1857                return Err(Error::NonuniqueInsts(vec![id]));
1858            }
1859            vec.push(rename);
1860            i += 1;
1861        }
1862
1863        i = 0;
1864        for nr in self.objects() {
1865            if nr.is_an_input() {
1866                continue;
1867            }
1868            for mut net in nr.nets_mut() {
1869                net.set_identifier(vec[i].clone());
1870                i += 1;
1871            }
1872        }
1873
1874        for nr in self.objects() {
1875            if nr.is_an_input() {
1876                continue;
1877            }
1878
1879            nr.set_instance_name(vec[i].clone());
1880            i += 1;
1881        }
1882
1883        Ok(())
1884    }
1885
1886    /// Retains the [DrivenNet]s in `set`, given they are used. Otherwise, they are cleaned and returned in a `Ok(vec)`.
1887    pub fn retain_once(&self, set: &mut HashSet<DrivenNet<I>>) -> Result<Vec<Object<I>>, Error> {
1888        let mut dead_objs = HashSet::new();
1889        {
1890            let fan_out = self.get_analysis::<FanOutTable<I>>()?;
1891            for obj in self.objects() {
1892                let mut is_dead = true;
1893                for net in obj.outputs() {
1894                    // This should account for outputs
1895                    if fan_out.net_has_uses(&net.as_net()) {
1896                        is_dead = false;
1897                    } else {
1898                        set.remove(&net);
1899                    }
1900                }
1901                if is_dead && !obj.is_an_input() {
1902                    dead_objs.insert(obj.unwrap().borrow().index);
1903                }
1904            }
1905        }
1906
1907        if dead_objs.is_empty() {
1908            return Ok(vec![]);
1909        }
1910
1911        let old_objects = self.objects.take();
1912
1913        // Check no dangling references will be created before mutating
1914        for i in dead_objs.iter() {
1915            let rc = &old_objects[*i];
1916            if Rc::strong_count(rc) > 1 {
1917                self.objects.replace(old_objects.clone());
1918                return Err(Error::DanglingReference(
1919                    rc.borrow().get().get_nets().to_vec(),
1920                ));
1921            }
1922        }
1923
1924        let mut removed = Vec::new();
1925        let mut remap: HashMap<usize, usize> = HashMap::new();
1926        for (old_index, obj) in old_objects.into_iter().enumerate() {
1927            if dead_objs.contains(&old_index) {
1928                removed.push(obj.borrow().get().clone());
1929                continue;
1930            }
1931
1932            let new_index = self.objects.borrow().len();
1933            remap.insert(old_index, new_index);
1934            obj.borrow_mut().index = new_index;
1935            self.objects.borrow_mut().push(obj);
1936        }
1937
1938        for obj in self.objects.borrow().iter() {
1939            for operand in obj.borrow_mut().inds_mut() {
1940                let root = operand.root();
1941                let root = *remap.get(&root).unwrap_or(&root);
1942                *operand = operand.remap(root);
1943            }
1944        }
1945
1946        let pairs: Vec<_> = self.outputs.take().into_iter().collect();
1947        for (operand, net) in pairs {
1948            let root = operand.root();
1949            let root = *remap.get(&root).unwrap_or(&root);
1950            let new_operand = operand.remap(root);
1951            self.outputs.borrow_mut().insert(new_operand, net);
1952        }
1953
1954        Ok(removed)
1955    }
1956
1957    /// Removes unused nodes from the netlist, until it stops changing.
1958    /// Returns `Ok(vec)` of the removed objects.
1959    pub fn clean(&self) -> Result<Vec<Object<I>>, Error> {
1960        let mut removed = Vec::new();
1961        let mut r = self.retain_once(&mut HashSet::new())?;
1962        while !r.is_empty() {
1963            removed.extend(r);
1964            r = self.retain_once(&mut HashSet::new())?;
1965        }
1966        Ok(removed)
1967    }
1968
1969    /// Retains the [DrivenNet]s in `set`, given they are used. Otherwise, they are cleaned and returned in a `Ok(vec)`.
1970    pub fn retain(&self, set: &mut HashSet<DrivenNet<I>>) -> Result<Vec<Object<I>>, Error> {
1971        let mut removed = Vec::new();
1972        let mut r = self.retain_once(set)?;
1973        while !r.is_empty() {
1974            removed.extend(r);
1975            r = self.retain_once(set)?;
1976        }
1977        Ok(removed)
1978    }
1979
1980    /// Returns Ok if all the nets/insts are uniquely named
1981    fn nets_insts_unique(&self) -> Result<(), Error> {
1982        let mut nets = HashSet::new();
1983        let mut stems = HashSet::new();
1984        for net in self {
1985            if !nets.insert(net.clone().take_identifier()) {
1986                return Err(Error::NonuniqueNets(vec![net]));
1987            }
1988            if !stems.insert(net.get_identifier().get_stem().to_string())
1989                && net.get_identifier().get_bit_index().is_none()
1990            {
1991                return Err(Error::NonuniqueNets(vec![net]));
1992            }
1993        }
1994        for inst in self.objects() {
1995            if let Some(name) = inst.get_instance_name()
1996                && !stems.insert(name.get_stem().to_string())
1997            {
1998                return Err(Error::NonuniqueInsts(vec![name]));
1999            }
2000            if let Some(name) = inst.get_instance_name()
2001                && name.get_bit_index().is_some()
2002            {
2003                return Err(Error::InstantiableError(format!(
2004                    "Instance identifier {name} cannot be indexed"
2005                )));
2006            }
2007        }
2008        Ok(())
2009    }
2010
2011    /// Checks that check netref matches input and output size of instance
2012    fn check_io(&self) -> Result<(), Error> {
2013        for inst in self.objects() {
2014            let unwrapped = inst.unwrap();
2015
2016            let olen = unwrapped.borrow().operands.len();
2017            let nlen = unwrapped.borrow().get().get_nets().len();
2018
2019            if let Some(inst) = unwrapped.borrow().get().get_instance_type() {
2020                let inlen = inst.get_input_ports().iter().count();
2021                let outlen = inst.get_output_ports().iter().count();
2022                if olen != inlen {
2023                    return Err(Error::ArgumentMismatch(inlen, olen));
2024                }
2025
2026                if nlen != outlen {
2027                    return Err(Error::InstantiableError(format!(
2028                        "Instantiable type has incorrect number of outputs. Expected {outlen}, found {nlen}"
2029                    )));
2030                }
2031            }
2032        }
2033        Ok(())
2034    }
2035
2036    fn connections_type_check(&self) -> Result<(), Error> {
2037        for conn in self.connections() {
2038            let target = *conn.target().get_port().get_type();
2039            let source = *conn.src().as_net().get_type();
2040            if target != source {
2041                return Err(Error::TypeError(conn.src().as_net().clone()));
2042            }
2043        }
2044        Ok(())
2045    }
2046
2047    fn cells_check(&self) -> Result<(), Error> {
2048        for inst in self.objects() {
2049            if let Some(inst_type) = inst.get_instance_type()
2050                && let Err(rsn) = inst_type.verify()
2051            {
2052                return Err(Error::InstantiableError(format!(
2053                    "Instantiable {} invalid: {}",
2054                    inst_type.get_name(),
2055                    rsn
2056                )));
2057            }
2058        }
2059        Ok(())
2060    }
2061
2062    /// Verifies that a netlist is well-formed.
2063    pub fn verify(&self) -> Result<(), Error> {
2064        if self.outputs.borrow().is_empty() {
2065            return Err(Error::NoOutputs);
2066        }
2067
2068        self.check_io()?;
2069        self.nets_insts_unique()?;
2070        self.connections_type_check()?;
2071        self.cells_check()?;
2072
2073        Ok(())
2074    }
2075}
2076
2077/// Represent a driven net alongside its connection to an input port
2078#[derive(Debug, Clone)]
2079pub struct Connection<I: Instantiable> {
2080    driver: DrivenNet<I>,
2081    input: InputPort<I>,
2082}
2083
2084impl<I> Connection<I>
2085where
2086    I: Instantiable,
2087{
2088    fn new(driver: DrivenNet<I>, input: InputPort<I>) -> Self {
2089        Self { driver, input }
2090    }
2091
2092    /// Return the driver of the connection
2093    pub fn src(&self) -> DrivenNet<I> {
2094        self.driver.clone()
2095    }
2096
2097    /// Return the net along the connection
2098    pub fn net(&self) -> Net {
2099        self.driver.as_net().clone()
2100    }
2101
2102    /// Returns the input port of the connection
2103    pub fn target(&self) -> InputPort<I> {
2104        self.input.clone()
2105    }
2106}
2107
2108impl<I> std::fmt::Display for Connection<I>
2109where
2110    I: Instantiable,
2111{
2112    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2113        self.net().fmt(f)
2114    }
2115}
2116
2117/// Backend language emitters
2118pub mod emitter {
2119    #[cfg(feature = "graph")]
2120    use super::NetRef;
2121    use super::{Analysis, Error, Identifier, Instantiable, Netlist};
2122    #[cfg(feature = "graph")]
2123    use std::collections::HashMap;
2124    use std::collections::{BTreeMap, HashSet};
2125
2126    /// Options for the Verilog emitter
2127    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2128    pub struct VerilogEmitterConfig {
2129        /// The character used to indent the code(e.g. space, tab)
2130        pub indent_char: char,
2131        /// The number of characters used to change the indentation level
2132        pub indent_width: usize,
2133        /// Whether to use ANSI style module decl
2134        pub ansi_style: bool,
2135        /// Whether to emit constants as cells or literals
2136        pub emit_const_cells: bool,
2137    }
2138
2139    impl VerilogEmitterConfig {
2140        /// Return a config that is roughly equivalent to the old emitter
2141        pub fn legacy() -> Self {
2142            Self {
2143                indent_char: ' ',
2144                indent_width: 2,
2145                ansi_style: false,
2146                emit_const_cells: false,
2147            }
2148        }
2149    }
2150
2151    impl Default for VerilogEmitterConfig {
2152        fn default() -> Self {
2153            Self {
2154                indent_char: ' ',
2155                indent_width: 2,
2156                ansi_style: true,
2157                emit_const_cells: false,
2158            }
2159        }
2160    }
2161
2162    enum VerilogNet {
2163        Net(Identifier),
2164        Bus(Identifier, (usize, usize)),
2165    }
2166
2167    impl VerilogNet {
2168        fn id(&self) -> &Identifier {
2169            match self {
2170                VerilogNet::Net(id) => id,
2171                VerilogNet::Bus(id, _) => id,
2172            }
2173        }
2174    }
2175
2176    impl std::fmt::Display for VerilogNet {
2177        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2178            write!(f, "wire ")?;
2179            match self {
2180                VerilogNet::Net(net) => write!(f, "{}", net.get_stem()),
2181                VerilogNet::Bus(net, (h, l)) => write!(f, "[{}:{}] {}", h, l, net.get_stem()),
2182            }
2183        }
2184    }
2185
2186    /// A Verilog emitter for a netlist
2187    pub struct VerilogEmitter<'a, I: Instantiable> {
2188        netlist: &'a Netlist<I>,
2189        config: VerilogEmitterConfig,
2190        inputs: Vec<VerilogNet>,
2191        outputs: Vec<VerilogNet>,
2192        others: Vec<VerilogNet>,
2193    }
2194
2195    impl<'a, I: Instantiable> VerilogEmitter<'a, I> {
2196        fn get_nets(
2197            nl: &'a Netlist<I>,
2198            emit_consts: bool,
2199        ) -> (Vec<VerilogNet>, Vec<VerilogNet>, Vec<VerilogNet>) {
2200            let mut seen: HashSet<Identifier> = HashSet::new();
2201            let mut inputs: BTreeMap<Identifier, (usize, usize)> = BTreeMap::new();
2202            let mut outputs: BTreeMap<Identifier, (usize, usize)> = BTreeMap::new();
2203            let mut others: BTreeMap<Identifier, (usize, usize)> = BTreeMap::new();
2204
2205            for (_, output) in nl.outputs() {
2206                let output = output.take_identifier();
2207                let stem = output.get_stem();
2208                seen.insert(stem.clone());
2209                let entry = outputs.entry(stem.clone()).or_default();
2210                if let Some(idx) = output.get_bit_index() {
2211                    entry.1 = entry.1.min(idx);
2212                    entry.0 = entry.0.max(idx);
2213                }
2214            }
2215
2216            for input in nl.inputs() {
2217                let input = input.get_identifier();
2218                let stem = input.get_stem();
2219                seen.insert(stem.clone());
2220                let entry = inputs.entry(stem.clone()).or_default();
2221                if let Some(idx) = input.get_bit_index() {
2222                    entry.1 = entry.1.min(idx);
2223                    entry.0 = entry.0.max(idx);
2224                }
2225            }
2226
2227            for obj in nl.objects() {
2228                if !emit_consts
2229                    && obj
2230                        .get_instance_type()
2231                        .and_then(|i| i.get_constant())
2232                        .is_some()
2233                {
2234                    continue;
2235                }
2236
2237                for net in obj.nets() {
2238                    let id = net.get_identifier();
2239                    let stem = id.get_stem();
2240                    if !seen.contains(&stem) {
2241                        let entry = others.entry(stem.clone()).or_default();
2242                        if let Some(idx) = id.get_bit_index() {
2243                            entry.1 = entry.1.min(idx);
2244                            entry.0 = entry.0.max(idx);
2245                        }
2246                    }
2247                }
2248            }
2249
2250            let inputs = inputs
2251                .into_iter()
2252                .map(|(id, (h, l))| {
2253                    if h == l {
2254                        VerilogNet::Net(id)
2255                    } else {
2256                        VerilogNet::Bus(id, (h, l))
2257                    }
2258                })
2259                .collect::<Vec<_>>();
2260
2261            let outputs = outputs
2262                .into_iter()
2263                .map(|(id, (h, l))| {
2264                    if h == l {
2265                        VerilogNet::Net(id)
2266                    } else {
2267                        VerilogNet::Bus(id, (h, l))
2268                    }
2269                })
2270                .collect::<Vec<_>>();
2271
2272            let others = others
2273                .into_iter()
2274                .map(|(id, (h, l))| {
2275                    if h == l {
2276                        VerilogNet::Net(id)
2277                    } else {
2278                        VerilogNet::Bus(id, (h, l))
2279                    }
2280                })
2281                .collect::<Vec<_>>();
2282
2283            (inputs, outputs, others)
2284        }
2285
2286        /// Create a new Verilog emitter for the given netlist
2287        pub fn new(netlist: &'a Netlist<I>, config: VerilogEmitterConfig) -> Self {
2288            let (inputs, outputs, others) = Self::get_nets(netlist, config.emit_const_cells);
2289            Self {
2290                netlist,
2291                config,
2292                inputs,
2293                outputs,
2294                others,
2295            }
2296        }
2297
2298        /// Create a new Verilog emitter for the given netlist with the default options
2299        pub fn new_default(netlist: &'a Netlist<I>) -> Self {
2300            Self::new(netlist, VerilogEmitterConfig::default())
2301        }
2302
2303        /// Use spaces to indent the Verilog
2304        pub fn with_spaces(self) -> Self {
2305            Self {
2306                config: VerilogEmitterConfig {
2307                    indent_char: ' ',
2308                    ..self.config
2309                },
2310                ..self
2311            }
2312        }
2313
2314        /// Use tabs to indent the Verilog
2315        pub fn with_tabs(self) -> Self {
2316            Self {
2317                config: VerilogEmitterConfig {
2318                    indent_char: '\t',
2319                    ..self.config
2320                },
2321                ..self
2322            }
2323        }
2324
2325        /// Set the indentation level
2326        pub fn with_indent(self, width: usize) -> Self {
2327            Self {
2328                config: VerilogEmitterConfig {
2329                    indent_width: width,
2330                    ..self.config
2331                },
2332                ..self
2333            }
2334        }
2335
2336        /// Use ANSI style module declaration
2337        pub fn with_ansi_style(self) -> Self {
2338            Self {
2339                config: VerilogEmitterConfig {
2340                    ansi_style: true,
2341                    ..self.config
2342                },
2343                ..self
2344            }
2345        }
2346
2347        /// Use non-ANSI style module declaration
2348        pub fn with_nonansi_style(self) -> Self {
2349            Self {
2350                config: VerilogEmitterConfig {
2351                    ansi_style: false,
2352                    ..self.config
2353                },
2354                ..self
2355            }
2356        }
2357
2358        /// Emit constants as cells instead of literals
2359        pub fn with_emitted_constants(self) -> Self {
2360            Self {
2361                config: VerilogEmitterConfig {
2362                    emit_const_cells: true,
2363                    ..self.config
2364                },
2365                ..self
2366            }
2367        }
2368    }
2369
2370    impl<'a, I: Instantiable> Analysis<'a, I> for VerilogEmitter<'a, I> {
2371        fn build(netlist: &'a Netlist<I>) -> Result<Self, Error> {
2372            Ok(Self::new_default(netlist))
2373        }
2374    }
2375
2376    impl<'a, I: Instantiable> VerilogEmitter<'a, I> {
2377        fn get_indent(&self, level: usize) -> String {
2378            self.config
2379                .indent_char
2380                .to_string()
2381                .repeat(self.config.indent_width * level)
2382        }
2383
2384        fn emit_ansi_header(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2385            assert!(self.config.ansi_style);
2386
2387            writeln!(f, "module {} (", self.netlist.get_name())?;
2388            let indent = self.get_indent(1);
2389            for input in &self.inputs {
2390                writeln!(f, "{}input {},", indent, input)?;
2391            }
2392            let l = self.outputs.len();
2393            for (i, output) in self.outputs.iter().enumerate() {
2394                write!(f, "{}output {}", indent, output)?;
2395                if i != l - 1 {
2396                    writeln!(f, ",")?;
2397                }
2398            }
2399            writeln!(f)?;
2400            writeln!(f, ");")
2401        }
2402
2403        fn emit_nonansi_header(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2404            assert!(!self.config.ansi_style);
2405
2406            writeln!(f, "module {} (", self.netlist.get_name())?;
2407            let indent = self.get_indent(1);
2408            for input in &self.inputs {
2409                writeln!(f, "{}{},", indent, input.id())?;
2410            }
2411            let l = self.outputs.len();
2412            for (i, output) in self.outputs.iter().enumerate() {
2413                write!(f, "{}{}", indent, output.id())?;
2414                if i != l - 1 {
2415                    writeln!(f, ",")?;
2416                }
2417            }
2418            writeln!(f)?;
2419            writeln!(f, ");")
2420        }
2421
2422        fn emit_net_decls(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2423            let indent = self.get_indent(1);
2424            if !self.config.ansi_style {
2425                for net in &self.inputs {
2426                    writeln!(f, "{}input {};", indent, net)?;
2427                }
2428                for net in &self.outputs {
2429                    writeln!(f, "{}output {};", indent, net)?;
2430                }
2431            }
2432
2433            for net in &self.others {
2434                writeln!(f, "{}{};", indent, net)?;
2435            }
2436            writeln!(f)
2437        }
2438
2439        fn emit_instances(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2440            let indent = self.get_indent(1);
2441            for nr in self
2442                .netlist
2443                .matches(|i| self.config.emit_const_cells || i.get_constant().is_none())
2444            {
2445                for attribute in nr.attributes() {
2446                    if let Some(value) = attribute.value() {
2447                        writeln!(f, "{}(* {} = {} *)", indent, attribute.key(), value)?;
2448                    } else {
2449                        writeln!(f, "{}(* {} *)", indent, attribute.key())?;
2450                    }
2451                }
2452                let inst = nr.get_instance_type().unwrap().clone();
2453                write!(f, "{}{} ", indent, inst.get_name())?;
2454                let params = inst.parameters();
2455                if !params.is_empty() {
2456                    writeln!(f, "#(")?;
2457                    let indent = self.get_indent(2);
2458                    let l = params.len();
2459                    for (i, (k, v)) in params.into_iter().enumerate() {
2460                        write!(f, "{}.{}({})", indent, k, v)?;
2461                        if i != l - 1 {
2462                            writeln!(f, ",")?;
2463                        }
2464                    }
2465                    writeln!(f)?;
2466                    let indent = self.get_indent(1);
2467                    write!(f, "{}) ", indent)?;
2468                }
2469                writeln!(f, "{} (", nr.get_instance_name().unwrap())?;
2470                let indent = self.get_indent(2);
2471                for input in nr.inputs() {
2472                    if let Some(driver) = self.netlist.get_driver(nr.clone(), input.get_input_num())
2473                    {
2474                        let rhs = if !self.config.emit_const_cells
2475                            && let Some(logic) =
2476                                driver.get_instance_type().and_then(|i| i.get_constant())
2477                        {
2478                            logic.to_string()
2479                        } else {
2480                            driver.get_identifier().to_string()
2481                        };
2482
2483                        writeln!(f, "{}.{}({}),", indent, input.get_port(), rhs)?;
2484                    }
2485                }
2486                let outputs = nr.outputs().collect::<Vec<_>>();
2487                let l = outputs.len();
2488                for (i, output) in outputs.into_iter().enumerate() {
2489                    write!(
2490                        f,
2491                        "{}.{}({})",
2492                        indent,
2493                        output.get_port(),
2494                        output.get_identifier()
2495                    )?;
2496                    if i != l - 1 {
2497                        writeln!(f, ",")?;
2498                    }
2499                }
2500                let indent = self.get_indent(1);
2501                writeln!(f)?;
2502                writeln!(f, "{});", indent)?;
2503            }
2504            writeln!(f)
2505        }
2506
2507        fn emit_output_assignments(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2508            let indent = self.get_indent(1);
2509            for (operand, net) in self.netlist.outputs() {
2510                if operand.get_identifier() != *net.get_identifier() {
2511                    let rhs = if !self.config.emit_const_cells
2512                        && let Some(logic) =
2513                            operand.get_instance_type().and_then(|i| i.get_constant())
2514                    {
2515                        logic.to_string()
2516                    } else {
2517                        operand.get_identifier().to_string()
2518                    };
2519                    writeln!(f, "{}assign {} = {};", indent, net.get_identifier(), rhs)?;
2520                }
2521            }
2522            writeln!(f)
2523        }
2524
2525        /// Emit the netlist as a Verilog module
2526        pub fn emit(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2527            if self.config.ansi_style {
2528                self.emit_ansi_header(f)?;
2529            } else {
2530                self.emit_nonansi_header(f)?;
2531            }
2532
2533            self.emit_net_decls(f)?;
2534            self.emit_instances(f)?;
2535            self.emit_output_assignments(f)?;
2536
2537            writeln!(f, "endmodule")
2538        }
2539
2540        /// Emit the netlist to a Verilog string
2541        pub fn emit_to_string(&self) -> String {
2542            self.to_string()
2543        }
2544    }
2545
2546    impl<'a, I: Instantiable> std::fmt::Display for VerilogEmitter<'a, I> {
2547        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2548            self.emit(f)
2549        }
2550    }
2551
2552    /// An RGB color struct
2553    #[cfg(feature = "graph")]
2554    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2555    pub struct RGB {
2556        /// Red channel
2557        pub r: u8,
2558        /// Green channel
2559        pub g: u8,
2560        /// Blue channel
2561        pub b: u8,
2562    }
2563
2564    #[cfg(feature = "graph")]
2565    impl std::fmt::Display for RGB {
2566        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2567            write!(f, "#{:02x}{:02x}{:02x}", self.r, self.g, self.b)
2568        }
2569    }
2570
2571    /// A function that optionally maps an object to a color
2572    #[cfg(feature = "graph")]
2573    pub type ColorFunc<T> = dyn Fn(&T, Option<RGB>) -> Option<RGB>;
2574
2575    /// Emits a graphviz (dot) representation of the netlist
2576    #[cfg(feature = "graph")]
2577    pub struct DotEmitter<'a, I: Instantiable> {
2578        netlist: &'a Netlist<I>,
2579        overrides_netref: HashMap<NetRef<I>, RGB>,
2580        color_netref: Box<ColorFunc<NetRef<I>>>,
2581        color_inst: Box<ColorFunc<I>>,
2582    }
2583
2584    #[cfg(feature = "graph")]
2585    impl<'a, I: Instantiable> DotEmitter<'a, I> {
2586        /// Create a new dot emitter for the given netlist
2587        pub fn new(netlist: &'a Netlist<I>) -> Self {
2588            Self {
2589                netlist,
2590                overrides_netref: HashMap::new(),
2591                color_netref: Box::new(|_, _| None),
2592                color_inst: Box::new(|_, _| None),
2593            }
2594        }
2595
2596        /// Override the color of a specific netref
2597        pub fn override_color(&mut self, netref: NetRef<I>, color: RGB) {
2598            self.overrides_netref.insert(netref, color);
2599        }
2600
2601        /// Color nodes based on [NetRef] properties
2602        pub fn with_net_coloring<F: Fn(&NetRef<I>, Option<RGB>) -> Option<RGB> + 'static>(
2603            self,
2604            f: F,
2605        ) -> Self {
2606            Self {
2607                color_netref: Box::new(f),
2608                ..self
2609            }
2610        }
2611
2612        /// Color nodes based on [Instantiable] properties
2613        pub fn with_instance_coloring<F: Fn(&I, Option<RGB>) -> Option<RGB> + 'static>(
2614            self,
2615            f: F,
2616        ) -> Self {
2617            Self {
2618                color_inst: Box::new(f),
2619                ..self
2620            }
2621        }
2622
2623        fn get_color(&self, netref: &NetRef<I>) -> Option<RGB> {
2624            if let Some(color) = self.overrides_netref.get(netref) {
2625                return Some(*color);
2626            }
2627            let color = match netref.get_instance_type() {
2628                Some(inst) => (self.color_inst)(&inst, None),
2629                None => None,
2630            };
2631            (self.color_netref)(netref, color)
2632        }
2633
2634        /// Emit the netlist as a graphviz / dot
2635        pub fn emit(&self) -> String {
2636            use super::super::graph::{Edge, MultiDiGraph, Node};
2637            use super::Net;
2638            use petgraph::dot::{Config, Dot};
2639            use petgraph::graph::{DiGraph, EdgeReference, NodeIndex};
2640            let analysis = MultiDiGraph::new(self.netlist);
2641            let graph = analysis.get_graph();
2642
2643            let node_impl = |_graph: &DiGraph<Node<I, String>, Edge<I, Net>>,
2644                             node: (NodeIndex, &Node<I, String>)| {
2645                let n = node.1;
2646                let mut attr = String::new();
2647
2648                match n {
2649                    Node::NetRef(nr) if nr.get_instance_type().is_some() => {
2650                        attr += "shape=record, ";
2651                        if let Some(color) = self.get_color(nr) {
2652                            attr += &format!("style=filled, fillcolor=\"{color}\", ");
2653                        }
2654                    }
2655                    _ => attr += "shape=ellipse, ",
2656                }
2657
2658                match n {
2659                    Node::NetRef(nr)
2660                        if let Some(inst_type) = nr.get_instance_type()
2661                            && !inst_type.is_driverless() =>
2662                    {
2663                        let mut record = "{ { ".to_string();
2664
2665                        let l = nr.get_num_input_ports();
2666                        for (i, port) in nr.inputs().enumerate() {
2667                            let id = port.get_port().get_identifier().clone();
2668                            record += &format!("{{ <{}> {} }}", id, id);
2669
2670                            if i != l - 1 {
2671                                record += " | ";
2672                            }
2673                        }
2674
2675                        record += &format!(
2676                            " }} | {}({}) }}",
2677                            inst_type.get_name(),
2678                            nr.get_instance_name().unwrap()
2679                        );
2680                        attr += &format!("label=\"{record}\"");
2681                    }
2682                    _ => attr += &format!("label=\"{n}\""),
2683                }
2684
2685                attr
2686            };
2687
2688            fn edge_impl<I: Instantiable>(
2689                _graph: &DiGraph<Node<I, String>, Edge<I, Net>>,
2690                edge: EdgeReference<Edge<I, Net>>,
2691            ) -> String {
2692                match edge.weight() {
2693                    Edge::Connection(c) => {
2694                        format!(", port=\"{}\"", c.target().get_port().get_identifier())
2695                    }
2696                    _ => String::new(),
2697                }
2698            }
2699
2700            let dot =
2701                Dot::with_attr_getters(graph, &[Config::NodeNoLabel], &edge_impl::<I>, &node_impl);
2702
2703            // Post-process to add port specifiers to the edges.
2704            let mut result = String::new();
2705            for line in dot.to_string().lines() {
2706                if line.contains("->") && line.contains("port=") {
2707                    let port = line
2708                        .split("port=\"")
2709                        .nth(1)
2710                        .unwrap()
2711                        .split('"')
2712                        .next()
2713                        .unwrap();
2714                    let (l, r) = line.split_once("->").unwrap();
2715                    let (l, r) = (l, r.trim());
2716                    let (d, r) = r.split_once(" ").unwrap();
2717                    result += &format!("{l}-> {d}:{port} {r}\n");
2718                } else {
2719                    result += line;
2720                    result += "\n";
2721                }
2722            }
2723
2724            result
2725        }
2726    }
2727
2728    #[cfg(feature = "graph")]
2729    impl<'a, I: Instantiable> std::fmt::Display for DotEmitter<'a, I> {
2730        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2731            write!(f, "{}", self.emit())
2732        }
2733    }
2734}
2735
2736/// Strategies for fast batching netlist rewrites
2737pub mod rewriter {
2738    use super::{DrivenNet, Error, Instantiable, NetRef, Netlist, Operand};
2739    use crate::graph::FanOutTable;
2740    use std::collections::HashMap;
2741    use std::rc::Rc;
2742
2743    /// Uses a union-find to batch replacements in a netlist closer to O(n) time.
2744    /// The replacement only considers the uses of a net that existed at the time of creation of [NetMapper].
2745    /// Connections created after the creation of the [NetMapper] will not be replaced.
2746    pub struct NetMapper<'a, I: Instantiable> {
2747        parent: HashMap<DrivenNet<I>, DrivenNet<I>>,
2748        netlist: &'a Netlist<I>,
2749        fanout: FanOutTable<'a, I>,
2750    }
2751
2752    impl<'a, I: Instantiable> NetMapper<'a, I> {
2753        /// Create a new empty mapper.
2754        pub fn new(netlist: &'a Netlist<I>) -> Result<Self, Error> {
2755            Ok(Self {
2756                parent: HashMap::new(),
2757                netlist,
2758                fanout: netlist.get_analysis::<FanOutTable<I>>()?,
2759            })
2760        }
2761
2762        /// Get the final replacement for the net
2763        pub fn find(&self, x: DrivenNet<I>) -> DrivenNet<I> {
2764            let mut root = x;
2765            while let Some(p) = self.parent.get(&root) {
2766                root = p.clone();
2767            }
2768            root
2769        }
2770
2771        /// Add a replacement to the mapper. Returns an error if the replacement creates a cycle.
2772        ///
2773        /// # Panics
2774        /// If `of` was already mapped to `with`
2775        pub fn replace(&mut self, of: DrivenNet<I>, with: DrivenNet<I>) -> DrivenNet<I> {
2776            let of_root = self.find(of.clone());
2777            let with_root = self.find(with);
2778            if of_root == with_root {
2779                panic!("Already mapped by NetMapper: {of}");
2780            }
2781            self.parent.insert(of_root, with_root);
2782            of
2783        }
2784
2785        /// Apply the replacements to the netlist.
2786        /// Returns the nets that were replaced.
2787        pub fn apply(self) -> Result<Vec<DrivenNet<I>>, Error> {
2788            // Build the one-pass map
2789            let mut map: HashMap<Operand, Operand> = HashMap::new();
2790            for k in self.parent.keys().cloned() {
2791                let v = self.find(k.clone());
2792                if k != v {
2793                    map.insert(k.get_operand(), v.get_operand());
2794                }
2795            }
2796
2797            drop(self.parent);
2798
2799            // Check that replacements are all valid
2800            for (of, with) in map.iter() {
2801                let unwrapped = self.netlist.objects.borrow()[of.root()].clone();
2802                let i = of.secondary();
2803                let k = of.secondary();
2804                let nr = NetRef::wrap(unwrapped.clone());
2805
2806                if of.root() == with.root() {
2807                    if i == k {
2808                        continue;
2809                    }
2810
2811                    if Rc::strong_count(&unwrapped) - self.fanout.get_ref_count(&nr) > 4 {
2812                        return Err(Error::DanglingReference(nr.nets().collect()));
2813                    }
2814                } else if Rc::strong_count(&unwrapped) - self.fanout.get_ref_count(&nr) > 3 {
2815                    return Err(Error::DanglingReference(nr.nets().collect()));
2816                }
2817
2818                let old_index = of;
2819                let of = DrivenNet::new(i, nr);
2820
2821                if let Some(nets) = self.netlist.outputs.borrow().get(old_index)
2822                    && nets.contains(&of.as_net())
2823                {
2824                    if of.is_an_input() {
2825                        return Err(Error::NonuniqueNets(nets.iter().cloned().collect()));
2826                    } else {
2827                        let id = of.as_net().get_identifier().clone() + "_replaced".into();
2828                        of.as_net_mut().set_identifier(id);
2829                    }
2830                }
2831            }
2832
2833            let objects = self.netlist.objects.borrow();
2834            for (of, &with) in map.iter() {
2835                let of = DrivenNet::new(of.secondary(), NetRef::wrap(objects[of.root()].clone()));
2836                for u in self.fanout.get_users(&of) {
2837                    let place = u.pos;
2838                    let u = u.unwrap().unwrap();
2839                    let operands = &mut u.borrow_mut().operands;
2840                    operands[place] = Some(with);
2841                }
2842            }
2843
2844            for (of, &with) in map.iter() {
2845                // Move all the old outputs to the new key
2846                let outs = self.netlist.outputs.borrow_mut().remove(of);
2847                if let Some(outs) = outs {
2848                    self.netlist
2849                        .outputs
2850                        .borrow_mut()
2851                        .entry(with)
2852                        .or_default()
2853                        .extend(outs);
2854                }
2855            }
2856
2857            let res: Vec<_> = map
2858                .into_keys()
2859                .map(|operand| {
2860                    DrivenNet::new(
2861                        operand.secondary(),
2862                        NetRef::wrap(self.netlist.objects.borrow()[operand.root()].clone()),
2863                    )
2864                })
2865                .collect();
2866
2867            Ok(res)
2868        }
2869    }
2870}
2871
2872/// A collection of iterators for the netlist
2873pub mod iter {
2874
2875    use super::{
2876        Connection, DrivenNet, InputPort, Instantiable, Net, NetRef, Netlist, Operand, WeakIndex,
2877    };
2878    use std::collections::{HashMap, HashSet};
2879    /// An iterator over the nets in a netlist
2880    pub struct NetIterator<'a, I: Instantiable> {
2881        netlist: &'a Netlist<I>,
2882        index: usize,
2883        subindex: usize,
2884    }
2885
2886    impl<'a, I> NetIterator<'a, I>
2887    where
2888        I: Instantiable,
2889    {
2890        /// Creates a new iterator for the netlist
2891        pub fn new(netlist: &'a Netlist<I>) -> Self {
2892            Self {
2893                netlist,
2894                index: 0,
2895                subindex: 0,
2896            }
2897        }
2898    }
2899
2900    impl<I> Iterator for NetIterator<'_, I>
2901    where
2902        I: Instantiable,
2903    {
2904        type Item = Net;
2905
2906        fn next(&mut self) -> Option<Self::Item> {
2907            while self.index < self.netlist.objects.borrow().len() {
2908                let objects = self.netlist.objects.borrow();
2909                let object = objects[self.index].borrow();
2910                if self.subindex < object.get().get_nets().len() {
2911                    let net = object.get().get_nets()[self.subindex].clone();
2912                    self.subindex += 1;
2913                    return Some(net);
2914                }
2915                self.subindex = 0;
2916                self.index += 1;
2917            }
2918            None
2919        }
2920    }
2921
2922    /// An iterator over the objects in a netlist
2923    pub struct ObjectIterator<'a, I: Instantiable> {
2924        netlist: &'a Netlist<I>,
2925        index: usize,
2926    }
2927
2928    impl<'a, I> ObjectIterator<'a, I>
2929    where
2930        I: Instantiable,
2931    {
2932        /// Creates a new  object iterator for the netlist
2933        pub fn new(netlist: &'a Netlist<I>) -> Self {
2934            Self { netlist, index: 0 }
2935        }
2936    }
2937
2938    impl<I> Iterator for ObjectIterator<'_, I>
2939    where
2940        I: Instantiable,
2941    {
2942        type Item = NetRef<I>;
2943
2944        fn next(&mut self) -> Option<Self::Item> {
2945            if self.index < self.netlist.objects.borrow().len() {
2946                let objects = self.netlist.objects.borrow();
2947                let object = &objects[self.index];
2948                self.index += 1;
2949                return Some(NetRef::wrap(object.clone()));
2950            }
2951            None
2952        }
2953    }
2954
2955    /// An iterator over the connections in a netlist
2956    pub struct ConnectionIterator<'a, I: Instantiable> {
2957        netlist: &'a Netlist<I>,
2958        index: usize,
2959        subindex: usize,
2960    }
2961
2962    impl<'a, I> ConnectionIterator<'a, I>
2963    where
2964        I: Instantiable,
2965    {
2966        /// Create a new connection iterator for the netlist
2967        pub fn new(netlist: &'a Netlist<I>) -> Self {
2968            Self {
2969                netlist,
2970                index: 0,
2971                subindex: 0,
2972            }
2973        }
2974    }
2975
2976    impl<I> Iterator for ConnectionIterator<'_, I>
2977    where
2978        I: Instantiable,
2979    {
2980        type Item = super::Connection<I>;
2981
2982        fn next(&mut self) -> Option<Self::Item> {
2983            while self.index < self.netlist.objects.borrow().len() {
2984                let objects = self.netlist.objects.borrow();
2985                let object = objects[self.index].borrow();
2986                let noperands = object.operands.len();
2987                while self.subindex < noperands {
2988                    if let Some(operand) = &object.operands[self.subindex] {
2989                        let driver = match operand {
2990                            Operand::DirectIndex(idx) => {
2991                                DrivenNet::new(0, NetRef::wrap(objects[*idx].clone()))
2992                            }
2993                            Operand::CellIndex(idx, j) => {
2994                                DrivenNet::new(*j, NetRef::wrap(objects[*idx].clone()))
2995                            }
2996                        };
2997                        let input = InputPort::new(
2998                            self.subindex,
2999                            NetRef::wrap(objects[self.index].clone()),
3000                        );
3001                        self.subindex += 1;
3002                        return Some(Connection::new(driver, input));
3003                    }
3004                    self.subindex += 1;
3005                }
3006                self.subindex = 0;
3007                self.index += 1;
3008            }
3009            None
3010        }
3011    }
3012
3013    /// A stack that can check contains in roughly O(1) time.
3014    #[derive(Clone)]
3015    struct Walk<T: std::hash::Hash + PartialEq + Eq + Clone> {
3016        stack: Vec<T>,
3017        counter: HashMap<T, usize>,
3018    }
3019
3020    impl<T> Walk<T>
3021    where
3022        T: std::hash::Hash + PartialEq + Eq + Clone,
3023    {
3024        /// Create a new, empty Stack.
3025        fn new() -> Self {
3026            Self {
3027                stack: Vec::new(),
3028                counter: HashMap::new(),
3029            }
3030        }
3031
3032        /// Inserts an element into the stack
3033        fn push(&mut self, item: T) {
3034            self.stack.push(item.clone());
3035            *self.counter.entry(item).or_insert(0) += 1;
3036        }
3037
3038        /// Returns true if the stack shows a cycle
3039        fn contains_cycle(&self) -> bool {
3040            self.counter.values().any(|&count| count > 1)
3041        }
3042
3043        /// Returns true if the stack contains a cycle to the root node
3044        fn root_cycle(&self) -> bool {
3045            if self.stack.is_empty() {
3046                return false;
3047            }
3048            self.counter[&self.stack[0]] > 1
3049        }
3050
3051        /// Returns a reference to the last element in the stack
3052        fn last(&self) -> Option<&T> {
3053            self.stack.last()
3054        }
3055    }
3056
3057    /// A depth-first iterator over the circuit nodes in a netlist
3058    /// # Examples
3059    ///
3060    /// ```
3061    /// use safety_net::iter::DFSIterator;
3062    /// use safety_net::GateNetlist;
3063    ///
3064    /// let netlist = GateNetlist::new("example".into());
3065    /// netlist.insert_input("input1".into());
3066    /// let mut nodes = Vec::new();
3067    /// let mut dfs = DFSIterator::new(&netlist, netlist.last().unwrap());
3068    /// while let Some(n) = dfs.next() {
3069    ///     if dfs.check_cycles() {
3070    ///         panic!("Cycle detected in the netlist");
3071    ///     }
3072    ///     nodes.push(n);
3073    /// }
3074    /// ```
3075    pub struct DFSIterator<'a, I: Instantiable> {
3076        dfs: NetDFSIterator<'a, I>,
3077        seen: HashSet<NetRef<I>>,
3078    }
3079
3080    impl<'a, I> DFSIterator<'a, I>
3081    where
3082        I: Instantiable,
3083    {
3084        /// Create a new DFS iterator for the netlist starting at `from`.
3085        pub fn new(netlist: &'a Netlist<I>, from: NetRef<I>) -> Self {
3086            Self {
3087                dfs: NetDFSIterator::new(netlist, DrivenNet::new(0, from)),
3088                seen: HashSet::new(),
3089            }
3090        }
3091    }
3092
3093    impl<I> DFSIterator<'_, I>
3094    where
3095        I: Instantiable,
3096    {
3097        /// Check if the DFS traversal has encountered a cycle yet.
3098        pub fn check_cycles(&self) -> bool {
3099            self.dfs.check_cycles()
3100        }
3101
3102        /// Consumes the iterator to detect cycles in the netlist.
3103        pub fn detect_cycles(self) -> bool {
3104            self.dfs.detect_cycles()
3105        }
3106
3107        /// Check if the DFS traversal has encountered the root `from`` again.
3108        pub fn check_self_loop(&self) -> bool {
3109            self.dfs.check_self_loop()
3110        }
3111
3112        /// Consumes the iterator to detect if the DFS traversal will encounter the root `from` again.
3113        pub fn detect_self_loop(self) -> bool {
3114            self.dfs.detect_self_loop()
3115        }
3116    }
3117
3118    impl<I> Iterator for DFSIterator<'_, I>
3119    where
3120        I: Instantiable,
3121    {
3122        type Item = NetRef<I>;
3123
3124        fn next(&mut self) -> Option<Self::Item> {
3125            let d = self.dfs.next()?;
3126            if self.seen.insert(d.clone().unwrap()) {
3127                Some(d.unwrap())
3128            } else {
3129                self.next()
3130            }
3131        }
3132    }
3133
3134    type TermFn<I> = Box<dyn Fn(&DrivenNet<I>) -> bool + 'static>;
3135
3136    /// Depth-first iterator that works like DFSIterator but iterates over DrivenNet
3137    pub struct NetDFSIterator<'a, I: Instantiable> {
3138        netlist: &'a Netlist<I>,
3139        stacks: Vec<Walk<DrivenNet<I>>>,
3140        visited: HashSet<usize>,
3141        visited_net: HashSet<(usize, usize)>,
3142        any_cycle: bool,
3143        root_cycle: bool,
3144        terminate: TermFn<I>,
3145    }
3146
3147    impl<'a, I> NetDFSIterator<'a, I>
3148    where
3149        I: Instantiable,
3150    {
3151        /// Create a new DFS DrivenNet iterator for the netlist starting at `from`, ignoring all dependencies beyond the `terminate` condition.
3152        /// Terminators themselves *are* included in the iteration.
3153        pub fn new_filtered<F: Fn(&DrivenNet<I>) -> bool + 'static>(
3154            netlist: &'a Netlist<I>,
3155            from: DrivenNet<I>,
3156            terminate: F,
3157        ) -> Self {
3158            let mut s = Walk::new();
3159            s.push(from);
3160            Self {
3161                netlist,
3162                stacks: vec![s],
3163                visited: HashSet::new(),
3164                visited_net: HashSet::new(),
3165                any_cycle: false,
3166                root_cycle: false,
3167                terminate: Box::new(terminate),
3168            }
3169        }
3170
3171        /// Create a new DFS DrivenNet iterator for the netlist starting at `from`.
3172        pub fn new(netlist: &'a Netlist<I>, from: DrivenNet<I>) -> Self {
3173            Self::new_filtered(netlist, from, |_| false)
3174        }
3175    }
3176
3177    impl<I> NetDFSIterator<'_, I>
3178    where
3179        I: Instantiable,
3180    {
3181        /// Check if the DFS traversal has encountered a cycle yet.
3182        pub fn check_cycles(&self) -> bool {
3183            self.any_cycle
3184        }
3185
3186        /// Consumes the iterator to detect cycles in the netlist.
3187        pub fn detect_cycles(mut self) -> bool {
3188            if self.any_cycle {
3189                return true;
3190            }
3191
3192            while let Some(_) = self.next() {
3193                if self.any_cycle {
3194                    return true;
3195                }
3196            }
3197
3198            self.any_cycle
3199        }
3200
3201        /// Check if the DFS traversal has encountered the root `from` again.
3202        pub fn check_self_loop(&self) -> bool {
3203            self.root_cycle
3204        }
3205
3206        /// Consumes the iterator to detect if the DFS traversal will encounter the root `from` again.
3207        pub fn detect_self_loop(mut self) -> bool {
3208            if self.root_cycle {
3209                return true;
3210            }
3211
3212            while let Some(_) = self.next() {
3213                if self.root_cycle {
3214                    return true;
3215                }
3216            }
3217
3218            self.root_cycle
3219        }
3220    }
3221
3222    impl<I> Iterator for NetDFSIterator<'_, I>
3223    where
3224        I: Instantiable,
3225    {
3226        type Item = DrivenNet<I>;
3227
3228        fn next(&mut self) -> Option<Self::Item> {
3229            if let Some(walk) = self.stacks.pop() {
3230                self.any_cycle |= walk.contains_cycle();
3231                self.root_cycle |= walk.root_cycle();
3232                let item = walk.last().cloned();
3233                let uw = item.clone().unwrap().unwrap().unwrap();
3234                let index = uw.borrow().get_index();
3235                let secondary = item.as_ref().unwrap().pos;
3236                if self.visited.insert(index) {
3237                    if !(self.terminate)(item.as_ref().unwrap()) {
3238                        let operands = &uw.borrow().operands;
3239                        for operand in operands.iter().flatten() {
3240                            let mut new_walk = walk.clone();
3241                            new_walk.push(DrivenNet::new(
3242                                operand.secondary(),
3243                                NetRef::wrap(self.netlist.index_weak(&operand.root())),
3244                            ));
3245                            self.stacks.push(new_walk);
3246                        }
3247                    }
3248                    self.visited_net.insert((index, secondary));
3249                    return item;
3250                }
3251
3252                if self.visited_net.insert((index, secondary)) {
3253                    return item;
3254                }
3255
3256                return self.next();
3257            }
3258
3259            None
3260        }
3261    }
3262}
3263
3264impl<'a, I> IntoIterator for &'a Netlist<I>
3265where
3266    I: Instantiable,
3267{
3268    type Item = Net;
3269    type IntoIter = iter::NetIterator<'a, I>;
3270
3271    fn into_iter(self) -> Self::IntoIter {
3272        iter::NetIterator::new(self)
3273    }
3274}
3275
3276/// Filter invariants of [Instantiable] in a netlist. Use it like you would `matches!`.
3277/// Example: ```filter_nodes!(netlist, Gate::AND(_));```
3278#[macro_export]
3279macro_rules! filter_nodes {
3280    ($netlist:ident, $pattern:pat $(if $guard:expr)? $(,)?) => {
3281        $netlist.matches(|f| match f {
3282            $pattern $(if $guard)? => true,
3283            _ => false
3284        })
3285    };
3286}
3287
3288impl<I> Netlist<I>
3289where
3290    I: Instantiable,
3291{
3292    /// Returns an iterator over the circuit nodes in the netlist.
3293    pub fn objects(&self) -> impl Iterator<Item = NetRef<I>> {
3294        iter::ObjectIterator::new(self)
3295    }
3296
3297    /// Returns an iterator over the circuit nodes that match the instance type.
3298    pub fn matches<F>(&self, filter: F) -> impl Iterator<Item = NetRef<I>>
3299    where
3300        F: Fn(&I) -> bool,
3301    {
3302        self.objects().filter(move |f| {
3303            if let Some(inst_type) = f.get_instance_type() {
3304                filter(&inst_type)
3305            } else {
3306                false
3307            }
3308        })
3309    }
3310
3311    /// Returns an iterator to principal inputs in the netlist as references.
3312    pub fn inputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
3313        self.objects()
3314            .filter(|n| n.is_an_input())
3315            .map(|n| DrivenNet::new(0, n))
3316    }
3317
3318    /// Returns an iterator to circuit nodes that drive an output in the netlist.
3319    pub fn outputs(&self) -> Vec<(DrivenNet<I>, Net)> {
3320        self.outputs
3321            .borrow()
3322            .iter()
3323            .flat_map(|(k, nets)| {
3324                nets.iter().map(|n| {
3325                    (
3326                        DrivenNet::new(k.secondary(), NetRef::wrap(self.index_weak(&k.root()))),
3327                        n.clone(),
3328                    )
3329                })
3330            })
3331            .collect()
3332    }
3333
3334    /// Returns an iterator over the wire connections in the netlist.
3335    pub fn connections(&self) -> impl Iterator<Item = Connection<I>> {
3336        iter::ConnectionIterator::new(self)
3337    }
3338
3339    /// Returns a depth-first search iterator over the nodes in the netlist.
3340    ///
3341    /// # Panics
3342    /// `from` does not belong to this netlist
3343    pub fn node_dfs(&self, from: NetRef<I>) -> impl Iterator<Item = NetRef<I>> {
3344        self.belongs(&from);
3345        iter::DFSIterator::new(self, from)
3346    }
3347
3348    /// Returns a depth-first search iterator over the nodes in the netlist, with the nodes in DrivenNet form.
3349    ///
3350    /// # Panics
3351    /// `from` does not belong to this netlist
3352    pub fn net_dfs(&self, from: DrivenNet<I>) -> impl Iterator<Item = DrivenNet<I>> {
3353        self.belongs(&from.clone().unwrap());
3354        iter::NetDFSIterator::new(self, from)
3355    }
3356
3357    #[cfg(feature = "serde")]
3358    /// Serializes the netlist to a writer.
3359    pub fn serialize(self, writer: impl std::io::Write) -> Result<(), serde_json::Error>
3360    where
3361        I: ::serde::Serialize,
3362    {
3363        serde::netlist_serialize(self, writer)
3364    }
3365
3366    #[cfg(feature = "graph")]
3367    /// Converts the current configuration of the netlist to a graphviz string
3368    pub fn dot_string(&self) -> String {
3369        use emitter::DotEmitter;
3370        let emitter = DotEmitter::new(self);
3371        emitter.emit()
3372    }
3373
3374    #[cfg(feature = "graph")]
3375    /// Dumps the current netlist to <module_name>.dot in the current working directory.
3376    pub fn dump_dot(&self) -> std::io::Result<()> {
3377        use std::io::Write;
3378        let mut dir = std::env::current_dir()?;
3379        let mod_name = format!("{}.dot", self.get_name());
3380        dir.push(mod_name);
3381        let mut file = std::fs::File::create(dir)?;
3382        let dot = self.dot_string();
3383        write!(file, "{dot}")
3384    }
3385}
3386
3387impl<I> std::fmt::Display for Netlist<I>
3388where
3389    I: Instantiable,
3390{
3391    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3392        use emitter::{VerilogEmitter, VerilogEmitterConfig};
3393        let emitter = VerilogEmitter::new(self, VerilogEmitterConfig::legacy());
3394        emitter.fmt(f)
3395    }
3396}
3397
3398/// A type alias for a netlist of gates
3399pub type GateNetlist = Netlist<Gate>;
3400/// A type alias to Gate circuit nodes
3401pub type GateRef = NetRef<Gate>;
3402
3403#[cfg(test)]
3404mod tests {
3405    use super::iter::{DFSIterator, NetDFSIterator};
3406    use super::*;
3407    #[test]
3408    fn test_delete_netlist() {
3409        let netlist = Netlist::new("simple_example".into());
3410
3411        // Add the the two inputs
3412        let input1 = netlist.insert_input("input1".into());
3413        let input2 = netlist.insert_input("input2".into());
3414
3415        // Instantiate an AND gate
3416        let instance = netlist
3417            .insert_gate(
3418                Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3419                "my_and".into(),
3420                &[input1.clone(), input2.clone()],
3421            )
3422            .unwrap();
3423
3424        // Make this AND gate an output
3425        let instance = instance.expose_as_output().unwrap();
3426        instance.delete_uses().unwrap();
3427        // We can still clean this mostly empty netlist
3428        assert!(netlist.clean().is_ok());
3429        input1.expose_with_name("an_output".into());
3430        assert!(netlist.clean().is_ok());
3431    }
3432
3433    #[test]
3434    #[should_panic(expected = "Attempted to create a gate with a sliced identifier")]
3435    fn gate_w_slice_panics() {
3436        Gate::new_logical("AND[1]".into(), vec!["A".into(), "B".into()], "Y".into());
3437    }
3438
3439    #[test]
3440    fn gates_dont_have_params() {
3441        // The baseline implementation of gates do not have parameters.
3442        let gate = Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into());
3443        assert!(!gate.has_parameter(&"id".into()));
3444        assert!(gate.get_parameter(&"id".into()).is_none());
3445        assert_eq!(*gate.get_gate_name(), "AND".into());
3446    }
3447
3448    #[test]
3449    fn operand_conversions() {
3450        let operand = Operand::CellIndex(3, 2);
3451        assert_eq!(operand.to_string(), "3.2");
3452        let parsed = "3.2".parse::<Operand>();
3453        assert!(parsed.is_ok());
3454        let parsed = parsed.unwrap();
3455        assert_eq!(operand, parsed);
3456    }
3457
3458    #[test]
3459    #[should_panic(expected = "out of bounds for netref")]
3460    fn test_bad_output() {
3461        let netlist = GateNetlist::new("min_module".into());
3462        let a = netlist.insert_input("a".into());
3463        DrivenNet::new(1, a.unwrap());
3464    }
3465
3466    #[test]
3467    fn test_netdfsiterator() {
3468        let netlist = Netlist::new("dfs_netlist".into());
3469
3470        // inputs
3471        let a = netlist.insert_input("a".into());
3472        let b = netlist.insert_input("b".into());
3473        let c = netlist.insert_input("c".into());
3474        let d = netlist.insert_input("d".into());
3475        let e = netlist.insert_input("e".into());
3476
3477        // gates
3478        let n1 = netlist
3479            .insert_gate(
3480                Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into()),
3481                "n1".into(),
3482                &[a.clone(), b.clone()],
3483            )
3484            .unwrap()
3485            .get_output(0);
3486        let n2 = netlist
3487            .insert_gate(
3488                Gate::new_logical("NOR".into(), vec!["A".into(), "B".into()], "Y".into()),
3489                "n2".into(),
3490                &[d.clone(), e.clone()],
3491            )
3492            .unwrap()
3493            .get_output(0);
3494        let n3 = netlist
3495            .insert_gate(
3496                Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3497                "n3".into(),
3498                &[n1.clone(), c.clone()],
3499            )
3500            .unwrap()
3501            .get_output(0);
3502        let n4 = netlist
3503            .insert_gate(
3504                Gate::new_logical("NAND".into(), vec!["A".into(), "B".into()], "Y".into()),
3505                "n4".into(),
3506                &[n3.clone(), n2.clone()],
3507            )
3508            .unwrap()
3509            .get_output(0);
3510        n4.clone().expose_with_name("y".into());
3511
3512        // test DFSIterator
3513        let mut dfs = NetDFSIterator::new(&netlist, n4.clone());
3514        assert_eq!(dfs.next(), Some(n4));
3515        assert_eq!(dfs.next(), Some(n2));
3516        assert_eq!(dfs.next(), Some(e));
3517        assert_eq!(dfs.next(), Some(d));
3518        assert_eq!(dfs.next(), Some(n3));
3519        assert_eq!(dfs.next(), Some(c));
3520        assert_eq!(dfs.next(), Some(n1));
3521        assert_eq!(dfs.next(), Some(b));
3522        assert_eq!(dfs.next(), Some(a));
3523        assert_eq!(dfs.next(), None);
3524    }
3525
3526    #[test]
3527    fn test_dfs_cycles() {
3528        let netlist = Netlist::new("dfs_cycles".into());
3529
3530        // inputs
3531        let a = netlist.insert_input("a".into());
3532
3533        // gates
3534        let and = netlist.insert_gate_disconnected(
3535            Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3536            "and".into(),
3537        );
3538
3539        // connect and form cycle
3540        a.connect(and.get_input(0));
3541        and.get_output(0).connect(and.get_input(1));
3542
3543        // test dfs iterators
3544        let dfs = DFSIterator::new(&netlist, and.clone());
3545        let driven_dfs = NetDFSIterator::new(&netlist, and.get_output(0));
3546
3547        assert!(dfs.detect_cycles());
3548        assert!(driven_dfs.detect_cycles());
3549    }
3550
3551    #[test]
3552    fn test_netdfsiterator_with_boundary() {
3553        let netlist = Netlist::new("dfs_netlist".into());
3554
3555        // inputs
3556        let a = netlist.insert_input("a".into());
3557        let b = netlist.insert_input("b".into());
3558        let c = netlist.insert_input("c".into());
3559        let d = netlist.insert_input("d".into());
3560        let e = netlist.insert_input("e".into());
3561
3562        // gates
3563        let n1 = netlist
3564            .insert_gate(
3565                Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into()),
3566                "n1".into(),
3567                &[a.clone(), b.clone()],
3568            )
3569            .unwrap()
3570            .get_output(0);
3571        let n2 = netlist
3572            .insert_gate(
3573                Gate::new_logical("NOR".into(), vec!["A".into(), "B".into()], "Y".into()),
3574                "n2".into(),
3575                &[d.clone(), e.clone()],
3576            )
3577            .unwrap()
3578            .get_output(0);
3579        let n3 = netlist
3580            .insert_gate(
3581                Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3582                "n3".into(),
3583                &[n1.clone(), c.clone()],
3584            )
3585            .unwrap()
3586            .get_output(0);
3587        let n4 = netlist
3588            .insert_gate(
3589                Gate::new_logical("NAND".into(), vec!["A".into(), "B".into()], "Y".into()),
3590                "n4".into(),
3591                &[n3.clone(), n2.clone()],
3592            )
3593            .unwrap()
3594            .get_output(0);
3595
3596        // Stop DFS expansion at n3 to emulate a traversal boundary.
3597        let n3_boundary = n3.clone();
3598        let mut dfs =
3599            NetDFSIterator::new_filtered(&netlist, n4.clone(), move |n| *n == n3_boundary);
3600        assert_eq!(dfs.next(), Some(n4));
3601        assert_eq!(dfs.next(), Some(n2));
3602        assert_eq!(dfs.next(), Some(e));
3603        assert_eq!(dfs.next(), Some(d));
3604        assert_eq!(dfs.next(), Some(n3));
3605        assert_eq!(dfs.next(), None);
3606    }
3607
3608    #[test]
3609    fn test_dfs_convergence() {
3610        let netlist = GateNetlist::new("example".into());
3611        let gate = Gate::new_logical_multi(
3612            "FA".into(),
3613            vec!["A".into(), "B".into()],
3614            vec!["S".into(), "COUT".into()],
3615        );
3616        let a = netlist.insert_input("a".into());
3617        let b = netlist.insert_input("b".into());
3618        let gate = netlist.insert_gate(gate, "g".into(), &[a, b]).unwrap();
3619        let s = gate.get_output(0);
3620        let c = gate.get_output(1);
3621        let gate = Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into());
3622        let d = netlist.insert_gate(gate, "h".into(), &[s, c]).unwrap();
3623
3624        let dfs = NetDFSIterator::new(&netlist, d.get_output(0));
3625        let c = dfs.count();
3626        assert_eq!(c, 5);
3627
3628        let dfs = DFSIterator::new(&netlist, d.clone());
3629        let c = dfs.count();
3630        assert_eq!(c, 4);
3631    }
3632
3633    #[test]
3634    fn test_operand_comparison() {
3635        let a = Operand::CellIndex(3, 0);
3636        let b = Operand::DirectIndex(3);
3637        assert_eq!(a.cmp(&b), std::cmp::Ordering::Greater);
3638        assert_eq!(b.cmp(&a), std::cmp::Ordering::Less);
3639    }
3640}
3641#[cfg(feature = "serde")]
3642/// Serde support for netlists
3643pub mod serde {
3644    use super::{Identifier, Netlist, Operand, OwnedObject, WeakIndex};
3645    use crate::{
3646        attribute::{AttributeKey, AttributeValue},
3647        circuit::{Instantiable, Net, Object},
3648    };
3649    use serde::{Deserialize, Serialize, de::DeserializeOwned};
3650    use std::cell::RefCell;
3651    use std::{
3652        collections::{BTreeMap, BTreeSet},
3653        rc::Rc,
3654    };
3655
3656    #[derive(Debug, Serialize, Deserialize)]
3657    struct SerdeObject<I>
3658    where
3659        I: Instantiable + Serialize,
3660    {
3661        /// The object that is owned by the netlist
3662        object: Object<I>,
3663        /// The list of operands for the object
3664        operands: Vec<Option<Operand>>,
3665        /// A collection of attributes for the object
3666        attributes: BTreeMap<AttributeKey, AttributeValue>,
3667    }
3668
3669    impl<I, O> From<OwnedObject<I, O>> for SerdeObject<I>
3670    where
3671        I: Instantiable + Serialize,
3672        O: WeakIndex<usize, Output = OwnedObject<I, O>>,
3673    {
3674        fn from(value: OwnedObject<I, O>) -> Self {
3675            SerdeObject {
3676                object: value.object,
3677                operands: value.operands,
3678                attributes: value.attributes,
3679            }
3680        }
3681    }
3682
3683    impl<I> SerdeObject<I>
3684    where
3685        I: Instantiable + Serialize,
3686    {
3687        fn into_owned_object<O>(self, owner: &Rc<O>, index: usize) -> OwnedObject<I, O>
3688        where
3689            O: WeakIndex<usize, Output = OwnedObject<I, O>>,
3690        {
3691            OwnedObject {
3692                object: self.object,
3693                owner: Rc::downgrade(owner),
3694                operands: self.operands,
3695                attributes: self.attributes,
3696                index,
3697            }
3698        }
3699    }
3700
3701    #[derive(Debug, Serialize, Deserialize)]
3702    struct SerdeNetlist<I>
3703    where
3704        I: Instantiable + Serialize,
3705    {
3706        /// The name of the netlist
3707        name: Identifier,
3708        /// The list of objects in the netlist, such as inputs, modules, and primitives
3709        objects: Vec<SerdeObject<I>>,
3710        /// The list of operands that point to objects which are outputs.
3711        /// Indices must be a string if we want to support JSON.
3712        /// Each operand can map to multiple nets, supporting output aliases.
3713        outputs: BTreeMap<String, BTreeSet<Net>>,
3714    }
3715
3716    impl<I> From<Netlist<I>> for SerdeNetlist<I>
3717    where
3718        I: Instantiable + Serialize,
3719    {
3720        fn from(value: Netlist<I>) -> Self {
3721            SerdeNetlist {
3722                name: value.name.into_inner(),
3723                objects: value
3724                    .objects
3725                    .into_inner()
3726                    .into_iter()
3727                    .map(|o| {
3728                        Rc::try_unwrap(o)
3729                            .ok()
3730                            .expect("Cannot serialize with live references")
3731                            .into_inner()
3732                            .into()
3733                    })
3734                    .collect(),
3735                outputs: value
3736                    .outputs
3737                    .into_inner()
3738                    .into_iter()
3739                    // Indices must be a string if we want to support JSON.
3740                    .map(|(o, nets)| (o.to_string(), nets.into_iter().collect()))
3741                    .collect(),
3742            }
3743        }
3744    }
3745
3746    impl<I> SerdeNetlist<I>
3747    where
3748        I: Instantiable + Serialize,
3749    {
3750        /// Convert the serialized netlist back into a reference-counted netlist.
3751        fn into_netlist(self) -> Rc<Netlist<I>> {
3752            let netlist = Netlist::new(self.name);
3753            let outputs: BTreeMap<Operand, BTreeSet<Net>> = self
3754                .outputs
3755                .into_iter()
3756                .map(|(k, v)| {
3757                    let operand = k.parse::<Operand>().expect("Invalid index");
3758                    (operand, v.into_iter().collect())
3759                })
3760                .collect();
3761            let objects = self
3762                .objects
3763                .into_iter()
3764                .enumerate()
3765                .map(|(i, o)| {
3766                    let owned_object = o.into_owned_object(&netlist, i);
3767                    Rc::new(RefCell::new(owned_object))
3768                })
3769                .collect::<Vec<_>>();
3770            {
3771                let mut objs_mut = netlist.objects.borrow_mut();
3772                *objs_mut = objects;
3773                let mut outputs_mut = netlist.outputs.borrow_mut();
3774                *outputs_mut = outputs;
3775            }
3776            netlist
3777        }
3778    }
3779
3780    /// Serialize the netlist into the writer.
3781    pub fn netlist_serialize<I: Instantiable + Serialize>(
3782        netlist: Netlist<I>,
3783        writer: impl std::io::Write,
3784    ) -> Result<(), serde_json::Error> {
3785        let sobj: SerdeNetlist<I> = netlist.into();
3786        serde_json::to_writer_pretty(writer, &sobj)
3787    }
3788
3789    /// Deserialize a netlist from the reader.
3790    pub fn netlist_deserialize<I: Instantiable + Serialize + DeserializeOwned>(
3791        reader: impl std::io::Read,
3792    ) -> Result<Rc<Netlist<I>>, serde_json::Error> {
3793        let sobj: SerdeNetlist<I> = serde_json::from_reader(reader)?;
3794        Ok(sobj.into_netlist())
3795    }
3796}