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 pub fn get_input_num(&self) -> usize {
1050 self.pos
1051 }
1052}
1053
1054impl<I> std::fmt::Display for InputPort<I>
1055where
1056 I: Instantiable,
1057{
1058 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1059 self.get_port().fmt(f)
1060 }
1061}
1062
1063#[derive(Debug, Clone)]
1065pub struct DrivenNet<I: Instantiable> {
1066 pos: usize,
1067 netref: NetRef<I>,
1068}
1069
1070impl<I> DrivenNet<I>
1071where
1072 I: Instantiable,
1073{
1074 fn new(pos: usize, netref: NetRef<I>) -> Self {
1075 if pos >= netref.clone().unwrap().borrow().get().get_nets().len() {
1076 panic!(
1077 "Position {} out of bounds for netref with {} outputted nets",
1078 pos,
1079 netref.unwrap().borrow().get().get_nets().len()
1080 );
1081 }
1082 Self { pos, netref }
1083 }
1084
1085 fn get_operand(&self) -> Operand {
1087 if self.netref.is_multi_output() {
1088 Operand::CellIndex(self.netref.clone().unwrap().borrow().get_index(), self.pos)
1089 } else {
1090 Operand::DirectIndex(self.netref.clone().unwrap().borrow().get_index())
1091 }
1092 }
1093
1094 pub fn as_net(&self) -> Ref<'_, Net> {
1096 self.netref.get_net(self.pos)
1097 }
1098
1099 pub fn as_net_mut(&self) -> RefMut<'_, Net> {
1101 self.netref.get_net_mut(self.pos)
1102 }
1103
1104 pub fn is_an_input(&self) -> bool {
1106 self.netref.is_an_input()
1107 }
1108
1109 pub fn get_port(&self) -> Net {
1111 if self.netref.is_an_input() {
1112 panic!("Net is not driven by a primitive");
1113 }
1114 self.netref
1115 .get_instance_type()
1116 .unwrap()
1117 .get_output_port(self.pos)
1118 .clone()
1119 }
1120
1121 pub fn connect(&self, input: InputPort<I>) {
1123 let operand = self.get_operand();
1124 let index = input.netref.unwrap().borrow().get_index();
1125 let netlist = self
1126 .netref
1127 .clone()
1128 .unwrap()
1129 .borrow()
1130 .owner
1131 .upgrade()
1132 .expect("Output port is unlinked from netlist");
1133 let obj = netlist.index_weak(&index);
1134 obj.borrow_mut().operands[input.pos] = Some(operand);
1135 }
1136
1137 pub fn is_top_level_output(&self) -> bool {
1139 let netlist = self
1140 .netref
1141 .clone()
1142 .unwrap()
1143 .borrow()
1144 .owner
1145 .upgrade()
1146 .expect("DrivenNet is unlinked from netlist");
1147 let outputs = netlist.outputs.borrow();
1148 outputs.contains_key(&self.get_operand())
1149 }
1150
1151 pub fn unwrap(self) -> NetRef<I> {
1153 self.netref
1154 }
1155
1156 pub fn get_identifier(&self) -> Identifier {
1158 self.as_net().get_identifier().clone()
1159 }
1160
1161 pub fn expose_with_name(self, name: Identifier) -> Self {
1168 let netlist = self
1169 .netref
1170 .clone()
1171 .unwrap()
1172 .borrow()
1173 .owner
1174 .upgrade()
1175 .expect("DrivenNet is unlinked from netlist");
1176 netlist.expose_net_with_name(self.clone(), name);
1177 self
1178 }
1179
1180 pub fn remove_output(&self, net_name: &Identifier) -> bool {
1187 let netlist = self
1188 .netref
1189 .clone()
1190 .unwrap()
1191 .borrow()
1192 .owner
1193 .upgrade()
1194 .expect("DrivenNet is unlinked from netlist");
1195 netlist.remove_output(self, net_name)
1196 }
1197
1198 pub fn remove_all_outputs(&self) -> usize {
1205 let netlist = self
1206 .netref
1207 .clone()
1208 .unwrap()
1209 .borrow()
1210 .owner
1211 .upgrade()
1212 .expect("DrivenNet is unlinked from netlist");
1213 netlist.remove_outputs(self)
1214 }
1215
1216 pub fn get_output_index(&self) -> Option<usize> {
1218 if self.netref.is_an_input() {
1219 None
1220 } else {
1221 Some(self.pos)
1222 }
1223 }
1224
1225 pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
1227 self.netref.get_instance_type()
1228 }
1229}
1230
1231impl<I> std::fmt::Display for DrivenNet<I>
1232where
1233 I: Instantiable,
1234{
1235 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1236 self.as_net().fmt(f)
1237 }
1238}
1239
1240impl<I> PartialEq for DrivenNet<I>
1241where
1242 I: Instantiable,
1243{
1244 fn eq(&self, other: &Self) -> bool {
1245 self.netref == other.netref && self.pos == other.pos
1246 }
1247}
1248
1249impl<I> Eq for DrivenNet<I> where I: Instantiable {}
1250
1251impl<I> std::hash::Hash for DrivenNet<I>
1252where
1253 I: Instantiable,
1254{
1255 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1256 self.netref.hash(state);
1257 self.pos.hash(state);
1258 }
1259}
1260
1261impl<I> Ord for DrivenNet<I>
1262where
1263 I: Instantiable,
1264{
1265 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
1266 match self.netref.cmp(&other.netref) {
1267 std::cmp::Ordering::Equal => self.pos.cmp(&other.pos),
1268 ord => ord,
1269 }
1270 }
1271}
1272
1273impl<I> PartialOrd for DrivenNet<I>
1274where
1275 I: Instantiable,
1276{
1277 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1278 Some(self.cmp(other))
1279 }
1280}
1281
1282impl<I> WeakIndex<usize> for Netlist<I>
1283where
1284 I: Instantiable,
1285{
1286 type Output = OwnedObject<I, Self>;
1287
1288 fn index_weak(&self, index: &usize) -> Rc<RefCell<Self::Output>> {
1289 self.objects.borrow()[*index].clone()
1290 }
1291}
1292
1293impl<I> Netlist<I>
1294where
1295 I: Instantiable,
1296{
1297 pub fn new(name: String) -> Rc<Self> {
1299 Rc::new(Self {
1300 name: RefCell::new(name),
1301 objects: RefCell::new(Vec::new()),
1302 outputs: RefCell::new(HashMap::new()),
1303 })
1304 }
1305
1306 pub fn reclaim(self: Rc<Self>) -> Option<Self> {
1308 Rc::try_unwrap(self).ok()
1309 }
1310
1311 pub fn deep_clone(self: &Rc<Self>) -> Rc<Self> {
1313 let dc = Rc::new(Self {
1314 name: self.name.clone(),
1315 objects: RefCell::new(Vec::new()),
1316 outputs: self.outputs.clone(),
1317 });
1318
1319 let objects_linked: Vec<NetRefT<I>> = self
1320 .objects
1321 .borrow()
1322 .iter()
1323 .map(|obj| {
1324 Rc::new(RefCell::new(OwnedObject {
1325 object: obj.borrow().object.clone(),
1326 owner: Rc::downgrade(&dc),
1327 operands: obj.borrow().operands.clone(),
1328 attributes: obj.borrow().attributes.clone(),
1329 index: obj.borrow().index,
1330 }))
1331 })
1332 .collect();
1333
1334 *dc.objects.borrow_mut() = objects_linked;
1335
1336 dc
1337 }
1338
1339 fn insert_object(
1344 self: &Rc<Self>,
1345 object: Object<I>,
1346 operands: &[DrivenNet<I>],
1347 ) -> Result<NetRef<I>, Error> {
1348 for operand in operands {
1349 self.belongs(&operand.clone().unwrap());
1350 }
1351 let index = self.objects.borrow().len();
1352 let weak = Rc::downgrade(self);
1353 let operands = operands
1354 .iter()
1355 .map(|net| Some(net.get_operand()))
1356 .collect::<Vec<_>>();
1357 let owned_object = Rc::new(RefCell::new(OwnedObject {
1358 object,
1359 owner: weak,
1360 operands,
1361 attributes: HashMap::new(),
1362 index,
1363 }));
1364 self.objects.borrow_mut().push(owned_object.clone());
1365 Ok(NetRef::wrap(owned_object))
1366 }
1367
1368 pub fn insert_input(self: &Rc<Self>, net: Net) -> DrivenNet<I> {
1370 let obj = Object::Input(net);
1371 self.insert_object(obj, &[]).unwrap().into()
1372 }
1373
1374 pub fn insert_input_escaped_logic_bus(
1376 self: &Rc<Self>,
1377 net: String,
1378 bw: usize,
1379 ) -> Vec<DrivenNet<I>> {
1380 Net::new_escaped_logic_bus(net, bw)
1381 .into_iter()
1382 .map(|n| self.insert_input(n))
1383 .collect()
1384 }
1385
1386 pub fn insert_gate(
1388 self: &Rc<Self>,
1389 inst_type: I,
1390 inst_name: Identifier,
1391 operands: &[DrivenNet<I>],
1392 ) -> Result<NetRef<I>, Error> {
1393 let nets = inst_type
1394 .get_output_ports()
1395 .into_iter()
1396 .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1397 .collect::<Vec<_>>();
1398 let input_count = inst_type.get_input_ports().into_iter().count();
1399 if operands.len() != input_count {
1400 return Err(Error::ArgumentMismatch(input_count, operands.len()));
1401 }
1402 let obj = Object::Instance(nets, inst_name, inst_type);
1403 self.insert_object(obj, operands)
1404 }
1405
1406 pub fn insert_gate_disconnected(
1408 self: &Rc<Self>,
1409 inst_type: I,
1410 inst_name: Identifier,
1411 ) -> NetRef<I> {
1412 let nets = inst_type
1413 .get_output_ports()
1414 .into_iter()
1415 .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1416 .collect::<Vec<_>>();
1417 let object = Object::Instance(nets, inst_name, inst_type);
1418 let index = self.objects.borrow().len();
1419 let weak = Rc::downgrade(self);
1420 let input_count = object
1421 .get_instance_type()
1422 .unwrap()
1423 .get_input_ports()
1424 .into_iter()
1425 .count();
1426 let operands = vec![None; input_count];
1427 let owned_object = Rc::new(RefCell::new(OwnedObject {
1428 object,
1429 owner: weak,
1430 operands,
1431 attributes: HashMap::new(),
1432 index,
1433 }));
1434 self.objects.borrow_mut().push(owned_object.clone());
1435 NetRef::wrap(owned_object)
1436 }
1437
1438 pub fn insert_constant(
1440 self: &Rc<Self>,
1441 value: Logic,
1442 inst_name: Identifier,
1443 ) -> Result<DrivenNet<I>, Error> {
1444 let obj = I::from_constant(value).ok_or(Error::InstantiableError(format!(
1445 "Instantiable type does not support constant value {}",
1446 value
1447 )))?;
1448 Ok(self.insert_gate_disconnected(obj, inst_name).into())
1449 }
1450
1451 fn belongs(&self, netref: &NetRef<I>) {
1455 if let Some(nl) = netref.netref.borrow().owner.upgrade() {
1456 if self.objects.borrow().len() != nl.objects.borrow().len() {
1457 panic!("NetRef does not belong to this netlist");
1458 }
1459
1460 if let Some(p) = self.objects.borrow().first()
1461 && let Some(np) = nl.objects.borrow().first()
1462 && !Rc::ptr_eq(p, np)
1463 {
1464 panic!("NetRef does not belong to this netlist");
1465 }
1466 }
1467
1468 if netref.netref.borrow().index >= self.objects.borrow().len() {
1469 panic!("NetRef does not belong to this netlist");
1470 }
1471 }
1472
1473 pub fn get_driver(&self, netref: NetRef<I>, index: usize) -> Option<NetRef<I>> {
1480 self.belongs(&netref);
1481 let op = netref.unwrap().borrow().operands[index]?;
1482 Some(NetRef::wrap(self.index_weak(&op.root()).clone()))
1483 }
1484
1485 pub fn expose_net_with_name(&self, net: DrivenNet<I>, name: Identifier) -> DrivenNet<I> {
1491 self.belongs(&net.clone().unwrap());
1492 let mut outputs = self.outputs.borrow_mut();
1493 let named_net = net.as_net().with_name(name);
1494 outputs
1495 .entry(net.get_operand())
1496 .or_default()
1497 .insert(named_net);
1498 net
1499 }
1500
1501 pub fn expose_net(&self, net: DrivenNet<I>) -> Result<DrivenNet<I>, Error> {
1506 self.belongs(&net.clone().unwrap());
1507 if net.is_an_input() {
1508 return Err(Error::InputNeedsAlias(net.as_net().clone()));
1509 }
1510 let mut outputs = self.outputs.borrow_mut();
1511 outputs
1512 .entry(net.get_operand())
1513 .or_default()
1514 .insert(net.as_net().clone());
1515 Ok(net)
1516 }
1517
1518 pub fn remove_output(&self, operand: &DrivenNet<I>, net_name: &Identifier) -> bool {
1524 self.belongs(&operand.clone().unwrap());
1525 let mut outputs = self.outputs.borrow_mut();
1526 if let Some(nets) = outputs.get_mut(&operand.get_operand()) {
1527 let net_to_remove = Net::new(net_name.clone(), crate::circuit::DataType::logic());
1529 if nets.remove(&net_to_remove) {
1530 if nets.is_empty() {
1532 outputs.remove(&operand.get_operand());
1533 }
1534 return true;
1535 }
1536 }
1537 false
1538 }
1539
1540 pub fn remove_outputs(&self, operand: &DrivenNet<I>) -> usize {
1543 self.outputs
1545 .borrow_mut()
1546 .remove(&operand.get_operand())
1547 .map(|nets| nets.len())
1548 .unwrap_or(0)
1549 }
1550
1551 pub fn clear_outputs(&self) {
1553 self.outputs.borrow_mut().clear();
1554 }
1555
1556 pub fn delete_net_uses(&self, netref: NetRef<I>) -> Result<Object<I>, Error> {
1561 self.belongs(&netref);
1562 let unwrapped = netref.clone().unwrap();
1563 if Rc::strong_count(&unwrapped) > 3 {
1564 return Err(Error::DanglingReference(netref.nets().collect()));
1565 }
1566 let old_index = unwrapped.borrow().get_index();
1567 let objects = self.objects.borrow();
1568 for oref in objects.iter() {
1569 let operands = &mut oref.borrow_mut().operands;
1570 for operand in operands.iter_mut() {
1571 if let Some(op) = operand {
1572 match op {
1573 Operand::DirectIndex(idx) | Operand::CellIndex(idx, _)
1574 if *idx == old_index =>
1575 {
1576 *operand = None;
1577 }
1578 _ => (),
1579 }
1580 }
1581 }
1582 }
1583
1584 let outputs: Vec<Operand> = self
1585 .outputs
1586 .borrow()
1587 .keys()
1588 .filter(|operand| match operand {
1589 Operand::DirectIndex(idx) | Operand::CellIndex(idx, _) => *idx == old_index,
1590 })
1591 .cloned()
1592 .collect();
1593
1594 for operand in outputs {
1595 self.outputs.borrow_mut().remove(&operand);
1596 }
1597
1598 Ok(netref.unwrap().borrow().get().clone())
1599 }
1600
1601 pub fn replace_net_uses(
1606 &self,
1607 of: DrivenNet<I>,
1608 with: &DrivenNet<I>,
1609 ) -> Result<Object<I>, Error> {
1610 {
1611 self.belongs(&of.clone().unwrap());
1612 self.belongs(&with.clone().unwrap());
1613 }
1614 let unwrapped = of.clone().unwrap().unwrap();
1615 let i = of.get_output_index();
1616 let k = with.get_output_index();
1617
1618 if of.clone().unwrap() == with.clone().unwrap() {
1619 if i == k {
1620 return Ok(of.unwrap().unwrap().borrow().get().clone());
1621 }
1622
1623 if Rc::strong_count(&unwrapped) > 4 {
1624 return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1625 }
1626 } else if Rc::strong_count(&unwrapped) > 3 {
1627 return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1628 }
1629
1630 let old_index = of.get_operand();
1631
1632 if let Some(nets) = self.outputs.borrow().get(&old_index)
1633 && nets.contains(&*of.as_net())
1634 {
1635 return Err(Error::NonuniqueNets(nets.iter().cloned().collect()));
1636 }
1637
1638 let new_index = with.get_operand();
1639 let objects = self.objects.borrow();
1640 for oref in objects.iter() {
1641 let operands = &mut oref.borrow_mut().operands;
1642 for operand in operands.iter_mut() {
1643 if let Some(op) = operand
1644 && *op == old_index
1645 {
1646 *operand = Some(new_index);
1647 }
1648 }
1649 }
1650
1651 let outs = self.outputs.borrow_mut().remove(&old_index);
1653 if let Some(outs) = outs {
1654 self.outputs
1655 .borrow_mut()
1656 .entry(new_index)
1657 .or_default()
1658 .extend(outs);
1659 }
1660
1661 Ok(of.unwrap().unwrap().borrow().get().clone())
1662 }
1663}
1664
1665impl<I> Netlist<I>
1666where
1667 I: Instantiable,
1668{
1669 pub fn get_name(&self) -> Ref<'_, String> {
1671 self.name.borrow()
1672 }
1673
1674 pub fn set_name(&self, name: String) {
1679 *self.name.borrow_mut() = name;
1680 }
1681
1682 pub fn get_input_ports(&self) -> impl Iterator<Item = Net> {
1684 self.objects().filter_map(|oref| {
1685 if oref.is_an_input() {
1686 Some(oref.as_net().clone())
1687 } else {
1688 None
1689 }
1690 })
1691 }
1692
1693 pub fn get_output_ports(&self) -> Vec<Net> {
1695 self.outputs
1696 .borrow()
1697 .values()
1698 .flat_map(|nets| nets.iter().cloned())
1699 .collect()
1700 }
1701
1702 pub fn get_analysis<'a, A: Analysis<'a, I>>(&'a self) -> Result<A, Error> {
1704 A::build(self)
1705 }
1706
1707 pub fn find_net(&self, net: &Net) -> Option<DrivenNet<I>> {
1710 for obj in self.objects() {
1711 for o in obj.outputs() {
1712 if *o.as_net() == *net {
1713 return Some(o);
1714 }
1715 }
1716 }
1717 None
1718 }
1719
1720 pub fn first(&self) -> Option<NetRef<I>> {
1722 self.objects
1723 .borrow()
1724 .first()
1725 .map(|nr| NetRef::wrap(nr.clone()))
1726 }
1727
1728 pub fn last(&self) -> Option<NetRef<I>> {
1730 self.objects
1731 .borrow()
1732 .last()
1733 .map(|nr| NetRef::wrap(nr.clone()))
1734 }
1735
1736 pub fn len(&self) -> usize {
1738 self.objects.borrow().len()
1739 }
1740
1741 pub fn is_empty(&self) -> bool {
1743 self.objects.borrow().is_empty()
1744 }
1745
1746 pub fn drives_an_output(&self, netref: NetRef<I>) -> bool {
1751 self.belongs(&netref);
1752 let my_index = netref.unwrap().borrow().get_index();
1753 for key in self.outputs.borrow().keys() {
1754 if key.root() == my_index {
1755 return true;
1756 }
1757 }
1758 false
1759 }
1760
1761 pub fn rename_nets<F: Fn(&Identifier, usize) -> Identifier>(&self, f: F) -> Result<(), Error> {
1779 let mut i: usize = 0;
1780 for nr in self.objects() {
1781 if nr.is_an_input() {
1782 continue;
1783 }
1784 for mut net in nr.nets_mut() {
1785 let rename = f(net.get_identifier(), i);
1786 net.set_identifier(rename);
1787 i += 1;
1788 }
1789 }
1790
1791 for nr in self.objects() {
1792 if nr.is_an_input() {
1793 continue;
1794 }
1795
1796 let rename = f(&nr.get_instance_name().unwrap(), i);
1797 nr.set_instance_name(rename);
1798 i += 1;
1799 }
1800
1801 self.verify()
1802 }
1803
1804 pub fn retain_once(&self, set: &mut HashSet<DrivenNet<I>>) -> Result<Vec<Object<I>>, Error> {
1806 let mut dead_objs = HashSet::new();
1807 {
1808 let fan_out = self.get_analysis::<FanOutTable<I>>()?;
1809 for obj in self.objects() {
1810 let mut is_dead = true;
1811 for net in obj.outputs() {
1812 if fan_out.net_has_uses(&net.as_net()) {
1814 is_dead = false;
1815 } else {
1816 set.remove(&net);
1817 }
1818 }
1819 if is_dead && !obj.is_an_input() {
1820 dead_objs.insert(obj.unwrap().borrow().index);
1821 }
1822 }
1823 }
1824
1825 if dead_objs.is_empty() {
1826 return Ok(vec![]);
1827 }
1828
1829 let old_objects = self.objects.take();
1830
1831 for i in dead_objs.iter() {
1833 let rc = &old_objects[*i];
1834 if Rc::strong_count(rc) > 1 {
1835 self.objects.replace(old_objects.clone());
1836 return Err(Error::DanglingReference(
1837 rc.borrow().get().get_nets().to_vec(),
1838 ));
1839 }
1840 }
1841
1842 let mut removed = Vec::new();
1843 let mut remap: HashMap<usize, usize> = HashMap::new();
1844 for (old_index, obj) in old_objects.into_iter().enumerate() {
1845 if dead_objs.contains(&old_index) {
1846 removed.push(obj.borrow().get().clone());
1847 continue;
1848 }
1849
1850 let new_index = self.objects.borrow().len();
1851 remap.insert(old_index, new_index);
1852 obj.borrow_mut().index = new_index;
1853 self.objects.borrow_mut().push(obj);
1854 }
1855
1856 for obj in self.objects.borrow().iter() {
1857 for operand in obj.borrow_mut().inds_mut() {
1858 let root = operand.root();
1859 let root = *remap.get(&root).unwrap_or(&root);
1860 *operand = operand.remap(root);
1861 }
1862 }
1863
1864 let pairs: Vec<_> = self.outputs.take().into_iter().collect();
1865 for (operand, net) in pairs {
1866 let root = operand.root();
1867 let root = *remap.get(&root).unwrap_or(&root);
1868 let new_operand = operand.remap(root);
1869 self.outputs.borrow_mut().insert(new_operand, net);
1870 }
1871
1872 Ok(removed)
1873 }
1874
1875 pub fn clean(&self) -> Result<Vec<Object<I>>, Error> {
1878 let mut removed = Vec::new();
1879 let mut r = self.retain_once(&mut HashSet::new())?;
1880 while !r.is_empty() {
1881 removed.extend(r);
1882 r = self.retain_once(&mut HashSet::new())?;
1883 }
1884 Ok(removed)
1885 }
1886
1887 pub fn retain(&self, set: &mut HashSet<DrivenNet<I>>) -> Result<Vec<Object<I>>, Error> {
1889 let mut removed = Vec::new();
1890 let mut r = self.retain_once(set)?;
1891 while !r.is_empty() {
1892 removed.extend(r);
1893 r = self.retain_once(set)?;
1894 }
1895 Ok(removed)
1896 }
1897
1898 fn nets_insts_unique(&self) -> Result<(), Error> {
1900 let mut nets = HashSet::new();
1901 for net in self {
1902 if !nets.insert(net.clone().take_identifier()) {
1903 return Err(Error::NonuniqueNets(vec![net]));
1904 }
1905 }
1906 for inst in self.objects() {
1907 if let Some(name) = inst.get_instance_name()
1908 && !nets.insert(name.clone())
1909 {
1910 return Err(Error::NonuniqueInsts(vec![name]));
1911 }
1912 }
1913 Ok(())
1914 }
1915
1916 pub fn verify(&self) -> Result<(), Error> {
1918 if self.outputs.borrow().is_empty() {
1919 return Err(Error::NoOutputs);
1920 }
1921
1922 self.nets_insts_unique()?;
1923
1924 Ok(())
1925 }
1926}
1927
1928#[derive(Debug, Clone)]
1930pub struct Connection<I: Instantiable> {
1931 driver: DrivenNet<I>,
1932 input: InputPort<I>,
1933}
1934
1935impl<I> Connection<I>
1936where
1937 I: Instantiable,
1938{
1939 fn new(driver: DrivenNet<I>, input: InputPort<I>) -> Self {
1940 Self { driver, input }
1941 }
1942
1943 pub fn src(&self) -> DrivenNet<I> {
1945 self.driver.clone()
1946 }
1947
1948 pub fn net(&self) -> Net {
1950 self.driver.as_net().clone()
1951 }
1952
1953 pub fn target(&self) -> InputPort<I> {
1955 self.input.clone()
1956 }
1957}
1958
1959impl<I> std::fmt::Display for Connection<I>
1960where
1961 I: Instantiable,
1962{
1963 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1964 self.net().fmt(f)
1965 }
1966}
1967
1968pub mod iter {
1970
1971 use super::{
1972 Connection, DrivenNet, InputPort, Instantiable, Net, NetRef, Netlist, Operand, WeakIndex,
1973 };
1974 use std::collections::{HashMap, HashSet};
1975 pub struct NetIterator<'a, I: Instantiable> {
1977 netlist: &'a Netlist<I>,
1978 index: usize,
1979 subindex: usize,
1980 }
1981
1982 impl<'a, I> NetIterator<'a, I>
1983 where
1984 I: Instantiable,
1985 {
1986 pub fn new(netlist: &'a Netlist<I>) -> Self {
1988 Self {
1989 netlist,
1990 index: 0,
1991 subindex: 0,
1992 }
1993 }
1994 }
1995
1996 impl<I> Iterator for NetIterator<'_, I>
1997 where
1998 I: Instantiable,
1999 {
2000 type Item = Net;
2001
2002 fn next(&mut self) -> Option<Self::Item> {
2003 while self.index < self.netlist.objects.borrow().len() {
2004 let objects = self.netlist.objects.borrow();
2005 let object = objects[self.index].borrow();
2006 if self.subindex < object.get().get_nets().len() {
2007 let net = object.get().get_nets()[self.subindex].clone();
2008 self.subindex += 1;
2009 return Some(net);
2010 }
2011 self.subindex = 0;
2012 self.index += 1;
2013 }
2014 None
2015 }
2016 }
2017
2018 pub struct ObjectIterator<'a, I: Instantiable> {
2020 netlist: &'a Netlist<I>,
2021 index: usize,
2022 }
2023
2024 impl<'a, I> ObjectIterator<'a, I>
2025 where
2026 I: Instantiable,
2027 {
2028 pub fn new(netlist: &'a Netlist<I>) -> Self {
2030 Self { netlist, index: 0 }
2031 }
2032 }
2033
2034 impl<I> Iterator for ObjectIterator<'_, I>
2035 where
2036 I: Instantiable,
2037 {
2038 type Item = NetRef<I>;
2039
2040 fn next(&mut self) -> Option<Self::Item> {
2041 if self.index < self.netlist.objects.borrow().len() {
2042 let objects = self.netlist.objects.borrow();
2043 let object = &objects[self.index];
2044 self.index += 1;
2045 return Some(NetRef::wrap(object.clone()));
2046 }
2047 None
2048 }
2049 }
2050
2051 pub struct ConnectionIterator<'a, I: Instantiable> {
2053 netlist: &'a Netlist<I>,
2054 index: usize,
2055 subindex: usize,
2056 }
2057
2058 impl<'a, I> ConnectionIterator<'a, I>
2059 where
2060 I: Instantiable,
2061 {
2062 pub fn new(netlist: &'a Netlist<I>) -> Self {
2064 Self {
2065 netlist,
2066 index: 0,
2067 subindex: 0,
2068 }
2069 }
2070 }
2071
2072 impl<I> Iterator for ConnectionIterator<'_, I>
2073 where
2074 I: Instantiable,
2075 {
2076 type Item = super::Connection<I>;
2077
2078 fn next(&mut self) -> Option<Self::Item> {
2079 while self.index < self.netlist.objects.borrow().len() {
2080 let objects = self.netlist.objects.borrow();
2081 let object = objects[self.index].borrow();
2082 let noperands = object.operands.len();
2083 while self.subindex < noperands {
2084 if let Some(operand) = &object.operands[self.subindex] {
2085 let driver = match operand {
2086 Operand::DirectIndex(idx) => {
2087 DrivenNet::new(0, NetRef::wrap(objects[*idx].clone()))
2088 }
2089 Operand::CellIndex(idx, j) => {
2090 DrivenNet::new(*j, NetRef::wrap(objects[*idx].clone()))
2091 }
2092 };
2093 let input = InputPort::new(
2094 self.subindex,
2095 NetRef::wrap(objects[self.index].clone()),
2096 );
2097 self.subindex += 1;
2098 return Some(Connection::new(driver, input));
2099 }
2100 self.subindex += 1;
2101 }
2102 self.subindex = 0;
2103 self.index += 1;
2104 }
2105 None
2106 }
2107 }
2108
2109 #[derive(Clone)]
2111 struct Walk<T: std::hash::Hash + PartialEq + Eq + Clone> {
2112 stack: Vec<T>,
2113 counter: HashMap<T, usize>,
2114 }
2115
2116 impl<T> Walk<T>
2117 where
2118 T: std::hash::Hash + PartialEq + Eq + Clone,
2119 {
2120 fn new() -> Self {
2122 Self {
2123 stack: Vec::new(),
2124 counter: HashMap::new(),
2125 }
2126 }
2127
2128 fn push(&mut self, item: T) {
2130 self.stack.push(item.clone());
2131 *self.counter.entry(item).or_insert(0) += 1;
2132 }
2133
2134 fn contains_cycle(&self) -> bool {
2136 self.counter.values().any(|&count| count > 1)
2137 }
2138
2139 fn root_cycle(&self) -> bool {
2141 if self.stack.is_empty() {
2142 return false;
2143 }
2144 self.counter[&self.stack[0]] > 1
2145 }
2146
2147 fn last(&self) -> Option<&T> {
2149 self.stack.last()
2150 }
2151 }
2152
2153 pub struct DFSIterator<'a, I: Instantiable> {
2172 dfs: NetDFSIterator<'a, I>,
2173 }
2174
2175 impl<'a, I> DFSIterator<'a, I>
2176 where
2177 I: Instantiable,
2178 {
2179 pub fn new(netlist: &'a Netlist<I>, from: NetRef<I>) -> Self {
2181 Self {
2182 dfs: NetDFSIterator::new(netlist, DrivenNet::new(0, from)),
2183 }
2184 }
2185 }
2186
2187 impl<I> DFSIterator<'_, I>
2188 where
2189 I: Instantiable,
2190 {
2191 pub fn check_cycles(&self) -> bool {
2193 self.dfs.check_cycles()
2194 }
2195
2196 pub fn detect_cycles(self) -> bool {
2198 self.dfs.detect_cycles()
2199 }
2200
2201 pub fn check_self_loop(&self) -> bool {
2203 self.dfs.check_self_loop()
2204 }
2205
2206 pub fn detect_self_loop(self) -> bool {
2208 self.dfs.detect_self_loop()
2209 }
2210 }
2211
2212 impl<I> Iterator for DFSIterator<'_, I>
2213 where
2214 I: Instantiable,
2215 {
2216 type Item = NetRef<I>;
2217
2218 fn next(&mut self) -> Option<Self::Item> {
2219 self.dfs.next().map(|d| d.unwrap())
2220 }
2221 }
2222
2223 type TermFn<I> = Box<dyn Fn(&DrivenNet<I>) -> bool + 'static>;
2224
2225 pub struct NetDFSIterator<'a, I: Instantiable> {
2227 netlist: &'a Netlist<I>,
2228 stacks: Vec<Walk<DrivenNet<I>>>,
2229 visited: HashSet<usize>,
2230 any_cycle: bool,
2231 root_cycle: bool,
2232 terminate: TermFn<I>,
2233 }
2234
2235 impl<'a, I> NetDFSIterator<'a, I>
2236 where
2237 I: Instantiable,
2238 {
2239 pub fn new_filtered<F: Fn(&DrivenNet<I>) -> bool + 'static>(
2242 netlist: &'a Netlist<I>,
2243 from: DrivenNet<I>,
2244 terminate: F,
2245 ) -> Self {
2246 let mut s = Walk::new();
2247 s.push(from);
2248 Self {
2249 netlist,
2250 stacks: vec![s],
2251 visited: HashSet::new(),
2252 any_cycle: false,
2253 root_cycle: false,
2254 terminate: Box::new(terminate),
2255 }
2256 }
2257
2258 pub fn new(netlist: &'a Netlist<I>, from: DrivenNet<I>) -> Self {
2260 Self::new_filtered(netlist, from, |_| false)
2261 }
2262 }
2263
2264 impl<I> NetDFSIterator<'_, I>
2265 where
2266 I: Instantiable,
2267 {
2268 pub fn check_cycles(&self) -> bool {
2270 self.any_cycle
2271 }
2272
2273 pub fn detect_cycles(mut self) -> bool {
2275 if self.any_cycle {
2276 return true;
2277 }
2278
2279 while let Some(_) = self.next() {
2280 if self.any_cycle {
2281 return true;
2282 }
2283 }
2284
2285 self.any_cycle
2286 }
2287
2288 pub fn check_self_loop(&self) -> bool {
2290 self.root_cycle
2291 }
2292
2293 pub fn detect_self_loop(mut self) -> bool {
2295 if self.root_cycle {
2296 return true;
2297 }
2298
2299 while let Some(_) = self.next() {
2300 if self.root_cycle {
2301 return true;
2302 }
2303 }
2304
2305 self.root_cycle
2306 }
2307 }
2308
2309 impl<I> Iterator for NetDFSIterator<'_, I>
2310 where
2311 I: Instantiable,
2312 {
2313 type Item = DrivenNet<I>;
2314
2315 fn next(&mut self) -> Option<Self::Item> {
2316 if let Some(walk) = self.stacks.pop() {
2317 self.any_cycle |= walk.contains_cycle();
2318 self.root_cycle |= walk.root_cycle();
2319 let item = walk.last().cloned();
2320 let uw = item.clone().unwrap().unwrap().unwrap();
2321 let index = uw.borrow().get_index();
2322 if self.visited.insert(index) {
2323 if !(self.terminate)(item.as_ref().unwrap()) {
2324 let operands = &uw.borrow().operands;
2325 for operand in operands.iter().flatten() {
2326 let mut new_walk = walk.clone();
2327 new_walk.push(DrivenNet::new(
2328 operand.secondary(),
2329 NetRef::wrap(self.netlist.index_weak(&operand.root())),
2330 ));
2331 self.stacks.push(new_walk);
2332 }
2333 }
2334 return item;
2335 }
2336
2337 return self.next();
2338 }
2339
2340 None
2341 }
2342 }
2343}
2344
2345impl<'a, I> IntoIterator for &'a Netlist<I>
2346where
2347 I: Instantiable,
2348{
2349 type Item = Net;
2350 type IntoIter = iter::NetIterator<'a, I>;
2351
2352 fn into_iter(self) -> Self::IntoIter {
2353 iter::NetIterator::new(self)
2354 }
2355}
2356
2357#[macro_export]
2360macro_rules! filter_nodes {
2361 ($netlist:ident, $pattern:pat $(if $guard:expr)? $(,)?) => {
2362 $netlist.matches(|f| match f {
2363 $pattern $(if $guard)? => true,
2364 _ => false
2365 })
2366 };
2367}
2368
2369impl<I> Netlist<I>
2370where
2371 I: Instantiable,
2372{
2373 pub fn objects(&self) -> impl Iterator<Item = NetRef<I>> {
2375 iter::ObjectIterator::new(self)
2376 }
2377
2378 pub fn matches<F>(&self, filter: F) -> impl Iterator<Item = NetRef<I>>
2380 where
2381 F: Fn(&I) -> bool,
2382 {
2383 self.objects().filter(move |f| {
2384 if let Some(inst_type) = f.get_instance_type() {
2385 filter(&inst_type)
2386 } else {
2387 false
2388 }
2389 })
2390 }
2391
2392 pub fn inputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
2394 self.objects()
2395 .filter(|n| n.is_an_input())
2396 .map(|n| DrivenNet::new(0, n))
2397 }
2398
2399 pub fn outputs(&self) -> Vec<(DrivenNet<I>, Net)> {
2401 self.outputs
2402 .borrow()
2403 .iter()
2404 .flat_map(|(k, nets)| {
2405 nets.iter().map(|n| {
2406 (
2407 DrivenNet::new(k.secondary(), NetRef::wrap(self.index_weak(&k.root()))),
2408 n.clone(),
2409 )
2410 })
2411 })
2412 .collect()
2413 }
2414
2415 pub fn connections(&self) -> impl Iterator<Item = Connection<I>> {
2417 iter::ConnectionIterator::new(self)
2418 }
2419
2420 pub fn node_dfs(&self, from: NetRef<I>) -> impl Iterator<Item = NetRef<I>> {
2425 self.belongs(&from);
2426 iter::DFSIterator::new(self, from)
2427 }
2428
2429 pub fn net_dfs(&self, from: DrivenNet<I>) -> impl Iterator<Item = DrivenNet<I>> {
2434 self.belongs(&from.clone().unwrap());
2435 iter::NetDFSIterator::new(self, from)
2436 }
2437
2438 #[cfg(feature = "serde")]
2439 pub fn serialize(self, writer: impl std::io::Write) -> Result<(), serde_json::Error>
2441 where
2442 I: ::serde::Serialize,
2443 {
2444 serde::netlist_serialize(self, writer)
2445 }
2446
2447 #[cfg(feature = "graph")]
2448 pub fn dot_string(&self) -> Result<String, Error> {
2450 use super::graph::MultiDiGraph;
2451 let analysis = self.get_analysis::<MultiDiGraph<_>>()?;
2452 let graph = analysis.get_graph();
2453 let dot = petgraph::dot::Dot::with_config(graph, &[]);
2454 Ok(dot.to_string())
2455 }
2456
2457 #[cfg(feature = "graph")]
2458 pub fn dump_dot(&self) -> std::io::Result<()> {
2460 use super::graph::MultiDiGraph;
2461 use std::io::Write;
2462 let mut dir = std::env::current_dir()?;
2463 let mod_name = format!("{}.dot", self.get_name());
2464 dir.push(mod_name);
2465 let mut file = std::fs::File::create(dir)?;
2466 if let Err(e) = self.verify() {
2467 write!(file, "Netlist verification failed: {e}")
2468 } else {
2469 let analysis = self.get_analysis::<MultiDiGraph<_>>().unwrap();
2470 let graph = analysis.get_graph();
2471 let dot = petgraph::dot::Dot::with_config(graph, &[]);
2472 write!(file, "{dot}")
2473 }
2474 }
2475}
2476
2477impl<I> std::fmt::Display for Netlist<I>
2478where
2479 I: Instantiable,
2480{
2481 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2482 let objects = self.objects.borrow();
2484 let outputs = self.outputs.borrow();
2485
2486 writeln!(f, "module {} (", self.get_name())?;
2487
2488 let level = 2;
2490 let indent = " ".repeat(level);
2491 for oref in objects.iter() {
2492 let owned = oref.borrow();
2493 let obj = owned.get();
2494 if let Object::Input(net) = obj {
2495 writeln!(f, "{}{},", indent, net.get_identifier().emit_name())?;
2496 }
2497 }
2498
2499 let all_outputs: Vec<_> = outputs.iter().flat_map(|(_, nets)| nets.iter()).collect();
2501 for (i, net) in all_outputs.iter().enumerate() {
2502 if i == all_outputs.len() - 1 {
2503 writeln!(f, "{}{}", indent, net.get_identifier().emit_name())?;
2504 } else {
2505 writeln!(f, "{}{},", indent, net.get_identifier().emit_name())?;
2506 }
2507 }
2508 writeln!(f, ");")?;
2509
2510 let mut already_decl = HashSet::new();
2512 for oref in objects.iter() {
2513 let owned = oref.borrow();
2514 let obj = owned.get();
2515 if let Object::Input(net) = obj {
2516 writeln!(f, "{}input {};", indent, net.get_identifier().emit_name())?;
2517 writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2518 already_decl.insert(net.clone());
2519 }
2520 }
2521 for nets in outputs.values() {
2522 for net in nets {
2523 if !already_decl.contains(net) {
2524 writeln!(f, "{}output {};", indent, net.get_identifier().emit_name())?;
2525 writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2526 already_decl.insert(net.clone());
2527 }
2528 }
2529 }
2530 for oref in objects.iter() {
2531 let owned = oref.borrow();
2532 let obj = owned.get();
2533 if let Object::Instance(nets, _, inst_type) = obj
2534 && inst_type.get_constant().is_none()
2535 {
2536 for net in nets.iter() {
2537 if !already_decl.contains(net) {
2538 writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2539 already_decl.insert(net.clone());
2540 }
2541 }
2542 }
2543 }
2544
2545 for oref in objects.iter() {
2546 let owned = oref.borrow();
2547 let obj = owned.get();
2548
2549 if let Some(inst_type) = obj.get_instance_type()
2551 && inst_type.get_constant().is_some()
2552 {
2553 continue;
2554 }
2555
2556 if let Object::Instance(nets, inst_name, inst_type) = obj {
2557 for (k, v) in owned.attributes.iter() {
2558 if let Some(value) = v {
2559 writeln!(f, "{indent}(* {k} = \"{value}\" *)")?;
2560 } else {
2561 writeln!(f, "{indent}(* {k} *)")?;
2562 }
2563 }
2564
2565 write!(f, "{}{} ", indent, inst_type.get_name())?;
2566 if inst_type.is_parameterized() {
2567 writeln!(f, "#(")?;
2568 let level = 4;
2569 let indent = " ".repeat(level);
2570 let params: Vec<_> = inst_type.parameters().collect();
2571 for (i, (k, v)) in params.iter().enumerate() {
2572 if i == params.len() - 1 {
2573 writeln!(f, "{indent}.{k}({v})")?;
2574 } else {
2575 writeln!(f, "{indent}.{k}({v}),")?;
2576 }
2577 }
2578 let level = 2;
2579 let indent = " ".repeat(level);
2580 write!(f, "{indent}) ")?;
2581 }
2582 writeln!(f, "{} (", inst_name.emit_name())?;
2583 let level = 4;
2584 let indent = " ".repeat(level);
2585 for (idx, port) in inst_type.get_input_ports().into_iter().enumerate() {
2586 let port_name = port.get_identifier().emit_name();
2587 if let Some(operand) = owned.operands[idx].as_ref() {
2588 let operand_net = match operand {
2589 Operand::DirectIndex(idx) => objects[*idx].borrow().as_net().clone(),
2590 Operand::CellIndex(idx, j) => {
2591 objects[*idx].borrow().get_net(*j).clone()
2592 }
2593 };
2594
2595 let operand_str = if let Some(inst_type) =
2596 objects[operand.root()].borrow().get().get_instance_type()
2597 && let Some(logic) = inst_type.get_constant()
2598 {
2599 logic.to_string()
2600 } else {
2601 operand_net.get_identifier().emit_name()
2602 };
2603
2604 writeln!(f, "{}.{}({}),", indent, port_name, operand_str)?;
2605 }
2606 }
2607
2608 for (idx, net) in nets.iter().enumerate() {
2609 let port_name = inst_type.get_output_port(idx).get_identifier().emit_name();
2610 if idx == nets.len() - 1 {
2611 writeln!(
2612 f,
2613 "{}.{}({})",
2614 indent,
2615 port_name,
2616 net.get_identifier().emit_name()
2617 )?;
2618 } else {
2619 writeln!(
2620 f,
2621 "{}.{}({}),",
2622 indent,
2623 port_name,
2624 net.get_identifier().emit_name()
2625 )?;
2626 }
2627 }
2628
2629 let level = 2;
2630 let indent = " ".repeat(level);
2631 writeln!(f, "{indent});")?;
2632 }
2633 }
2634
2635 for (driver, nets) in outputs.iter() {
2636 for net in nets {
2637 let driver_net = match driver {
2638 Operand::DirectIndex(idx) => self.index_weak(idx).borrow().as_net().clone(),
2639 Operand::CellIndex(idx, j) => self.index_weak(idx).borrow().get_net(*j).clone(),
2640 };
2641
2642 let driver_str = if let Some(inst_type) = self
2643 .index_weak(&driver.root())
2644 .borrow()
2645 .get()
2646 .get_instance_type()
2647 && let Some(logic) = inst_type.get_constant()
2648 {
2649 logic.to_string()
2650 } else {
2651 driver_net.get_identifier().emit_name()
2652 };
2653
2654 if net.get_identifier() != driver_net.get_identifier() {
2655 writeln!(
2656 f,
2657 "{}assign {} = {};",
2658 indent,
2659 net.get_identifier().emit_name(),
2660 driver_str
2661 )?;
2662 }
2663 }
2664 }
2665
2666 writeln!(f, "endmodule")
2667 }
2668}
2669
2670pub type GateNetlist = Netlist<Gate>;
2672pub type GateRef = NetRef<Gate>;
2674
2675#[cfg(test)]
2676mod tests {
2677 use super::iter::{DFSIterator, NetDFSIterator};
2678 use super::*;
2679 #[test]
2680 fn test_delete_netlist() {
2681 let netlist = Netlist::new("simple_example".to_string());
2682
2683 let input1 = netlist.insert_input("input1".into());
2685 let input2 = netlist.insert_input("input2".into());
2686
2687 let instance = netlist
2689 .insert_gate(
2690 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
2691 "my_and".into(),
2692 &[input1.clone(), input2.clone()],
2693 )
2694 .unwrap();
2695
2696 let instance = instance.expose_as_output().unwrap();
2698 instance.delete_uses().unwrap();
2699 assert!(netlist.clean().is_ok());
2701 input1.expose_with_name("an_output".into());
2702 assert!(netlist.clean().is_ok());
2703 }
2704
2705 #[test]
2706 #[should_panic(expected = "Attempted to create a gate with a sliced identifier")]
2707 fn gate_w_slice_panics() {
2708 Gate::new_logical("AND[1]".into(), vec!["A".into(), "B".into()], "Y".into());
2709 }
2710
2711 #[test]
2712 fn gates_dont_have_params() {
2713 let gate = Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into());
2715 assert!(!gate.has_parameter(&"id".into()));
2716 assert!(gate.get_parameter(&"id".into()).is_none());
2717 assert_eq!(*gate.get_gate_name(), "AND".into());
2718 }
2719
2720 #[test]
2721 fn operand_conversions() {
2722 let operand = Operand::CellIndex(3, 2);
2723 assert_eq!(operand.to_string(), "3.2");
2724 let parsed = "3.2".parse::<Operand>();
2725 assert!(parsed.is_ok());
2726 let parsed = parsed.unwrap();
2727 assert_eq!(operand, parsed);
2728 }
2729
2730 #[test]
2731 #[should_panic(expected = "out of bounds for netref")]
2732 fn test_bad_output() {
2733 let netlist = GateNetlist::new("min_module".to_string());
2734 let a = netlist.insert_input("a".into());
2735 DrivenNet::new(1, a.unwrap());
2736 }
2737
2738 #[test]
2739 fn test_netdfsiterator() {
2740 let netlist = Netlist::new("dfs_netlist".to_string());
2741
2742 let a = netlist.insert_input("a".into());
2744 let b = netlist.insert_input("b".into());
2745 let c = netlist.insert_input("c".into());
2746 let d = netlist.insert_input("d".into());
2747 let e = netlist.insert_input("e".into());
2748
2749 let n1 = netlist
2751 .insert_gate(
2752 Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into()),
2753 "n1".into(),
2754 &[a.clone(), b.clone()],
2755 )
2756 .unwrap()
2757 .get_output(0);
2758 let n2 = netlist
2759 .insert_gate(
2760 Gate::new_logical("NOR".into(), vec!["A".into(), "B".into()], "Y".into()),
2761 "n2".into(),
2762 &[d.clone(), e.clone()],
2763 )
2764 .unwrap()
2765 .get_output(0);
2766 let n3 = netlist
2767 .insert_gate(
2768 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
2769 "n3".into(),
2770 &[n1.clone(), c.clone()],
2771 )
2772 .unwrap()
2773 .get_output(0);
2774 let n4 = netlist
2775 .insert_gate(
2776 Gate::new_logical("NAND".into(), vec!["A".into(), "B".into()], "Y".into()),
2777 "n4".into(),
2778 &[n3.clone(), n2.clone()],
2779 )
2780 .unwrap()
2781 .get_output(0);
2782 n4.clone().expose_with_name("y".into());
2783
2784 let mut dfs = NetDFSIterator::new(&netlist, n4.clone());
2786 assert_eq!(dfs.next(), Some(n4));
2787 assert_eq!(dfs.next(), Some(n2));
2788 assert_eq!(dfs.next(), Some(e));
2789 assert_eq!(dfs.next(), Some(d));
2790 assert_eq!(dfs.next(), Some(n3));
2791 assert_eq!(dfs.next(), Some(c));
2792 assert_eq!(dfs.next(), Some(n1));
2793 assert_eq!(dfs.next(), Some(b));
2794 assert_eq!(dfs.next(), Some(a));
2795 assert_eq!(dfs.next(), None);
2796 }
2797
2798 #[test]
2799 fn test_dfs_cycles() {
2800 let netlist = Netlist::new("dfs_cycles".to_string());
2801
2802 let a = netlist.insert_input("a".into());
2804
2805 let and = netlist.insert_gate_disconnected(
2807 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
2808 "and".into(),
2809 );
2810
2811 a.connect(and.get_input(0));
2813 and.get_output(0).connect(and.get_input(1));
2814
2815 let dfs = DFSIterator::new(&netlist, and.clone());
2817 let driven_dfs = NetDFSIterator::new(&netlist, and.get_output(0));
2818
2819 assert!(dfs.detect_cycles());
2820 assert!(driven_dfs.detect_cycles());
2821 }
2822
2823 #[test]
2824 fn test_netdfsiterator_with_boundary() {
2825 let netlist = Netlist::new("dfs_netlist".to_string());
2826
2827 let a = netlist.insert_input("a".into());
2829 let b = netlist.insert_input("b".into());
2830 let c = netlist.insert_input("c".into());
2831 let d = netlist.insert_input("d".into());
2832 let e = netlist.insert_input("e".into());
2833
2834 let n1 = netlist
2836 .insert_gate(
2837 Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into()),
2838 "n1".into(),
2839 &[a.clone(), b.clone()],
2840 )
2841 .unwrap()
2842 .get_output(0);
2843 let n2 = netlist
2844 .insert_gate(
2845 Gate::new_logical("NOR".into(), vec!["A".into(), "B".into()], "Y".into()),
2846 "n2".into(),
2847 &[d.clone(), e.clone()],
2848 )
2849 .unwrap()
2850 .get_output(0);
2851 let n3 = netlist
2852 .insert_gate(
2853 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
2854 "n3".into(),
2855 &[n1.clone(), c.clone()],
2856 )
2857 .unwrap()
2858 .get_output(0);
2859 let n4 = netlist
2860 .insert_gate(
2861 Gate::new_logical("NAND".into(), vec!["A".into(), "B".into()], "Y".into()),
2862 "n4".into(),
2863 &[n3.clone(), n2.clone()],
2864 )
2865 .unwrap()
2866 .get_output(0);
2867
2868 let n3_boundary = n3.clone();
2870 let mut dfs =
2871 NetDFSIterator::new_filtered(&netlist, n4.clone(), move |n| *n == n3_boundary);
2872 assert_eq!(dfs.next(), Some(n4));
2873 assert_eq!(dfs.next(), Some(n2));
2874 assert_eq!(dfs.next(), Some(e));
2875 assert_eq!(dfs.next(), Some(d));
2876 assert_eq!(dfs.next(), Some(n3));
2877 assert_eq!(dfs.next(), None);
2878 }
2879}
2880#[cfg(feature = "serde")]
2881pub mod serde {
2883 use super::{Netlist, Operand, OwnedObject, WeakIndex};
2884 use crate::{
2885 attribute::{AttributeKey, AttributeValue},
2886 circuit::{Instantiable, Net, Object},
2887 };
2888 use serde::{Deserialize, Serialize, de::DeserializeOwned};
2889 use std::cell::RefCell;
2890 use std::{
2891 collections::{BTreeSet, HashMap},
2892 rc::Rc,
2893 };
2894
2895 #[derive(Debug, Serialize, Deserialize)]
2896 struct SerdeObject<I>
2897 where
2898 I: Instantiable + Serialize,
2899 {
2900 object: Object<I>,
2902 operands: Vec<Option<Operand>>,
2904 attributes: HashMap<AttributeKey, AttributeValue>,
2906 }
2907
2908 impl<I, O> From<OwnedObject<I, O>> for SerdeObject<I>
2909 where
2910 I: Instantiable + Serialize,
2911 O: WeakIndex<usize, Output = OwnedObject<I, O>>,
2912 {
2913 fn from(value: OwnedObject<I, O>) -> Self {
2914 SerdeObject {
2915 object: value.object,
2916 operands: value.operands,
2917 attributes: value.attributes,
2918 }
2919 }
2920 }
2921
2922 impl<I> SerdeObject<I>
2923 where
2924 I: Instantiable + Serialize,
2925 {
2926 fn into_owned_object<O>(self, owner: &Rc<O>, index: usize) -> OwnedObject<I, O>
2927 where
2928 O: WeakIndex<usize, Output = OwnedObject<I, O>>,
2929 {
2930 OwnedObject {
2931 object: self.object,
2932 owner: Rc::downgrade(owner),
2933 operands: self.operands,
2934 attributes: self.attributes,
2935 index,
2936 }
2937 }
2938 }
2939
2940 #[derive(Debug, Serialize, Deserialize)]
2941 struct SerdeNetlist<I>
2942 where
2943 I: Instantiable + Serialize,
2944 {
2945 name: String,
2947 objects: Vec<SerdeObject<I>>,
2949 outputs: HashMap<String, BTreeSet<Net>>,
2953 }
2954
2955 impl<I> From<Netlist<I>> for SerdeNetlist<I>
2956 where
2957 I: Instantiable + Serialize,
2958 {
2959 fn from(value: Netlist<I>) -> Self {
2960 SerdeNetlist {
2961 name: value.name.into_inner(),
2962 objects: value
2963 .objects
2964 .into_inner()
2965 .into_iter()
2966 .map(|o| {
2967 Rc::try_unwrap(o)
2968 .ok()
2969 .expect("Cannot serialize with live references")
2970 .into_inner()
2971 .into()
2972 })
2973 .collect(),
2974 outputs: value
2975 .outputs
2976 .into_inner()
2977 .into_iter()
2978 .map(|(o, nets)| (o.to_string(), nets.into_iter().collect()))
2980 .collect(),
2981 }
2982 }
2983 }
2984
2985 impl<I> SerdeNetlist<I>
2986 where
2987 I: Instantiable + Serialize,
2988 {
2989 fn into_netlist(self) -> Rc<Netlist<I>> {
2991 let netlist = Netlist::new(self.name);
2992 let outputs: HashMap<Operand, BTreeSet<Net>> = self
2993 .outputs
2994 .into_iter()
2995 .map(|(k, v)| {
2996 let operand = k.parse::<Operand>().expect("Invalid index");
2997 (operand, v.into_iter().collect())
2998 })
2999 .collect();
3000 let objects = self
3001 .objects
3002 .into_iter()
3003 .enumerate()
3004 .map(|(i, o)| {
3005 let owned_object = o.into_owned_object(&netlist, i);
3006 Rc::new(RefCell::new(owned_object))
3007 })
3008 .collect::<Vec<_>>();
3009 {
3010 let mut objs_mut = netlist.objects.borrow_mut();
3011 *objs_mut = objects;
3012 let mut outputs_mut = netlist.outputs.borrow_mut();
3013 *outputs_mut = outputs;
3014 }
3015 netlist
3016 }
3017 }
3018
3019 pub fn netlist_serialize<I: Instantiable + Serialize>(
3021 netlist: Netlist<I>,
3022 writer: impl std::io::Write,
3023 ) -> Result<(), serde_json::Error> {
3024 let sobj: SerdeNetlist<I> = netlist.into();
3025 serde_json::to_writer_pretty(writer, &sobj)
3026 }
3027
3028 pub fn netlist_deserialize<I: Instantiable + Serialize + DeserializeOwned>(
3030 reader: impl std::io::Read,
3031 ) -> Result<Rc<Netlist<I>>, serde_json::Error> {
3032 let sobj: SerdeNetlist<I> = serde_json::from_reader(reader)?;
3033 Ok(sobj.into_netlist())
3034 }
3035}