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