Skip to main content

safety_net/
netlist.rs

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