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::{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, 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    ///
635    /// # Panics
636    ///
637    /// Panics if the cell is a multi-output circuit node.
638    /// Panics if the reference to the netlist is lost.
639    pub fn expose_with_name(self, name: Identifier) -> Self {
640        let netlist = self
641            .netref
642            .borrow()
643            .owner
644            .upgrade()
645            .expect("NetRef is unlinked from netlist");
646        netlist.expose_net_with_name(self.clone().into(), name);
647        self
648    }
649
650    /// Exposes the `net` driven by this circuit node as a top-level output.
651    /// Errors if `net` is not driven by this circuit node.
652    ///
653    /// # Panics
654    /// Panics if the reference to the netlist is lost.
655    pub fn expose_net(&self, net: &Net) -> Result<(), Error> {
656        let netlist = self
657            .netref
658            .borrow()
659            .owner
660            .upgrade()
661            .expect("NetRef is unlinked from netlist");
662        let net_index = self
663            .netref
664            .borrow()
665            .find_net(net)
666            .ok_or(Error::NetNotFound(net.clone()))?;
667        let dr = DrivenNet::new(net_index, self.clone());
668        netlist.expose_net(dr)?;
669        Ok(())
670    }
671
672    /// Returns the circuit node that drives the `index`th input
673    pub fn get_driver(&self, index: usize) -> Option<Self> {
674        self.netref.borrow().get_driver(index).map(NetRef::wrap)
675    }
676
677    /// Returns the net that drives the `index`th input
678    ///
679    /// # Panics
680    ///
681    /// Panics if the reference to the netlist is lost.
682    pub fn get_driver_net(&self, index: usize) -> Option<Net> {
683        self.netref.borrow().get_driver_net(index)
684    }
685
686    /// Returns a request to mutably borrow the operand net
687    /// This requires another borrow in the form of [MutBorrowReq]
688    ///
689    /// # Panics
690    ///
691    /// Panics if the reference to the netlist is lost.
692    pub fn req_driver_net(&self, index: usize) -> Option<MutBorrowReq<I>> {
693        let net = self.get_driver_net(index)?;
694        let operand = self.get_driver(index).unwrap();
695        Some(MutBorrowReq::new(operand, net))
696    }
697
698    /// Returns the number of input ports for this circuit node.
699    pub fn get_num_input_ports(&self) -> usize {
700        if let Some(inst_type) = self.get_instance_type() {
701            inst_type.get_input_ports().into_iter().count()
702        } else {
703            0
704        }
705    }
706
707    /// Returns `true` if this circuit node has all its input ports connected.
708    pub fn is_fully_connected(&self) -> bool {
709        assert_eq!(
710            self.netref.borrow().operands.len(),
711            self.get_num_input_ports()
712        );
713        self.netref.borrow().operands.iter().all(|o| o.is_some())
714    }
715
716    /// Returns an iterator to the driving circuit nodes.
717    pub fn drivers(&self) -> impl Iterator<Item = Option<Self>> {
718        let drivers: Vec<Option<Self>> = self
719            .netref
720            .borrow()
721            .drivers()
722            .map(|o| o.map(NetRef::wrap))
723            .collect();
724        drivers.into_iter()
725    }
726
727    /// Returns an interator to the driving nets.
728    pub fn driver_nets(&self) -> impl Iterator<Item = Option<Net>> {
729        let vec: Vec<Option<Net>> = self.netref.borrow().driver_nets().collect();
730        vec.into_iter()
731    }
732
733    /// Returns an iterator to the output nets of this circuit node.
734    #[allow(clippy::unnecessary_to_owned)]
735    pub fn nets(&self) -> impl Iterator<Item = Net> {
736        self.netref.borrow().get().get_nets().to_vec().into_iter()
737    }
738
739    /// Returns an iterator to the output nets of this circuit node, along with port information.
740    pub fn inputs(&self) -> impl Iterator<Item = InputPort<I>> {
741        let len = self.netref.borrow().operands.len();
742        (0..len).map(move |i| InputPort::new(i, self.clone()))
743    }
744
745    /// Returns an iterator to the output nets of this circuit node, along with port information.
746    pub fn outputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
747        let len = self.netref.borrow().get().get_nets().len();
748        (0..len).map(move |i| DrivenNet::new(i, self.clone()))
749    }
750
751    /// Returns an iterator to mutate the output nets of this circuit node.
752    pub fn nets_mut(&self) -> impl Iterator<Item = RefMut<'_, Net>> {
753        let nnets = self.netref.borrow().get().get_nets().len();
754        (0..nnets).map(|i| self.get_net_mut(i))
755    }
756
757    /// Returns `true` if this circuit node drives the given net.
758    pub fn drives_net(&self, net: &Net) -> bool {
759        self.netref.borrow().find_net(net).is_some()
760    }
761
762    /// Returns `true` if this circuit node drives a top-level output.
763    ///
764    /// # Panics
765    /// Panics if the weak reference to the netlist is lost.
766    pub fn drives_a_top_output(&self) -> bool {
767        let netlist = self
768            .netref
769            .borrow()
770            .owner
771            .upgrade()
772            .expect("NetRef is unlinked from netlist");
773        netlist.drives_an_output(self.clone())
774    }
775
776    /// Attempts to find a mutable reference to `net` within this circuit node.
777    pub fn find_net_mut(&self, net: &Net) -> Option<RefMut<'_, Net>> {
778        RefMut::filter_map(self.netref.borrow_mut(), |f| f.find_net_mut(net)).ok()
779    }
780
781    /// Returns `true` if this circuit node has multiple outputs/nets.
782    pub fn is_multi_output(&self) -> bool {
783        self.netref.borrow().get().get_nets().len() > 1
784    }
785
786    /// Deletes the uses of this circuit node from the netlist.
787    ///
788    /// # Panics
789    ///
790    /// Panics if the reference to the netlist is lost.
791    pub fn delete_uses(self) -> Result<Object<I>, Error> {
792        let netlist = self
793            .netref
794            .borrow()
795            .owner
796            .upgrade()
797            .expect("NetRef is unlinked from netlist");
798        netlist.delete_net_uses(self)
799    }
800
801    /// Replaces the uses of this circuit node in the netlist with another circuit node.
802    ///
803    /// # Panics
804    ///
805    /// Panics if either `self` is a multi-output circuit node.
806    /// Panics if the weak reference to the netlist is lost.
807    pub fn replace_uses_with(self, other: &DrivenNet<I>) -> Result<Object<I>, Error> {
808        let netlist = self
809            .netref
810            .borrow()
811            .owner
812            .upgrade()
813            .expect("NetRef is unlinked from netlist");
814        netlist.replace_net_uses(self.into(), other)
815    }
816
817    /// Clears the attribute with the given key on this circuit node.
818    pub fn clear_attribute(&self, k: &AttributeKey) -> Option<AttributeValue> {
819        self.netref.borrow_mut().clear_attribute(k)
820    }
821
822    /// Set an attribute without a value
823    pub fn set_attribute(&self, k: AttributeKey) {
824        self.netref.borrow_mut().set_attribute(k);
825    }
826
827    /// Insert an attribute on this node with a value
828    pub fn insert_attribute(&self, k: AttributeKey, v: String) -> Option<AttributeValue> {
829        self.netref.borrow_mut().insert_attribute(k, v)
830    }
831
832    /// Returns an iterator to the attributes at this circuit node
833    pub fn attributes(&self) -> impl Iterator<Item = Attribute> {
834        let v: Vec<_> = self.netref.borrow().attributes().collect();
835        v.into_iter()
836    }
837}
838
839impl<I> std::fmt::Display for NetRef<I>
840where
841    I: Instantiable,
842{
843    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
844        self.netref.borrow().object.fmt(f)
845    }
846}
847
848impl<I> From<NetRef<I>> for DrivenNet<I>
849where
850    I: Instantiable,
851{
852    fn from(val: NetRef<I>) -> Self {
853        if val.is_multi_output() {
854            panic!("Cannot convert a multi-output netref to an output port");
855        }
856        DrivenNet::new(0, val)
857    }
858}
859
860impl<I> From<&NetRef<I>> for DrivenNet<I>
861where
862    I: Instantiable,
863{
864    fn from(val: &NetRef<I>) -> Self {
865        if val.is_multi_output() {
866            panic!("Cannot convert a multi-output netref to an output port");
867        }
868        DrivenNet::new(0, val.clone())
869    }
870}
871
872/// Facilitates mutable borrows to driver nets
873pub struct MutBorrowReq<I: Instantiable> {
874    from: NetRef<I>,
875    ind: Net,
876}
877
878impl<I> MutBorrowReq<I>
879where
880    I: Instantiable,
881{
882    /// Creates a new mutable borrow request
883    fn new(from: NetRef<I>, ind: Net) -> Self {
884        Self { from, ind }
885    }
886
887    /// Mutably borrows the requested net from the circuit node
888    pub fn borrow_mut(&self) -> RefMut<'_, Net> {
889        self.from.find_net_mut(&self.ind).unwrap()
890    }
891
892    /// Returns `true` if the circuit node is an input
893    pub fn is_an_input(&self) -> bool {
894        self.from.is_an_input()
895    }
896
897    /// Attempts to borrow the net mutably if the condition `f` is satisfied.
898    pub fn borrow_mut_if(&self, f: impl Fn(&NetRef<I>) -> bool) -> Option<RefMut<'_, Net>> {
899        if f(&self.from) {
900            Some(self.borrow_mut())
901        } else {
902            None
903        }
904    }
905}
906
907/// A netlist data structure
908#[derive(Debug)]
909pub struct Netlist<I>
910where
911    I: Instantiable,
912{
913    /// The name of the netlist
914    name: RefCell<String>,
915    /// The list of objects in the netlist, such as inputs, modules, and primitives
916    objects: RefCell<Vec<NetRefT<I>>>,
917    /// The list of operands that point to objects which are outputs
918    outputs: RefCell<HashMap<Operand, Net>>,
919}
920
921/// Represent the input port of a primitive
922#[derive(Debug, Clone)]
923pub struct InputPort<I: Instantiable> {
924    pos: usize,
925    netref: NetRef<I>,
926}
927
928impl<I> InputPort<I>
929where
930    I: Instantiable,
931{
932    fn new(pos: usize, netref: NetRef<I>) -> Self {
933        if pos >= netref.clone().unwrap().borrow().operands.len() {
934            panic!(
935                "Position {} out of bounds for netref with {} input nets",
936                pos,
937                netref.unwrap().borrow().get().get_nets().len()
938            );
939        }
940        Self { pos, netref }
941    }
942
943    /// Returns the net that is driving this input port
944    pub fn get_driver(&self) -> Option<DrivenNet<I>> {
945        if self.netref.is_an_input() {
946            panic!("Input port is not driven by a primitive");
947        }
948        if let Some(prev_operand) = self.netref.clone().unwrap().borrow().operands[self.pos].clone()
949        {
950            let netlist = self
951                .netref
952                .clone()
953                .unwrap()
954                .borrow()
955                .owner
956                .upgrade()
957                .expect("Input port is unlinked from netlist");
958            let driver_nr = netlist.index_weak(&prev_operand.root());
959            let nr = NetRef::wrap(driver_nr);
960            let pos = prev_operand.secondary();
961            Some(DrivenNet::new(pos, nr))
962        } else {
963            None
964        }
965    }
966
967    /// Disconnects an input port and returns the previous [DrivenNet] if it was connected.
968    pub fn disconnect(&self) -> Option<DrivenNet<I>> {
969        let val = self.get_driver();
970        self.netref.clone().unwrap().borrow_mut().operands[self.pos] = None;
971        val
972    }
973
974    /// Get the input port associated with this connection
975    pub fn get_port(&self) -> Net {
976        if self.netref.is_an_input() {
977            panic!("Net is not driven by a primitive");
978        }
979        self.netref
980            .get_instance_type()
981            .unwrap()
982            .get_input_port(self.pos)
983            .clone()
984    }
985
986    /// Connects this input port to a driven net.
987    pub fn connect(self, output: DrivenNet<I>) {
988        output.connect(self);
989    }
990
991    /// Return the underlying circuit node
992    pub fn unwrap(self) -> NetRef<I> {
993        self.netref
994    }
995}
996
997impl<I> std::fmt::Display for InputPort<I>
998where
999    I: Instantiable,
1000{
1001    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1002        self.get_port().fmt(f)
1003    }
1004}
1005
1006/// Represent a net that is being driven by a [Instantiable]
1007#[derive(Debug, Clone)]
1008pub struct DrivenNet<I: Instantiable> {
1009    pos: usize,
1010    netref: NetRef<I>,
1011}
1012
1013impl<I> DrivenNet<I>
1014where
1015    I: Instantiable,
1016{
1017    fn new(pos: usize, netref: NetRef<I>) -> Self {
1018        if pos >= netref.clone().unwrap().borrow().get().get_nets().len() {
1019            panic!(
1020                "Position {} out of bounds for netref with {} outputted nets",
1021                pos,
1022                netref.unwrap().borrow().get().get_nets().len()
1023            );
1024        }
1025        Self { pos, netref }
1026    }
1027
1028    /// Returns the index that can address this net in the netlist.
1029    fn get_operand(&self) -> Operand {
1030        if self.netref.is_multi_output() {
1031            Operand::CellIndex(self.netref.clone().unwrap().borrow().get_index(), self.pos)
1032        } else {
1033            Operand::DirectIndex(self.netref.clone().unwrap().borrow().get_index())
1034        }
1035    }
1036
1037    /// Borrow the net being driven
1038    pub fn as_net(&self) -> Ref<'_, Net> {
1039        self.netref.get_net(self.pos)
1040    }
1041
1042    /// Get a mutable reference to the net being driven
1043    pub fn as_net_mut(&self) -> RefMut<'_, Net> {
1044        self.netref.get_net_mut(self.pos)
1045    }
1046
1047    /// Returns `true` if this net is a principal input
1048    pub fn is_an_input(&self) -> bool {
1049        self.netref.is_an_input()
1050    }
1051
1052    /// Get the output port associated with this connection
1053    pub fn get_port(&self) -> Net {
1054        if self.netref.is_an_input() {
1055            panic!("Net is not driven by a primitive");
1056        }
1057        self.netref
1058            .get_instance_type()
1059            .unwrap()
1060            .get_output_port(self.pos)
1061            .clone()
1062    }
1063
1064    /// Connects the net driven by this output port to the given input port.
1065    pub fn connect(&self, input: InputPort<I>) {
1066        let operand = self.get_operand();
1067        let index = input.netref.unwrap().borrow().get_index();
1068        let netlist = self
1069            .netref
1070            .clone()
1071            .unwrap()
1072            .borrow()
1073            .owner
1074            .upgrade()
1075            .expect("Output port is unlinked from netlist");
1076        let obj = netlist.index_weak(&index);
1077        obj.borrow_mut().operands[input.pos] = Some(operand.clone());
1078    }
1079
1080    /// Returns `true` if this net is a top-level output in the netlist.
1081    pub fn is_top_level_output(&self) -> bool {
1082        let netlist = self
1083            .netref
1084            .clone()
1085            .unwrap()
1086            .borrow()
1087            .owner
1088            .upgrade()
1089            .expect("DrivenNet is unlinked from netlist");
1090        let outputs = netlist.outputs.borrow();
1091        outputs.contains_key(&self.get_operand())
1092    }
1093
1094    /// Return the underlying circuit node
1095    pub fn unwrap(self) -> NetRef<I> {
1096        self.netref
1097    }
1098
1099    /// Returns a copy of the identifier of the net being driven.
1100    pub fn get_identifier(&self) -> Identifier {
1101        self.as_net().get_identifier().clone()
1102    }
1103
1104    /// Expose this driven net as a module output
1105    ///
1106    /// # Panics
1107    ///
1108    /// Panics if the weak reference to the netlist is dead.
1109    pub fn expose_with_name(self, name: Identifier) -> Self {
1110        let netlist = self
1111            .netref
1112            .clone()
1113            .unwrap()
1114            .borrow()
1115            .owner
1116            .upgrade()
1117            .expect("DrivenNet is unlinked from netlist");
1118        netlist.expose_net_with_name(self.clone(), name);
1119        self
1120    }
1121
1122    /// Returns the output position, if the net is the output of a gate.
1123    pub fn get_output_index(&self) -> Option<usize> {
1124        if self.netref.is_an_input() {
1125            None
1126        } else {
1127            Some(self.pos)
1128        }
1129    }
1130
1131    /// Returns the [Instantiable] type driving this net, if it has a driver.
1132    pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
1133        self.netref.get_instance_type()
1134    }
1135}
1136
1137impl<I> std::fmt::Display for DrivenNet<I>
1138where
1139    I: Instantiable,
1140{
1141    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1142        self.as_net().fmt(f)
1143    }
1144}
1145
1146impl<I> PartialEq for DrivenNet<I>
1147where
1148    I: Instantiable,
1149{
1150    fn eq(&self, other: &Self) -> bool {
1151        self.netref == other.netref && self.pos == other.pos
1152    }
1153}
1154
1155impl<I> Eq for DrivenNet<I> where I: Instantiable {}
1156
1157impl<I> std::hash::Hash for DrivenNet<I>
1158where
1159    I: Instantiable,
1160{
1161    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1162        self.netref.hash(state);
1163        self.pos.hash(state);
1164    }
1165}
1166
1167impl<I> WeakIndex<usize> for Netlist<I>
1168where
1169    I: Instantiable,
1170{
1171    type Output = OwnedObject<I, Self>;
1172
1173    fn index_weak(&self, index: &usize) -> Rc<RefCell<Self::Output>> {
1174        self.objects.borrow()[*index].clone()
1175    }
1176}
1177
1178impl<I> Netlist<I>
1179where
1180    I: Instantiable,
1181{
1182    /// Creates a new netlist with the given name
1183    pub fn new(name: String) -> Rc<Self> {
1184        Rc::new(Self {
1185            name: RefCell::new(name),
1186            objects: RefCell::new(Vec::new()),
1187            outputs: RefCell::new(HashMap::new()),
1188        })
1189    }
1190
1191    /// Attempts to reclaim the netlist, returning [Some] if successful.
1192    pub fn reclaim(self: Rc<Self>) -> Option<Self> {
1193        Rc::try_unwrap(self).ok()
1194    }
1195
1196    /// Use interior mutability to add an object to the netlist. Returns a mutable reference to the created object.
1197    fn insert_object(
1198        self: &Rc<Self>,
1199        object: Object<I>,
1200        operands: &[DrivenNet<I>],
1201    ) -> Result<NetRef<I>, Error> {
1202        let index = self.objects.borrow().len();
1203        let weak = Rc::downgrade(self);
1204        let operands = operands
1205            .iter()
1206            .map(|net| Some(net.get_operand()))
1207            .collect::<Vec<_>>();
1208        let owned_object = Rc::new(RefCell::new(OwnedObject {
1209            object,
1210            owner: weak,
1211            operands,
1212            attributes: HashMap::new(),
1213            index,
1214        }));
1215        self.objects.borrow_mut().push(owned_object.clone());
1216        Ok(NetRef::wrap(owned_object))
1217    }
1218
1219    /// Inserts an input net to the netlist
1220    pub fn insert_input(self: &Rc<Self>, net: Net) -> DrivenNet<I> {
1221        let obj = Object::Input(net);
1222        self.insert_object(obj, &[]).unwrap().into()
1223    }
1224
1225    /// Inserts a four-state logic input port to the netlist
1226    pub fn insert_input_escaped_logic_bus(
1227        self: &Rc<Self>,
1228        net: String,
1229        bw: usize,
1230    ) -> Vec<DrivenNet<I>> {
1231        Net::new_escaped_logic_bus(net, bw)
1232            .into_iter()
1233            .map(|n| self.insert_input(n))
1234            .collect()
1235    }
1236
1237    /// Inserts a gate to the netlist
1238    pub fn insert_gate(
1239        self: &Rc<Self>,
1240        inst_type: I,
1241        inst_name: Identifier,
1242        operands: &[DrivenNet<I>],
1243    ) -> Result<NetRef<I>, Error> {
1244        let nets = inst_type
1245            .get_output_ports()
1246            .into_iter()
1247            .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1248            .collect::<Vec<_>>();
1249        let input_count = inst_type.get_input_ports().into_iter().count();
1250        if operands.len() != input_count {
1251            return Err(Error::ArgumentMismatch(input_count, operands.len()));
1252        }
1253        let obj = Object::Instance(nets, inst_name, inst_type);
1254        self.insert_object(obj, operands)
1255    }
1256
1257    /// Use interior mutability to add an object to the netlist. Returns a mutable reference to the created object.
1258    pub fn insert_gate_disconnected(
1259        self: &Rc<Self>,
1260        inst_type: I,
1261        inst_name: Identifier,
1262    ) -> NetRef<I> {
1263        let nets = inst_type
1264            .get_output_ports()
1265            .into_iter()
1266            .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1267            .collect::<Vec<_>>();
1268        let object = Object::Instance(nets, inst_name, inst_type);
1269        let index = self.objects.borrow().len();
1270        let weak = Rc::downgrade(self);
1271        let input_count = object
1272            .get_instance_type()
1273            .unwrap()
1274            .get_input_ports()
1275            .into_iter()
1276            .count();
1277        let operands = vec![None; input_count];
1278        let owned_object = Rc::new(RefCell::new(OwnedObject {
1279            object,
1280            owner: weak,
1281            operands,
1282            attributes: HashMap::new(),
1283            index,
1284        }));
1285        self.objects.borrow_mut().push(owned_object.clone());
1286        NetRef::wrap(owned_object)
1287    }
1288
1289    /// Inserts a constant [Logic] value to the netlist
1290    pub fn insert_constant(
1291        self: &Rc<Self>,
1292        value: Logic,
1293        inst_name: Identifier,
1294    ) -> Result<DrivenNet<I>, Error> {
1295        let obj = I::from_constant(value).ok_or(Error::InstantiableError(format!(
1296            "Instantiable type does not support constant value {}",
1297            value
1298        )))?;
1299        Ok(self.insert_gate_disconnected(obj, inst_name).into())
1300    }
1301
1302    /// Returns the driving node at input position `index` for `netref`
1303    ///
1304    /// # Panics
1305    ///
1306    /// Panics if `index` is out of bounds
1307    pub fn get_driver(&self, netref: NetRef<I>, index: usize) -> Option<NetRef<I>> {
1308        let op = netref.unwrap().borrow().operands[index].clone()?;
1309        Some(NetRef::wrap(self.index_weak(&op.root()).clone()))
1310    }
1311
1312    /// Set an added object as a top-level output.
1313    pub fn expose_net_with_name(&self, net: DrivenNet<I>, name: Identifier) -> DrivenNet<I> {
1314        let mut outputs = self.outputs.borrow_mut();
1315        outputs.insert(net.get_operand(), net.as_net().with_name(name));
1316        net
1317    }
1318
1319    /// Set an added object as a top-level output.
1320    pub fn expose_net(&self, net: DrivenNet<I>) -> Result<DrivenNet<I>, Error> {
1321        if net.is_an_input() {
1322            return Err(Error::InputNeedsAlias(net.as_net().clone()));
1323        }
1324        let mut outputs = self.outputs.borrow_mut();
1325        outputs.insert(net.get_operand(), net.as_net().clone());
1326        Ok(net)
1327    }
1328
1329    /// Unlink a circuit node from the rest of the netlist. Return the object that was being stored.
1330    pub fn delete_net_uses(&self, netref: NetRef<I>) -> Result<Object<I>, Error> {
1331        let unwrapped = netref.clone().unwrap();
1332        if Rc::strong_count(&unwrapped) > 3 {
1333            return Err(Error::DanglingReference(netref.nets().collect()));
1334        }
1335        let old_index = unwrapped.borrow().get_index();
1336        let objects = self.objects.borrow();
1337        for oref in objects.iter() {
1338            let operands = &mut oref.borrow_mut().operands;
1339            for operand in operands.iter_mut() {
1340                if let Some(op) = operand {
1341                    match op {
1342                        Operand::DirectIndex(idx) | Operand::CellIndex(idx, _)
1343                            if *idx == old_index =>
1344                        {
1345                            *operand = None;
1346                        }
1347                        _ => (),
1348                    }
1349                }
1350            }
1351        }
1352
1353        let outputs: Vec<Operand> = self
1354            .outputs
1355            .borrow()
1356            .keys()
1357            .filter(|operand| match operand {
1358                Operand::DirectIndex(idx) | Operand::CellIndex(idx, _) => *idx == old_index,
1359            })
1360            .cloned()
1361            .collect();
1362
1363        for operand in outputs {
1364            self.outputs.borrow_mut().remove(&operand);
1365        }
1366
1367        Ok(netref.unwrap().borrow().get().clone())
1368    }
1369
1370    /// Replaces the uses of a circuit node with another circuit node. The [Object] stored at `of` is returned.
1371    pub fn replace_net_uses(
1372        &self,
1373        of: DrivenNet<I>,
1374        with: &DrivenNet<I>,
1375    ) -> Result<Object<I>, Error> {
1376        let unwrapped = of.clone().unwrap().unwrap();
1377        let i = of.get_output_index();
1378        let k = with.get_output_index();
1379
1380        if of.clone().unwrap() == with.clone().unwrap() {
1381            if i == k {
1382                return Ok(of.unwrap().unwrap().borrow().get().clone());
1383            }
1384
1385            if Rc::strong_count(&unwrapped) > 4 {
1386                return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1387            }
1388        } else if Rc::strong_count(&unwrapped) > 3 {
1389            return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1390        }
1391
1392        let old_index = of.get_operand();
1393
1394        if let Some(v) = self.outputs.borrow().get(&old_index)
1395            && *v == *of.as_net()
1396        {
1397            return Err(Error::NonuniqueNets(vec![v.clone()]));
1398        }
1399
1400        let new_index = with.get_operand();
1401        let objects = self.objects.borrow();
1402        for oref in objects.iter() {
1403            let operands = &mut oref.borrow_mut().operands;
1404            for operand in operands.iter_mut() {
1405                if let Some(op) = operand
1406                    && *op == old_index
1407                {
1408                    *operand = Some(new_index.clone());
1409                }
1410            }
1411        }
1412
1413        let already_mapped = self.outputs.borrow().contains_key(&new_index);
1414        let old_mapping = self.outputs.borrow_mut().remove(&old_index);
1415
1416        if already_mapped {
1417            self.outputs.borrow_mut().remove(&old_index);
1418        } else if let Some(v) = old_mapping {
1419            self.outputs.borrow_mut().insert(new_index, v.clone());
1420        }
1421
1422        Ok(of.unwrap().unwrap().borrow().get().clone())
1423    }
1424}
1425
1426impl<I> Netlist<I>
1427where
1428    I: Instantiable,
1429{
1430    /// Returns the name of the netlist module
1431    pub fn get_name(&self) -> Ref<'_, String> {
1432        self.name.borrow()
1433    }
1434
1435    /// Sets the name of the netlist module
1436    /// # Panics
1437    ///
1438    /// Panics if the module name cannot be borrowed mutably.
1439    pub fn set_name(&self, name: String) {
1440        *self.name.borrow_mut() = name;
1441    }
1442
1443    /// Iterates over the input ports of the netlist.
1444    pub fn get_input_ports(&self) -> impl Iterator<Item = Net> {
1445        self.objects().filter_map(|oref| {
1446            if oref.is_an_input() {
1447                Some(oref.as_net().clone())
1448            } else {
1449                None
1450            }
1451        })
1452    }
1453
1454    /// Returns a list of output nets
1455    pub fn get_output_ports(&self) -> Vec<Net> {
1456        self.outputs.borrow().values().cloned().collect::<Vec<_>>()
1457    }
1458
1459    /// Constructs an analysis of the netlist.
1460    pub fn get_analysis<'a, A: Analysis<'a, I>>(&'a self) -> Result<A, Error> {
1461        A::build(self)
1462    }
1463
1464    /// Finds the first circuit node that drives the `net`. This operation is O(n).
1465    /// This should be unique provided the netlist is well-formed.
1466    pub fn find_net(&self, net: &Net) -> Option<DrivenNet<I>> {
1467        for obj in self.objects() {
1468            for o in obj.outputs() {
1469                if *o.as_net() == *net {
1470                    return Some(o);
1471                }
1472            }
1473        }
1474        None
1475    }
1476
1477    /// Returns a `NetRef` to the first circuit node
1478    pub fn first(&self) -> Option<NetRef<I>> {
1479        self.objects
1480            .borrow()
1481            .first()
1482            .map(|nr| NetRef::wrap(nr.clone()))
1483    }
1484
1485    /// Returns a `NetRef` to the last circuit node
1486    pub fn last(&self) -> Option<NetRef<I>> {
1487        self.objects
1488            .borrow()
1489            .last()
1490            .map(|nr| NetRef::wrap(nr.clone()))
1491    }
1492
1493    /// Returns `true` if an output of `netref` which is driving a module output.
1494    pub fn drives_an_output(&self, netref: NetRef<I>) -> bool {
1495        let my_index = netref.unwrap().borrow().get_index();
1496        for key in self.outputs.borrow().keys() {
1497            if key.root() == my_index {
1498                return true;
1499            }
1500        }
1501        false
1502    }
1503
1504    /// Rename nets and instances in the netlist using the provided *injective* function.
1505    /// Returns an error if the function is not injective.
1506    pub fn rename_nets<F: Fn(usize) -> Identifier>(&self, f: F) -> Result<(), Error> {
1507        let mut i: usize = 0;
1508        for nr in self.objects() {
1509            if nr.is_an_input() {
1510                continue;
1511            }
1512            for mut net in nr.nets_mut() {
1513                net.set_identifier(f(i));
1514                i += 1;
1515            }
1516        }
1517
1518        for nr in self.objects() {
1519            if nr.is_an_input() {
1520                continue;
1521            }
1522
1523            nr.set_instance_name(f(i));
1524            i += 1;
1525        }
1526
1527        self.verify()
1528    }
1529
1530    /// Cleans unused nodes from the netlist, returning `Ok(true)` if the netlist changed.
1531    pub fn clean_once(&self) -> Result<bool, Error> {
1532        let mut dead_objs = HashSet::new();
1533        {
1534            let fan_out = self.get_analysis::<FanOutTable<I>>()?;
1535            for obj in self.objects() {
1536                let mut is_dead = true;
1537                for net in obj.nets() {
1538                    // This should account for outputs
1539                    if fan_out.net_has_uses(&net) {
1540                        is_dead = false;
1541                        break;
1542                    }
1543                }
1544                if is_dead && !obj.is_an_input() {
1545                    dead_objs.insert(obj.unwrap().borrow().index);
1546                }
1547            }
1548        }
1549
1550        if dead_objs.is_empty() {
1551            return Ok(false);
1552        }
1553
1554        let old_objects = self.objects.take();
1555        let mut remap: HashMap<usize, usize> = HashMap::new();
1556        for (old_index, obj) in old_objects.into_iter().enumerate() {
1557            if dead_objs.contains(&old_index) {
1558                // 1. this ref, 2. as an output
1559                if Rc::strong_count(&obj) > 2 {
1560                    return Err(Error::DanglingReference(
1561                        obj.borrow().get().get_nets().to_vec(),
1562                    ));
1563                }
1564                continue;
1565            }
1566            let new_index = self.objects.borrow().len();
1567            remap.insert(old_index, new_index);
1568            obj.borrow_mut().index = new_index;
1569            self.objects.borrow_mut().push(obj);
1570        }
1571
1572        for obj in self.objects.borrow().iter() {
1573            for operand in obj.borrow_mut().inds_mut() {
1574                let root = operand.root();
1575                let root = *remap.get(&root).unwrap_or(&root);
1576                *operand = operand.clone().remap(root);
1577            }
1578        }
1579
1580        let pairs: Vec<_> = self.outputs.take().into_iter().collect();
1581        for (operand, net) in pairs {
1582            let root = operand.root();
1583            let root = *remap.get(&root).unwrap_or(&root);
1584            let new_operand = operand.clone().remap(root);
1585            self.outputs.borrow_mut().insert(new_operand, net);
1586        }
1587
1588        Ok(true)
1589    }
1590
1591    /// Greedly removes unused nodes from the netlist, until it stops changing.
1592    /// Returns true if the netlist was changed.
1593    pub fn clean(&self) -> Result<bool, Error> {
1594        if !self.clean_once()? {
1595            Ok(false)
1596        } else {
1597            let mut changed = true;
1598            while changed {
1599                changed = self.clean_once()?;
1600            }
1601            Ok(true)
1602        }
1603    }
1604
1605    /// Returns `true` if all the nets are uniquely named
1606    fn nets_unique(&self) -> Result<(), Error> {
1607        let mut nets = HashSet::new();
1608        for net in self.into_iter() {
1609            if !nets.insert(net.clone().take_identifier()) {
1610                return Err(Error::NonuniqueNets(vec![net]));
1611            }
1612        }
1613        Ok(())
1614    }
1615
1616    /// Returns `true` if all the nets are uniquely named
1617    fn insts_unique(&self) -> Result<(), Error> {
1618        let mut insts = HashSet::new();
1619        for inst in self.objects() {
1620            if let Some(name) = inst.get_instance_name()
1621                && !insts.insert(name.clone())
1622            {
1623                return Err(Error::NonuniqueInsts(vec![name]));
1624            }
1625        }
1626        Ok(())
1627    }
1628
1629    /// Verifies that a netlist is well-formed.
1630    pub fn verify(&self) -> Result<(), Error> {
1631        if self.outputs.borrow().is_empty() {
1632            return Err(Error::NoOutputs);
1633        }
1634
1635        self.nets_unique()?;
1636
1637        self.insts_unique()?;
1638
1639        Ok(())
1640    }
1641}
1642
1643/// Represent a driven net alongside its connection to an input port
1644#[derive(Debug, Clone)]
1645pub struct Connection<I: Instantiable> {
1646    driver: DrivenNet<I>,
1647    input: InputPort<I>,
1648}
1649
1650impl<I> Connection<I>
1651where
1652    I: Instantiable,
1653{
1654    fn new(driver: DrivenNet<I>, input: InputPort<I>) -> Self {
1655        Self { driver, input }
1656    }
1657
1658    /// Return the driver of the connection
1659    pub fn src(&self) -> DrivenNet<I> {
1660        self.driver.clone()
1661    }
1662
1663    /// Return the net along the connection
1664    pub fn net(&self) -> Net {
1665        self.driver.as_net().clone()
1666    }
1667
1668    /// Returns the input port of the connection
1669    pub fn target(&self) -> InputPort<I> {
1670        self.input.clone()
1671    }
1672}
1673
1674impl<I> std::fmt::Display for Connection<I>
1675where
1676    I: Instantiable,
1677{
1678    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1679        self.net().fmt(f)
1680    }
1681}
1682
1683/// A collection of iterators for the netlist
1684pub mod iter {
1685
1686    use super::{
1687        Connection, DrivenNet, InputPort, Instantiable, Net, NetRef, Netlist, Operand, WeakIndex,
1688    };
1689    use std::collections::{HashMap, HashSet};
1690    /// An iterator over the nets in a netlist
1691    pub struct NetIterator<'a, I: Instantiable> {
1692        netlist: &'a Netlist<I>,
1693        index: usize,
1694        subindex: usize,
1695    }
1696
1697    impl<'a, I> NetIterator<'a, I>
1698    where
1699        I: Instantiable,
1700    {
1701        /// Creates a new iterator for the netlist
1702        pub fn new(netlist: &'a Netlist<I>) -> Self {
1703            Self {
1704                netlist,
1705                index: 0,
1706                subindex: 0,
1707            }
1708        }
1709    }
1710
1711    impl<I> Iterator for NetIterator<'_, I>
1712    where
1713        I: Instantiable,
1714    {
1715        type Item = Net;
1716
1717        fn next(&mut self) -> Option<Self::Item> {
1718            while self.index < self.netlist.objects.borrow().len() {
1719                let objects = self.netlist.objects.borrow();
1720                let object = objects[self.index].borrow();
1721                if self.subindex < object.get().get_nets().len() {
1722                    let net = object.get().get_nets()[self.subindex].clone();
1723                    self.subindex += 1;
1724                    return Some(net);
1725                }
1726                self.subindex = 0;
1727                self.index += 1;
1728            }
1729            None
1730        }
1731    }
1732
1733    /// An iterator over the objects in a netlist
1734    pub struct ObjectIterator<'a, I: Instantiable> {
1735        netlist: &'a Netlist<I>,
1736        index: usize,
1737    }
1738
1739    impl<'a, I> ObjectIterator<'a, I>
1740    where
1741        I: Instantiable,
1742    {
1743        /// Creates a new  object iterator for the netlist
1744        pub fn new(netlist: &'a Netlist<I>) -> Self {
1745            Self { netlist, index: 0 }
1746        }
1747    }
1748
1749    impl<I> Iterator for ObjectIterator<'_, I>
1750    where
1751        I: Instantiable,
1752    {
1753        type Item = NetRef<I>;
1754
1755        fn next(&mut self) -> Option<Self::Item> {
1756            if self.index < self.netlist.objects.borrow().len() {
1757                let objects = self.netlist.objects.borrow();
1758                let object = &objects[self.index];
1759                self.index += 1;
1760                return Some(NetRef::wrap(object.clone()));
1761            }
1762            None
1763        }
1764    }
1765
1766    /// An iterator over the connections in a netlist
1767    pub struct ConnectionIterator<'a, I: Instantiable> {
1768        netlist: &'a Netlist<I>,
1769        index: usize,
1770        subindex: usize,
1771    }
1772
1773    impl<'a, I> ConnectionIterator<'a, I>
1774    where
1775        I: Instantiable,
1776    {
1777        /// Create a new connection iterator for the netlist
1778        pub fn new(netlist: &'a Netlist<I>) -> Self {
1779            Self {
1780                netlist,
1781                index: 0,
1782                subindex: 0,
1783            }
1784        }
1785    }
1786
1787    impl<I> Iterator for ConnectionIterator<'_, I>
1788    where
1789        I: Instantiable,
1790    {
1791        type Item = super::Connection<I>;
1792
1793        fn next(&mut self) -> Option<Self::Item> {
1794            while self.index < self.netlist.objects.borrow().len() {
1795                let objects = self.netlist.objects.borrow();
1796                let object = objects[self.index].borrow();
1797                let noperands = object.operands.len();
1798                while self.subindex < noperands {
1799                    if let Some(operand) = &object.operands[self.subindex] {
1800                        let driver = match operand {
1801                            Operand::DirectIndex(idx) => {
1802                                DrivenNet::new(0, NetRef::wrap(objects[*idx].clone()))
1803                            }
1804                            Operand::CellIndex(idx, j) => {
1805                                DrivenNet::new(*j, NetRef::wrap(objects[*idx].clone()))
1806                            }
1807                        };
1808                        let input = InputPort::new(
1809                            self.subindex,
1810                            NetRef::wrap(objects[self.index].clone()),
1811                        );
1812                        self.subindex += 1;
1813                        return Some(Connection::new(driver, input));
1814                    }
1815                    self.subindex += 1;
1816                }
1817                self.subindex = 0;
1818                self.index += 1;
1819            }
1820            None
1821        }
1822    }
1823
1824    /// A stack that can check contains in roughly O(1) time.
1825    #[derive(Clone)]
1826    struct Walk<T: std::hash::Hash + PartialEq + Eq + Clone> {
1827        stack: Vec<T>,
1828        counter: HashMap<T, usize>,
1829    }
1830
1831    impl<T> Walk<T>
1832    where
1833        T: std::hash::Hash + PartialEq + Eq + Clone,
1834    {
1835        /// Create a new, empty Stack.
1836        fn new() -> Self {
1837            Self {
1838                stack: Vec::new(),
1839                counter: HashMap::new(),
1840            }
1841        }
1842
1843        /// Inserts an element into the stack
1844        fn push(&mut self, item: T) {
1845            self.stack.push(item.clone());
1846            *self.counter.entry(item).or_insert(0) += 1;
1847        }
1848
1849        /// Returns true if the stack shows a cycle
1850        fn contains_cycle(&self) -> bool {
1851            self.counter.values().any(|&count| count > 1)
1852        }
1853
1854        /// Returns a reference to the last element in the stack
1855        fn last(&self) -> Option<&T> {
1856            self.stack.last()
1857        }
1858    }
1859
1860    /// A depth-first iterator over the circuit nodes in a netlist
1861    /// # Examples
1862    ///
1863    /// ```
1864    /// use safety_net::iter::DFSIterator;
1865    /// use safety_net::GateNetlist;
1866    ///
1867    /// let netlist = GateNetlist::new("example".to_string());
1868    /// netlist.insert_input("input1".into());
1869    /// let mut nodes = Vec::new();
1870    /// let mut dfs = DFSIterator::new(&netlist, netlist.last().unwrap());
1871    /// while let Some(n) = dfs.next() {
1872    ///     if dfs.check_cycles() {
1873    ///         panic!("Cycle detected in the netlist");
1874    ///     }
1875    ///     nodes.push(n);
1876    /// }
1877    /// ```
1878    pub struct DFSIterator<'a, I: Instantiable> {
1879        netlist: &'a Netlist<I>,
1880        stacks: Vec<Walk<NetRef<I>>>,
1881        visited: HashSet<usize>,
1882        cycles: bool,
1883    }
1884
1885    impl<'a, I> DFSIterator<'a, I>
1886    where
1887        I: Instantiable,
1888    {
1889        /// Create a new DFS iterator for the netlist starting at `from`.
1890        pub fn new(netlist: &'a Netlist<I>, from: NetRef<I>) -> Self {
1891            let mut s = Walk::new();
1892            s.push(from);
1893            Self {
1894                netlist,
1895                stacks: vec![s],
1896                visited: HashSet::new(),
1897                cycles: false,
1898            }
1899        }
1900    }
1901
1902    impl<I> DFSIterator<'_, I>
1903    where
1904        I: Instantiable,
1905    {
1906        /// Check if the DFS traversal has encountered a cycle yet.
1907        pub fn check_cycles(&self) -> bool {
1908            self.cycles
1909        }
1910
1911        /// Consumes the iterator to detect cycles in the netlist.
1912        pub fn detect_cycles(mut self) -> bool {
1913            if self.cycles {
1914                return true;
1915            }
1916
1917            while let Some(_) = self.next() {
1918                if self.cycles {
1919                    return true;
1920                }
1921            }
1922
1923            self.cycles
1924        }
1925    }
1926
1927    impl<I> Iterator for DFSIterator<'_, I>
1928    where
1929        I: Instantiable,
1930    {
1931        type Item = NetRef<I>;
1932
1933        fn next(&mut self) -> Option<Self::Item> {
1934            if let Some(walk) = self.stacks.pop() {
1935                let item = walk.last().cloned();
1936                let uw = item.clone().unwrap().unwrap();
1937                let index = uw.borrow().get_index();
1938                if self.visited.insert(index) {
1939                    let operands = &uw.borrow().operands;
1940                    for operand in operands.iter().flatten() {
1941                        let mut new_walk = walk.clone();
1942                        new_walk.push(NetRef::wrap(self.netlist.index_weak(&operand.root())));
1943                        if !new_walk.contains_cycle() {
1944                            self.stacks.push(new_walk);
1945                        } else {
1946                            self.cycles = true;
1947                        }
1948                    }
1949                    return item;
1950                }
1951
1952                return self.next();
1953            }
1954
1955            None
1956        }
1957    }
1958}
1959
1960impl<'a, I> IntoIterator for &'a Netlist<I>
1961where
1962    I: Instantiable,
1963{
1964    type Item = Net;
1965    type IntoIter = iter::NetIterator<'a, I>;
1966
1967    fn into_iter(self) -> Self::IntoIter {
1968        iter::NetIterator::new(self)
1969    }
1970}
1971
1972/// Filter invariants of [Instantiable] in a netlist. Use it like you would `matches!`.
1973/// Example: ```filter_nodes!(netlist, Gate::AND(_));```
1974#[macro_export]
1975macro_rules! filter_nodes {
1976    ($netlist:ident, $pattern:pat $(if $guard:expr)? $(,)?) => {
1977        $netlist.matches(|f| match f {
1978            $pattern $(if $guard)? => true,
1979            _ => false
1980        })
1981    };
1982}
1983
1984impl<I> Netlist<I>
1985where
1986    I: Instantiable,
1987{
1988    /// Returns an iterator over the circuit nodes in the netlist.
1989    pub fn objects(&self) -> impl Iterator<Item = NetRef<I>> {
1990        iter::ObjectIterator::new(self)
1991    }
1992
1993    /// Returns an iterator over the circuit nodes that match the instance type.
1994    pub fn matches<F>(&self, filter: F) -> impl Iterator<Item = NetRef<I>>
1995    where
1996        F: Fn(&I) -> bool,
1997    {
1998        self.objects().filter(move |f| {
1999            if let Some(inst_type) = f.get_instance_type() {
2000                filter(&inst_type)
2001            } else {
2002                false
2003            }
2004        })
2005    }
2006
2007    /// Returns an iterator to principal inputs in the netlist as references.
2008    pub fn inputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
2009        self.objects()
2010            .filter(|n| n.is_an_input())
2011            .map(|n| DrivenNet::new(0, n))
2012    }
2013
2014    /// Returns an iterator to circuit nodes that drive an output in the netlist.
2015    pub fn outputs(&self) -> Vec<(DrivenNet<I>, Net)> {
2016        self.outputs
2017            .borrow()
2018            .iter()
2019            .map(|(k, n)| {
2020                (
2021                    DrivenNet::new(k.secondary(), NetRef::wrap(self.index_weak(&k.root()))),
2022                    n.clone(),
2023                )
2024            })
2025            .collect()
2026    }
2027
2028    /// Returns an iterator over the wire connections in the netlist.
2029    pub fn connections(&self) -> impl Iterator<Item = Connection<I>> {
2030        iter::ConnectionIterator::new(self)
2031    }
2032
2033    /// Returns a depth-first search iterator over the nodes in the netlist.
2034    pub fn dfs(&self, from: NetRef<I>) -> impl Iterator<Item = NetRef<I>> {
2035        iter::DFSIterator::new(self, from)
2036    }
2037
2038    #[cfg(feature = "serde")]
2039    /// Serializes the netlist to a writer.
2040    pub fn serialize(self, writer: impl std::io::Write) -> Result<(), serde_json::Error>
2041    where
2042        I: ::serde::Serialize,
2043    {
2044        serde::netlist_serialize(self, writer)
2045    }
2046}
2047
2048impl<I> std::fmt::Display for Netlist<I>
2049where
2050    I: Instantiable,
2051{
2052    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2053        // Borrow everything first
2054        let objects = self.objects.borrow();
2055        let outputs = self.outputs.borrow();
2056
2057        writeln!(f, "module {} (", self.get_name())?;
2058
2059        // Print inputs and outputs
2060        let level = 2;
2061        let indent = " ".repeat(level);
2062        for oref in objects.iter() {
2063            let owned = oref.borrow();
2064            let obj = owned.get();
2065            if let Object::Input(net) = obj {
2066                writeln!(f, "{}{},", indent, net.get_identifier().emit_name())?;
2067            }
2068        }
2069        for (i, (_, net)) in outputs.iter().enumerate() {
2070            if i == outputs.len() - 1 {
2071                writeln!(f, "{}{}", indent, net.get_identifier().emit_name())?;
2072            } else {
2073                writeln!(f, "{}{},", indent, net.get_identifier().emit_name())?;
2074            }
2075        }
2076        writeln!(f, ");")?;
2077
2078        // Make wire decls
2079        let mut already_decl = HashSet::new();
2080        for oref in objects.iter() {
2081            let owned = oref.borrow();
2082            let obj = owned.get();
2083            if let Object::Input(net) = obj {
2084                writeln!(f, "{}input {};", indent, net.get_identifier().emit_name())?;
2085                writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2086                already_decl.insert(net.clone());
2087            }
2088        }
2089        for (_, net) in outputs.iter() {
2090            if !already_decl.contains(net) {
2091                writeln!(f, "{}output {};", indent, net.get_identifier().emit_name())?;
2092                writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2093                already_decl.insert(net.clone());
2094            }
2095        }
2096        for oref in objects.iter() {
2097            let owned = oref.borrow();
2098            let obj = owned.get();
2099            if let Object::Instance(nets, _, inst_type) = obj
2100                && inst_type.get_constant().is_none()
2101            {
2102                for net in nets.iter() {
2103                    if !already_decl.contains(net) {
2104                        writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2105                        already_decl.insert(net.clone());
2106                    }
2107                }
2108            }
2109        }
2110
2111        for oref in objects.iter() {
2112            let owned = oref.borrow();
2113            let obj = owned.get();
2114
2115            // Skip emitting constants as their uses will be hard-wired
2116            if let Some(inst_type) = obj.get_instance_type()
2117                && inst_type.get_constant().is_some()
2118            {
2119                continue;
2120            }
2121
2122            if let Object::Instance(nets, inst_name, inst_type) = obj {
2123                for (k, v) in owned.attributes.iter() {
2124                    if let Some(value) = v {
2125                        writeln!(f, "{indent}(* {k} = \"{value}\" *)")?;
2126                    } else {
2127                        writeln!(f, "{indent}(* {k} *)")?;
2128                    }
2129                }
2130
2131                write!(f, "{}{} ", indent, inst_type.get_name())?;
2132                if inst_type.is_parameterized() {
2133                    writeln!(f, "#(")?;
2134                    let level = 4;
2135                    let indent = " ".repeat(level);
2136                    let params: Vec<_> = inst_type.parameters().collect();
2137                    for (i, (k, v)) in params.iter().enumerate() {
2138                        if i == params.len() - 1 {
2139                            writeln!(f, "{indent}.{k}({v})")?;
2140                        } else {
2141                            writeln!(f, "{indent}.{k}({v}),")?;
2142                        }
2143                    }
2144                    let level = 2;
2145                    let indent = " ".repeat(level);
2146                    write!(f, "{indent}) ")?;
2147                }
2148                writeln!(f, "{} (", inst_name.emit_name())?;
2149                let level = 4;
2150                let indent = " ".repeat(level);
2151                for (idx, port) in inst_type.get_input_ports().into_iter().enumerate() {
2152                    let port_name = port.get_identifier().emit_name();
2153                    if let Some(operand) = owned.operands[idx].as_ref() {
2154                        let operand_net = match operand {
2155                            Operand::DirectIndex(idx) => objects[*idx].borrow().as_net().clone(),
2156                            Operand::CellIndex(idx, j) => {
2157                                objects[*idx].borrow().get_net(*j).clone()
2158                            }
2159                        };
2160
2161                        let operand_str = if let Some(inst_type) =
2162                            objects[operand.root()].borrow().get().get_instance_type()
2163                            && let Some(logic) = inst_type.get_constant()
2164                        {
2165                            logic.to_string()
2166                        } else {
2167                            operand_net.get_identifier().emit_name()
2168                        };
2169
2170                        writeln!(f, "{}.{}({}),", indent, port_name, operand_str)?;
2171                    }
2172                }
2173
2174                for (idx, net) in nets.iter().enumerate() {
2175                    let port_name = inst_type.get_output_port(idx).get_identifier().emit_name();
2176                    if idx == nets.len() - 1 {
2177                        writeln!(
2178                            f,
2179                            "{}.{}({})",
2180                            indent,
2181                            port_name,
2182                            net.get_identifier().emit_name()
2183                        )?;
2184                    } else {
2185                        writeln!(
2186                            f,
2187                            "{}.{}({}),",
2188                            indent,
2189                            port_name,
2190                            net.get_identifier().emit_name()
2191                        )?;
2192                    }
2193                }
2194
2195                let level = 2;
2196                let indent = " ".repeat(level);
2197                writeln!(f, "{indent});")?;
2198            }
2199        }
2200
2201        for (driver, net) in outputs.iter() {
2202            let driver_net = match driver {
2203                Operand::DirectIndex(idx) => self.index_weak(idx).borrow().as_net().clone(),
2204                Operand::CellIndex(idx, j) => self.index_weak(idx).borrow().get_net(*j).clone(),
2205            };
2206
2207            let driver_str = if let Some(inst_type) = self
2208                .index_weak(&driver.root())
2209                .borrow()
2210                .get()
2211                .get_instance_type()
2212                && let Some(logic) = inst_type.get_constant()
2213            {
2214                logic.to_string()
2215            } else {
2216                driver_net.get_identifier().emit_name()
2217            };
2218
2219            if net.get_identifier() != driver_net.get_identifier() {
2220                writeln!(
2221                    f,
2222                    "{}assign {} = {};",
2223                    indent,
2224                    net.get_identifier().emit_name(),
2225                    driver_str
2226                )?;
2227            }
2228        }
2229
2230        writeln!(f, "endmodule")
2231    }
2232}
2233
2234/// A type alias for a netlist of gates
2235pub type GateNetlist = Netlist<Gate>;
2236/// A type alias to Gate circuit nodes
2237pub type GateRef = NetRef<Gate>;
2238
2239#[cfg(test)]
2240mod tests {
2241    use super::*;
2242    #[test]
2243    fn test_delete_netlist() {
2244        let netlist = Netlist::new("simple_example".to_string());
2245
2246        // Add the the two inputs
2247        let input1 = netlist.insert_input("input1".into());
2248        let input2 = netlist.insert_input("input2".into());
2249
2250        // Instantiate an AND gate
2251        let instance = netlist
2252            .insert_gate(
2253                Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
2254                "my_and".into(),
2255                &[input1.clone(), input2.clone()],
2256            )
2257            .unwrap();
2258
2259        // Make this AND gate an output
2260        let instance = instance.expose_as_output().unwrap();
2261        instance.delete_uses().unwrap();
2262        // Cannot clean a netlist that is in a invalid state
2263        assert!(netlist.clean().is_err());
2264        input1.expose_with_name("an_output".into());
2265        assert!(netlist.clean().is_ok());
2266    }
2267
2268    #[test]
2269    #[should_panic(expected = "Attempted to create a gate with a sliced identifier")]
2270    fn gate_w_slice_panics() {
2271        Gate::new_logical("AND[1]".into(), vec!["A".into(), "B".into()], "Y".into());
2272    }
2273
2274    #[test]
2275    fn gates_dont_have_params() {
2276        // The baseline implementation of gates do not have parameters.
2277        let gate = Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into());
2278        assert!(!gate.has_parameter(&"id".into()));
2279        assert!(gate.get_parameter(&"id".into()).is_none());
2280        assert_eq!(*gate.get_gate_name(), "AND".into());
2281    }
2282
2283    #[test]
2284    fn operand_conversions() {
2285        let operand = Operand::CellIndex(3, 2);
2286        assert_eq!(operand.to_string(), "3.2");
2287        let parsed = "3.2".parse::<Operand>();
2288        assert!(parsed.is_ok());
2289        let parsed = parsed.unwrap();
2290        assert_eq!(operand, parsed);
2291    }
2292
2293    #[test]
2294    #[should_panic(expected = "out of bounds for netref")]
2295    fn test_bad_output() {
2296        let netlist = GateNetlist::new("min_module".to_string());
2297        let a = netlist.insert_input("a".into());
2298        DrivenNet::new(1, a.unwrap());
2299    }
2300}
2301
2302#[cfg(feature = "serde")]
2303/// Serde support for netlists
2304pub mod serde {
2305    use super::{Netlist, Operand, OwnedObject, WeakIndex};
2306    use crate::{
2307        attribute::{AttributeKey, AttributeValue},
2308        circuit::{Instantiable, Net, Object},
2309    };
2310    use serde::{Deserialize, Serialize, de::DeserializeOwned};
2311    use std::cell::RefCell;
2312    use std::{collections::HashMap, rc::Rc};
2313
2314    #[derive(Debug, Serialize, Deserialize)]
2315    struct SerdeObject<I>
2316    where
2317        I: Instantiable + Serialize,
2318    {
2319        /// The object that is owned by the netlist
2320        object: Object<I>,
2321        /// The list of operands for the object
2322        operands: Vec<Option<Operand>>,
2323        /// A collection of attributes for the object
2324        attributes: HashMap<AttributeKey, AttributeValue>,
2325    }
2326
2327    impl<I, O> From<OwnedObject<I, O>> for SerdeObject<I>
2328    where
2329        I: Instantiable + Serialize,
2330        O: WeakIndex<usize, Output = OwnedObject<I, O>>,
2331    {
2332        fn from(value: OwnedObject<I, O>) -> Self {
2333            SerdeObject {
2334                object: value.object,
2335                operands: value.operands,
2336                attributes: value.attributes,
2337            }
2338        }
2339    }
2340
2341    impl<I> SerdeObject<I>
2342    where
2343        I: Instantiable + Serialize,
2344    {
2345        fn into_owned_object<O>(self, owner: &Rc<O>, index: usize) -> OwnedObject<I, O>
2346        where
2347            O: WeakIndex<usize, Output = OwnedObject<I, O>>,
2348        {
2349            OwnedObject {
2350                object: self.object,
2351                owner: Rc::downgrade(owner),
2352                operands: self.operands,
2353                attributes: self.attributes,
2354                index,
2355            }
2356        }
2357    }
2358
2359    #[derive(Debug, Serialize, Deserialize)]
2360    struct SerdeNetlist<I>
2361    where
2362        I: Instantiable + Serialize,
2363    {
2364        /// The name of the netlist
2365        name: String,
2366        /// The list of objects in the netlist, such as inputs, modules, and primitives
2367        objects: Vec<SerdeObject<I>>,
2368        /// The list of operands that point to objects which are outputs.
2369        /// Indices must be a string if we want to support JSON.
2370        outputs: HashMap<String, Net>,
2371    }
2372
2373    impl<I> From<Netlist<I>> for SerdeNetlist<I>
2374    where
2375        I: Instantiable + Serialize,
2376    {
2377        fn from(value: Netlist<I>) -> Self {
2378            SerdeNetlist {
2379                name: value.name.into_inner(),
2380                objects: value
2381                    .objects
2382                    .into_inner()
2383                    .into_iter()
2384                    .map(|o| {
2385                        Rc::try_unwrap(o)
2386                            .ok()
2387                            .expect("Cannot serialize with live references")
2388                            .into_inner()
2389                            .into()
2390                    })
2391                    .collect(),
2392                outputs: value
2393                    .outputs
2394                    .into_inner()
2395                    .into_iter()
2396                    // Indices must be a string if we want to support JSON.
2397                    .map(|(o, n)| (o.to_string(), n))
2398                    .collect(),
2399            }
2400        }
2401    }
2402
2403    impl<I> SerdeNetlist<I>
2404    where
2405        I: Instantiable + Serialize,
2406    {
2407        /// Convert the serialized netlist back into a reference-counted netlist.
2408        fn into_netlist(self) -> Rc<Netlist<I>> {
2409            let netlist = Netlist::new(self.name);
2410            let outputs: HashMap<Operand, Net> = self
2411                .outputs
2412                .into_iter()
2413                .map(|(k, v)| {
2414                    let operand = k.parse::<Operand>().expect("Invalid index");
2415                    (operand, v)
2416                })
2417                .collect();
2418            let objects = self
2419                .objects
2420                .into_iter()
2421                .enumerate()
2422                .map(|(i, o)| {
2423                    let owned_object = o.into_owned_object(&netlist, i);
2424                    Rc::new(RefCell::new(owned_object))
2425                })
2426                .collect::<Vec<_>>();
2427            {
2428                let mut objs_mut = netlist.objects.borrow_mut();
2429                *objs_mut = objects;
2430                let mut outputs_mut = netlist.outputs.borrow_mut();
2431                *outputs_mut = outputs;
2432            }
2433            netlist
2434        }
2435    }
2436
2437    /// Serialize the netlist into the writer.
2438    pub fn netlist_serialize<I: Instantiable + Serialize>(
2439        netlist: Netlist<I>,
2440        writer: impl std::io::Write,
2441    ) -> Result<(), serde_json::Error> {
2442        let sobj: SerdeNetlist<I> = netlist.into();
2443        serde_json::to_writer_pretty(writer, &sobj)
2444    }
2445
2446    /// Deserialize a netlist from the reader.
2447    pub fn netlist_deserialize<I: Instantiable + Serialize + DeserializeOwned>(
2448        reader: impl std::io::Read,
2449    ) -> Result<Rc<Netlist<I>>, serde_json::Error> {
2450        let sobj: SerdeNetlist<I> = serde_json::from_reader(reader)?;
2451        Ok(sobj.into_netlist())
2452    }
2453}