1use 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
21trait WeakIndex<Idx: ?Sized> {
23 type Output: ?Sized;
25 fn index_weak(&self, index: &Idx) -> Rc<RefCell<Self::Output>>;
27}
28
29#[derive(Debug, Clone)]
32#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
33pub struct Gate {
34 name: Identifier,
36 inputs: Vec<Net>,
38 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 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 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 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 pub fn set_gate_name(&mut self, new_name: Identifier) {
139 self.name = new_name;
140 }
141
142 pub fn get_gate_name(&self) -> &Identifier {
144 &self.name
145 }
146}
147
148#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
150#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
151enum Operand {
152 DirectIndex(usize),
154 CellIndex(usize, usize),
156}
157
158impl Operand {
159 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 fn root(&self) -> usize {
169 match self {
170 Operand::DirectIndex(idx) => *idx,
171 Operand::CellIndex(idx, _) => *idx,
172 }
173 }
174
175 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#[derive(Debug)]
213struct OwnedObject<I, O>
214where
215 I: Instantiable,
216 O: WeakIndex<usize, Output = Self>,
217{
218 object: Object<I>,
220 owner: Weak<O>,
222 operands: Vec<Option<Operand>>,
224 attributes: HashMap<AttributeKey, AttributeValue>,
226 index: usize,
228}
229
230impl<I, O> OwnedObject<I, O>
231where
232 I: Instantiable,
233 O: WeakIndex<usize, Output = Self>,
234{
235 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 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 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 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 fn get(&self) -> &Object<I> {
290 &self.object
291 }
292
293 fn get_mut(&mut self) -> &mut Object<I> {
295 &mut self.object
296 }
297
298 fn get_index(&self) -> usize {
300 self.index
301 }
302
303 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 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 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 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 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 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 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
435type NetRefT<I> = Rc<RefCell<OwnedObject<I, Netlist<I>>>>;
437
438#[derive(Clone)]
441pub struct NetRef<I>
442where
443 I: Instantiable,
444{
445 netref: NetRefT<I>,
446}
447
448impl<I> std::fmt::Debug for NetRef<I>
449where
450 I: Instantiable,
451{
452 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
453 let b = self.netref.borrow();
454 let o = b.get();
455 let i = b.index;
456 let owner = &b.owner;
457 match owner.upgrade() {
458 Some(owner) => {
459 let n = owner.get_name();
460 write!(f, "{{ owner: \"{n}\", index: {i}, val: \"{o}\" }}")
461 }
462 None => write!(f, "{{ owner: None, index: {i}, val: \"{o}\" }}"),
463 }
464 }
465}
466
467impl<I> PartialEq for NetRef<I>
468where
469 I: Instantiable,
470{
471 fn eq(&self, other: &Self) -> bool {
472 Rc::ptr_eq(&self.netref, &other.netref)
473 }
474}
475
476impl<I> Eq for NetRef<I> where I: Instantiable {}
477
478impl<I> Ord for NetRef<I>
479where
480 I: Instantiable,
481{
482 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
483 Rc::as_ptr(&self.netref).cmp(&Rc::as_ptr(&other.netref))
484 }
485}
486
487impl<I> PartialOrd for NetRef<I>
488where
489 I: Instantiable,
490{
491 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
492 Some(self.cmp(other))
493 }
494}
495
496impl<I> std::hash::Hash for NetRef<I>
497where
498 I: Instantiable,
499{
500 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
501 Rc::as_ptr(&self.netref).hash(state);
502 }
503}
504
505impl<I> NetRef<I>
506where
507 I: Instantiable,
508{
509 fn wrap(netref: NetRefT<I>) -> Self {
511 Self { netref }
512 }
513
514 fn unwrap(self) -> NetRefT<I> {
516 self.netref
517 }
518
519 pub fn as_net(&self) -> Ref<'_, Net> {
525 Ref::map(self.netref.borrow(), |f| f.as_net())
526 }
527
528 pub fn as_net_mut(&self) -> RefMut<'_, Net> {
534 RefMut::map(self.netref.borrow_mut(), |f| f.as_net_mut())
535 }
536
537 pub fn get_net(&self, idx: usize) -> Ref<'_, Net> {
539 Ref::map(self.netref.borrow(), |f| f.get_net(idx))
540 }
541
542 pub fn get_net_mut(&self, idx: usize) -> RefMut<'_, Net> {
544 RefMut::map(self.netref.borrow_mut(), |f| f.get_net_mut(idx))
545 }
546
547 pub fn get_output(&self, idx: usize) -> DrivenNet<I> {
549 DrivenNet::new(idx, self.clone())
550 }
551
552 pub fn find_output(&self, id: &Identifier) -> Option<DrivenNet<I>> {
554 let ind = self.get_instance_type()?.find_output(id)?;
555 Some(self.get_output(ind))
556 }
557
558 pub fn get_input(&self, idx: usize) -> InputPort<I> {
560 if self.is_an_input() {
561 panic!("Principal inputs do not have inputs");
562 }
563 InputPort::new(idx, self.clone())
564 }
565
566 pub fn find_input(&self, id: &Identifier) -> Option<InputPort<I>> {
568 let ind = self.get_instance_type()?.find_input(id)?;
569 Some(self.get_input(ind))
570 }
571
572 pub fn get_identifier(&self) -> Identifier {
578 self.as_net().get_identifier().clone()
579 }
580
581 pub fn set_identifier(&self, identifier: Identifier) {
587 self.as_net_mut().set_identifier(identifier)
588 }
589
590 pub fn is_an_input(&self) -> bool {
592 matches!(self.netref.borrow().get(), Object::Input(_))
593 }
594
595 pub fn get_obj(&self) -> Ref<'_, Object<I>> {
597 Ref::map(self.netref.borrow(), |f| f.get())
598 }
599
600 pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
602 Ref::filter_map(self.netref.borrow(), |f| f.get().get_instance_type()).ok()
603 }
604
605 pub fn get_instance_type_mut(&self) -> Option<RefMut<'_, I>> {
607 RefMut::filter_map(self.netref.borrow_mut(), |f| {
608 f.get_mut().get_instance_type_mut()
609 })
610 .ok()
611 }
612
613 pub fn get_instance_name(&self) -> Option<Identifier> {
615 match self.netref.borrow().get() {
616 Object::Instance(_, inst_name, _) => Some(inst_name.clone()),
617 _ => None,
618 }
619 }
620
621 pub fn set_instance_name(&self, name: Identifier) {
627 match self.netref.borrow_mut().get_mut() {
628 Object::Instance(_, inst_name, _) => *inst_name = name,
629 _ => panic!("Attempted to set instance name on a non-instance object"),
630 }
631 }
632
633 pub fn expose_as_output(self) -> Result<Self, Error> {
641 let netlist = self
642 .netref
643 .borrow()
644 .owner
645 .upgrade()
646 .expect("NetRef is unlinked from netlist");
647 netlist.expose_net(self.clone().into())?;
648 Ok(self)
649 }
650
651 pub fn expose_with_name(self, name: Identifier) -> Self {
659 let netlist = self
660 .netref
661 .borrow()
662 .owner
663 .upgrade()
664 .expect("NetRef is unlinked from netlist");
665 netlist.expose_net_with_name(self.clone().into(), name);
666 self
667 }
668
669 pub fn expose_net(&self, net: &Net) -> Result<(), Error> {
675 let netlist = self
676 .netref
677 .borrow()
678 .owner
679 .upgrade()
680 .expect("NetRef is unlinked from netlist");
681 let net_index = self
682 .netref
683 .borrow()
684 .find_net(net)
685 .ok_or(Error::NetNotFound(net.clone()))?;
686 let dr = DrivenNet::new(net_index, self.clone());
687 netlist.expose_net(dr)?;
688 Ok(())
689 }
690
691 pub fn remove_output(&self, net_name: &Identifier) -> bool {
699 let netlist = self
700 .netref
701 .borrow()
702 .owner
703 .upgrade()
704 .expect("NetRef is unlinked from netlist");
705 netlist.remove_output(&self.into(), net_name)
706 }
707
708 pub fn remove_all_outputs(&self) -> usize {
716 let netlist = self
717 .netref
718 .borrow()
719 .owner
720 .upgrade()
721 .expect("NetRef is unlinked from netlist");
722 netlist.remove_outputs(&self.into())
723 }
724
725 pub fn get_driver(&self, index: usize) -> Option<Self> {
727 self.netref.borrow().get_driver(index).map(NetRef::wrap)
728 }
729
730 pub fn get_driver_net(&self, index: usize) -> Option<Net> {
736 self.netref.borrow().get_driver_net(index)
737 }
738
739 pub fn req_driver_net(&self, index: usize) -> Option<MutBorrowReq<I>> {
746 let net = self.get_driver_net(index)?;
747 let operand = self.get_driver(index).unwrap();
748 Some(MutBorrowReq::new(operand, net))
749 }
750
751 pub fn get_num_input_ports(&self) -> usize {
753 if let Some(inst_type) = self.get_instance_type() {
754 inst_type.get_input_ports().into_iter().count()
755 } else {
756 0
757 }
758 }
759
760 pub fn is_fully_connected(&self) -> bool {
762 assert_eq!(
763 self.netref.borrow().operands.len(),
764 self.get_num_input_ports()
765 );
766 self.netref.borrow().operands.iter().all(|o| o.is_some())
767 }
768
769 pub fn drivers(&self) -> impl Iterator<Item = Option<Self>> {
771 let drivers: Vec<Option<Self>> = self
772 .netref
773 .borrow()
774 .drivers()
775 .map(|o| o.map(NetRef::wrap))
776 .collect();
777 drivers.into_iter()
778 }
779
780 pub fn driver_nets(&self) -> impl Iterator<Item = Option<Net>> {
782 let vec: Vec<Option<Net>> = self.netref.borrow().driver_nets().collect();
783 vec.into_iter()
784 }
785
786 #[allow(clippy::unnecessary_to_owned)]
788 pub fn nets(&self) -> impl Iterator<Item = Net> {
789 self.netref.borrow().get().get_nets().to_vec().into_iter()
790 }
791
792 pub fn inputs(&self) -> impl Iterator<Item = InputPort<I>> {
794 let len = self.netref.borrow().operands.len();
795 (0..len).map(move |i| InputPort::new(i, self.clone()))
796 }
797
798 pub fn outputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
800 let len = self.netref.borrow().get().get_nets().len();
801 (0..len).map(move |i| DrivenNet::new(i, self.clone()))
802 }
803
804 pub fn nets_mut(&self) -> impl Iterator<Item = RefMut<'_, Net>> {
806 let nnets = self.netref.borrow().get().get_nets().len();
807 (0..nnets).map(|i| self.get_net_mut(i))
808 }
809
810 pub fn drives_net(&self, net: &Net) -> bool {
812 self.netref.borrow().find_net(net).is_some()
813 }
814
815 pub fn drives_a_top_output(&self) -> bool {
820 let netlist = self
821 .netref
822 .borrow()
823 .owner
824 .upgrade()
825 .expect("NetRef is unlinked from netlist");
826 netlist.drives_an_output(self.clone())
827 }
828
829 pub fn find_net_mut(&self, net: &Net) -> Option<RefMut<'_, Net>> {
831 RefMut::filter_map(self.netref.borrow_mut(), |f| f.find_net_mut(net)).ok()
832 }
833
834 pub fn is_multi_output(&self) -> bool {
836 self.netref.borrow().get().get_nets().len() > 1
837 }
838
839 pub fn delete_uses(self) -> Result<Object<I>, Error> {
845 let netlist = self
846 .netref
847 .borrow()
848 .owner
849 .upgrade()
850 .expect("NetRef is unlinked from netlist");
851 netlist.delete_net_uses(self)
852 }
853
854 pub fn replace_uses_with(self, other: &DrivenNet<I>) -> Result<Object<I>, Error> {
861 let netlist = self
862 .netref
863 .borrow()
864 .owner
865 .upgrade()
866 .expect("NetRef is unlinked from netlist");
867 netlist.replace_net_uses(self.into(), other)
868 }
869
870 pub fn clear_attribute(&self, k: &AttributeKey) -> Option<AttributeValue> {
872 self.netref.borrow_mut().clear_attribute(k)
873 }
874
875 pub fn set_attribute(&self, k: AttributeKey) {
877 self.netref.borrow_mut().set_attribute(k);
878 }
879
880 pub fn insert_attribute(&self, k: AttributeKey, v: String) -> Option<AttributeValue> {
882 self.netref.borrow_mut().insert_attribute(k, v)
883 }
884
885 pub fn attributes(&self) -> impl Iterator<Item = Attribute> {
887 let v: Vec<_> = self.netref.borrow().attributes().collect();
888 v.into_iter()
889 }
890}
891
892impl<I> std::fmt::Display for NetRef<I>
893where
894 I: Instantiable,
895{
896 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
897 self.netref.borrow().object.fmt(f)
898 }
899}
900
901impl<I> From<NetRef<I>> for DrivenNet<I>
902where
903 I: Instantiable,
904{
905 fn from(val: NetRef<I>) -> Self {
906 if val.is_multi_output() {
907 panic!("Cannot convert a multi-output netref to an output port");
908 }
909 DrivenNet::new(0, val)
910 }
911}
912
913impl<I> From<&NetRef<I>> for DrivenNet<I>
914where
915 I: Instantiable,
916{
917 fn from(val: &NetRef<I>) -> Self {
918 if val.is_multi_output() {
919 panic!("Cannot convert a multi-output netref to an output port");
920 }
921 DrivenNet::new(0, val.clone())
922 }
923}
924
925pub struct MutBorrowReq<I: Instantiable> {
927 from: NetRef<I>,
928 ind: Net,
929}
930
931impl<I> MutBorrowReq<I>
932where
933 I: Instantiable,
934{
935 fn new(from: NetRef<I>, ind: Net) -> Self {
937 Self { from, ind }
938 }
939
940 pub fn borrow_mut(&self) -> RefMut<'_, Net> {
942 self.from.find_net_mut(&self.ind).unwrap()
943 }
944
945 pub fn is_an_input(&self) -> bool {
947 self.from.is_an_input()
948 }
949
950 pub fn borrow_mut_if(&self, f: impl Fn(&NetRef<I>) -> bool) -> Option<RefMut<'_, Net>> {
952 if f(&self.from) {
953 Some(self.borrow_mut())
954 } else {
955 None
956 }
957 }
958}
959
960#[derive(Debug)]
962pub struct Netlist<I>
963where
964 I: Instantiable,
965{
966 name: RefCell<String>,
968 objects: RefCell<Vec<NetRefT<I>>>,
970 outputs: RefCell<HashMap<Operand, BTreeSet<Net>>>,
972}
973
974#[derive(Debug, Clone)]
976pub struct InputPort<I: Instantiable> {
977 pos: usize,
978 netref: NetRef<I>,
979}
980
981impl<I> InputPort<I>
982where
983 I: Instantiable,
984{
985 fn new(pos: usize, netref: NetRef<I>) -> Self {
986 if pos >= netref.clone().unwrap().borrow().operands.len() {
987 panic!(
988 "Position {} out of bounds for netref with {} input nets",
989 pos,
990 netref.unwrap().borrow().get().get_nets().len()
991 );
992 }
993 Self { pos, netref }
994 }
995
996 pub fn get_driver(&self) -> Option<DrivenNet<I>> {
998 if self.netref.is_an_input() {
999 panic!("Input port is not driven by a primitive");
1000 }
1001 if let Some(prev_operand) = self.netref.clone().unwrap().borrow().operands[self.pos] {
1002 let netlist = self
1003 .netref
1004 .clone()
1005 .unwrap()
1006 .borrow()
1007 .owner
1008 .upgrade()
1009 .expect("Input port is unlinked from netlist");
1010 let driver_nr = netlist.index_weak(&prev_operand.root());
1011 let nr = NetRef::wrap(driver_nr);
1012 let pos = prev_operand.secondary();
1013 Some(DrivenNet::new(pos, nr))
1014 } else {
1015 None
1016 }
1017 }
1018
1019 pub fn disconnect(&self) -> Option<DrivenNet<I>> {
1021 let val = self.get_driver();
1022 self.netref.clone().unwrap().borrow_mut().operands[self.pos] = None;
1023 val
1024 }
1025
1026 pub fn get_port(&self) -> Net {
1028 if self.netref.is_an_input() {
1029 panic!("Net is not driven by a primitive");
1030 }
1031 self.netref
1032 .get_instance_type()
1033 .unwrap()
1034 .get_input_port(self.pos)
1035 .clone()
1036 }
1037
1038 pub fn connect(self, output: DrivenNet<I>) {
1040 output.connect(self);
1041 }
1042
1043 pub fn unwrap(self) -> NetRef<I> {
1045 self.netref
1046 }
1047}
1048
1049impl<I> std::fmt::Display for InputPort<I>
1050where
1051 I: Instantiable,
1052{
1053 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1054 self.get_port().fmt(f)
1055 }
1056}
1057
1058#[derive(Debug, Clone)]
1060pub struct DrivenNet<I: Instantiable> {
1061 pos: usize,
1062 netref: NetRef<I>,
1063}
1064
1065impl<I> DrivenNet<I>
1066where
1067 I: Instantiable,
1068{
1069 fn new(pos: usize, netref: NetRef<I>) -> Self {
1070 if pos >= netref.clone().unwrap().borrow().get().get_nets().len() {
1071 panic!(
1072 "Position {} out of bounds for netref with {} outputted nets",
1073 pos,
1074 netref.unwrap().borrow().get().get_nets().len()
1075 );
1076 }
1077 Self { pos, netref }
1078 }
1079
1080 fn get_operand(&self) -> Operand {
1082 if self.netref.is_multi_output() {
1083 Operand::CellIndex(self.netref.clone().unwrap().borrow().get_index(), self.pos)
1084 } else {
1085 Operand::DirectIndex(self.netref.clone().unwrap().borrow().get_index())
1086 }
1087 }
1088
1089 pub fn as_net(&self) -> Ref<'_, Net> {
1091 self.netref.get_net(self.pos)
1092 }
1093
1094 pub fn as_net_mut(&self) -> RefMut<'_, Net> {
1096 self.netref.get_net_mut(self.pos)
1097 }
1098
1099 pub fn is_an_input(&self) -> bool {
1101 self.netref.is_an_input()
1102 }
1103
1104 pub fn get_port(&self) -> Net {
1106 if self.netref.is_an_input() {
1107 panic!("Net is not driven by a primitive");
1108 }
1109 self.netref
1110 .get_instance_type()
1111 .unwrap()
1112 .get_output_port(self.pos)
1113 .clone()
1114 }
1115
1116 pub fn connect(&self, input: InputPort<I>) {
1118 let operand = self.get_operand();
1119 let index = input.netref.unwrap().borrow().get_index();
1120 let netlist = self
1121 .netref
1122 .clone()
1123 .unwrap()
1124 .borrow()
1125 .owner
1126 .upgrade()
1127 .expect("Output port is unlinked from netlist");
1128 let obj = netlist.index_weak(&index);
1129 obj.borrow_mut().operands[input.pos] = Some(operand);
1130 }
1131
1132 pub fn is_top_level_output(&self) -> bool {
1134 let netlist = self
1135 .netref
1136 .clone()
1137 .unwrap()
1138 .borrow()
1139 .owner
1140 .upgrade()
1141 .expect("DrivenNet is unlinked from netlist");
1142 let outputs = netlist.outputs.borrow();
1143 outputs.contains_key(&self.get_operand())
1144 }
1145
1146 pub fn unwrap(self) -> NetRef<I> {
1148 self.netref
1149 }
1150
1151 pub fn get_identifier(&self) -> Identifier {
1153 self.as_net().get_identifier().clone()
1154 }
1155
1156 pub fn expose_with_name(self, name: Identifier) -> Self {
1163 let netlist = self
1164 .netref
1165 .clone()
1166 .unwrap()
1167 .borrow()
1168 .owner
1169 .upgrade()
1170 .expect("DrivenNet is unlinked from netlist");
1171 netlist.expose_net_with_name(self.clone(), name);
1172 self
1173 }
1174
1175 pub fn remove_output(&self, net_name: &Identifier) -> bool {
1182 let netlist = self
1183 .netref
1184 .clone()
1185 .unwrap()
1186 .borrow()
1187 .owner
1188 .upgrade()
1189 .expect("DrivenNet is unlinked from netlist");
1190 netlist.remove_output(self, net_name)
1191 }
1192
1193 pub fn remove_all_outputs(&self) -> usize {
1200 let netlist = self
1201 .netref
1202 .clone()
1203 .unwrap()
1204 .borrow()
1205 .owner
1206 .upgrade()
1207 .expect("DrivenNet is unlinked from netlist");
1208 netlist.remove_outputs(self)
1209 }
1210
1211 pub fn get_output_index(&self) -> Option<usize> {
1213 if self.netref.is_an_input() {
1214 None
1215 } else {
1216 Some(self.pos)
1217 }
1218 }
1219
1220 pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
1222 self.netref.get_instance_type()
1223 }
1224}
1225
1226impl<I> std::fmt::Display for DrivenNet<I>
1227where
1228 I: Instantiable,
1229{
1230 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1231 self.as_net().fmt(f)
1232 }
1233}
1234
1235impl<I> PartialEq for DrivenNet<I>
1236where
1237 I: Instantiable,
1238{
1239 fn eq(&self, other: &Self) -> bool {
1240 self.netref == other.netref && self.pos == other.pos
1241 }
1242}
1243
1244impl<I> Eq for DrivenNet<I> where I: Instantiable {}
1245
1246impl<I> std::hash::Hash for DrivenNet<I>
1247where
1248 I: Instantiable,
1249{
1250 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1251 self.netref.hash(state);
1252 self.pos.hash(state);
1253 }
1254}
1255
1256impl<I> Ord for DrivenNet<I>
1257where
1258 I: Instantiable,
1259{
1260 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
1261 match self.netref.cmp(&other.netref) {
1262 std::cmp::Ordering::Equal => self.pos.cmp(&other.pos),
1263 ord => ord,
1264 }
1265 }
1266}
1267
1268impl<I> PartialOrd for DrivenNet<I>
1269where
1270 I: Instantiable,
1271{
1272 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1273 Some(self.cmp(other))
1274 }
1275}
1276
1277impl<I> WeakIndex<usize> for Netlist<I>
1278where
1279 I: Instantiable,
1280{
1281 type Output = OwnedObject<I, Self>;
1282
1283 fn index_weak(&self, index: &usize) -> Rc<RefCell<Self::Output>> {
1284 self.objects.borrow()[*index].clone()
1285 }
1286}
1287
1288impl<I> Netlist<I>
1289where
1290 I: Instantiable,
1291{
1292 pub fn new(name: String) -> Rc<Self> {
1294 Rc::new(Self {
1295 name: RefCell::new(name),
1296 objects: RefCell::new(Vec::new()),
1297 outputs: RefCell::new(HashMap::new()),
1298 })
1299 }
1300
1301 pub fn reclaim(self: Rc<Self>) -> Option<Self> {
1303 Rc::try_unwrap(self).ok()
1304 }
1305
1306 pub fn deep_clone(self: &Rc<Self>) -> Rc<Self> {
1308 let dc = Rc::new(Self {
1309 name: self.name.clone(),
1310 objects: RefCell::new(Vec::new()),
1311 outputs: self.outputs.clone(),
1312 });
1313
1314 let objects_linked: Vec<NetRefT<I>> = self
1315 .objects
1316 .borrow()
1317 .iter()
1318 .map(|obj| {
1319 Rc::new(RefCell::new(OwnedObject {
1320 object: obj.borrow().object.clone(),
1321 owner: Rc::downgrade(&dc),
1322 operands: obj.borrow().operands.clone(),
1323 attributes: obj.borrow().attributes.clone(),
1324 index: obj.borrow().index,
1325 }))
1326 })
1327 .collect();
1328
1329 *dc.objects.borrow_mut() = objects_linked;
1330
1331 dc
1332 }
1333
1334 fn insert_object(
1339 self: &Rc<Self>,
1340 object: Object<I>,
1341 operands: &[DrivenNet<I>],
1342 ) -> Result<NetRef<I>, Error> {
1343 for operand in operands {
1344 self.belongs(&operand.clone().unwrap());
1345 }
1346 let index = self.objects.borrow().len();
1347 let weak = Rc::downgrade(self);
1348 let operands = operands
1349 .iter()
1350 .map(|net| Some(net.get_operand()))
1351 .collect::<Vec<_>>();
1352 let owned_object = Rc::new(RefCell::new(OwnedObject {
1353 object,
1354 owner: weak,
1355 operands,
1356 attributes: HashMap::new(),
1357 index,
1358 }));
1359 self.objects.borrow_mut().push(owned_object.clone());
1360 Ok(NetRef::wrap(owned_object))
1361 }
1362
1363 pub fn insert_input(self: &Rc<Self>, net: Net) -> DrivenNet<I> {
1365 let obj = Object::Input(net);
1366 self.insert_object(obj, &[]).unwrap().into()
1367 }
1368
1369 pub fn insert_input_escaped_logic_bus(
1371 self: &Rc<Self>,
1372 net: String,
1373 bw: usize,
1374 ) -> Vec<DrivenNet<I>> {
1375 Net::new_escaped_logic_bus(net, bw)
1376 .into_iter()
1377 .map(|n| self.insert_input(n))
1378 .collect()
1379 }
1380
1381 pub fn insert_gate(
1383 self: &Rc<Self>,
1384 inst_type: I,
1385 inst_name: Identifier,
1386 operands: &[DrivenNet<I>],
1387 ) -> Result<NetRef<I>, Error> {
1388 let nets = inst_type
1389 .get_output_ports()
1390 .into_iter()
1391 .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1392 .collect::<Vec<_>>();
1393 let input_count = inst_type.get_input_ports().into_iter().count();
1394 if operands.len() != input_count {
1395 return Err(Error::ArgumentMismatch(input_count, operands.len()));
1396 }
1397 let obj = Object::Instance(nets, inst_name, inst_type);
1398 self.insert_object(obj, operands)
1399 }
1400
1401 pub fn insert_gate_disconnected(
1403 self: &Rc<Self>,
1404 inst_type: I,
1405 inst_name: Identifier,
1406 ) -> NetRef<I> {
1407 let nets = inst_type
1408 .get_output_ports()
1409 .into_iter()
1410 .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1411 .collect::<Vec<_>>();
1412 let object = Object::Instance(nets, inst_name, inst_type);
1413 let index = self.objects.borrow().len();
1414 let weak = Rc::downgrade(self);
1415 let input_count = object
1416 .get_instance_type()
1417 .unwrap()
1418 .get_input_ports()
1419 .into_iter()
1420 .count();
1421 let operands = vec![None; input_count];
1422 let owned_object = Rc::new(RefCell::new(OwnedObject {
1423 object,
1424 owner: weak,
1425 operands,
1426 attributes: HashMap::new(),
1427 index,
1428 }));
1429 self.objects.borrow_mut().push(owned_object.clone());
1430 NetRef::wrap(owned_object)
1431 }
1432
1433 pub fn insert_constant(
1435 self: &Rc<Self>,
1436 value: Logic,
1437 inst_name: Identifier,
1438 ) -> Result<DrivenNet<I>, Error> {
1439 let obj = I::from_constant(value).ok_or(Error::InstantiableError(format!(
1440 "Instantiable type does not support constant value {}",
1441 value
1442 )))?;
1443 Ok(self.insert_gate_disconnected(obj, inst_name).into())
1444 }
1445
1446 fn belongs(&self, netref: &NetRef<I>) {
1450 if let Some(nl) = netref.netref.borrow().owner.upgrade() {
1451 if self.objects.borrow().len() != nl.objects.borrow().len() {
1452 panic!("NetRef does not belong to this netlist");
1453 }
1454
1455 if let Some(p) = self.objects.borrow().first()
1456 && let Some(np) = nl.objects.borrow().first()
1457 && !Rc::ptr_eq(p, np)
1458 {
1459 panic!("NetRef does not belong to this netlist");
1460 }
1461 }
1462
1463 if netref.netref.borrow().index >= self.objects.borrow().len() {
1464 panic!("NetRef does not belong to this netlist");
1465 }
1466 }
1467
1468 pub fn get_driver(&self, netref: NetRef<I>, index: usize) -> Option<NetRef<I>> {
1475 self.belongs(&netref);
1476 let op = netref.unwrap().borrow().operands[index]?;
1477 Some(NetRef::wrap(self.index_weak(&op.root()).clone()))
1478 }
1479
1480 pub fn expose_net_with_name(&self, net: DrivenNet<I>, name: Identifier) -> DrivenNet<I> {
1486 self.belongs(&net.clone().unwrap());
1487 let mut outputs = self.outputs.borrow_mut();
1488 let named_net = net.as_net().with_name(name);
1489 outputs
1490 .entry(net.get_operand())
1491 .or_default()
1492 .insert(named_net);
1493 net
1494 }
1495
1496 pub fn expose_net(&self, net: DrivenNet<I>) -> Result<DrivenNet<I>, Error> {
1501 self.belongs(&net.clone().unwrap());
1502 if net.is_an_input() {
1503 return Err(Error::InputNeedsAlias(net.as_net().clone()));
1504 }
1505 let mut outputs = self.outputs.borrow_mut();
1506 outputs
1507 .entry(net.get_operand())
1508 .or_default()
1509 .insert(net.as_net().clone());
1510 Ok(net)
1511 }
1512
1513 pub fn remove_output(&self, operand: &DrivenNet<I>, net_name: &Identifier) -> bool {
1519 self.belongs(&operand.clone().unwrap());
1520 let mut outputs = self.outputs.borrow_mut();
1521 if let Some(nets) = outputs.get_mut(&operand.get_operand()) {
1522 let net_to_remove = Net::new(net_name.clone(), crate::circuit::DataType::logic());
1524 if nets.remove(&net_to_remove) {
1525 if nets.is_empty() {
1527 outputs.remove(&operand.get_operand());
1528 }
1529 return true;
1530 }
1531 }
1532 false
1533 }
1534
1535 pub fn remove_outputs(&self, operand: &DrivenNet<I>) -> usize {
1538 self.outputs
1540 .borrow_mut()
1541 .remove(&operand.get_operand())
1542 .map(|nets| nets.len())
1543 .unwrap_or(0)
1544 }
1545
1546 pub fn clear_outputs(&self) {
1548 self.outputs.borrow_mut().clear();
1549 }
1550
1551 pub fn delete_net_uses(&self, netref: NetRef<I>) -> Result<Object<I>, Error> {
1556 self.belongs(&netref);
1557 let unwrapped = netref.clone().unwrap();
1558 if Rc::strong_count(&unwrapped) > 3 {
1559 return Err(Error::DanglingReference(netref.nets().collect()));
1560 }
1561 let old_index = unwrapped.borrow().get_index();
1562 let objects = self.objects.borrow();
1563 for oref in objects.iter() {
1564 let operands = &mut oref.borrow_mut().operands;
1565 for operand in operands.iter_mut() {
1566 if let Some(op) = operand {
1567 match op {
1568 Operand::DirectIndex(idx) | Operand::CellIndex(idx, _)
1569 if *idx == old_index =>
1570 {
1571 *operand = None;
1572 }
1573 _ => (),
1574 }
1575 }
1576 }
1577 }
1578
1579 let outputs: Vec<Operand> = self
1580 .outputs
1581 .borrow()
1582 .keys()
1583 .filter(|operand| match operand {
1584 Operand::DirectIndex(idx) | Operand::CellIndex(idx, _) => *idx == old_index,
1585 })
1586 .cloned()
1587 .collect();
1588
1589 for operand in outputs {
1590 self.outputs.borrow_mut().remove(&operand);
1591 }
1592
1593 Ok(netref.unwrap().borrow().get().clone())
1594 }
1595
1596 pub fn replace_net_uses(
1601 &self,
1602 of: DrivenNet<I>,
1603 with: &DrivenNet<I>,
1604 ) -> Result<Object<I>, Error> {
1605 {
1606 self.belongs(&of.clone().unwrap());
1607 self.belongs(&with.clone().unwrap());
1608 }
1609 let unwrapped = of.clone().unwrap().unwrap();
1610 let i = of.get_output_index();
1611 let k = with.get_output_index();
1612
1613 if of.clone().unwrap() == with.clone().unwrap() {
1614 if i == k {
1615 return Ok(of.unwrap().unwrap().borrow().get().clone());
1616 }
1617
1618 if Rc::strong_count(&unwrapped) > 4 {
1619 return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1620 }
1621 } else if Rc::strong_count(&unwrapped) > 3 {
1622 return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1623 }
1624
1625 let old_index = of.get_operand();
1626
1627 if let Some(nets) = self.outputs.borrow().get(&old_index)
1628 && nets.contains(&*of.as_net())
1629 {
1630 return Err(Error::NonuniqueNets(nets.iter().cloned().collect()));
1631 }
1632
1633 let new_index = with.get_operand();
1634 let objects = self.objects.borrow();
1635 for oref in objects.iter() {
1636 let operands = &mut oref.borrow_mut().operands;
1637 for operand in operands.iter_mut() {
1638 if let Some(op) = operand
1639 && *op == old_index
1640 {
1641 *operand = Some(new_index);
1642 }
1643 }
1644 }
1645
1646 let outs = self.outputs.borrow_mut().remove(&old_index);
1648 if let Some(outs) = outs {
1649 self.outputs
1650 .borrow_mut()
1651 .entry(new_index)
1652 .or_default()
1653 .extend(outs);
1654 }
1655
1656 Ok(of.unwrap().unwrap().borrow().get().clone())
1657 }
1658}
1659
1660impl<I> Netlist<I>
1661where
1662 I: Instantiable,
1663{
1664 pub fn get_name(&self) -> Ref<'_, String> {
1666 self.name.borrow()
1667 }
1668
1669 pub fn set_name(&self, name: String) {
1674 *self.name.borrow_mut() = name;
1675 }
1676
1677 pub fn get_input_ports(&self) -> impl Iterator<Item = Net> {
1679 self.objects().filter_map(|oref| {
1680 if oref.is_an_input() {
1681 Some(oref.as_net().clone())
1682 } else {
1683 None
1684 }
1685 })
1686 }
1687
1688 pub fn get_output_ports(&self) -> Vec<Net> {
1690 self.outputs
1691 .borrow()
1692 .values()
1693 .flat_map(|nets| nets.iter().cloned())
1694 .collect()
1695 }
1696
1697 pub fn get_analysis<'a, A: Analysis<'a, I>>(&'a self) -> Result<A, Error> {
1699 A::build(self)
1700 }
1701
1702 pub fn find_net(&self, net: &Net) -> Option<DrivenNet<I>> {
1705 for obj in self.objects() {
1706 for o in obj.outputs() {
1707 if *o.as_net() == *net {
1708 return Some(o);
1709 }
1710 }
1711 }
1712 None
1713 }
1714
1715 pub fn first(&self) -> Option<NetRef<I>> {
1717 self.objects
1718 .borrow()
1719 .first()
1720 .map(|nr| NetRef::wrap(nr.clone()))
1721 }
1722
1723 pub fn last(&self) -> Option<NetRef<I>> {
1725 self.objects
1726 .borrow()
1727 .last()
1728 .map(|nr| NetRef::wrap(nr.clone()))
1729 }
1730
1731 pub fn len(&self) -> usize {
1733 self.objects.borrow().len()
1734 }
1735
1736 pub fn is_empty(&self) -> bool {
1738 self.objects.borrow().is_empty()
1739 }
1740
1741 pub fn drives_an_output(&self, netref: NetRef<I>) -> bool {
1746 self.belongs(&netref);
1747 let my_index = netref.unwrap().borrow().get_index();
1748 for key in self.outputs.borrow().keys() {
1749 if key.root() == my_index {
1750 return true;
1751 }
1752 }
1753 false
1754 }
1755
1756 pub fn rename_nets<F: Fn(&Identifier, usize) -> Identifier>(&self, f: F) -> Result<(), Error> {
1774 let mut i: usize = 0;
1775 for nr in self.objects() {
1776 if nr.is_an_input() {
1777 continue;
1778 }
1779 for mut net in nr.nets_mut() {
1780 let rename = f(net.get_identifier(), i);
1781 net.set_identifier(rename);
1782 i += 1;
1783 }
1784 }
1785
1786 for nr in self.objects() {
1787 if nr.is_an_input() {
1788 continue;
1789 }
1790
1791 let rename = f(&nr.get_instance_name().unwrap(), i);
1792 nr.set_instance_name(rename);
1793 i += 1;
1794 }
1795
1796 self.verify()
1797 }
1798
1799 pub fn clean_once(&self) -> Result<Vec<Object<I>>, Error> {
1801 let mut dead_objs = HashSet::new();
1802 {
1803 let fan_out = self.get_analysis::<FanOutTable<I>>()?;
1804 for obj in self.objects() {
1805 let mut is_dead = true;
1806 for net in obj.nets() {
1807 if fan_out.net_has_uses(&net) {
1809 is_dead = false;
1810 break;
1811 }
1812 }
1813 if is_dead && !obj.is_an_input() {
1814 dead_objs.insert(obj.unwrap().borrow().index);
1815 }
1816 }
1817 }
1818
1819 if dead_objs.is_empty() {
1820 return Ok(vec![]);
1821 }
1822
1823 let old_objects = self.objects.take();
1824
1825 for i in dead_objs.iter() {
1827 let rc = &old_objects[*i];
1828 if Rc::strong_count(rc) > 1 {
1829 self.objects.replace(old_objects.clone());
1830 return Err(Error::DanglingReference(
1831 rc.borrow().get().get_nets().to_vec(),
1832 ));
1833 }
1834 }
1835
1836 let mut removed = Vec::new();
1837 let mut remap: HashMap<usize, usize> = HashMap::new();
1838 for (old_index, obj) in old_objects.into_iter().enumerate() {
1839 if dead_objs.contains(&old_index) {
1840 removed.push(obj.borrow().get().clone());
1841 continue;
1842 }
1843
1844 let new_index = self.objects.borrow().len();
1845 remap.insert(old_index, new_index);
1846 obj.borrow_mut().index = new_index;
1847 self.objects.borrow_mut().push(obj);
1848 }
1849
1850 for obj in self.objects.borrow().iter() {
1851 for operand in obj.borrow_mut().inds_mut() {
1852 let root = operand.root();
1853 let root = *remap.get(&root).unwrap_or(&root);
1854 *operand = operand.remap(root);
1855 }
1856 }
1857
1858 let pairs: Vec<_> = self.outputs.take().into_iter().collect();
1859 for (operand, net) in pairs {
1860 let root = operand.root();
1861 let root = *remap.get(&root).unwrap_or(&root);
1862 let new_operand = operand.remap(root);
1863 self.outputs.borrow_mut().insert(new_operand, net);
1864 }
1865
1866 Ok(removed)
1867 }
1868
1869 pub fn clean(&self) -> Result<Vec<Object<I>>, Error> {
1872 let mut removed = Vec::new();
1873 let mut r = self.clean_once()?;
1874 while !r.is_empty() {
1875 removed.extend(r);
1876 r = self.clean_once()?;
1877 }
1878 Ok(removed)
1879 }
1880
1881 fn nets_insts_unique(&self) -> Result<(), Error> {
1883 let mut nets = HashSet::new();
1884 for net in self {
1885 if !nets.insert(net.clone().take_identifier()) {
1886 return Err(Error::NonuniqueNets(vec![net]));
1887 }
1888 }
1889 for inst in self.objects() {
1890 if let Some(name) = inst.get_instance_name()
1891 && !nets.insert(name.clone())
1892 {
1893 return Err(Error::NonuniqueInsts(vec![name]));
1894 }
1895 }
1896 Ok(())
1897 }
1898
1899 pub fn verify(&self) -> Result<(), Error> {
1901 if self.outputs.borrow().is_empty() {
1902 return Err(Error::NoOutputs);
1903 }
1904
1905 self.nets_insts_unique()?;
1906
1907 Ok(())
1908 }
1909}
1910
1911#[derive(Debug, Clone)]
1913pub struct Connection<I: Instantiable> {
1914 driver: DrivenNet<I>,
1915 input: InputPort<I>,
1916}
1917
1918impl<I> Connection<I>
1919where
1920 I: Instantiable,
1921{
1922 fn new(driver: DrivenNet<I>, input: InputPort<I>) -> Self {
1923 Self { driver, input }
1924 }
1925
1926 pub fn src(&self) -> DrivenNet<I> {
1928 self.driver.clone()
1929 }
1930
1931 pub fn net(&self) -> Net {
1933 self.driver.as_net().clone()
1934 }
1935
1936 pub fn target(&self) -> InputPort<I> {
1938 self.input.clone()
1939 }
1940}
1941
1942impl<I> std::fmt::Display for Connection<I>
1943where
1944 I: Instantiable,
1945{
1946 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1947 self.net().fmt(f)
1948 }
1949}
1950
1951pub mod iter {
1953
1954 use super::{
1955 Connection, DrivenNet, InputPort, Instantiable, Net, NetRef, Netlist, Operand, WeakIndex,
1956 };
1957 use std::collections::{HashMap, HashSet};
1958 pub struct NetIterator<'a, I: Instantiable> {
1960 netlist: &'a Netlist<I>,
1961 index: usize,
1962 subindex: usize,
1963 }
1964
1965 impl<'a, I> NetIterator<'a, I>
1966 where
1967 I: Instantiable,
1968 {
1969 pub fn new(netlist: &'a Netlist<I>) -> Self {
1971 Self {
1972 netlist,
1973 index: 0,
1974 subindex: 0,
1975 }
1976 }
1977 }
1978
1979 impl<I> Iterator for NetIterator<'_, I>
1980 where
1981 I: Instantiable,
1982 {
1983 type Item = Net;
1984
1985 fn next(&mut self) -> Option<Self::Item> {
1986 while self.index < self.netlist.objects.borrow().len() {
1987 let objects = self.netlist.objects.borrow();
1988 let object = objects[self.index].borrow();
1989 if self.subindex < object.get().get_nets().len() {
1990 let net = object.get().get_nets()[self.subindex].clone();
1991 self.subindex += 1;
1992 return Some(net);
1993 }
1994 self.subindex = 0;
1995 self.index += 1;
1996 }
1997 None
1998 }
1999 }
2000
2001 pub struct ObjectIterator<'a, I: Instantiable> {
2003 netlist: &'a Netlist<I>,
2004 index: usize,
2005 }
2006
2007 impl<'a, I> ObjectIterator<'a, I>
2008 where
2009 I: Instantiable,
2010 {
2011 pub fn new(netlist: &'a Netlist<I>) -> Self {
2013 Self { netlist, index: 0 }
2014 }
2015 }
2016
2017 impl<I> Iterator for ObjectIterator<'_, I>
2018 where
2019 I: Instantiable,
2020 {
2021 type Item = NetRef<I>;
2022
2023 fn next(&mut self) -> Option<Self::Item> {
2024 if self.index < self.netlist.objects.borrow().len() {
2025 let objects = self.netlist.objects.borrow();
2026 let object = &objects[self.index];
2027 self.index += 1;
2028 return Some(NetRef::wrap(object.clone()));
2029 }
2030 None
2031 }
2032 }
2033
2034 pub struct ConnectionIterator<'a, I: Instantiable> {
2036 netlist: &'a Netlist<I>,
2037 index: usize,
2038 subindex: usize,
2039 }
2040
2041 impl<'a, I> ConnectionIterator<'a, I>
2042 where
2043 I: Instantiable,
2044 {
2045 pub fn new(netlist: &'a Netlist<I>) -> Self {
2047 Self {
2048 netlist,
2049 index: 0,
2050 subindex: 0,
2051 }
2052 }
2053 }
2054
2055 impl<I> Iterator for ConnectionIterator<'_, I>
2056 where
2057 I: Instantiable,
2058 {
2059 type Item = super::Connection<I>;
2060
2061 fn next(&mut self) -> Option<Self::Item> {
2062 while self.index < self.netlist.objects.borrow().len() {
2063 let objects = self.netlist.objects.borrow();
2064 let object = objects[self.index].borrow();
2065 let noperands = object.operands.len();
2066 while self.subindex < noperands {
2067 if let Some(operand) = &object.operands[self.subindex] {
2068 let driver = match operand {
2069 Operand::DirectIndex(idx) => {
2070 DrivenNet::new(0, NetRef::wrap(objects[*idx].clone()))
2071 }
2072 Operand::CellIndex(idx, j) => {
2073 DrivenNet::new(*j, NetRef::wrap(objects[*idx].clone()))
2074 }
2075 };
2076 let input = InputPort::new(
2077 self.subindex,
2078 NetRef::wrap(objects[self.index].clone()),
2079 );
2080 self.subindex += 1;
2081 return Some(Connection::new(driver, input));
2082 }
2083 self.subindex += 1;
2084 }
2085 self.subindex = 0;
2086 self.index += 1;
2087 }
2088 None
2089 }
2090 }
2091
2092 #[derive(Clone)]
2094 struct Walk<T: std::hash::Hash + PartialEq + Eq + Clone> {
2095 stack: Vec<T>,
2096 counter: HashMap<T, usize>,
2097 }
2098
2099 impl<T> Walk<T>
2100 where
2101 T: std::hash::Hash + PartialEq + Eq + Clone,
2102 {
2103 fn new() -> Self {
2105 Self {
2106 stack: Vec::new(),
2107 counter: HashMap::new(),
2108 }
2109 }
2110
2111 fn push(&mut self, item: T) {
2113 self.stack.push(item.clone());
2114 *self.counter.entry(item).or_insert(0) += 1;
2115 }
2116
2117 fn contains_cycle(&self) -> bool {
2119 self.counter.values().any(|&count| count > 1)
2120 }
2121
2122 fn root_cycle(&self) -> bool {
2124 if self.stack.is_empty() {
2125 return false;
2126 }
2127 self.counter[&self.stack[0]] > 1
2128 }
2129
2130 fn last(&self) -> Option<&T> {
2132 self.stack.last()
2133 }
2134 }
2135
2136 pub struct DFSIterator<'a, I: Instantiable> {
2155 dfs: NetDFSIterator<'a, I>,
2156 }
2157
2158 impl<'a, I> DFSIterator<'a, I>
2159 where
2160 I: Instantiable,
2161 {
2162 pub fn new(netlist: &'a Netlist<I>, from: NetRef<I>) -> Self {
2164 Self {
2165 dfs: NetDFSIterator::new(netlist, DrivenNet::new(0, from)),
2166 }
2167 }
2168 }
2169
2170 impl<I> DFSIterator<'_, I>
2171 where
2172 I: Instantiable,
2173 {
2174 pub fn check_cycles(&self) -> bool {
2176 self.dfs.check_cycles()
2177 }
2178
2179 pub fn detect_cycles(self) -> bool {
2181 self.dfs.detect_cycles()
2182 }
2183
2184 pub fn check_self_loop(&self) -> bool {
2186 self.dfs.check_self_loop()
2187 }
2188
2189 pub fn detect_self_loop(self) -> bool {
2191 self.dfs.detect_self_loop()
2192 }
2193 }
2194
2195 impl<I> Iterator for DFSIterator<'_, I>
2196 where
2197 I: Instantiable,
2198 {
2199 type Item = NetRef<I>;
2200
2201 fn next(&mut self) -> Option<Self::Item> {
2202 self.dfs.next().map(|d| d.unwrap())
2203 }
2204 }
2205
2206 type TermFn<I> = Box<dyn Fn(&DrivenNet<I>) -> bool + 'static>;
2207
2208 pub struct NetDFSIterator<'a, I: Instantiable> {
2210 netlist: &'a Netlist<I>,
2211 stacks: Vec<Walk<DrivenNet<I>>>,
2212 visited: HashSet<usize>,
2213 any_cycle: bool,
2214 root_cycle: bool,
2215 terminate: TermFn<I>,
2216 }
2217
2218 impl<'a, I> NetDFSIterator<'a, I>
2219 where
2220 I: Instantiable,
2221 {
2222 pub fn new_filtered<F: Fn(&DrivenNet<I>) -> bool + 'static>(
2225 netlist: &'a Netlist<I>,
2226 from: DrivenNet<I>,
2227 terminate: F,
2228 ) -> Self {
2229 let mut s = Walk::new();
2230 s.push(from);
2231 Self {
2232 netlist,
2233 stacks: vec![s],
2234 visited: HashSet::new(),
2235 any_cycle: false,
2236 root_cycle: false,
2237 terminate: Box::new(terminate),
2238 }
2239 }
2240
2241 pub fn new(netlist: &'a Netlist<I>, from: DrivenNet<I>) -> Self {
2243 Self::new_filtered(netlist, from, |_| false)
2244 }
2245 }
2246
2247 impl<I> NetDFSIterator<'_, I>
2248 where
2249 I: Instantiable,
2250 {
2251 pub fn check_cycles(&self) -> bool {
2253 self.any_cycle
2254 }
2255
2256 pub fn detect_cycles(mut self) -> bool {
2258 if self.any_cycle {
2259 return true;
2260 }
2261
2262 while let Some(_) = self.next() {
2263 if self.any_cycle {
2264 return true;
2265 }
2266 }
2267
2268 self.any_cycle
2269 }
2270
2271 pub fn check_self_loop(&self) -> bool {
2273 self.root_cycle
2274 }
2275
2276 pub fn detect_self_loop(mut self) -> bool {
2278 if self.root_cycle {
2279 return true;
2280 }
2281
2282 while let Some(_) = self.next() {
2283 if self.root_cycle {
2284 return true;
2285 }
2286 }
2287
2288 self.root_cycle
2289 }
2290 }
2291
2292 impl<I> Iterator for NetDFSIterator<'_, I>
2293 where
2294 I: Instantiable,
2295 {
2296 type Item = DrivenNet<I>;
2297
2298 fn next(&mut self) -> Option<Self::Item> {
2299 if let Some(walk) = self.stacks.pop() {
2300 self.any_cycle |= walk.contains_cycle();
2301 self.root_cycle |= walk.root_cycle();
2302 let item = walk.last().cloned();
2303 let uw = item.clone().unwrap().unwrap().unwrap();
2304 let index = uw.borrow().get_index();
2305 if self.visited.insert(index) {
2306 if !(self.terminate)(item.as_ref().unwrap()) {
2307 let operands = &uw.borrow().operands;
2308 for operand in operands.iter().flatten() {
2309 let mut new_walk = walk.clone();
2310 new_walk.push(DrivenNet::new(
2311 operand.secondary(),
2312 NetRef::wrap(self.netlist.index_weak(&operand.root())),
2313 ));
2314 self.stacks.push(new_walk);
2315 }
2316 }
2317 return item;
2318 }
2319
2320 return self.next();
2321 }
2322
2323 None
2324 }
2325 }
2326}
2327
2328impl<'a, I> IntoIterator for &'a Netlist<I>
2329where
2330 I: Instantiable,
2331{
2332 type Item = Net;
2333 type IntoIter = iter::NetIterator<'a, I>;
2334
2335 fn into_iter(self) -> Self::IntoIter {
2336 iter::NetIterator::new(self)
2337 }
2338}
2339
2340#[macro_export]
2343macro_rules! filter_nodes {
2344 ($netlist:ident, $pattern:pat $(if $guard:expr)? $(,)?) => {
2345 $netlist.matches(|f| match f {
2346 $pattern $(if $guard)? => true,
2347 _ => false
2348 })
2349 };
2350}
2351
2352impl<I> Netlist<I>
2353where
2354 I: Instantiable,
2355{
2356 pub fn objects(&self) -> impl Iterator<Item = NetRef<I>> {
2358 iter::ObjectIterator::new(self)
2359 }
2360
2361 pub fn matches<F>(&self, filter: F) -> impl Iterator<Item = NetRef<I>>
2363 where
2364 F: Fn(&I) -> bool,
2365 {
2366 self.objects().filter(move |f| {
2367 if let Some(inst_type) = f.get_instance_type() {
2368 filter(&inst_type)
2369 } else {
2370 false
2371 }
2372 })
2373 }
2374
2375 pub fn inputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
2377 self.objects()
2378 .filter(|n| n.is_an_input())
2379 .map(|n| DrivenNet::new(0, n))
2380 }
2381
2382 pub fn outputs(&self) -> Vec<(DrivenNet<I>, Net)> {
2384 self.outputs
2385 .borrow()
2386 .iter()
2387 .flat_map(|(k, nets)| {
2388 nets.iter().map(|n| {
2389 (
2390 DrivenNet::new(k.secondary(), NetRef::wrap(self.index_weak(&k.root()))),
2391 n.clone(),
2392 )
2393 })
2394 })
2395 .collect()
2396 }
2397
2398 pub fn connections(&self) -> impl Iterator<Item = Connection<I>> {
2400 iter::ConnectionIterator::new(self)
2401 }
2402
2403 pub fn node_dfs(&self, from: NetRef<I>) -> impl Iterator<Item = NetRef<I>> {
2408 self.belongs(&from);
2409 iter::DFSIterator::new(self, from)
2410 }
2411
2412 pub fn net_dfs(&self, from: DrivenNet<I>) -> impl Iterator<Item = DrivenNet<I>> {
2417 self.belongs(&from.clone().unwrap());
2418 iter::NetDFSIterator::new(self, from)
2419 }
2420
2421 #[cfg(feature = "serde")]
2422 pub fn serialize(self, writer: impl std::io::Write) -> Result<(), serde_json::Error>
2424 where
2425 I: ::serde::Serialize,
2426 {
2427 serde::netlist_serialize(self, writer)
2428 }
2429
2430 #[cfg(feature = "graph")]
2431 pub fn dot_string(&self) -> Result<String, Error> {
2433 use super::graph::MultiDiGraph;
2434 let analysis = self.get_analysis::<MultiDiGraph<_>>()?;
2435 let graph = analysis.get_graph();
2436 let dot = petgraph::dot::Dot::with_config(graph, &[]);
2437 Ok(dot.to_string())
2438 }
2439
2440 #[cfg(feature = "graph")]
2441 pub fn dump_dot(&self) -> std::io::Result<()> {
2443 use super::graph::MultiDiGraph;
2444 use std::io::Write;
2445 let mut dir = std::env::current_dir()?;
2446 let mod_name = format!("{}.dot", self.get_name());
2447 dir.push(mod_name);
2448 let mut file = std::fs::File::create(dir)?;
2449 if let Err(e) = self.verify() {
2450 write!(file, "Netlist verification failed: {e}")
2451 } else {
2452 let analysis = self.get_analysis::<MultiDiGraph<_>>().unwrap();
2453 let graph = analysis.get_graph();
2454 let dot = petgraph::dot::Dot::with_config(graph, &[]);
2455 write!(file, "{dot}")
2456 }
2457 }
2458}
2459
2460impl<I> std::fmt::Display for Netlist<I>
2461where
2462 I: Instantiable,
2463{
2464 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2465 let objects = self.objects.borrow();
2467 let outputs = self.outputs.borrow();
2468
2469 writeln!(f, "module {} (", self.get_name())?;
2470
2471 let level = 2;
2473 let indent = " ".repeat(level);
2474 for oref in objects.iter() {
2475 let owned = oref.borrow();
2476 let obj = owned.get();
2477 if let Object::Input(net) = obj {
2478 writeln!(f, "{}{},", indent, net.get_identifier().emit_name())?;
2479 }
2480 }
2481
2482 let all_outputs: Vec<_> = outputs.iter().flat_map(|(_, nets)| nets.iter()).collect();
2484 for (i, net) in all_outputs.iter().enumerate() {
2485 if i == all_outputs.len() - 1 {
2486 writeln!(f, "{}{}", indent, net.get_identifier().emit_name())?;
2487 } else {
2488 writeln!(f, "{}{},", indent, net.get_identifier().emit_name())?;
2489 }
2490 }
2491 writeln!(f, ");")?;
2492
2493 let mut already_decl = HashSet::new();
2495 for oref in objects.iter() {
2496 let owned = oref.borrow();
2497 let obj = owned.get();
2498 if let Object::Input(net) = obj {
2499 writeln!(f, "{}input {};", indent, net.get_identifier().emit_name())?;
2500 writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2501 already_decl.insert(net.clone());
2502 }
2503 }
2504 for nets in outputs.values() {
2505 for net in nets {
2506 if !already_decl.contains(net) {
2507 writeln!(f, "{}output {};", indent, net.get_identifier().emit_name())?;
2508 writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2509 already_decl.insert(net.clone());
2510 }
2511 }
2512 }
2513 for oref in objects.iter() {
2514 let owned = oref.borrow();
2515 let obj = owned.get();
2516 if let Object::Instance(nets, _, inst_type) = obj
2517 && inst_type.get_constant().is_none()
2518 {
2519 for net in nets.iter() {
2520 if !already_decl.contains(net) {
2521 writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2522 already_decl.insert(net.clone());
2523 }
2524 }
2525 }
2526 }
2527
2528 for oref in objects.iter() {
2529 let owned = oref.borrow();
2530 let obj = owned.get();
2531
2532 if let Some(inst_type) = obj.get_instance_type()
2534 && inst_type.get_constant().is_some()
2535 {
2536 continue;
2537 }
2538
2539 if let Object::Instance(nets, inst_name, inst_type) = obj {
2540 for (k, v) in owned.attributes.iter() {
2541 if let Some(value) = v {
2542 writeln!(f, "{indent}(* {k} = \"{value}\" *)")?;
2543 } else {
2544 writeln!(f, "{indent}(* {k} *)")?;
2545 }
2546 }
2547
2548 write!(f, "{}{} ", indent, inst_type.get_name())?;
2549 if inst_type.is_parameterized() {
2550 writeln!(f, "#(")?;
2551 let level = 4;
2552 let indent = " ".repeat(level);
2553 let params: Vec<_> = inst_type.parameters().collect();
2554 for (i, (k, v)) in params.iter().enumerate() {
2555 if i == params.len() - 1 {
2556 writeln!(f, "{indent}.{k}({v})")?;
2557 } else {
2558 writeln!(f, "{indent}.{k}({v}),")?;
2559 }
2560 }
2561 let level = 2;
2562 let indent = " ".repeat(level);
2563 write!(f, "{indent}) ")?;
2564 }
2565 writeln!(f, "{} (", inst_name.emit_name())?;
2566 let level = 4;
2567 let indent = " ".repeat(level);
2568 for (idx, port) in inst_type.get_input_ports().into_iter().enumerate() {
2569 let port_name = port.get_identifier().emit_name();
2570 if let Some(operand) = owned.operands[idx].as_ref() {
2571 let operand_net = match operand {
2572 Operand::DirectIndex(idx) => objects[*idx].borrow().as_net().clone(),
2573 Operand::CellIndex(idx, j) => {
2574 objects[*idx].borrow().get_net(*j).clone()
2575 }
2576 };
2577
2578 let operand_str = if let Some(inst_type) =
2579 objects[operand.root()].borrow().get().get_instance_type()
2580 && let Some(logic) = inst_type.get_constant()
2581 {
2582 logic.to_string()
2583 } else {
2584 operand_net.get_identifier().emit_name()
2585 };
2586
2587 writeln!(f, "{}.{}({}),", indent, port_name, operand_str)?;
2588 }
2589 }
2590
2591 for (idx, net) in nets.iter().enumerate() {
2592 let port_name = inst_type.get_output_port(idx).get_identifier().emit_name();
2593 if idx == nets.len() - 1 {
2594 writeln!(
2595 f,
2596 "{}.{}({})",
2597 indent,
2598 port_name,
2599 net.get_identifier().emit_name()
2600 )?;
2601 } else {
2602 writeln!(
2603 f,
2604 "{}.{}({}),",
2605 indent,
2606 port_name,
2607 net.get_identifier().emit_name()
2608 )?;
2609 }
2610 }
2611
2612 let level = 2;
2613 let indent = " ".repeat(level);
2614 writeln!(f, "{indent});")?;
2615 }
2616 }
2617
2618 for (driver, nets) in outputs.iter() {
2619 for net in nets {
2620 let driver_net = match driver {
2621 Operand::DirectIndex(idx) => self.index_weak(idx).borrow().as_net().clone(),
2622 Operand::CellIndex(idx, j) => self.index_weak(idx).borrow().get_net(*j).clone(),
2623 };
2624
2625 let driver_str = if let Some(inst_type) = self
2626 .index_weak(&driver.root())
2627 .borrow()
2628 .get()
2629 .get_instance_type()
2630 && let Some(logic) = inst_type.get_constant()
2631 {
2632 logic.to_string()
2633 } else {
2634 driver_net.get_identifier().emit_name()
2635 };
2636
2637 if net.get_identifier() != driver_net.get_identifier() {
2638 writeln!(
2639 f,
2640 "{}assign {} = {};",
2641 indent,
2642 net.get_identifier().emit_name(),
2643 driver_str
2644 )?;
2645 }
2646 }
2647 }
2648
2649 writeln!(f, "endmodule")
2650 }
2651}
2652
2653pub type GateNetlist = Netlist<Gate>;
2655pub type GateRef = NetRef<Gate>;
2657
2658#[cfg(test)]
2659mod tests {
2660 use super::iter::{DFSIterator, NetDFSIterator};
2661 use super::*;
2662 #[test]
2663 fn test_delete_netlist() {
2664 let netlist = Netlist::new("simple_example".to_string());
2665
2666 let input1 = netlist.insert_input("input1".into());
2668 let input2 = netlist.insert_input("input2".into());
2669
2670 let instance = netlist
2672 .insert_gate(
2673 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
2674 "my_and".into(),
2675 &[input1.clone(), input2.clone()],
2676 )
2677 .unwrap();
2678
2679 let instance = instance.expose_as_output().unwrap();
2681 instance.delete_uses().unwrap();
2682 assert!(netlist.clean().is_err());
2684 input1.expose_with_name("an_output".into());
2685 assert!(netlist.clean().is_ok());
2686 }
2687
2688 #[test]
2689 #[should_panic(expected = "Attempted to create a gate with a sliced identifier")]
2690 fn gate_w_slice_panics() {
2691 Gate::new_logical("AND[1]".into(), vec!["A".into(), "B".into()], "Y".into());
2692 }
2693
2694 #[test]
2695 fn gates_dont_have_params() {
2696 let gate = Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into());
2698 assert!(!gate.has_parameter(&"id".into()));
2699 assert!(gate.get_parameter(&"id".into()).is_none());
2700 assert_eq!(*gate.get_gate_name(), "AND".into());
2701 }
2702
2703 #[test]
2704 fn operand_conversions() {
2705 let operand = Operand::CellIndex(3, 2);
2706 assert_eq!(operand.to_string(), "3.2");
2707 let parsed = "3.2".parse::<Operand>();
2708 assert!(parsed.is_ok());
2709 let parsed = parsed.unwrap();
2710 assert_eq!(operand, parsed);
2711 }
2712
2713 #[test]
2714 #[should_panic(expected = "out of bounds for netref")]
2715 fn test_bad_output() {
2716 let netlist = GateNetlist::new("min_module".to_string());
2717 let a = netlist.insert_input("a".into());
2718 DrivenNet::new(1, a.unwrap());
2719 }
2720
2721 #[test]
2722 fn test_netdfsiterator() {
2723 let netlist = Netlist::new("dfs_netlist".to_string());
2724
2725 let a = netlist.insert_input("a".into());
2727 let b = netlist.insert_input("b".into());
2728 let c = netlist.insert_input("c".into());
2729 let d = netlist.insert_input("d".into());
2730 let e = netlist.insert_input("e".into());
2731
2732 let n1 = netlist
2734 .insert_gate(
2735 Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into()),
2736 "n1".into(),
2737 &[a.clone(), b.clone()],
2738 )
2739 .unwrap()
2740 .get_output(0);
2741 let n2 = netlist
2742 .insert_gate(
2743 Gate::new_logical("NOR".into(), vec!["A".into(), "B".into()], "Y".into()),
2744 "n2".into(),
2745 &[d.clone(), e.clone()],
2746 )
2747 .unwrap()
2748 .get_output(0);
2749 let n3 = netlist
2750 .insert_gate(
2751 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
2752 "n3".into(),
2753 &[n1.clone(), c.clone()],
2754 )
2755 .unwrap()
2756 .get_output(0);
2757 let n4 = netlist
2758 .insert_gate(
2759 Gate::new_logical("NAND".into(), vec!["A".into(), "B".into()], "Y".into()),
2760 "n4".into(),
2761 &[n3.clone(), n2.clone()],
2762 )
2763 .unwrap()
2764 .get_output(0);
2765 n4.clone().expose_with_name("y".into());
2766
2767 let mut dfs = NetDFSIterator::new(&netlist, n4.clone());
2769 assert_eq!(dfs.next(), Some(n4));
2770 assert_eq!(dfs.next(), Some(n2));
2771 assert_eq!(dfs.next(), Some(e));
2772 assert_eq!(dfs.next(), Some(d));
2773 assert_eq!(dfs.next(), Some(n3));
2774 assert_eq!(dfs.next(), Some(c));
2775 assert_eq!(dfs.next(), Some(n1));
2776 assert_eq!(dfs.next(), Some(b));
2777 assert_eq!(dfs.next(), Some(a));
2778 assert_eq!(dfs.next(), None);
2779 }
2780
2781 #[test]
2782 fn test_dfs_cycles() {
2783 let netlist = Netlist::new("dfs_cycles".to_string());
2784
2785 let a = netlist.insert_input("a".into());
2787
2788 let and = netlist.insert_gate_disconnected(
2790 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
2791 "and".into(),
2792 );
2793
2794 a.connect(and.get_input(0));
2796 and.get_output(0).connect(and.get_input(1));
2797
2798 let dfs = DFSIterator::new(&netlist, and.clone());
2800 let driven_dfs = NetDFSIterator::new(&netlist, and.get_output(0));
2801
2802 assert!(dfs.detect_cycles());
2803 assert!(driven_dfs.detect_cycles());
2804 }
2805
2806 #[test]
2807 fn test_netdfsiterator_with_boundary() {
2808 let netlist = Netlist::new("dfs_netlist".to_string());
2809
2810 let a = netlist.insert_input("a".into());
2812 let b = netlist.insert_input("b".into());
2813 let c = netlist.insert_input("c".into());
2814 let d = netlist.insert_input("d".into());
2815 let e = netlist.insert_input("e".into());
2816
2817 let n1 = netlist
2819 .insert_gate(
2820 Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into()),
2821 "n1".into(),
2822 &[a.clone(), b.clone()],
2823 )
2824 .unwrap()
2825 .get_output(0);
2826 let n2 = netlist
2827 .insert_gate(
2828 Gate::new_logical("NOR".into(), vec!["A".into(), "B".into()], "Y".into()),
2829 "n2".into(),
2830 &[d.clone(), e.clone()],
2831 )
2832 .unwrap()
2833 .get_output(0);
2834 let n3 = netlist
2835 .insert_gate(
2836 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
2837 "n3".into(),
2838 &[n1.clone(), c.clone()],
2839 )
2840 .unwrap()
2841 .get_output(0);
2842 let n4 = netlist
2843 .insert_gate(
2844 Gate::new_logical("NAND".into(), vec!["A".into(), "B".into()], "Y".into()),
2845 "n4".into(),
2846 &[n3.clone(), n2.clone()],
2847 )
2848 .unwrap()
2849 .get_output(0);
2850
2851 let n3_boundary = n3.clone();
2853 let mut dfs =
2854 NetDFSIterator::new_filtered(&netlist, n4.clone(), move |n| *n == n3_boundary);
2855 assert_eq!(dfs.next(), Some(n4));
2856 assert_eq!(dfs.next(), Some(n2));
2857 assert_eq!(dfs.next(), Some(e));
2858 assert_eq!(dfs.next(), Some(d));
2859 assert_eq!(dfs.next(), Some(n3));
2860 assert_eq!(dfs.next(), None);
2861 }
2862}
2863#[cfg(feature = "serde")]
2864pub mod serde {
2866 use super::{Netlist, Operand, OwnedObject, WeakIndex};
2867 use crate::{
2868 attribute::{AttributeKey, AttributeValue},
2869 circuit::{Instantiable, Net, Object},
2870 };
2871 use serde::{Deserialize, Serialize, de::DeserializeOwned};
2872 use std::cell::RefCell;
2873 use std::{
2874 collections::{BTreeSet, HashMap},
2875 rc::Rc,
2876 };
2877
2878 #[derive(Debug, Serialize, Deserialize)]
2879 struct SerdeObject<I>
2880 where
2881 I: Instantiable + Serialize,
2882 {
2883 object: Object<I>,
2885 operands: Vec<Option<Operand>>,
2887 attributes: HashMap<AttributeKey, AttributeValue>,
2889 }
2890
2891 impl<I, O> From<OwnedObject<I, O>> for SerdeObject<I>
2892 where
2893 I: Instantiable + Serialize,
2894 O: WeakIndex<usize, Output = OwnedObject<I, O>>,
2895 {
2896 fn from(value: OwnedObject<I, O>) -> Self {
2897 SerdeObject {
2898 object: value.object,
2899 operands: value.operands,
2900 attributes: value.attributes,
2901 }
2902 }
2903 }
2904
2905 impl<I> SerdeObject<I>
2906 where
2907 I: Instantiable + Serialize,
2908 {
2909 fn into_owned_object<O>(self, owner: &Rc<O>, index: usize) -> OwnedObject<I, O>
2910 where
2911 O: WeakIndex<usize, Output = OwnedObject<I, O>>,
2912 {
2913 OwnedObject {
2914 object: self.object,
2915 owner: Rc::downgrade(owner),
2916 operands: self.operands,
2917 attributes: self.attributes,
2918 index,
2919 }
2920 }
2921 }
2922
2923 #[derive(Debug, Serialize, Deserialize)]
2924 struct SerdeNetlist<I>
2925 where
2926 I: Instantiable + Serialize,
2927 {
2928 name: String,
2930 objects: Vec<SerdeObject<I>>,
2932 outputs: HashMap<String, BTreeSet<Net>>,
2936 }
2937
2938 impl<I> From<Netlist<I>> for SerdeNetlist<I>
2939 where
2940 I: Instantiable + Serialize,
2941 {
2942 fn from(value: Netlist<I>) -> Self {
2943 SerdeNetlist {
2944 name: value.name.into_inner(),
2945 objects: value
2946 .objects
2947 .into_inner()
2948 .into_iter()
2949 .map(|o| {
2950 Rc::try_unwrap(o)
2951 .ok()
2952 .expect("Cannot serialize with live references")
2953 .into_inner()
2954 .into()
2955 })
2956 .collect(),
2957 outputs: value
2958 .outputs
2959 .into_inner()
2960 .into_iter()
2961 .map(|(o, nets)| (o.to_string(), nets.into_iter().collect()))
2963 .collect(),
2964 }
2965 }
2966 }
2967
2968 impl<I> SerdeNetlist<I>
2969 where
2970 I: Instantiable + Serialize,
2971 {
2972 fn into_netlist(self) -> Rc<Netlist<I>> {
2974 let netlist = Netlist::new(self.name);
2975 let outputs: HashMap<Operand, BTreeSet<Net>> = self
2976 .outputs
2977 .into_iter()
2978 .map(|(k, v)| {
2979 let operand = k.parse::<Operand>().expect("Invalid index");
2980 (operand, v.into_iter().collect())
2981 })
2982 .collect();
2983 let objects = self
2984 .objects
2985 .into_iter()
2986 .enumerate()
2987 .map(|(i, o)| {
2988 let owned_object = o.into_owned_object(&netlist, i);
2989 Rc::new(RefCell::new(owned_object))
2990 })
2991 .collect::<Vec<_>>();
2992 {
2993 let mut objs_mut = netlist.objects.borrow_mut();
2994 *objs_mut = objects;
2995 let mut outputs_mut = netlist.outputs.borrow_mut();
2996 *outputs_mut = outputs;
2997 }
2998 netlist
2999 }
3000 }
3001
3002 pub fn netlist_serialize<I: Instantiable + Serialize>(
3004 netlist: Netlist<I>,
3005 writer: impl std::io::Write,
3006 ) -> Result<(), serde_json::Error> {
3007 let sobj: SerdeNetlist<I> = netlist.into();
3008 serde_json::to_writer_pretty(writer, &sobj)
3009 }
3010
3011 pub fn netlist_deserialize<I: Instantiable + Serialize + DeserializeOwned>(
3013 reader: impl std::io::Read,
3014 ) -> Result<Rc<Netlist<I>>, serde_json::Error> {
3015 let sobj: SerdeNetlist<I> = serde_json::from_reader(reader)?;
3016 Ok(sobj.into_netlist())
3017 }
3018}