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::{BTreeMap, 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 Ord for Operand {
159 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
160 match (self, other) {
161 (Operand::DirectIndex(a), Operand::DirectIndex(b)) => a.cmp(b),
162 (Operand::CellIndex(a, b), Operand::CellIndex(c, d)) => (a, b).cmp(&(c, d)),
163 (Operand::DirectIndex(a), Operand::CellIndex(c, d)) => {
164 if a == c && *d == 0 {
165 std::cmp::Ordering::Less
166 } else {
167 (a, &0).cmp(&(c, d))
168 }
169 }
170 (Operand::CellIndex(a, b), Operand::DirectIndex(c)) => {
171 if a == c && *b == 0 {
172 std::cmp::Ordering::Greater
173 } else {
174 (a, b).cmp(&(c, &0))
175 }
176 }
177 }
178 }
179}
180
181impl PartialOrd for Operand {
182 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
183 Some(self.cmp(other))
184 }
185}
186
187impl Operand {
188 fn remap(self, x: usize) -> Self {
190 match self {
191 Operand::DirectIndex(_idx) => Operand::DirectIndex(x),
192 Operand::CellIndex(_idx, j) => Operand::CellIndex(x, j),
193 }
194 }
195
196 fn root(&self) -> usize {
198 match self {
199 Operand::DirectIndex(idx) => *idx,
200 Operand::CellIndex(idx, _) => *idx,
201 }
202 }
203
204 fn secondary(&self) -> usize {
206 match self {
207 Operand::DirectIndex(_) => 0,
208 Operand::CellIndex(_, j) => *j,
209 }
210 }
211}
212
213impl std::fmt::Display for Operand {
214 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
215 match self {
216 Operand::DirectIndex(idx) => write!(f, "{idx}"),
217 Operand::CellIndex(idx, j) => write!(f, "{idx}.{j}"),
218 }
219 }
220}
221
222impl std::str::FromStr for Operand {
223 type Err = ParseIntError;
224
225 fn from_str(s: &str) -> Result<Self, Self::Err> {
226 match s.split_once('.') {
227 Some((idx, j)) => {
228 let idx = idx.parse::<usize>()?;
229 let j = j.parse::<usize>()?;
230 Ok(Operand::CellIndex(idx, j))
231 }
232 None => {
233 let idx = s.parse::<usize>()?;
234 Ok(Operand::DirectIndex(idx))
235 }
236 }
237 }
238}
239
240#[derive(Debug)]
242struct OwnedObject<I, O>
243where
244 I: Instantiable,
245 O: WeakIndex<usize, Output = Self>,
246{
247 object: Object<I>,
249 owner: Weak<O>,
251 operands: Vec<Option<Operand>>,
253 attributes: BTreeMap<AttributeKey, AttributeValue>,
255 index: usize,
257}
258
259impl<I, O> OwnedObject<I, O>
260where
261 I: Instantiable,
262 O: WeakIndex<usize, Output = Self>,
263{
264 fn inds_mut(&mut self) -> impl Iterator<Item = &mut Operand> {
266 self.operands
267 .iter_mut()
268 .filter_map(|operand| operand.as_mut())
269 }
270
271 fn get_driver(&self, index: usize) -> Option<Rc<RefCell<Self>>> {
273 self.operands[index].as_ref().map(|operand| {
274 self.owner
275 .upgrade()
276 .expect("Object is unlinked from netlist")
277 .index_weak(&operand.root())
278 })
279 }
280
281 fn drivers(&self) -> impl Iterator<Item = Option<Rc<RefCell<Self>>>> {
283 self.operands.iter().map(|operand| {
284 operand.as_ref().map(|operand| {
285 self.owner
286 .upgrade()
287 .expect("Object is unlinked from netlist")
288 .index_weak(&operand.root())
289 })
290 })
291 }
292
293 fn driver_nets(&self) -> impl Iterator<Item = Option<Net>> {
295 self.operands.iter().map(|operand| {
296 operand.as_ref().map(|operand| match operand {
297 Operand::DirectIndex(idx) => self
298 .owner
299 .upgrade()
300 .expect("Object is unlinked from netlist")
301 .index_weak(idx)
302 .borrow()
303 .as_net()
304 .clone(),
305 Operand::CellIndex(idx, j) => self
306 .owner
307 .upgrade()
308 .expect("Object is unlinked from netlist")
309 .index_weak(idx)
310 .borrow()
311 .get_net(*j)
312 .clone(),
313 })
314 })
315 }
316
317 fn get(&self) -> &Object<I> {
319 &self.object
320 }
321
322 fn get_mut(&mut self) -> &mut Object<I> {
324 &mut self.object
325 }
326
327 fn get_index(&self) -> usize {
329 self.index
330 }
331
332 fn as_net(&self) -> &Net {
334 match &self.object {
335 Object::Input(net) => net,
336 Object::Instance(nets, _, _) => {
337 if nets.len() > 1 {
338 panic!("Attempt to grab the net of a multi-output instance");
339 } else {
340 nets.first().expect("Instance is missing a net to drive")
341 }
342 }
343 }
344 }
345
346 fn as_net_mut(&mut self) -> &mut Net {
348 match &mut self.object {
349 Object::Input(net) => net,
350 Object::Instance(nets, _, _) => {
351 if nets.len() > 1 {
352 panic!("Attempt to grab the net of a multi-output instance");
353 } else {
354 nets.first_mut()
355 .expect("Instance is missing a net to drive")
356 }
357 }
358 }
359 }
360
361 fn get_net(&self, idx: usize) -> &Net {
363 match &self.object {
364 Object::Input(net) => {
365 if idx != 0 {
366 panic!("Nonzero index on an input object");
367 }
368 net
369 }
370 Object::Instance(nets, _, _) => &nets[idx],
371 }
372 }
373
374 fn get_net_mut(&mut self, idx: usize) -> &mut Net {
376 match &mut self.object {
377 Object::Input(net) => {
378 if idx != 0 {
379 panic!("Nonzero index on an input object");
380 }
381 net
382 }
383 Object::Instance(nets, _, _) => &mut nets[idx],
384 }
385 }
386
387 fn find_net(&self, net: &Net) -> Option<usize> {
389 match &self.object {
390 Object::Input(input_net) => {
391 if input_net == net {
392 Some(0)
393 } else {
394 None
395 }
396 }
397 Object::Instance(nets, _, _) => nets.iter().position(|n| n == net),
398 }
399 }
400
401 fn find_net_mut(&mut self, net: &Net) -> Option<&mut Net> {
403 match &mut self.object {
404 Object::Input(input_net) => {
405 if input_net == net {
406 Some(input_net)
407 } else {
408 None
409 }
410 }
411 Object::Instance(nets, _, _) => nets.iter_mut().find(|n| *n == net),
412 }
413 }
414
415 fn get_driver_net(&self, index: usize) -> Option<Net> {
421 let operand = &self.operands[index];
422 match operand {
423 Some(op) => match op {
424 Operand::DirectIndex(idx) => self
425 .owner
426 .upgrade()
427 .expect("Object is unlinked from netlist")
428 .index_weak(idx)
429 .borrow()
430 .as_net()
431 .clone()
432 .into(),
433 Operand::CellIndex(idx, j) => self
434 .owner
435 .upgrade()
436 .expect("Object is unlinked from netlist")
437 .index_weak(idx)
438 .borrow()
439 .get_net(*j)
440 .clone()
441 .into(),
442 },
443 None => None,
444 }
445 }
446
447 fn clear_attribute(&mut self, k: &AttributeKey) -> Option<AttributeValue> {
448 self.attributes.remove(k)
449 }
450
451 fn set_attribute(&mut self, k: AttributeKey) {
452 self.attributes.insert(k, None);
453 }
454
455 fn insert_attribute(&mut self, k: AttributeKey, v: Parameter) -> Option<AttributeValue> {
456 self.attributes.insert(k, Some(v))
457 }
458
459 fn attributes(&self) -> impl Iterator<Item = Attribute> {
460 Attribute::from_pairs(self.attributes.clone().into_iter())
461 }
462}
463
464type NetRefT<I> = Rc<RefCell<OwnedObject<I, Netlist<I>>>>;
466
467#[derive(Clone)]
470pub struct NetRef<I>
471where
472 I: Instantiable,
473{
474 netref: NetRefT<I>,
475}
476
477impl<I> std::fmt::Debug for NetRef<I>
478where
479 I: Instantiable,
480{
481 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
482 let b = self.netref.borrow();
483 let o = b.get();
484 let i = b.index;
485 let owner = &b.owner;
486 match owner.upgrade() {
487 Some(owner) => {
488 let n = owner.get_name();
489 write!(f, "{{ owner: \"{n}\", index: {i}, val: \"{o}\" }}")
490 }
491 None => write!(f, "{{ owner: None, index: {i}, val: \"{o}\" }}"),
492 }
493 }
494}
495
496impl<I> PartialEq for NetRef<I>
497where
498 I: Instantiable,
499{
500 fn eq(&self, other: &Self) -> bool {
501 Rc::ptr_eq(&self.netref, &other.netref)
502 }
503}
504
505impl<I> Eq for NetRef<I> where I: Instantiable {}
506
507impl<I> Ord for NetRef<I>
508where
509 I: Instantiable,
510{
511 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
512 Rc::as_ptr(&self.netref).cmp(&Rc::as_ptr(&other.netref))
513 }
514}
515
516impl<I> PartialOrd for NetRef<I>
517where
518 I: Instantiable,
519{
520 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
521 Some(self.cmp(other))
522 }
523}
524
525impl<I> std::hash::Hash for NetRef<I>
526where
527 I: Instantiable,
528{
529 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
530 Rc::as_ptr(&self.netref).hash(state);
531 }
532}
533
534impl<I> NetRef<I>
535where
536 I: Instantiable,
537{
538 fn wrap(netref: NetRefT<I>) -> Self {
540 Self { netref }
541 }
542
543 fn unwrap(self) -> NetRefT<I> {
545 self.netref
546 }
547
548 pub fn as_net(&self) -> Ref<'_, Net> {
554 Ref::map(self.netref.borrow(), |f| f.as_net())
555 }
556
557 pub fn as_net_mut(&self) -> RefMut<'_, Net> {
563 RefMut::map(self.netref.borrow_mut(), |f| f.as_net_mut())
564 }
565
566 pub fn get_net(&self, idx: usize) -> Ref<'_, Net> {
568 Ref::map(self.netref.borrow(), |f| f.get_net(idx))
569 }
570
571 pub fn get_net_mut(&self, idx: usize) -> RefMut<'_, Net> {
573 RefMut::map(self.netref.borrow_mut(), |f| f.get_net_mut(idx))
574 }
575
576 pub fn get_output(&self, idx: usize) -> DrivenNet<I> {
582 let len = self.netref.borrow().get().get_nets().len();
583 if idx >= len {
584 panic!("Output index {idx} is out of bounds for circuit node with {len} outputs");
585 }
586 DrivenNet::new(idx, self.clone())
587 }
588
589 pub fn find_output(&self, id: &Identifier) -> Option<DrivenNet<I>> {
591 let ind = self.get_instance_type()?.find_output(id)?;
592 Some(self.get_output(ind))
593 }
594
595 pub fn get_input(&self, idx: usize) -> InputPort<I> {
601 if self.is_an_input() {
602 panic!("Principal inputs do not have inputs");
603 }
604 let len = self.netref.borrow().operands.len();
605 if idx >= len {
606 panic!("Input index {idx} is out of bounds for circuit node with {len} inputs");
607 }
608 InputPort::new(idx, self.clone())
609 }
610
611 pub fn find_input(&self, id: &Identifier) -> Option<InputPort<I>> {
613 let ind = self.get_instance_type()?.find_input(id)?;
614 Some(self.get_input(ind))
615 }
616
617 pub fn get_identifier(&self) -> Identifier {
623 self.as_net().get_identifier().clone()
624 }
625
626 pub fn set_identifier(&self, identifier: Identifier) {
632 self.as_net_mut().set_identifier(identifier)
633 }
634
635 pub fn is_an_input(&self) -> bool {
637 matches!(self.netref.borrow().get(), Object::Input(_))
638 }
639
640 pub fn get_obj(&self) -> Ref<'_, Object<I>> {
642 Ref::map(self.netref.borrow(), |f| f.get())
643 }
644
645 pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
647 Ref::filter_map(self.netref.borrow(), |f| f.get().get_instance_type()).ok()
648 }
649
650 pub fn get_instance_type_mut(&self) -> Option<RefMut<'_, I>> {
652 RefMut::filter_map(self.netref.borrow_mut(), |f| {
653 f.get_mut().get_instance_type_mut()
654 })
655 .ok()
656 }
657
658 pub fn get_instance_name(&self) -> Option<Identifier> {
660 match self.netref.borrow().get() {
661 Object::Instance(_, inst_name, _) => Some(inst_name.clone()),
662 _ => None,
663 }
664 }
665
666 pub fn set_instance_name(&self, name: Identifier) {
672 match self.netref.borrow_mut().get_mut() {
673 Object::Instance(_, inst_name, _) => *inst_name = name,
674 _ => panic!("Attempted to set instance name on a non-instance object"),
675 }
676 }
677
678 pub fn expose_as_output(self) -> Result<Self, Error> {
686 let netlist = self
687 .netref
688 .borrow()
689 .owner
690 .upgrade()
691 .expect("NetRef is unlinked from netlist");
692 netlist.expose_net(self.clone().into())?;
693 Ok(self)
694 }
695
696 pub fn expose_with_name(self, name: Identifier) -> Self {
704 let netlist = self
705 .netref
706 .borrow()
707 .owner
708 .upgrade()
709 .expect("NetRef is unlinked from netlist");
710 netlist.expose_net_with_name(self.clone().into(), name);
711 self
712 }
713
714 pub fn expose_net(&self, net: &Net) -> Result<(), Error> {
720 let netlist = self
721 .netref
722 .borrow()
723 .owner
724 .upgrade()
725 .expect("NetRef is unlinked from netlist");
726 let net_index = self
727 .netref
728 .borrow()
729 .find_net(net)
730 .ok_or(Error::NetNotFound(net.clone()))?;
731 let dr = DrivenNet::new(net_index, self.clone());
732 netlist.expose_net(dr)?;
733 Ok(())
734 }
735
736 pub fn remove_output(&self, net_name: &Identifier) -> bool {
744 let netlist = self
745 .netref
746 .borrow()
747 .owner
748 .upgrade()
749 .expect("NetRef is unlinked from netlist");
750 netlist.remove_output(&self.into(), net_name)
751 }
752
753 pub fn remove_all_outputs(&self) -> usize {
761 let netlist = self
762 .netref
763 .borrow()
764 .owner
765 .upgrade()
766 .expect("NetRef is unlinked from netlist");
767 netlist.remove_outputs(&self.into())
768 }
769
770 pub fn get_driver(&self, index: usize) -> Option<Self> {
772 self.netref.borrow().get_driver(index).map(NetRef::wrap)
773 }
774
775 pub fn get_driver_net(&self, index: usize) -> Option<Net> {
781 self.netref.borrow().get_driver_net(index)
782 }
783
784 pub fn get_num_input_ports(&self) -> usize {
786 if let Some(inst_type) = self.get_instance_type() {
787 inst_type.get_input_ports().into_iter().count()
788 } else {
789 0
790 }
791 }
792
793 pub fn is_fully_connected(&self) -> bool {
795 assert_eq!(
796 self.netref.borrow().operands.len(),
797 self.get_num_input_ports()
798 );
799 self.netref.borrow().operands.iter().all(|o| o.is_some())
800 }
801
802 pub fn drivers(&self) -> impl Iterator<Item = Option<Self>> {
804 let drivers: Vec<Option<Self>> = self
805 .netref
806 .borrow()
807 .drivers()
808 .map(|o| o.map(NetRef::wrap))
809 .collect();
810 drivers.into_iter()
811 }
812
813 pub fn driver_nets(&self) -> impl Iterator<Item = Option<Net>> {
815 let vec: Vec<Option<Net>> = self.netref.borrow().driver_nets().collect();
816 vec.into_iter()
817 }
818
819 #[allow(clippy::unnecessary_to_owned)]
821 pub fn nets(&self) -> impl Iterator<Item = Net> {
822 self.netref.borrow().get().get_nets().to_vec().into_iter()
823 }
824
825 pub fn inputs(&self) -> impl Iterator<Item = InputPort<I>> {
827 let len = self.netref.borrow().operands.len();
828 (0..len).map(move |i| InputPort::new(i, self.clone()))
829 }
830
831 pub fn outputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
833 let len = self.netref.borrow().get().get_nets().len();
834 (0..len).map(move |i| DrivenNet::new(i, self.clone()))
835 }
836
837 pub fn nets_mut(&self) -> impl Iterator<Item = RefMut<'_, Net>> {
839 let nnets = self.netref.borrow().get().get_nets().len();
840 (0..nnets).map(|i| self.get_net_mut(i))
841 }
842
843 pub fn drives_net(&self, net: &Net) -> bool {
845 self.netref.borrow().find_net(net).is_some()
846 }
847
848 pub fn drives_a_top_output(&self) -> bool {
853 let netlist = self
854 .netref
855 .borrow()
856 .owner
857 .upgrade()
858 .expect("NetRef is unlinked from netlist");
859 netlist.drives_an_output(self.clone())
860 }
861
862 pub fn find_net_mut(&self, net: &Net) -> Option<RefMut<'_, Net>> {
864 RefMut::filter_map(self.netref.borrow_mut(), |f| f.find_net_mut(net)).ok()
865 }
866
867 pub fn is_multi_output(&self) -> bool {
869 self.netref.borrow().get().get_nets().len() > 1
870 }
871
872 pub fn delete_uses(self) -> Result<Object<I>, Error> {
878 let netlist = self
879 .netref
880 .borrow()
881 .owner
882 .upgrade()
883 .expect("NetRef is unlinked from netlist");
884 netlist.delete_net_uses(self)
885 }
886
887 pub fn replace_uses_with(self, other: &DrivenNet<I>) -> Result<NetRef<I>, Error> {
897 let netlist = self
898 .netref
899 .borrow()
900 .owner
901 .upgrade()
902 .expect("NetRef is unlinked from netlist");
903 netlist
904 .replace_net_uses(self.into(), other)
905 .map(|d| d.unwrap())
906 }
907
908 pub fn clear_attribute(&self, k: &AttributeKey) -> Option<AttributeValue> {
910 self.netref.borrow_mut().clear_attribute(k)
911 }
912
913 pub fn set_attribute(&self, k: AttributeKey) {
915 self.netref.borrow_mut().set_attribute(k);
916 }
917
918 pub fn insert_attribute(&self, k: AttributeKey, v: Parameter) -> Option<AttributeValue> {
920 self.netref.borrow_mut().insert_attribute(k, v)
921 }
922
923 pub fn attributes(&self) -> impl Iterator<Item = Attribute> {
925 let v: Vec<_> = self.netref.borrow().attributes().collect();
926 v.into_iter()
927 }
928}
929
930impl<I> std::fmt::Display for NetRef<I>
931where
932 I: Instantiable,
933{
934 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
935 self.netref.borrow().object.fmt(f)
936 }
937}
938
939impl<I> From<NetRef<I>> for DrivenNet<I>
940where
941 I: Instantiable,
942{
943 fn from(val: NetRef<I>) -> Self {
944 if val.is_multi_output() {
945 panic!("Cannot convert a multi-output netref to an output port");
946 }
947 DrivenNet::new(0, val)
948 }
949}
950
951impl<I> From<&NetRef<I>> for DrivenNet<I>
952where
953 I: Instantiable,
954{
955 fn from(val: &NetRef<I>) -> Self {
956 if val.is_multi_output() {
957 panic!("Cannot convert a multi-output netref to an output port");
958 }
959 DrivenNet::new(0, val.clone())
960 }
961}
962
963#[derive(Debug)]
965pub struct Netlist<I>
966where
967 I: Instantiable,
968{
969 name: RefCell<Identifier>,
971 objects: RefCell<Vec<NetRefT<I>>>,
973 outputs: RefCell<BTreeMap<Operand, BTreeSet<Net>>>,
975}
976
977#[derive(Debug, Clone)]
979pub struct InputPort<I: Instantiable> {
980 pos: usize,
981 netref: NetRef<I>,
982}
983
984impl<I> InputPort<I>
985where
986 I: Instantiable,
987{
988 fn new(pos: usize, netref: NetRef<I>) -> Self {
989 if pos >= netref.clone().unwrap().borrow().operands.len() {
990 panic!(
991 "Position {} out of bounds for netref with {} input nets",
992 pos,
993 netref.unwrap().borrow().get().get_nets().len()
994 );
995 }
996 Self { pos, netref }
997 }
998
999 pub fn get_driver(&self) -> Option<DrivenNet<I>> {
1001 if self.netref.is_an_input() {
1002 panic!("Input port is not driven by a primitive");
1003 }
1004 if let Some(prev_operand) = self.netref.clone().unwrap().borrow().operands[self.pos] {
1005 let netlist = self
1006 .netref
1007 .clone()
1008 .unwrap()
1009 .borrow()
1010 .owner
1011 .upgrade()
1012 .expect("Input port is unlinked from netlist");
1013 let driver_nr = netlist.index_weak(&prev_operand.root());
1014 let nr = NetRef::wrap(driver_nr);
1015 let pos = prev_operand.secondary();
1016 Some(DrivenNet::new(pos, nr))
1017 } else {
1018 None
1019 }
1020 }
1021
1022 pub fn disconnect(&self) -> Option<DrivenNet<I>> {
1024 let val = self.get_driver();
1025 self.netref.clone().unwrap().borrow_mut().operands[self.pos] = None;
1026 val
1027 }
1028
1029 pub fn get_port(&self) -> Net {
1031 if self.netref.is_an_input() {
1032 panic!("Net is not driven by a primitive");
1033 }
1034 self.netref
1035 .get_instance_type()
1036 .unwrap()
1037 .get_input_port(self.pos)
1038 .clone()
1039 }
1040
1041 pub fn connect(self, output: DrivenNet<I>) {
1043 output.connect(self);
1044 }
1045
1046 pub fn unwrap(self) -> NetRef<I> {
1048 self.netref
1049 }
1050
1051 pub fn get_input_num(&self) -> usize {
1053 self.pos
1054 }
1055}
1056
1057impl<I> std::fmt::Display for InputPort<I>
1058where
1059 I: Instantiable,
1060{
1061 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1062 self.get_port().fmt(f)
1063 }
1064}
1065
1066#[derive(Debug, Clone)]
1068pub struct DrivenNet<I: Instantiable> {
1069 pos: usize,
1070 netref: NetRef<I>,
1071}
1072
1073impl<I> DrivenNet<I>
1074where
1075 I: Instantiable,
1076{
1077 fn new(pos: usize, netref: NetRef<I>) -> Self {
1078 if pos >= netref.clone().unwrap().borrow().get().get_nets().len() {
1079 panic!(
1080 "Position {} out of bounds for netref with {} outputted nets",
1081 pos,
1082 netref.unwrap().borrow().get().get_nets().len()
1083 );
1084 }
1085 Self { pos, netref }
1086 }
1087
1088 fn get_operand(&self) -> Operand {
1090 if self.netref.is_multi_output() {
1091 Operand::CellIndex(self.netref.clone().unwrap().borrow().get_index(), self.pos)
1092 } else {
1093 Operand::DirectIndex(self.netref.clone().unwrap().borrow().get_index())
1094 }
1095 }
1096
1097 pub fn as_net(&self) -> Ref<'_, Net> {
1099 self.netref.get_net(self.pos)
1100 }
1101
1102 pub fn as_net_mut(&self) -> RefMut<'_, Net> {
1104 self.netref.get_net_mut(self.pos)
1105 }
1106
1107 pub fn is_an_input(&self) -> bool {
1109 self.netref.is_an_input()
1110 }
1111
1112 pub fn get_port(&self) -> Net {
1114 if self.netref.is_an_input() {
1115 panic!("Net is not driven by a primitive");
1116 }
1117 self.netref
1118 .get_instance_type()
1119 .unwrap()
1120 .get_output_port(self.pos)
1121 .clone()
1122 }
1123
1124 pub fn connect(&self, input: InputPort<I>) {
1126 let operand = self.get_operand();
1127 let index = input.netref.unwrap().borrow().get_index();
1128 let netlist = self
1129 .netref
1130 .clone()
1131 .unwrap()
1132 .borrow()
1133 .owner
1134 .upgrade()
1135 .expect("Output port is unlinked from netlist");
1136 let obj = netlist.index_weak(&index);
1137 obj.borrow_mut().operands[input.pos] = Some(operand);
1138 }
1139
1140 pub fn is_top_level_output(&self) -> bool {
1142 let netlist = self
1143 .netref
1144 .clone()
1145 .unwrap()
1146 .borrow()
1147 .owner
1148 .upgrade()
1149 .expect("DrivenNet is unlinked from netlist");
1150 let outputs = netlist.outputs.borrow();
1151 outputs.contains_key(&self.get_operand())
1152 }
1153
1154 pub fn unwrap(self) -> NetRef<I> {
1156 self.netref
1157 }
1158
1159 pub fn get_identifier(&self) -> Identifier {
1161 self.as_net().get_identifier().clone()
1162 }
1163
1164 pub fn expose_with_name(self, name: Identifier) -> Self {
1171 let netlist = self
1172 .netref
1173 .clone()
1174 .unwrap()
1175 .borrow()
1176 .owner
1177 .upgrade()
1178 .expect("DrivenNet is unlinked from netlist");
1179 netlist.expose_net_with_name(self.clone(), name);
1180 self
1181 }
1182
1183 pub fn remove_output(&self, net_name: &Identifier) -> bool {
1190 let netlist = self
1191 .netref
1192 .clone()
1193 .unwrap()
1194 .borrow()
1195 .owner
1196 .upgrade()
1197 .expect("DrivenNet is unlinked from netlist");
1198 netlist.remove_output(self, net_name)
1199 }
1200
1201 pub fn remove_all_outputs(&self) -> usize {
1208 let netlist = self
1209 .netref
1210 .clone()
1211 .unwrap()
1212 .borrow()
1213 .owner
1214 .upgrade()
1215 .expect("DrivenNet is unlinked from netlist");
1216 netlist.remove_outputs(self)
1217 }
1218
1219 pub fn get_output_index(&self) -> Option<usize> {
1221 if self.netref.is_an_input() {
1222 None
1223 } else {
1224 Some(self.pos)
1225 }
1226 }
1227
1228 pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
1230 self.netref.get_instance_type()
1231 }
1232}
1233
1234impl<I> std::fmt::Display for DrivenNet<I>
1235where
1236 I: Instantiable,
1237{
1238 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1239 self.as_net().fmt(f)
1240 }
1241}
1242
1243impl<I> PartialEq for DrivenNet<I>
1244where
1245 I: Instantiable,
1246{
1247 fn eq(&self, other: &Self) -> bool {
1248 self.netref == other.netref && self.pos == other.pos
1249 }
1250}
1251
1252impl<I> Eq for DrivenNet<I> where I: Instantiable {}
1253
1254impl<I> std::hash::Hash for DrivenNet<I>
1255where
1256 I: Instantiable,
1257{
1258 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1259 self.netref.hash(state);
1260 self.pos.hash(state);
1261 }
1262}
1263
1264impl<I> Ord for DrivenNet<I>
1265where
1266 I: Instantiable,
1267{
1268 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
1269 match self.netref.cmp(&other.netref) {
1270 std::cmp::Ordering::Equal => self.pos.cmp(&other.pos),
1271 ord => ord,
1272 }
1273 }
1274}
1275
1276impl<I> PartialOrd for DrivenNet<I>
1277where
1278 I: Instantiable,
1279{
1280 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1281 Some(self.cmp(other))
1282 }
1283}
1284
1285impl<I> WeakIndex<usize> for Netlist<I>
1286where
1287 I: Instantiable,
1288{
1289 type Output = OwnedObject<I, Self>;
1290
1291 fn index_weak(&self, index: &usize) -> Rc<RefCell<Self::Output>> {
1292 self.objects.borrow()[*index].clone()
1293 }
1294}
1295
1296impl<I> Netlist<I>
1297where
1298 I: Instantiable,
1299{
1300 pub fn new(name: Identifier) -> Rc<Self> {
1302 Rc::new(Self {
1303 name: RefCell::new(name),
1304 objects: RefCell::new(Vec::new()),
1305 outputs: RefCell::new(BTreeMap::new()),
1306 })
1307 }
1308
1309 pub fn reclaim(self: Rc<Self>) -> Option<Self> {
1311 Rc::try_unwrap(self).ok()
1312 }
1313
1314 pub fn deep_clone(self: &Rc<Self>) -> Rc<Self> {
1316 let dc = Rc::new(Self {
1317 name: self.name.clone(),
1318 objects: RefCell::new(Vec::new()),
1319 outputs: self.outputs.clone(),
1320 });
1321
1322 let objects_linked: Vec<NetRefT<I>> = self
1323 .objects
1324 .borrow()
1325 .iter()
1326 .map(|obj| {
1327 let b = obj.borrow();
1328 Rc::new(RefCell::new(OwnedObject {
1329 object: b.object.clone(),
1330 owner: Rc::downgrade(&dc),
1331 operands: b.operands.clone(),
1332 attributes: b.attributes.clone(),
1333 index: b.index,
1334 }))
1335 })
1336 .collect();
1337
1338 *dc.objects.borrow_mut() = objects_linked;
1339
1340 dc
1341 }
1342
1343 fn insert_object(
1348 self: &Rc<Self>,
1349 object: Object<I>,
1350 operands: &[DrivenNet<I>],
1351 ) -> Result<NetRef<I>, Error> {
1352 for operand in operands {
1353 self.belongs(&operand.clone().unwrap());
1354 }
1355 let index = self.objects.borrow().len();
1356 let weak = Rc::downgrade(self);
1357 let operands = operands
1358 .iter()
1359 .map(|net| Some(net.get_operand()))
1360 .collect::<Vec<_>>();
1361 let owned_object = Rc::new(RefCell::new(OwnedObject {
1362 object,
1363 owner: weak,
1364 operands,
1365 attributes: BTreeMap::new(),
1366 index,
1367 }));
1368 self.objects.borrow_mut().push(owned_object.clone());
1369 Ok(NetRef::wrap(owned_object))
1370 }
1371
1372 pub fn insert_input(self: &Rc<Self>, net: Net) -> DrivenNet<I> {
1374 let obj = Object::Input(net);
1375 self.insert_object(obj, &[]).unwrap().into()
1376 }
1377
1378 pub fn insert_input_logic_bus(self: &Rc<Self>, net: String, bw: usize) -> Vec<DrivenNet<I>> {
1380 Net::new_logic_bus(net, bw)
1381 .into_iter()
1382 .map(|n| self.insert_input(n))
1383 .collect()
1384 }
1385
1386 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: BTreeMap::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<DrivenNet<I>> {
1480 self.belongs(&netref);
1481 let op = netref.unwrap().borrow().operands[index]?;
1482 Some(DrivenNet::new(
1483 op.secondary(),
1484 NetRef::wrap(self.index_weak(&op.root()).clone()),
1485 ))
1486 }
1487
1488 pub fn expose_net_with_name(&self, net: DrivenNet<I>, name: Identifier) -> DrivenNet<I> {
1494 self.belongs(&net.clone().unwrap());
1495 let mut outputs = self.outputs.borrow_mut();
1496 let named_net = net.as_net().with_name(name);
1497 outputs
1498 .entry(net.get_operand())
1499 .or_default()
1500 .insert(named_net);
1501 net
1502 }
1503
1504 pub fn expose_net(&self, net: DrivenNet<I>) -> Result<DrivenNet<I>, Error> {
1509 self.belongs(&net.clone().unwrap());
1510 if net.is_an_input() {
1511 return Err(Error::InputNeedsAlias(net.as_net().clone()));
1512 }
1513 let mut outputs = self.outputs.borrow_mut();
1514 outputs
1515 .entry(net.get_operand())
1516 .or_default()
1517 .insert(net.as_net().clone());
1518 Ok(net)
1519 }
1520
1521 pub fn remove_output(&self, operand: &DrivenNet<I>, net_name: &Identifier) -> bool {
1527 self.belongs(&operand.clone().unwrap());
1528 let mut outputs = self.outputs.borrow_mut();
1529 if let Some(nets) = outputs.get_mut(&operand.get_operand()) {
1530 let net_to_remove = Net::new(net_name.clone(), crate::circuit::DataType::logic());
1532 if nets.remove(&net_to_remove) {
1533 if nets.is_empty() {
1535 outputs.remove(&operand.get_operand());
1536 }
1537 return true;
1538 }
1539 }
1540 false
1541 }
1542
1543 pub fn remove_outputs(&self, operand: &DrivenNet<I>) -> usize {
1546 self.outputs
1548 .borrow_mut()
1549 .remove(&operand.get_operand())
1550 .map(|nets| nets.len())
1551 .unwrap_or(0)
1552 }
1553
1554 pub fn clear_outputs(&self) {
1556 self.outputs.borrow_mut().clear();
1557 }
1558
1559 pub fn delete_net_uses(&self, netref: NetRef<I>) -> Result<Object<I>, Error> {
1564 self.belongs(&netref);
1565 let unwrapped = netref.clone().unwrap();
1566 if Rc::strong_count(&unwrapped) > 3 {
1567 return Err(Error::DanglingReference(netref.nets().collect()));
1568 }
1569 let old_index = unwrapped.borrow().get_index();
1570 let objects = self.objects.borrow();
1571 for oref in objects.iter() {
1572 let operands = &mut oref.borrow_mut().operands;
1573 for operand in operands.iter_mut() {
1574 if let Some(op) = operand {
1575 match op {
1576 Operand::DirectIndex(idx) | Operand::CellIndex(idx, _)
1577 if *idx == old_index =>
1578 {
1579 *operand = None;
1580 }
1581 _ => (),
1582 }
1583 }
1584 }
1585 }
1586
1587 let outputs: Vec<Operand> = self
1588 .outputs
1589 .borrow()
1590 .keys()
1591 .filter(|operand| match operand {
1592 Operand::DirectIndex(idx) | Operand::CellIndex(idx, _) => *idx == old_index,
1593 })
1594 .cloned()
1595 .collect();
1596
1597 for operand in outputs {
1598 self.outputs.borrow_mut().remove(&operand);
1599 }
1600
1601 Ok(netref.unwrap().borrow().get().clone())
1602 }
1603
1604 pub fn replace_net_uses(
1612 &self,
1613 of: DrivenNet<I>,
1614 with: &DrivenNet<I>,
1615 ) -> Result<DrivenNet<I>, Error> {
1616 {
1617 self.belongs(&of.clone().unwrap());
1618 self.belongs(&with.clone().unwrap());
1619 }
1620 let unwrapped = of.clone().unwrap().unwrap();
1621 let i = of.get_output_index();
1622 let k = with.get_output_index();
1623
1624 if of.clone().unwrap() == with.clone().unwrap() {
1625 if i == k {
1626 return Ok(of);
1627 }
1628
1629 if Rc::strong_count(&unwrapped) > 4 {
1630 return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1631 }
1632 } else if Rc::strong_count(&unwrapped) > 3 {
1633 return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1634 }
1635
1636 let old_index = of.get_operand();
1637
1638 if let Some(nets) = self.outputs.borrow().get(&old_index)
1639 && nets.contains(&of.as_net())
1640 {
1641 if of.is_an_input() {
1642 return Err(Error::NonuniqueNets(nets.iter().cloned().collect()));
1643 } else {
1644 let id = of.as_net().get_identifier().clone() + "_replaced".into();
1645 of.as_net_mut().set_identifier(id);
1646 }
1647 }
1648
1649 let new_index = with.get_operand();
1650 let objects = self.objects.borrow();
1651 for oref in objects.iter() {
1652 let operands = &mut oref.borrow_mut().operands;
1653 for operand in operands.iter_mut() {
1654 if let Some(op) = operand
1655 && *op == old_index
1656 {
1657 *operand = Some(new_index);
1658 }
1659 }
1660 }
1661
1662 let outs = self.outputs.borrow_mut().remove(&old_index);
1664 if let Some(outs) = outs {
1665 self.outputs
1666 .borrow_mut()
1667 .entry(new_index)
1668 .or_default()
1669 .extend(outs);
1670 }
1671
1672 Ok(of)
1673 }
1674}
1675
1676impl<I> Netlist<I>
1677where
1678 I: Instantiable,
1679{
1680 pub fn get_name(&self) -> Ref<'_, Identifier> {
1682 self.name.borrow()
1683 }
1684
1685 pub fn set_name(&self, name: Identifier) {
1690 *self.name.borrow_mut() = name;
1691 }
1692
1693 pub fn get_input_ports(&self) -> impl Iterator<Item = Net> {
1695 self.objects().filter_map(|oref| {
1696 if oref.is_an_input() {
1697 Some(oref.as_net().clone())
1698 } else {
1699 None
1700 }
1701 })
1702 }
1703
1704 pub fn get_output_ports(&self) -> Vec<Net> {
1706 self.outputs
1707 .borrow()
1708 .values()
1709 .flat_map(|nets| nets.iter().cloned())
1710 .collect()
1711 }
1712
1713 pub fn get_analysis<'a, A: Analysis<'a, I>>(&'a self) -> Result<A, Error> {
1715 A::build(self)
1716 }
1717
1718 pub fn find_net(&self, net: &Net) -> Option<DrivenNet<I>> {
1721 for obj in self.objects() {
1722 for o in obj.outputs() {
1723 if *o.as_net() == *net {
1724 return Some(o);
1725 }
1726 }
1727 }
1728 None
1729 }
1730
1731 pub fn first(&self) -> Option<NetRef<I>> {
1733 self.objects
1734 .borrow()
1735 .first()
1736 .map(|nr| NetRef::wrap(nr.clone()))
1737 }
1738
1739 pub fn last(&self) -> Option<NetRef<I>> {
1741 self.objects
1742 .borrow()
1743 .last()
1744 .map(|nr| NetRef::wrap(nr.clone()))
1745 }
1746
1747 pub fn len(&self) -> usize {
1749 self.objects.borrow().len()
1750 }
1751
1752 pub fn is_empty(&self) -> bool {
1754 self.objects.borrow().is_empty()
1755 }
1756
1757 pub fn drives_an_output(&self, netref: NetRef<I>) -> bool {
1762 self.belongs(&netref);
1763 let my_index = netref.unwrap().borrow().get_index();
1764 for key in self.outputs.borrow().keys() {
1765 if key.root() == my_index {
1766 return true;
1767 }
1768 }
1769 false
1770 }
1771
1772 pub fn rename_nets<F: Fn(&Identifier, usize) -> Identifier>(&self, f: F) -> Result<(), Error> {
1790 let mut i: usize = 0;
1791 let mut set = HashSet::new();
1792 let mut vec = Vec::new();
1793 for nr in self.objects() {
1795 if nr.is_an_input() {
1796 continue;
1797 }
1798 for net in nr.nets() {
1799 let id = net.get_identifier().clone();
1800 let rename = f(&id, i);
1801 if !set.insert(rename.clone()) {
1802 return Err(Error::NonuniqueNets(vec![net]));
1803 }
1804 vec.push(rename);
1805 i += 1;
1806 }
1807 }
1808
1809 for nr in self.objects() {
1810 if nr.is_an_input() {
1811 continue;
1812 }
1813
1814 let id = nr.get_instance_name().unwrap();
1815 let rename = f(&id, i);
1816 if !set.insert(rename.clone()) {
1817 return Err(Error::NonuniqueInsts(vec![id]));
1818 }
1819 vec.push(rename);
1820 i += 1;
1821 }
1822
1823 i = 0;
1824 for nr in self.objects() {
1825 if nr.is_an_input() {
1826 continue;
1827 }
1828 for mut net in nr.nets_mut() {
1829 net.set_identifier(vec[i].clone());
1830 i += 1;
1831 }
1832 }
1833
1834 for nr in self.objects() {
1835 if nr.is_an_input() {
1836 continue;
1837 }
1838
1839 nr.set_instance_name(vec[i].clone());
1840 i += 1;
1841 }
1842
1843 Ok(())
1844 }
1845
1846 pub fn retain_once(&self, set: &mut HashSet<DrivenNet<I>>) -> Result<Vec<Object<I>>, Error> {
1848 let mut dead_objs = HashSet::new();
1849 {
1850 let fan_out = self.get_analysis::<FanOutTable<I>>()?;
1851 for obj in self.objects() {
1852 let mut is_dead = true;
1853 for net in obj.outputs() {
1854 if fan_out.net_has_uses(&net.as_net()) {
1856 is_dead = false;
1857 } else {
1858 set.remove(&net);
1859 }
1860 }
1861 if is_dead && !obj.is_an_input() {
1862 dead_objs.insert(obj.unwrap().borrow().index);
1863 }
1864 }
1865 }
1866
1867 if dead_objs.is_empty() {
1868 return Ok(vec![]);
1869 }
1870
1871 let old_objects = self.objects.take();
1872
1873 for i in dead_objs.iter() {
1875 let rc = &old_objects[*i];
1876 if Rc::strong_count(rc) > 1 {
1877 self.objects.replace(old_objects.clone());
1878 return Err(Error::DanglingReference(
1879 rc.borrow().get().get_nets().to_vec(),
1880 ));
1881 }
1882 }
1883
1884 let mut removed = Vec::new();
1885 let mut remap: HashMap<usize, usize> = HashMap::new();
1886 for (old_index, obj) in old_objects.into_iter().enumerate() {
1887 if dead_objs.contains(&old_index) {
1888 removed.push(obj.borrow().get().clone());
1889 continue;
1890 }
1891
1892 let new_index = self.objects.borrow().len();
1893 remap.insert(old_index, new_index);
1894 obj.borrow_mut().index = new_index;
1895 self.objects.borrow_mut().push(obj);
1896 }
1897
1898 for obj in self.objects.borrow().iter() {
1899 for operand in obj.borrow_mut().inds_mut() {
1900 let root = operand.root();
1901 let root = *remap.get(&root).unwrap_or(&root);
1902 *operand = operand.remap(root);
1903 }
1904 }
1905
1906 let pairs: Vec<_> = self.outputs.take().into_iter().collect();
1907 for (operand, net) in pairs {
1908 let root = operand.root();
1909 let root = *remap.get(&root).unwrap_or(&root);
1910 let new_operand = operand.remap(root);
1911 self.outputs.borrow_mut().insert(new_operand, net);
1912 }
1913
1914 Ok(removed)
1915 }
1916
1917 pub fn clean(&self) -> Result<Vec<Object<I>>, Error> {
1920 let mut removed = Vec::new();
1921 let mut r = self.retain_once(&mut HashSet::new())?;
1922 while !r.is_empty() {
1923 removed.extend(r);
1924 r = self.retain_once(&mut HashSet::new())?;
1925 }
1926 Ok(removed)
1927 }
1928
1929 pub fn retain(&self, set: &mut HashSet<DrivenNet<I>>) -> Result<Vec<Object<I>>, Error> {
1931 let mut removed = Vec::new();
1932 let mut r = self.retain_once(set)?;
1933 while !r.is_empty() {
1934 removed.extend(r);
1935 r = self.retain_once(set)?;
1936 }
1937 Ok(removed)
1938 }
1939
1940 fn nets_insts_unique(&self) -> Result<(), Error> {
1942 let mut nets = HashSet::new();
1943 let mut stems = HashSet::new();
1944 for net in self {
1945 if !nets.insert(net.clone().take_identifier()) {
1946 return Err(Error::NonuniqueNets(vec![net]));
1947 }
1948 if !stems.insert(net.get_identifier().get_stem().to_string())
1949 && net.get_identifier().get_bit_index().is_none()
1950 {
1951 return Err(Error::NonuniqueNets(vec![net]));
1952 }
1953 }
1954 for inst in self.objects() {
1955 if let Some(name) = inst.get_instance_name()
1956 && !stems.insert(name.get_stem().to_string())
1957 {
1958 return Err(Error::NonuniqueInsts(vec![name]));
1959 }
1960 if let Some(name) = inst.get_instance_name()
1961 && name.get_bit_index().is_some()
1962 {
1963 return Err(Error::InstantiableError(format!(
1964 "Instance identifier {name} cannot be indexed"
1965 )));
1966 }
1967 }
1968 Ok(())
1969 }
1970
1971 fn check_io(&self) -> Result<(), Error> {
1973 for inst in self.objects() {
1974 let unwrapped = inst.unwrap();
1975
1976 let olen = unwrapped.borrow().operands.len();
1977 let nlen = unwrapped.borrow().get().get_nets().len();
1978
1979 if let Some(inst) = unwrapped.borrow().get().get_instance_type() {
1980 let inlen = inst.get_input_ports().into_iter().count();
1981 let outlen = inst.get_output_ports().into_iter().count();
1982 if olen != inlen {
1983 return Err(Error::ArgumentMismatch(inlen, olen));
1984 }
1985
1986 if nlen != outlen {
1987 return Err(Error::InstantiableError(format!(
1988 "Instantiable type has incorrect number of outputs. Expected {outlen}, found {nlen}"
1989 )));
1990 }
1991 }
1992 }
1993 Ok(())
1994 }
1995
1996 fn connections_type_check(&self) -> Result<(), Error> {
1997 for conn in self.connections() {
1998 let target = *conn.target().get_port().get_type();
1999 let source = *conn.src().as_net().get_type();
2000 if target != source {
2001 return Err(Error::TypeError(conn.src().as_net().clone()));
2002 }
2003 }
2004 Ok(())
2005 }
2006
2007 pub fn verify(&self) -> Result<(), Error> {
2009 if self.outputs.borrow().is_empty() {
2010 return Err(Error::NoOutputs);
2011 }
2012
2013 self.check_io()?;
2014 self.nets_insts_unique()?;
2015 self.connections_type_check()?;
2016
2017 Ok(())
2018 }
2019}
2020
2021#[derive(Debug, Clone)]
2023pub struct Connection<I: Instantiable> {
2024 driver: DrivenNet<I>,
2025 input: InputPort<I>,
2026}
2027
2028impl<I> Connection<I>
2029where
2030 I: Instantiable,
2031{
2032 fn new(driver: DrivenNet<I>, input: InputPort<I>) -> Self {
2033 Self { driver, input }
2034 }
2035
2036 pub fn src(&self) -> DrivenNet<I> {
2038 self.driver.clone()
2039 }
2040
2041 pub fn net(&self) -> Net {
2043 self.driver.as_net().clone()
2044 }
2045
2046 pub fn target(&self) -> InputPort<I> {
2048 self.input.clone()
2049 }
2050}
2051
2052impl<I> std::fmt::Display for Connection<I>
2053where
2054 I: Instantiable,
2055{
2056 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2057 self.net().fmt(f)
2058 }
2059}
2060
2061pub mod emitter {
2063 #[cfg(feature = "graph")]
2064 use super::NetRef;
2065 use super::{Analysis, Error, Identifier, Instantiable, Netlist};
2066 #[cfg(feature = "graph")]
2067 use std::collections::HashMap;
2068 use std::collections::{BTreeMap, HashSet};
2069
2070 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2072 pub struct VerilogEmitterConfig {
2073 pub indent_char: char,
2075 pub indent_width: usize,
2077 pub ansi_style: bool,
2079 pub emit_const_cells: bool,
2081 }
2082
2083 impl VerilogEmitterConfig {
2084 pub fn legacy() -> Self {
2086 Self {
2087 indent_char: ' ',
2088 indent_width: 2,
2089 ansi_style: false,
2090 emit_const_cells: false,
2091 }
2092 }
2093 }
2094
2095 impl Default for VerilogEmitterConfig {
2096 fn default() -> Self {
2097 Self {
2098 indent_char: ' ',
2099 indent_width: 2,
2100 ansi_style: true,
2101 emit_const_cells: false,
2102 }
2103 }
2104 }
2105
2106 enum VerilogNet {
2107 Net(Identifier),
2108 Bus(Identifier, (usize, usize)),
2109 }
2110
2111 impl VerilogNet {
2112 fn id(&self) -> &Identifier {
2113 match self {
2114 VerilogNet::Net(id) => id,
2115 VerilogNet::Bus(id, _) => id,
2116 }
2117 }
2118 }
2119
2120 impl std::fmt::Display for VerilogNet {
2121 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2122 write!(f, "wire ")?;
2123 match self {
2124 VerilogNet::Net(net) => write!(f, "{}", net.get_stem()),
2125 VerilogNet::Bus(net, (h, l)) => write!(f, "[{}:{}] {}", h, l, net.get_stem()),
2126 }
2127 }
2128 }
2129
2130 pub struct VerilogEmitter<'a, I: Instantiable> {
2132 netlist: &'a Netlist<I>,
2133 config: VerilogEmitterConfig,
2134 inputs: Vec<VerilogNet>,
2135 outputs: Vec<VerilogNet>,
2136 others: Vec<VerilogNet>,
2137 }
2138
2139 impl<'a, I: Instantiable> VerilogEmitter<'a, I> {
2140 fn get_nets(
2141 nl: &'a Netlist<I>,
2142 emit_consts: bool,
2143 ) -> (Vec<VerilogNet>, Vec<VerilogNet>, Vec<VerilogNet>) {
2144 let mut seen: HashSet<Identifier> = HashSet::new();
2145 let mut inputs: BTreeMap<Identifier, (usize, usize)> = BTreeMap::new();
2146 let mut outputs: BTreeMap<Identifier, (usize, usize)> = BTreeMap::new();
2147 let mut others: BTreeMap<Identifier, (usize, usize)> = BTreeMap::new();
2148
2149 for (_, output) in nl.outputs() {
2150 let output = output.take_identifier();
2151 let stem = output.get_stem();
2152 seen.insert(stem.clone());
2153 let entry = outputs.entry(stem.clone()).or_default();
2154 if let Some(idx) = output.get_bit_index() {
2155 entry.1 = entry.1.min(idx);
2156 entry.0 = entry.0.max(idx);
2157 }
2158 }
2159
2160 for input in nl.inputs() {
2161 let input = input.get_identifier();
2162 let stem = input.get_stem();
2163 seen.insert(stem.clone());
2164 let entry = inputs.entry(stem.clone()).or_default();
2165 if let Some(idx) = input.get_bit_index() {
2166 entry.1 = entry.1.min(idx);
2167 entry.0 = entry.0.max(idx);
2168 }
2169 }
2170
2171 for obj in nl.objects() {
2172 if !emit_consts
2173 && obj
2174 .get_instance_type()
2175 .and_then(|i| i.get_constant())
2176 .is_some()
2177 {
2178 continue;
2179 }
2180
2181 for net in obj.nets() {
2182 let id = net.get_identifier();
2183 let stem = id.get_stem();
2184 if !seen.contains(&stem) {
2185 let entry = others.entry(stem.clone()).or_default();
2186 if let Some(idx) = id.get_bit_index() {
2187 entry.1 = entry.1.min(idx);
2188 entry.0 = entry.0.max(idx);
2189 }
2190 }
2191 }
2192 }
2193
2194 let inputs = inputs
2195 .into_iter()
2196 .map(|(id, (h, l))| {
2197 if h == l {
2198 VerilogNet::Net(id)
2199 } else {
2200 VerilogNet::Bus(id, (h, l))
2201 }
2202 })
2203 .collect::<Vec<_>>();
2204
2205 let outputs = outputs
2206 .into_iter()
2207 .map(|(id, (h, l))| {
2208 if h == l {
2209 VerilogNet::Net(id)
2210 } else {
2211 VerilogNet::Bus(id, (h, l))
2212 }
2213 })
2214 .collect::<Vec<_>>();
2215
2216 let others = others
2217 .into_iter()
2218 .map(|(id, (h, l))| {
2219 if h == l {
2220 VerilogNet::Net(id)
2221 } else {
2222 VerilogNet::Bus(id, (h, l))
2223 }
2224 })
2225 .collect::<Vec<_>>();
2226
2227 (inputs, outputs, others)
2228 }
2229
2230 pub fn new(netlist: &'a Netlist<I>, config: VerilogEmitterConfig) -> Self {
2232 let (inputs, outputs, others) = Self::get_nets(netlist, config.emit_const_cells);
2233 Self {
2234 netlist,
2235 config,
2236 inputs,
2237 outputs,
2238 others,
2239 }
2240 }
2241
2242 pub fn new_default(netlist: &'a Netlist<I>) -> Self {
2244 Self::new(netlist, VerilogEmitterConfig::default())
2245 }
2246
2247 pub fn with_spaces(self) -> Self {
2249 Self {
2250 config: VerilogEmitterConfig {
2251 indent_char: ' ',
2252 ..self.config
2253 },
2254 ..self
2255 }
2256 }
2257
2258 pub fn with_tabs(self) -> Self {
2260 Self {
2261 config: VerilogEmitterConfig {
2262 indent_char: '\t',
2263 ..self.config
2264 },
2265 ..self
2266 }
2267 }
2268
2269 pub fn with_indent(self, width: usize) -> Self {
2271 Self {
2272 config: VerilogEmitterConfig {
2273 indent_width: width,
2274 ..self.config
2275 },
2276 ..self
2277 }
2278 }
2279
2280 pub fn with_ansi_style(self) -> Self {
2282 Self {
2283 config: VerilogEmitterConfig {
2284 ansi_style: true,
2285 ..self.config
2286 },
2287 ..self
2288 }
2289 }
2290
2291 pub fn with_nonansi_style(self) -> Self {
2293 Self {
2294 config: VerilogEmitterConfig {
2295 ansi_style: false,
2296 ..self.config
2297 },
2298 ..self
2299 }
2300 }
2301
2302 pub fn with_emitted_constants(self) -> Self {
2304 Self {
2305 config: VerilogEmitterConfig {
2306 emit_const_cells: true,
2307 ..self.config
2308 },
2309 ..self
2310 }
2311 }
2312 }
2313
2314 impl<'a, I: Instantiable> Analysis<'a, I> for VerilogEmitter<'a, I> {
2315 fn build(netlist: &'a Netlist<I>) -> Result<Self, Error> {
2316 Ok(Self::new_default(netlist))
2317 }
2318 }
2319
2320 impl<'a, I: Instantiable> VerilogEmitter<'a, I> {
2321 fn get_indent(&self, level: usize) -> String {
2322 self.config
2323 .indent_char
2324 .to_string()
2325 .repeat(self.config.indent_width * level)
2326 }
2327
2328 fn emit_ansi_header(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2329 assert!(self.config.ansi_style);
2330
2331 writeln!(f, "module {} (", self.netlist.get_name())?;
2332 let indent = self.get_indent(1);
2333 for input in &self.inputs {
2334 writeln!(f, "{}input {},", indent, input)?;
2335 }
2336 let l = self.outputs.len();
2337 for (i, output) in self.outputs.iter().enumerate() {
2338 write!(f, "{}output {}", indent, output)?;
2339 if i != l - 1 {
2340 writeln!(f, ",")?;
2341 }
2342 }
2343 writeln!(f)?;
2344 writeln!(f, ");")
2345 }
2346
2347 fn emit_nonansi_header(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2348 assert!(!self.config.ansi_style);
2349
2350 writeln!(f, "module {} (", self.netlist.get_name())?;
2351 let indent = self.get_indent(1);
2352 for input in &self.inputs {
2353 writeln!(f, "{}{},", indent, input.id())?;
2354 }
2355 let l = self.outputs.len();
2356 for (i, output) in self.outputs.iter().enumerate() {
2357 write!(f, "{}{}", indent, output.id())?;
2358 if i != l - 1 {
2359 writeln!(f, ",")?;
2360 }
2361 }
2362 writeln!(f)?;
2363 writeln!(f, ");")
2364 }
2365
2366 fn emit_net_decls(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2367 let indent = self.get_indent(1);
2368 if !self.config.ansi_style {
2369 for net in &self.inputs {
2370 writeln!(f, "{}input {};", indent, net)?;
2371 }
2372 for net in &self.outputs {
2373 writeln!(f, "{}output {};", indent, net)?;
2374 }
2375 }
2376
2377 for net in &self.others {
2378 writeln!(f, "{}{};", indent, net)?;
2379 }
2380 writeln!(f)
2381 }
2382
2383 fn emit_instances(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2384 let indent = self.get_indent(1);
2385 for nr in self
2386 .netlist
2387 .matches(|i| self.config.emit_const_cells || i.get_constant().is_none())
2388 {
2389 for attribute in nr.attributes() {
2390 if let Some(value) = attribute.value() {
2391 writeln!(f, "{}(* {} = {} *)", indent, attribute.key(), value)?;
2392 } else {
2393 writeln!(f, "{}(* {} *)", indent, attribute.key())?;
2394 }
2395 }
2396 let inst = nr.get_instance_type().unwrap().clone();
2397 write!(f, "{}{} ", indent, inst.get_name())?;
2398 let params = inst.parameters().collect::<Vec<_>>();
2399 if !params.is_empty() {
2400 writeln!(f, "#(")?;
2401 let indent = self.get_indent(2);
2402 let l = params.len();
2403 for (i, (k, v)) in params.into_iter().enumerate() {
2404 write!(f, "{}.{}({})", indent, k, v)?;
2405 if i != l - 1 {
2406 writeln!(f, ",")?;
2407 }
2408 }
2409 writeln!(f)?;
2410 let indent = self.get_indent(1);
2411 write!(f, "{}) ", indent)?;
2412 }
2413 writeln!(f, "{} (", nr.get_instance_name().unwrap())?;
2414 let indent = self.get_indent(2);
2415 for input in nr.inputs() {
2416 if let Some(driver) = self.netlist.get_driver(nr.clone(), input.get_input_num())
2417 {
2418 let rhs = if !self.config.emit_const_cells
2419 && let Some(logic) =
2420 driver.get_instance_type().and_then(|i| i.get_constant())
2421 {
2422 logic.to_string()
2423 } else {
2424 driver.get_identifier().to_string()
2425 };
2426
2427 writeln!(f, "{}.{}({}),", indent, input.get_port(), rhs)?;
2428 }
2429 }
2430 let outputs = nr.outputs().collect::<Vec<_>>();
2431 let l = outputs.len();
2432 for (i, output) in outputs.into_iter().enumerate() {
2433 write!(
2434 f,
2435 "{}.{}({})",
2436 indent,
2437 output.get_port(),
2438 output.get_identifier()
2439 )?;
2440 if i != l - 1 {
2441 writeln!(f, ",")?;
2442 }
2443 }
2444 let indent = self.get_indent(1);
2445 writeln!(f)?;
2446 writeln!(f, "{});", indent)?;
2447 }
2448 writeln!(f)
2449 }
2450
2451 fn emit_output_assignments(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2452 let indent = self.get_indent(1);
2453 for (operand, net) in self.netlist.outputs() {
2454 if operand.get_identifier() != *net.get_identifier() {
2455 let rhs = if !self.config.emit_const_cells
2456 && let Some(logic) =
2457 operand.get_instance_type().and_then(|i| i.get_constant())
2458 {
2459 logic.to_string()
2460 } else {
2461 operand.get_identifier().to_string()
2462 };
2463 writeln!(f, "{}assign {} = {};", indent, net.get_identifier(), rhs)?;
2464 }
2465 }
2466 writeln!(f)
2467 }
2468
2469 pub fn emit(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2471 if self.config.ansi_style {
2472 self.emit_ansi_header(f)?;
2473 } else {
2474 self.emit_nonansi_header(f)?;
2475 }
2476
2477 self.emit_net_decls(f)?;
2478 self.emit_instances(f)?;
2479 self.emit_output_assignments(f)?;
2480
2481 writeln!(f, "endmodule")
2482 }
2483
2484 pub fn emit_to_string(&self) -> String {
2486 self.to_string()
2487 }
2488 }
2489
2490 impl<'a, I: Instantiable> std::fmt::Display for VerilogEmitter<'a, I> {
2491 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2492 self.emit(f)
2493 }
2494 }
2495
2496 #[cfg(feature = "graph")]
2498 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2499 pub struct RGB {
2500 pub r: u8,
2502 pub g: u8,
2504 pub b: u8,
2506 }
2507
2508 #[cfg(feature = "graph")]
2509 impl std::fmt::Display for RGB {
2510 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2511 write!(f, "#{:02x}{:02x}{:02x}", self.r, self.g, self.b)
2512 }
2513 }
2514
2515 #[cfg(feature = "graph")]
2517 pub type ColorFunc<T> = dyn Fn(&T, Option<RGB>) -> Option<RGB>;
2518
2519 #[cfg(feature = "graph")]
2521 pub struct DotEmitter<'a, I: Instantiable> {
2522 netlist: &'a Netlist<I>,
2523 overrides_netref: HashMap<NetRef<I>, RGB>,
2524 color_netref: Box<ColorFunc<NetRef<I>>>,
2525 color_inst: Box<ColorFunc<I>>,
2526 }
2527
2528 #[cfg(feature = "graph")]
2529 impl<'a, I: Instantiable> DotEmitter<'a, I> {
2530 pub fn new(netlist: &'a Netlist<I>) -> Self {
2532 Self {
2533 netlist,
2534 overrides_netref: HashMap::new(),
2535 color_netref: Box::new(|_, _| None),
2536 color_inst: Box::new(|_, _| None),
2537 }
2538 }
2539
2540 pub fn override_color(&mut self, netref: NetRef<I>, color: RGB) {
2542 self.overrides_netref.insert(netref, color);
2543 }
2544
2545 pub fn with_net_coloring<F: Fn(&NetRef<I>, Option<RGB>) -> Option<RGB> + 'static>(
2547 self,
2548 f: F,
2549 ) -> Self {
2550 Self {
2551 color_netref: Box::new(f),
2552 ..self
2553 }
2554 }
2555
2556 pub fn with_instance_coloring<F: Fn(&I, Option<RGB>) -> Option<RGB> + 'static>(
2558 self,
2559 f: F,
2560 ) -> Self {
2561 Self {
2562 color_inst: Box::new(f),
2563 ..self
2564 }
2565 }
2566
2567 fn get_color(&self, netref: &NetRef<I>) -> Option<RGB> {
2568 if let Some(color) = self.overrides_netref.get(netref) {
2569 return Some(*color);
2570 }
2571 let color = match netref.get_instance_type() {
2572 Some(inst) => (self.color_inst)(&inst, None),
2573 None => None,
2574 };
2575 (self.color_netref)(netref, color)
2576 }
2577
2578 pub fn emit(&self) -> String {
2580 use super::super::graph::{Edge, MultiDiGraph, Node};
2581 use super::Net;
2582 use petgraph::dot::{Config, Dot};
2583 use petgraph::graph::{DiGraph, EdgeReference, NodeIndex};
2584 let analysis = MultiDiGraph::new(self.netlist);
2585 let graph = analysis.get_graph();
2586
2587 let node_impl = |_graph: &DiGraph<Node<I, String>, Edge<I, Net>>,
2588 node: (NodeIndex, &Node<I, String>)| {
2589 let n = node.1;
2590 let mut attr = String::new();
2591
2592 match n {
2593 Node::NetRef(nr) if nr.get_instance_type().is_some() => {
2594 attr += "shape=record, ";
2595 if let Some(color) = self.get_color(nr) {
2596 attr += &format!("style=filled, fillcolor=\"{color}\", ");
2597 }
2598 }
2599 _ => attr += "shape=ellipse, ",
2600 }
2601
2602 match n {
2603 Node::NetRef(nr)
2604 if let Some(inst_type) = nr.get_instance_type()
2605 && !inst_type.is_driverless() =>
2606 {
2607 let mut record = "{ { ".to_string();
2608
2609 let l = nr.get_num_input_ports();
2610 for (i, port) in nr.inputs().enumerate() {
2611 let id = port.get_port().get_identifier().clone();
2612 record += &format!("{{ <{}> {} }}", id, id);
2613
2614 if i != l - 1 {
2615 record += " | ";
2616 }
2617 }
2618
2619 record += &format!(
2620 " }} | {}({}) }}",
2621 inst_type.get_name(),
2622 nr.get_instance_name().unwrap()
2623 );
2624 attr += &format!("label=\"{record}\"");
2625 }
2626 _ => attr += &format!("label=\"{n}\""),
2627 }
2628
2629 attr
2630 };
2631
2632 fn edge_impl<I: Instantiable>(
2633 _graph: &DiGraph<Node<I, String>, Edge<I, Net>>,
2634 edge: EdgeReference<Edge<I, Net>>,
2635 ) -> String {
2636 match edge.weight() {
2637 Edge::Connection(c) => {
2638 format!(", port=\"{}\"", c.target().get_port().get_identifier())
2639 }
2640 _ => String::new(),
2641 }
2642 }
2643
2644 let dot =
2645 Dot::with_attr_getters(graph, &[Config::NodeNoLabel], &edge_impl::<I>, &node_impl);
2646
2647 let mut result = String::new();
2649 for line in dot.to_string().lines() {
2650 if line.contains("->") && line.contains("port=") {
2651 let port = line
2652 .split("port=\"")
2653 .nth(1)
2654 .unwrap()
2655 .split('"')
2656 .next()
2657 .unwrap();
2658 let (l, r) = line.split_once("->").unwrap();
2659 let (l, r) = (l, r.trim());
2660 let (d, r) = r.split_once(" ").unwrap();
2661 result += &format!("{l}-> {d}:{port} {r}\n");
2662 } else {
2663 result += line;
2664 result += "\n";
2665 }
2666 }
2667
2668 result
2669 }
2670 }
2671
2672 #[cfg(feature = "graph")]
2673 impl<'a, I: Instantiable> std::fmt::Display for DotEmitter<'a, I> {
2674 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2675 write!(f, "{}", self.emit())
2676 }
2677 }
2678}
2679
2680pub mod rewriter {
2682 use super::{DrivenNet, Error, Instantiable, NetRef, Netlist, Operand};
2683 use crate::graph::FanOutTable;
2684 use std::collections::HashMap;
2685 use std::rc::Rc;
2686
2687 pub struct NetMapper<'a, I: Instantiable> {
2691 parent: HashMap<DrivenNet<I>, DrivenNet<I>>,
2692 netlist: &'a Netlist<I>,
2693 fanout: FanOutTable<'a, I>,
2694 }
2695
2696 impl<'a, I: Instantiable> NetMapper<'a, I> {
2697 pub fn new(netlist: &'a Netlist<I>) -> Result<Self, Error> {
2699 Ok(Self {
2700 parent: HashMap::new(),
2701 netlist,
2702 fanout: netlist.get_analysis::<FanOutTable<I>>()?,
2703 })
2704 }
2705
2706 pub fn find(&self, x: DrivenNet<I>) -> DrivenNet<I> {
2708 let mut root = x;
2709 while let Some(p) = self.parent.get(&root) {
2710 root = p.clone();
2711 }
2712 root
2713 }
2714
2715 pub fn replace(&mut self, of: DrivenNet<I>, with: DrivenNet<I>) -> DrivenNet<I> {
2720 let of_root = self.find(of.clone());
2721 let with_root = self.find(with);
2722 if of_root == with_root {
2723 panic!("Already mapped by NetMapper: {of}");
2724 }
2725 self.parent.insert(of_root, with_root);
2726 of
2727 }
2728
2729 pub fn apply(self) -> Result<Vec<DrivenNet<I>>, Error> {
2732 let mut map: HashMap<Operand, Operand> = HashMap::new();
2734 for k in self.parent.keys().cloned() {
2735 let v = self.find(k.clone());
2736 if k != v {
2737 map.insert(k.get_operand(), v.get_operand());
2738 }
2739 }
2740
2741 drop(self.parent);
2742
2743 for (of, with) in map.iter() {
2745 let unwrapped = self.netlist.objects.borrow()[of.root()].clone();
2746 let i = of.secondary();
2747 let k = of.secondary();
2748 let nr = NetRef::wrap(unwrapped.clone());
2749
2750 if of.root() == with.root() {
2751 if i == k {
2752 continue;
2753 }
2754
2755 if Rc::strong_count(&unwrapped) - self.fanout.get_ref_count(&nr) > 4 {
2756 return Err(Error::DanglingReference(nr.nets().collect()));
2757 }
2758 } else if Rc::strong_count(&unwrapped) - self.fanout.get_ref_count(&nr) > 3 {
2759 return Err(Error::DanglingReference(nr.nets().collect()));
2760 }
2761
2762 let old_index = of;
2763 let of = DrivenNet::new(i, nr);
2764
2765 if let Some(nets) = self.netlist.outputs.borrow().get(old_index)
2766 && nets.contains(&of.as_net())
2767 {
2768 if of.is_an_input() {
2769 return Err(Error::NonuniqueNets(nets.iter().cloned().collect()));
2770 } else {
2771 let id = of.as_net().get_identifier().clone() + "_replaced".into();
2772 of.as_net_mut().set_identifier(id);
2773 }
2774 }
2775 }
2776
2777 let objects = self.netlist.objects.borrow();
2778 for (of, &with) in map.iter() {
2779 let of = DrivenNet::new(of.secondary(), NetRef::wrap(objects[of.root()].clone()));
2780 for u in self.fanout.get_users(&of) {
2781 let place = u.pos;
2782 let u = u.unwrap().unwrap();
2783 let operands = &mut u.borrow_mut().operands;
2784 operands[place] = Some(with);
2785 }
2786 }
2787
2788 for (of, &with) in map.iter() {
2789 let outs = self.netlist.outputs.borrow_mut().remove(of);
2791 if let Some(outs) = outs {
2792 self.netlist
2793 .outputs
2794 .borrow_mut()
2795 .entry(with)
2796 .or_default()
2797 .extend(outs);
2798 }
2799 }
2800
2801 let res: Vec<_> = map
2802 .into_keys()
2803 .map(|operand| {
2804 DrivenNet::new(
2805 operand.secondary(),
2806 NetRef::wrap(self.netlist.objects.borrow()[operand.root()].clone()),
2807 )
2808 })
2809 .collect();
2810
2811 Ok(res)
2812 }
2813 }
2814}
2815
2816pub mod iter {
2818
2819 use super::{
2820 Connection, DrivenNet, InputPort, Instantiable, Net, NetRef, Netlist, Operand, WeakIndex,
2821 };
2822 use std::collections::{HashMap, HashSet};
2823 pub struct NetIterator<'a, I: Instantiable> {
2825 netlist: &'a Netlist<I>,
2826 index: usize,
2827 subindex: usize,
2828 }
2829
2830 impl<'a, I> NetIterator<'a, I>
2831 where
2832 I: Instantiable,
2833 {
2834 pub fn new(netlist: &'a Netlist<I>) -> Self {
2836 Self {
2837 netlist,
2838 index: 0,
2839 subindex: 0,
2840 }
2841 }
2842 }
2843
2844 impl<I> Iterator for NetIterator<'_, I>
2845 where
2846 I: Instantiable,
2847 {
2848 type Item = Net;
2849
2850 fn next(&mut self) -> Option<Self::Item> {
2851 while self.index < self.netlist.objects.borrow().len() {
2852 let objects = self.netlist.objects.borrow();
2853 let object = objects[self.index].borrow();
2854 if self.subindex < object.get().get_nets().len() {
2855 let net = object.get().get_nets()[self.subindex].clone();
2856 self.subindex += 1;
2857 return Some(net);
2858 }
2859 self.subindex = 0;
2860 self.index += 1;
2861 }
2862 None
2863 }
2864 }
2865
2866 pub struct ObjectIterator<'a, I: Instantiable> {
2868 netlist: &'a Netlist<I>,
2869 index: usize,
2870 }
2871
2872 impl<'a, I> ObjectIterator<'a, I>
2873 where
2874 I: Instantiable,
2875 {
2876 pub fn new(netlist: &'a Netlist<I>) -> Self {
2878 Self { netlist, index: 0 }
2879 }
2880 }
2881
2882 impl<I> Iterator for ObjectIterator<'_, I>
2883 where
2884 I: Instantiable,
2885 {
2886 type Item = NetRef<I>;
2887
2888 fn next(&mut self) -> Option<Self::Item> {
2889 if self.index < self.netlist.objects.borrow().len() {
2890 let objects = self.netlist.objects.borrow();
2891 let object = &objects[self.index];
2892 self.index += 1;
2893 return Some(NetRef::wrap(object.clone()));
2894 }
2895 None
2896 }
2897 }
2898
2899 pub struct ConnectionIterator<'a, I: Instantiable> {
2901 netlist: &'a Netlist<I>,
2902 index: usize,
2903 subindex: usize,
2904 }
2905
2906 impl<'a, I> ConnectionIterator<'a, I>
2907 where
2908 I: Instantiable,
2909 {
2910 pub fn new(netlist: &'a Netlist<I>) -> Self {
2912 Self {
2913 netlist,
2914 index: 0,
2915 subindex: 0,
2916 }
2917 }
2918 }
2919
2920 impl<I> Iterator for ConnectionIterator<'_, I>
2921 where
2922 I: Instantiable,
2923 {
2924 type Item = super::Connection<I>;
2925
2926 fn next(&mut self) -> Option<Self::Item> {
2927 while self.index < self.netlist.objects.borrow().len() {
2928 let objects = self.netlist.objects.borrow();
2929 let object = objects[self.index].borrow();
2930 let noperands = object.operands.len();
2931 while self.subindex < noperands {
2932 if let Some(operand) = &object.operands[self.subindex] {
2933 let driver = match operand {
2934 Operand::DirectIndex(idx) => {
2935 DrivenNet::new(0, NetRef::wrap(objects[*idx].clone()))
2936 }
2937 Operand::CellIndex(idx, j) => {
2938 DrivenNet::new(*j, NetRef::wrap(objects[*idx].clone()))
2939 }
2940 };
2941 let input = InputPort::new(
2942 self.subindex,
2943 NetRef::wrap(objects[self.index].clone()),
2944 );
2945 self.subindex += 1;
2946 return Some(Connection::new(driver, input));
2947 }
2948 self.subindex += 1;
2949 }
2950 self.subindex = 0;
2951 self.index += 1;
2952 }
2953 None
2954 }
2955 }
2956
2957 #[derive(Clone)]
2959 struct Walk<T: std::hash::Hash + PartialEq + Eq + Clone> {
2960 stack: Vec<T>,
2961 counter: HashMap<T, usize>,
2962 }
2963
2964 impl<T> Walk<T>
2965 where
2966 T: std::hash::Hash + PartialEq + Eq + Clone,
2967 {
2968 fn new() -> Self {
2970 Self {
2971 stack: Vec::new(),
2972 counter: HashMap::new(),
2973 }
2974 }
2975
2976 fn push(&mut self, item: T) {
2978 self.stack.push(item.clone());
2979 *self.counter.entry(item).or_insert(0) += 1;
2980 }
2981
2982 fn contains_cycle(&self) -> bool {
2984 self.counter.values().any(|&count| count > 1)
2985 }
2986
2987 fn root_cycle(&self) -> bool {
2989 if self.stack.is_empty() {
2990 return false;
2991 }
2992 self.counter[&self.stack[0]] > 1
2993 }
2994
2995 fn last(&self) -> Option<&T> {
2997 self.stack.last()
2998 }
2999 }
3000
3001 pub struct DFSIterator<'a, I: Instantiable> {
3020 dfs: NetDFSIterator<'a, I>,
3021 seen: HashSet<NetRef<I>>,
3022 }
3023
3024 impl<'a, I> DFSIterator<'a, I>
3025 where
3026 I: Instantiable,
3027 {
3028 pub fn new(netlist: &'a Netlist<I>, from: NetRef<I>) -> Self {
3030 Self {
3031 dfs: NetDFSIterator::new(netlist, DrivenNet::new(0, from)),
3032 seen: HashSet::new(),
3033 }
3034 }
3035 }
3036
3037 impl<I> DFSIterator<'_, I>
3038 where
3039 I: Instantiable,
3040 {
3041 pub fn check_cycles(&self) -> bool {
3043 self.dfs.check_cycles()
3044 }
3045
3046 pub fn detect_cycles(self) -> bool {
3048 self.dfs.detect_cycles()
3049 }
3050
3051 pub fn check_self_loop(&self) -> bool {
3053 self.dfs.check_self_loop()
3054 }
3055
3056 pub fn detect_self_loop(self) -> bool {
3058 self.dfs.detect_self_loop()
3059 }
3060 }
3061
3062 impl<I> Iterator for DFSIterator<'_, I>
3063 where
3064 I: Instantiable,
3065 {
3066 type Item = NetRef<I>;
3067
3068 fn next(&mut self) -> Option<Self::Item> {
3069 let d = self.dfs.next()?;
3070 if self.seen.insert(d.clone().unwrap()) {
3071 Some(d.unwrap())
3072 } else {
3073 self.next()
3074 }
3075 }
3076 }
3077
3078 type TermFn<I> = Box<dyn Fn(&DrivenNet<I>) -> bool + 'static>;
3079
3080 pub struct NetDFSIterator<'a, I: Instantiable> {
3082 netlist: &'a Netlist<I>,
3083 stacks: Vec<Walk<DrivenNet<I>>>,
3084 visited: HashSet<usize>,
3085 visited_net: HashSet<(usize, usize)>,
3086 any_cycle: bool,
3087 root_cycle: bool,
3088 terminate: TermFn<I>,
3089 }
3090
3091 impl<'a, I> NetDFSIterator<'a, I>
3092 where
3093 I: Instantiable,
3094 {
3095 pub fn new_filtered<F: Fn(&DrivenNet<I>) -> bool + 'static>(
3098 netlist: &'a Netlist<I>,
3099 from: DrivenNet<I>,
3100 terminate: F,
3101 ) -> Self {
3102 let mut s = Walk::new();
3103 s.push(from);
3104 Self {
3105 netlist,
3106 stacks: vec![s],
3107 visited: HashSet::new(),
3108 visited_net: HashSet::new(),
3109 any_cycle: false,
3110 root_cycle: false,
3111 terminate: Box::new(terminate),
3112 }
3113 }
3114
3115 pub fn new(netlist: &'a Netlist<I>, from: DrivenNet<I>) -> Self {
3117 Self::new_filtered(netlist, from, |_| false)
3118 }
3119 }
3120
3121 impl<I> NetDFSIterator<'_, I>
3122 where
3123 I: Instantiable,
3124 {
3125 pub fn check_cycles(&self) -> bool {
3127 self.any_cycle
3128 }
3129
3130 pub fn detect_cycles(mut self) -> bool {
3132 if self.any_cycle {
3133 return true;
3134 }
3135
3136 while let Some(_) = self.next() {
3137 if self.any_cycle {
3138 return true;
3139 }
3140 }
3141
3142 self.any_cycle
3143 }
3144
3145 pub fn check_self_loop(&self) -> bool {
3147 self.root_cycle
3148 }
3149
3150 pub fn detect_self_loop(mut self) -> bool {
3152 if self.root_cycle {
3153 return true;
3154 }
3155
3156 while let Some(_) = self.next() {
3157 if self.root_cycle {
3158 return true;
3159 }
3160 }
3161
3162 self.root_cycle
3163 }
3164 }
3165
3166 impl<I> Iterator for NetDFSIterator<'_, I>
3167 where
3168 I: Instantiable,
3169 {
3170 type Item = DrivenNet<I>;
3171
3172 fn next(&mut self) -> Option<Self::Item> {
3173 if let Some(walk) = self.stacks.pop() {
3174 self.any_cycle |= walk.contains_cycle();
3175 self.root_cycle |= walk.root_cycle();
3176 let item = walk.last().cloned();
3177 let uw = item.clone().unwrap().unwrap().unwrap();
3178 let index = uw.borrow().get_index();
3179 let secondary = item.as_ref().unwrap().pos;
3180 if self.visited.insert(index) {
3181 if !(self.terminate)(item.as_ref().unwrap()) {
3182 let operands = &uw.borrow().operands;
3183 for operand in operands.iter().flatten() {
3184 let mut new_walk = walk.clone();
3185 new_walk.push(DrivenNet::new(
3186 operand.secondary(),
3187 NetRef::wrap(self.netlist.index_weak(&operand.root())),
3188 ));
3189 self.stacks.push(new_walk);
3190 }
3191 }
3192 self.visited_net.insert((index, secondary));
3193 return item;
3194 }
3195
3196 if self.visited_net.insert((index, secondary)) {
3197 return item;
3198 }
3199
3200 return self.next();
3201 }
3202
3203 None
3204 }
3205 }
3206}
3207
3208impl<'a, I> IntoIterator for &'a Netlist<I>
3209where
3210 I: Instantiable,
3211{
3212 type Item = Net;
3213 type IntoIter = iter::NetIterator<'a, I>;
3214
3215 fn into_iter(self) -> Self::IntoIter {
3216 iter::NetIterator::new(self)
3217 }
3218}
3219
3220#[macro_export]
3223macro_rules! filter_nodes {
3224 ($netlist:ident, $pattern:pat $(if $guard:expr)? $(,)?) => {
3225 $netlist.matches(|f| match f {
3226 $pattern $(if $guard)? => true,
3227 _ => false
3228 })
3229 };
3230}
3231
3232impl<I> Netlist<I>
3233where
3234 I: Instantiable,
3235{
3236 pub fn objects(&self) -> impl Iterator<Item = NetRef<I>> {
3238 iter::ObjectIterator::new(self)
3239 }
3240
3241 pub fn matches<F>(&self, filter: F) -> impl Iterator<Item = NetRef<I>>
3243 where
3244 F: Fn(&I) -> bool,
3245 {
3246 self.objects().filter(move |f| {
3247 if let Some(inst_type) = f.get_instance_type() {
3248 filter(&inst_type)
3249 } else {
3250 false
3251 }
3252 })
3253 }
3254
3255 pub fn inputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
3257 self.objects()
3258 .filter(|n| n.is_an_input())
3259 .map(|n| DrivenNet::new(0, n))
3260 }
3261
3262 pub fn outputs(&self) -> Vec<(DrivenNet<I>, Net)> {
3264 self.outputs
3265 .borrow()
3266 .iter()
3267 .flat_map(|(k, nets)| {
3268 nets.iter().map(|n| {
3269 (
3270 DrivenNet::new(k.secondary(), NetRef::wrap(self.index_weak(&k.root()))),
3271 n.clone(),
3272 )
3273 })
3274 })
3275 .collect()
3276 }
3277
3278 pub fn connections(&self) -> impl Iterator<Item = Connection<I>> {
3280 iter::ConnectionIterator::new(self)
3281 }
3282
3283 pub fn node_dfs(&self, from: NetRef<I>) -> impl Iterator<Item = NetRef<I>> {
3288 self.belongs(&from);
3289 iter::DFSIterator::new(self, from)
3290 }
3291
3292 pub fn net_dfs(&self, from: DrivenNet<I>) -> impl Iterator<Item = DrivenNet<I>> {
3297 self.belongs(&from.clone().unwrap());
3298 iter::NetDFSIterator::new(self, from)
3299 }
3300
3301 #[cfg(feature = "serde")]
3302 pub fn serialize(self, writer: impl std::io::Write) -> Result<(), serde_json::Error>
3304 where
3305 I: ::serde::Serialize,
3306 {
3307 serde::netlist_serialize(self, writer)
3308 }
3309
3310 #[cfg(feature = "graph")]
3311 pub fn dot_string(&self) -> String {
3313 use emitter::DotEmitter;
3314 let emitter = DotEmitter::new(self);
3315 emitter.emit()
3316 }
3317
3318 #[cfg(feature = "graph")]
3319 pub fn dump_dot(&self) -> std::io::Result<()> {
3321 use std::io::Write;
3322 let mut dir = std::env::current_dir()?;
3323 let mod_name = format!("{}.dot", self.get_name());
3324 dir.push(mod_name);
3325 let mut file = std::fs::File::create(dir)?;
3326 let dot = self.dot_string();
3327 write!(file, "{dot}")
3328 }
3329}
3330
3331impl<I> std::fmt::Display for Netlist<I>
3332where
3333 I: Instantiable,
3334{
3335 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3336 use emitter::{VerilogEmitter, VerilogEmitterConfig};
3337 let emitter = VerilogEmitter::new(self, VerilogEmitterConfig::legacy());
3338 emitter.fmt(f)
3339 }
3340}
3341
3342pub type GateNetlist = Netlist<Gate>;
3344pub type GateRef = NetRef<Gate>;
3346
3347#[cfg(test)]
3348mod tests {
3349 use super::iter::{DFSIterator, NetDFSIterator};
3350 use super::*;
3351 #[test]
3352 fn test_delete_netlist() {
3353 let netlist = Netlist::new("simple_example".into());
3354
3355 let input1 = netlist.insert_input("input1".into());
3357 let input2 = netlist.insert_input("input2".into());
3358
3359 let instance = netlist
3361 .insert_gate(
3362 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3363 "my_and".into(),
3364 &[input1.clone(), input2.clone()],
3365 )
3366 .unwrap();
3367
3368 let instance = instance.expose_as_output().unwrap();
3370 instance.delete_uses().unwrap();
3371 assert!(netlist.clean().is_ok());
3373 input1.expose_with_name("an_output".into());
3374 assert!(netlist.clean().is_ok());
3375 }
3376
3377 #[test]
3378 #[should_panic(expected = "Attempted to create a gate with a sliced identifier")]
3379 fn gate_w_slice_panics() {
3380 Gate::new_logical("AND[1]".into(), vec!["A".into(), "B".into()], "Y".into());
3381 }
3382
3383 #[test]
3384 fn gates_dont_have_params() {
3385 let gate = Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into());
3387 assert!(!gate.has_parameter(&"id".into()));
3388 assert!(gate.get_parameter(&"id".into()).is_none());
3389 assert_eq!(*gate.get_gate_name(), "AND".into());
3390 }
3391
3392 #[test]
3393 fn operand_conversions() {
3394 let operand = Operand::CellIndex(3, 2);
3395 assert_eq!(operand.to_string(), "3.2");
3396 let parsed = "3.2".parse::<Operand>();
3397 assert!(parsed.is_ok());
3398 let parsed = parsed.unwrap();
3399 assert_eq!(operand, parsed);
3400 }
3401
3402 #[test]
3403 #[should_panic(expected = "out of bounds for netref")]
3404 fn test_bad_output() {
3405 let netlist = GateNetlist::new("min_module".into());
3406 let a = netlist.insert_input("a".into());
3407 DrivenNet::new(1, a.unwrap());
3408 }
3409
3410 #[test]
3411 fn test_netdfsiterator() {
3412 let netlist = Netlist::new("dfs_netlist".into());
3413
3414 let a = netlist.insert_input("a".into());
3416 let b = netlist.insert_input("b".into());
3417 let c = netlist.insert_input("c".into());
3418 let d = netlist.insert_input("d".into());
3419 let e = netlist.insert_input("e".into());
3420
3421 let n1 = netlist
3423 .insert_gate(
3424 Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into()),
3425 "n1".into(),
3426 &[a.clone(), b.clone()],
3427 )
3428 .unwrap()
3429 .get_output(0);
3430 let n2 = netlist
3431 .insert_gate(
3432 Gate::new_logical("NOR".into(), vec!["A".into(), "B".into()], "Y".into()),
3433 "n2".into(),
3434 &[d.clone(), e.clone()],
3435 )
3436 .unwrap()
3437 .get_output(0);
3438 let n3 = netlist
3439 .insert_gate(
3440 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3441 "n3".into(),
3442 &[n1.clone(), c.clone()],
3443 )
3444 .unwrap()
3445 .get_output(0);
3446 let n4 = netlist
3447 .insert_gate(
3448 Gate::new_logical("NAND".into(), vec!["A".into(), "B".into()], "Y".into()),
3449 "n4".into(),
3450 &[n3.clone(), n2.clone()],
3451 )
3452 .unwrap()
3453 .get_output(0);
3454 n4.clone().expose_with_name("y".into());
3455
3456 let mut dfs = NetDFSIterator::new(&netlist, n4.clone());
3458 assert_eq!(dfs.next(), Some(n4));
3459 assert_eq!(dfs.next(), Some(n2));
3460 assert_eq!(dfs.next(), Some(e));
3461 assert_eq!(dfs.next(), Some(d));
3462 assert_eq!(dfs.next(), Some(n3));
3463 assert_eq!(dfs.next(), Some(c));
3464 assert_eq!(dfs.next(), Some(n1));
3465 assert_eq!(dfs.next(), Some(b));
3466 assert_eq!(dfs.next(), Some(a));
3467 assert_eq!(dfs.next(), None);
3468 }
3469
3470 #[test]
3471 fn test_dfs_cycles() {
3472 let netlist = Netlist::new("dfs_cycles".into());
3473
3474 let a = netlist.insert_input("a".into());
3476
3477 let and = netlist.insert_gate_disconnected(
3479 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3480 "and".into(),
3481 );
3482
3483 a.connect(and.get_input(0));
3485 and.get_output(0).connect(and.get_input(1));
3486
3487 let dfs = DFSIterator::new(&netlist, and.clone());
3489 let driven_dfs = NetDFSIterator::new(&netlist, and.get_output(0));
3490
3491 assert!(dfs.detect_cycles());
3492 assert!(driven_dfs.detect_cycles());
3493 }
3494
3495 #[test]
3496 fn test_netdfsiterator_with_boundary() {
3497 let netlist = Netlist::new("dfs_netlist".into());
3498
3499 let a = netlist.insert_input("a".into());
3501 let b = netlist.insert_input("b".into());
3502 let c = netlist.insert_input("c".into());
3503 let d = netlist.insert_input("d".into());
3504 let e = netlist.insert_input("e".into());
3505
3506 let n1 = netlist
3508 .insert_gate(
3509 Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into()),
3510 "n1".into(),
3511 &[a.clone(), b.clone()],
3512 )
3513 .unwrap()
3514 .get_output(0);
3515 let n2 = netlist
3516 .insert_gate(
3517 Gate::new_logical("NOR".into(), vec!["A".into(), "B".into()], "Y".into()),
3518 "n2".into(),
3519 &[d.clone(), e.clone()],
3520 )
3521 .unwrap()
3522 .get_output(0);
3523 let n3 = netlist
3524 .insert_gate(
3525 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3526 "n3".into(),
3527 &[n1.clone(), c.clone()],
3528 )
3529 .unwrap()
3530 .get_output(0);
3531 let n4 = netlist
3532 .insert_gate(
3533 Gate::new_logical("NAND".into(), vec!["A".into(), "B".into()], "Y".into()),
3534 "n4".into(),
3535 &[n3.clone(), n2.clone()],
3536 )
3537 .unwrap()
3538 .get_output(0);
3539
3540 let n3_boundary = n3.clone();
3542 let mut dfs =
3543 NetDFSIterator::new_filtered(&netlist, n4.clone(), move |n| *n == n3_boundary);
3544 assert_eq!(dfs.next(), Some(n4));
3545 assert_eq!(dfs.next(), Some(n2));
3546 assert_eq!(dfs.next(), Some(e));
3547 assert_eq!(dfs.next(), Some(d));
3548 assert_eq!(dfs.next(), Some(n3));
3549 assert_eq!(dfs.next(), None);
3550 }
3551
3552 #[test]
3553 fn test_dfs_convergence() {
3554 let netlist = GateNetlist::new("example".into());
3555 let gate = Gate::new_logical_multi(
3556 "FA".into(),
3557 vec!["A".into(), "B".into()],
3558 vec!["S".into(), "COUT".into()],
3559 );
3560 let a = netlist.insert_input("a".into());
3561 let b = netlist.insert_input("b".into());
3562 let gate = netlist.insert_gate(gate, "g".into(), &[a, b]).unwrap();
3563 let s = gate.get_output(0);
3564 let c = gate.get_output(1);
3565 let gate = Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into());
3566 let d = netlist.insert_gate(gate, "h".into(), &[s, c]).unwrap();
3567
3568 let dfs = NetDFSIterator::new(&netlist, d.get_output(0));
3569 let c = dfs.count();
3570 assert_eq!(c, 5);
3571
3572 let dfs = DFSIterator::new(&netlist, d.clone());
3573 let c = dfs.count();
3574 assert_eq!(c, 4);
3575 }
3576
3577 #[test]
3578 fn test_operand_comparison() {
3579 let a = Operand::CellIndex(3, 0);
3580 let b = Operand::DirectIndex(3);
3581 assert_eq!(a.cmp(&b), std::cmp::Ordering::Greater);
3582 assert_eq!(b.cmp(&a), std::cmp::Ordering::Less);
3583 }
3584}
3585#[cfg(feature = "serde")]
3586pub mod serde {
3588 use super::{Identifier, Netlist, Operand, OwnedObject, WeakIndex};
3589 use crate::{
3590 attribute::{AttributeKey, AttributeValue},
3591 circuit::{Instantiable, Net, Object},
3592 };
3593 use serde::{Deserialize, Serialize, de::DeserializeOwned};
3594 use std::cell::RefCell;
3595 use std::{
3596 collections::{BTreeMap, BTreeSet},
3597 rc::Rc,
3598 };
3599
3600 #[derive(Debug, Serialize, Deserialize)]
3601 struct SerdeObject<I>
3602 where
3603 I: Instantiable + Serialize,
3604 {
3605 object: Object<I>,
3607 operands: Vec<Option<Operand>>,
3609 attributes: BTreeMap<AttributeKey, AttributeValue>,
3611 }
3612
3613 impl<I, O> From<OwnedObject<I, O>> for SerdeObject<I>
3614 where
3615 I: Instantiable + Serialize,
3616 O: WeakIndex<usize, Output = OwnedObject<I, O>>,
3617 {
3618 fn from(value: OwnedObject<I, O>) -> Self {
3619 SerdeObject {
3620 object: value.object,
3621 operands: value.operands,
3622 attributes: value.attributes,
3623 }
3624 }
3625 }
3626
3627 impl<I> SerdeObject<I>
3628 where
3629 I: Instantiable + Serialize,
3630 {
3631 fn into_owned_object<O>(self, owner: &Rc<O>, index: usize) -> OwnedObject<I, O>
3632 where
3633 O: WeakIndex<usize, Output = OwnedObject<I, O>>,
3634 {
3635 OwnedObject {
3636 object: self.object,
3637 owner: Rc::downgrade(owner),
3638 operands: self.operands,
3639 attributes: self.attributes,
3640 index,
3641 }
3642 }
3643 }
3644
3645 #[derive(Debug, Serialize, Deserialize)]
3646 struct SerdeNetlist<I>
3647 where
3648 I: Instantiable + Serialize,
3649 {
3650 name: Identifier,
3652 objects: Vec<SerdeObject<I>>,
3654 outputs: BTreeMap<String, BTreeSet<Net>>,
3658 }
3659
3660 impl<I> From<Netlist<I>> for SerdeNetlist<I>
3661 where
3662 I: Instantiable + Serialize,
3663 {
3664 fn from(value: Netlist<I>) -> Self {
3665 SerdeNetlist {
3666 name: value.name.into_inner(),
3667 objects: value
3668 .objects
3669 .into_inner()
3670 .into_iter()
3671 .map(|o| {
3672 Rc::try_unwrap(o)
3673 .ok()
3674 .expect("Cannot serialize with live references")
3675 .into_inner()
3676 .into()
3677 })
3678 .collect(),
3679 outputs: value
3680 .outputs
3681 .into_inner()
3682 .into_iter()
3683 .map(|(o, nets)| (o.to_string(), nets.into_iter().collect()))
3685 .collect(),
3686 }
3687 }
3688 }
3689
3690 impl<I> SerdeNetlist<I>
3691 where
3692 I: Instantiable + Serialize,
3693 {
3694 fn into_netlist(self) -> Rc<Netlist<I>> {
3696 let netlist = Netlist::new(self.name);
3697 let outputs: BTreeMap<Operand, BTreeSet<Net>> = self
3698 .outputs
3699 .into_iter()
3700 .map(|(k, v)| {
3701 let operand = k.parse::<Operand>().expect("Invalid index");
3702 (operand, v.into_iter().collect())
3703 })
3704 .collect();
3705 let objects = self
3706 .objects
3707 .into_iter()
3708 .enumerate()
3709 .map(|(i, o)| {
3710 let owned_object = o.into_owned_object(&netlist, i);
3711 Rc::new(RefCell::new(owned_object))
3712 })
3713 .collect::<Vec<_>>();
3714 {
3715 let mut objs_mut = netlist.objects.borrow_mut();
3716 *objs_mut = objects;
3717 let mut outputs_mut = netlist.outputs.borrow_mut();
3718 *outputs_mut = outputs;
3719 }
3720 netlist
3721 }
3722 }
3723
3724 pub fn netlist_serialize<I: Instantiable + Serialize>(
3726 netlist: Netlist<I>,
3727 writer: impl std::io::Write,
3728 ) -> Result<(), serde_json::Error> {
3729 let sobj: SerdeNetlist<I> = netlist.into();
3730 serde_json::to_writer_pretty(writer, &sobj)
3731 }
3732
3733 pub fn netlist_deserialize<I: Instantiable + Serialize + DeserializeOwned>(
3735 reader: impl std::io::Read,
3736 ) -> Result<Rc<Netlist<I>>, serde_json::Error> {
3737 let sobj: SerdeNetlist<I> = serde_json::from_reader(reader)?;
3738 Ok(sobj.into_netlist())
3739 }
3740}