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<NetRef<I>, Error> {
864 let netlist = self
865 .netref
866 .borrow()
867 .owner
868 .upgrade()
869 .expect("NetRef is unlinked from netlist");
870 netlist
871 .replace_net_uses(self.into(), other)
872 .map(|d| d.unwrap())
873 }
874
875 pub fn clear_attribute(&self, k: &AttributeKey) -> Option<AttributeValue> {
877 self.netref.borrow_mut().clear_attribute(k)
878 }
879
880 pub fn set_attribute(&self, k: AttributeKey) {
882 self.netref.borrow_mut().set_attribute(k);
883 }
884
885 pub fn insert_attribute(&self, k: AttributeKey, v: String) -> Option<AttributeValue> {
887 self.netref.borrow_mut().insert_attribute(k, v)
888 }
889
890 pub fn attributes(&self) -> impl Iterator<Item = Attribute> {
892 let v: Vec<_> = self.netref.borrow().attributes().collect();
893 v.into_iter()
894 }
895}
896
897impl<I> std::fmt::Display for NetRef<I>
898where
899 I: Instantiable,
900{
901 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
902 self.netref.borrow().object.fmt(f)
903 }
904}
905
906impl<I> From<NetRef<I>> for DrivenNet<I>
907where
908 I: Instantiable,
909{
910 fn from(val: NetRef<I>) -> Self {
911 if val.is_multi_output() {
912 panic!("Cannot convert a multi-output netref to an output port");
913 }
914 DrivenNet::new(0, val)
915 }
916}
917
918impl<I> From<&NetRef<I>> for DrivenNet<I>
919where
920 I: Instantiable,
921{
922 fn from(val: &NetRef<I>) -> Self {
923 if val.is_multi_output() {
924 panic!("Cannot convert a multi-output netref to an output port");
925 }
926 DrivenNet::new(0, val.clone())
927 }
928}
929
930pub struct MutBorrowReq<I: Instantiable> {
932 from: NetRef<I>,
933 ind: Net,
934}
935
936impl<I> MutBorrowReq<I>
937where
938 I: Instantiable,
939{
940 fn new(from: NetRef<I>, ind: Net) -> Self {
942 Self { from, ind }
943 }
944
945 pub fn borrow_mut(&self) -> RefMut<'_, Net> {
947 self.from.find_net_mut(&self.ind).unwrap()
948 }
949
950 pub fn is_an_input(&self) -> bool {
952 self.from.is_an_input()
953 }
954
955 pub fn borrow_mut_if(&self, f: impl Fn(&NetRef<I>) -> bool) -> Option<RefMut<'_, Net>> {
957 if f(&self.from) {
958 Some(self.borrow_mut())
959 } else {
960 None
961 }
962 }
963}
964
965#[derive(Debug)]
967pub struct Netlist<I>
968where
969 I: Instantiable,
970{
971 name: RefCell<String>,
973 objects: RefCell<Vec<NetRefT<I>>>,
975 outputs: RefCell<HashMap<Operand, BTreeSet<Net>>>,
977}
978
979#[derive(Debug, Clone)]
981pub struct InputPort<I: Instantiable> {
982 pos: usize,
983 netref: NetRef<I>,
984}
985
986impl<I> InputPort<I>
987where
988 I: Instantiable,
989{
990 fn new(pos: usize, netref: NetRef<I>) -> Self {
991 if pos >= netref.clone().unwrap().borrow().operands.len() {
992 panic!(
993 "Position {} out of bounds for netref with {} input nets",
994 pos,
995 netref.unwrap().borrow().get().get_nets().len()
996 );
997 }
998 Self { pos, netref }
999 }
1000
1001 pub fn get_driver(&self) -> Option<DrivenNet<I>> {
1003 if self.netref.is_an_input() {
1004 panic!("Input port is not driven by a primitive");
1005 }
1006 if let Some(prev_operand) = self.netref.clone().unwrap().borrow().operands[self.pos] {
1007 let netlist = self
1008 .netref
1009 .clone()
1010 .unwrap()
1011 .borrow()
1012 .owner
1013 .upgrade()
1014 .expect("Input port is unlinked from netlist");
1015 let driver_nr = netlist.index_weak(&prev_operand.root());
1016 let nr = NetRef::wrap(driver_nr);
1017 let pos = prev_operand.secondary();
1018 Some(DrivenNet::new(pos, nr))
1019 } else {
1020 None
1021 }
1022 }
1023
1024 pub fn disconnect(&self) -> Option<DrivenNet<I>> {
1026 let val = self.get_driver();
1027 self.netref.clone().unwrap().borrow_mut().operands[self.pos] = None;
1028 val
1029 }
1030
1031 pub fn get_port(&self) -> Net {
1033 if self.netref.is_an_input() {
1034 panic!("Net is not driven by a primitive");
1035 }
1036 self.netref
1037 .get_instance_type()
1038 .unwrap()
1039 .get_input_port(self.pos)
1040 .clone()
1041 }
1042
1043 pub fn connect(self, output: DrivenNet<I>) {
1045 output.connect(self);
1046 }
1047
1048 pub fn unwrap(self) -> NetRef<I> {
1050 self.netref
1051 }
1052
1053 pub fn get_input_num(&self) -> usize {
1055 self.pos
1056 }
1057}
1058
1059impl<I> std::fmt::Display for InputPort<I>
1060where
1061 I: Instantiable,
1062{
1063 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1064 self.get_port().fmt(f)
1065 }
1066}
1067
1068#[derive(Debug, Clone)]
1070pub struct DrivenNet<I: Instantiable> {
1071 pos: usize,
1072 netref: NetRef<I>,
1073}
1074
1075impl<I> DrivenNet<I>
1076where
1077 I: Instantiable,
1078{
1079 fn new(pos: usize, netref: NetRef<I>) -> Self {
1080 if pos >= netref.clone().unwrap().borrow().get().get_nets().len() {
1081 panic!(
1082 "Position {} out of bounds for netref with {} outputted nets",
1083 pos,
1084 netref.unwrap().borrow().get().get_nets().len()
1085 );
1086 }
1087 Self { pos, netref }
1088 }
1089
1090 fn get_operand(&self) -> Operand {
1092 if self.netref.is_multi_output() {
1093 Operand::CellIndex(self.netref.clone().unwrap().borrow().get_index(), self.pos)
1094 } else {
1095 Operand::DirectIndex(self.netref.clone().unwrap().borrow().get_index())
1096 }
1097 }
1098
1099 pub fn as_net(&self) -> Ref<'_, Net> {
1101 self.netref.get_net(self.pos)
1102 }
1103
1104 pub fn as_net_mut(&self) -> RefMut<'_, Net> {
1106 self.netref.get_net_mut(self.pos)
1107 }
1108
1109 pub fn is_an_input(&self) -> bool {
1111 self.netref.is_an_input()
1112 }
1113
1114 pub fn get_port(&self) -> Net {
1116 if self.netref.is_an_input() {
1117 panic!("Net is not driven by a primitive");
1118 }
1119 self.netref
1120 .get_instance_type()
1121 .unwrap()
1122 .get_output_port(self.pos)
1123 .clone()
1124 }
1125
1126 pub fn connect(&self, input: InputPort<I>) {
1128 let operand = self.get_operand();
1129 let index = input.netref.unwrap().borrow().get_index();
1130 let netlist = self
1131 .netref
1132 .clone()
1133 .unwrap()
1134 .borrow()
1135 .owner
1136 .upgrade()
1137 .expect("Output port is unlinked from netlist");
1138 let obj = netlist.index_weak(&index);
1139 obj.borrow_mut().operands[input.pos] = Some(operand);
1140 }
1141
1142 pub fn is_top_level_output(&self) -> bool {
1144 let netlist = self
1145 .netref
1146 .clone()
1147 .unwrap()
1148 .borrow()
1149 .owner
1150 .upgrade()
1151 .expect("DrivenNet is unlinked from netlist");
1152 let outputs = netlist.outputs.borrow();
1153 outputs.contains_key(&self.get_operand())
1154 }
1155
1156 pub fn unwrap(self) -> NetRef<I> {
1158 self.netref
1159 }
1160
1161 pub fn get_identifier(&self) -> Identifier {
1163 self.as_net().get_identifier().clone()
1164 }
1165
1166 pub fn expose_with_name(self, name: Identifier) -> Self {
1173 let netlist = self
1174 .netref
1175 .clone()
1176 .unwrap()
1177 .borrow()
1178 .owner
1179 .upgrade()
1180 .expect("DrivenNet is unlinked from netlist");
1181 netlist.expose_net_with_name(self.clone(), name);
1182 self
1183 }
1184
1185 pub fn remove_output(&self, net_name: &Identifier) -> bool {
1192 let netlist = self
1193 .netref
1194 .clone()
1195 .unwrap()
1196 .borrow()
1197 .owner
1198 .upgrade()
1199 .expect("DrivenNet is unlinked from netlist");
1200 netlist.remove_output(self, net_name)
1201 }
1202
1203 pub fn remove_all_outputs(&self) -> usize {
1210 let netlist = self
1211 .netref
1212 .clone()
1213 .unwrap()
1214 .borrow()
1215 .owner
1216 .upgrade()
1217 .expect("DrivenNet is unlinked from netlist");
1218 netlist.remove_outputs(self)
1219 }
1220
1221 pub fn get_output_index(&self) -> Option<usize> {
1223 if self.netref.is_an_input() {
1224 None
1225 } else {
1226 Some(self.pos)
1227 }
1228 }
1229
1230 pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
1232 self.netref.get_instance_type()
1233 }
1234}
1235
1236impl<I> std::fmt::Display for DrivenNet<I>
1237where
1238 I: Instantiable,
1239{
1240 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1241 self.as_net().fmt(f)
1242 }
1243}
1244
1245impl<I> PartialEq for DrivenNet<I>
1246where
1247 I: Instantiable,
1248{
1249 fn eq(&self, other: &Self) -> bool {
1250 self.netref == other.netref && self.pos == other.pos
1251 }
1252}
1253
1254impl<I> Eq for DrivenNet<I> where I: Instantiable {}
1255
1256impl<I> std::hash::Hash for DrivenNet<I>
1257where
1258 I: Instantiable,
1259{
1260 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1261 self.netref.hash(state);
1262 self.pos.hash(state);
1263 }
1264}
1265
1266impl<I> Ord for DrivenNet<I>
1267where
1268 I: Instantiable,
1269{
1270 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
1271 match self.netref.cmp(&other.netref) {
1272 std::cmp::Ordering::Equal => self.pos.cmp(&other.pos),
1273 ord => ord,
1274 }
1275 }
1276}
1277
1278impl<I> PartialOrd for DrivenNet<I>
1279where
1280 I: Instantiable,
1281{
1282 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1283 Some(self.cmp(other))
1284 }
1285}
1286
1287impl<I> WeakIndex<usize> for Netlist<I>
1288where
1289 I: Instantiable,
1290{
1291 type Output = OwnedObject<I, Self>;
1292
1293 fn index_weak(&self, index: &usize) -> Rc<RefCell<Self::Output>> {
1294 self.objects.borrow()[*index].clone()
1295 }
1296}
1297
1298impl<I> Netlist<I>
1299where
1300 I: Instantiable,
1301{
1302 pub fn new(name: String) -> Rc<Self> {
1304 Rc::new(Self {
1305 name: RefCell::new(name),
1306 objects: RefCell::new(Vec::new()),
1307 outputs: RefCell::new(HashMap::new()),
1308 })
1309 }
1310
1311 pub fn reclaim(self: Rc<Self>) -> Option<Self> {
1313 Rc::try_unwrap(self).ok()
1314 }
1315
1316 pub fn deep_clone(self: &Rc<Self>) -> Rc<Self> {
1318 let dc = Rc::new(Self {
1319 name: self.name.clone(),
1320 objects: RefCell::new(Vec::new()),
1321 outputs: self.outputs.clone(),
1322 });
1323
1324 let objects_linked: Vec<NetRefT<I>> = self
1325 .objects
1326 .borrow()
1327 .iter()
1328 .map(|obj| {
1329 Rc::new(RefCell::new(OwnedObject {
1330 object: obj.borrow().object.clone(),
1331 owner: Rc::downgrade(&dc),
1332 operands: obj.borrow().operands.clone(),
1333 attributes: obj.borrow().attributes.clone(),
1334 index: obj.borrow().index,
1335 }))
1336 })
1337 .collect();
1338
1339 *dc.objects.borrow_mut() = objects_linked;
1340
1341 dc
1342 }
1343
1344 fn insert_object(
1349 self: &Rc<Self>,
1350 object: Object<I>,
1351 operands: &[DrivenNet<I>],
1352 ) -> Result<NetRef<I>, Error> {
1353 for operand in operands {
1354 self.belongs(&operand.clone().unwrap());
1355 }
1356 let index = self.objects.borrow().len();
1357 let weak = Rc::downgrade(self);
1358 let operands = operands
1359 .iter()
1360 .map(|net| Some(net.get_operand()))
1361 .collect::<Vec<_>>();
1362 let owned_object = Rc::new(RefCell::new(OwnedObject {
1363 object,
1364 owner: weak,
1365 operands,
1366 attributes: HashMap::new(),
1367 index,
1368 }));
1369 self.objects.borrow_mut().push(owned_object.clone());
1370 Ok(NetRef::wrap(owned_object))
1371 }
1372
1373 pub fn insert_input(self: &Rc<Self>, net: Net) -> DrivenNet<I> {
1375 let obj = Object::Input(net);
1376 self.insert_object(obj, &[]).unwrap().into()
1377 }
1378
1379 pub fn insert_input_escaped_logic_bus(
1381 self: &Rc<Self>,
1382 net: String,
1383 bw: usize,
1384 ) -> Vec<DrivenNet<I>> {
1385 Net::new_escaped_logic_bus(net, bw)
1386 .into_iter()
1387 .map(|n| self.insert_input(n))
1388 .collect()
1389 }
1390
1391 pub fn insert_gate(
1393 self: &Rc<Self>,
1394 inst_type: I,
1395 inst_name: Identifier,
1396 operands: &[DrivenNet<I>],
1397 ) -> Result<NetRef<I>, Error> {
1398 let nets = inst_type
1399 .get_output_ports()
1400 .into_iter()
1401 .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1402 .collect::<Vec<_>>();
1403 let input_count = inst_type.get_input_ports().into_iter().count();
1404 if operands.len() != input_count {
1405 return Err(Error::ArgumentMismatch(input_count, operands.len()));
1406 }
1407 let obj = Object::Instance(nets, inst_name, inst_type);
1408 self.insert_object(obj, operands)
1409 }
1410
1411 pub fn insert_gate_disconnected(
1413 self: &Rc<Self>,
1414 inst_type: I,
1415 inst_name: Identifier,
1416 ) -> NetRef<I> {
1417 let nets = inst_type
1418 .get_output_ports()
1419 .into_iter()
1420 .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1421 .collect::<Vec<_>>();
1422 let object = Object::Instance(nets, inst_name, inst_type);
1423 let index = self.objects.borrow().len();
1424 let weak = Rc::downgrade(self);
1425 let input_count = object
1426 .get_instance_type()
1427 .unwrap()
1428 .get_input_ports()
1429 .into_iter()
1430 .count();
1431 let operands = vec![None; input_count];
1432 let owned_object = Rc::new(RefCell::new(OwnedObject {
1433 object,
1434 owner: weak,
1435 operands,
1436 attributes: HashMap::new(),
1437 index,
1438 }));
1439 self.objects.borrow_mut().push(owned_object.clone());
1440 NetRef::wrap(owned_object)
1441 }
1442
1443 pub fn insert_constant(
1445 self: &Rc<Self>,
1446 value: Logic,
1447 inst_name: Identifier,
1448 ) -> Result<DrivenNet<I>, Error> {
1449 let obj = I::from_constant(value).ok_or(Error::InstantiableError(format!(
1450 "Instantiable type does not support constant value {}",
1451 value
1452 )))?;
1453 Ok(self.insert_gate_disconnected(obj, inst_name).into())
1454 }
1455
1456 fn belongs(&self, netref: &NetRef<I>) {
1460 if let Some(nl) = netref.netref.borrow().owner.upgrade() {
1461 if self.objects.borrow().len() != nl.objects.borrow().len() {
1462 panic!("NetRef does not belong to this netlist");
1463 }
1464
1465 if let Some(p) = self.objects.borrow().first()
1466 && let Some(np) = nl.objects.borrow().first()
1467 && !Rc::ptr_eq(p, np)
1468 {
1469 panic!("NetRef does not belong to this netlist");
1470 }
1471 }
1472
1473 if netref.netref.borrow().index >= self.objects.borrow().len() {
1474 panic!("NetRef does not belong to this netlist");
1475 }
1476 }
1477
1478 pub fn get_driver(&self, netref: NetRef<I>, index: usize) -> Option<DrivenNet<I>> {
1485 self.belongs(&netref);
1486 let op = netref.unwrap().borrow().operands[index]?;
1487 Some(DrivenNet::new(
1488 op.secondary(),
1489 NetRef::wrap(self.index_weak(&op.root()).clone()),
1490 ))
1491 }
1492
1493 pub fn expose_net_with_name(&self, net: DrivenNet<I>, name: Identifier) -> DrivenNet<I> {
1499 self.belongs(&net.clone().unwrap());
1500 let mut outputs = self.outputs.borrow_mut();
1501 let named_net = net.as_net().with_name(name);
1502 outputs
1503 .entry(net.get_operand())
1504 .or_default()
1505 .insert(named_net);
1506 net
1507 }
1508
1509 pub fn expose_net(&self, net: DrivenNet<I>) -> Result<DrivenNet<I>, Error> {
1514 self.belongs(&net.clone().unwrap());
1515 if net.is_an_input() {
1516 return Err(Error::InputNeedsAlias(net.as_net().clone()));
1517 }
1518 let mut outputs = self.outputs.borrow_mut();
1519 outputs
1520 .entry(net.get_operand())
1521 .or_default()
1522 .insert(net.as_net().clone());
1523 Ok(net)
1524 }
1525
1526 pub fn remove_output(&self, operand: &DrivenNet<I>, net_name: &Identifier) -> bool {
1532 self.belongs(&operand.clone().unwrap());
1533 let mut outputs = self.outputs.borrow_mut();
1534 if let Some(nets) = outputs.get_mut(&operand.get_operand()) {
1535 let net_to_remove = Net::new(net_name.clone(), crate::circuit::DataType::logic());
1537 if nets.remove(&net_to_remove) {
1538 if nets.is_empty() {
1540 outputs.remove(&operand.get_operand());
1541 }
1542 return true;
1543 }
1544 }
1545 false
1546 }
1547
1548 pub fn remove_outputs(&self, operand: &DrivenNet<I>) -> usize {
1551 self.outputs
1553 .borrow_mut()
1554 .remove(&operand.get_operand())
1555 .map(|nets| nets.len())
1556 .unwrap_or(0)
1557 }
1558
1559 pub fn clear_outputs(&self) {
1561 self.outputs.borrow_mut().clear();
1562 }
1563
1564 pub fn delete_net_uses(&self, netref: NetRef<I>) -> Result<Object<I>, Error> {
1569 self.belongs(&netref);
1570 let unwrapped = netref.clone().unwrap();
1571 if Rc::strong_count(&unwrapped) > 3 {
1572 return Err(Error::DanglingReference(netref.nets().collect()));
1573 }
1574 let old_index = unwrapped.borrow().get_index();
1575 let objects = self.objects.borrow();
1576 for oref in objects.iter() {
1577 let operands = &mut oref.borrow_mut().operands;
1578 for operand in operands.iter_mut() {
1579 if let Some(op) = operand {
1580 match op {
1581 Operand::DirectIndex(idx) | Operand::CellIndex(idx, _)
1582 if *idx == old_index =>
1583 {
1584 *operand = None;
1585 }
1586 _ => (),
1587 }
1588 }
1589 }
1590 }
1591
1592 let outputs: Vec<Operand> = self
1593 .outputs
1594 .borrow()
1595 .keys()
1596 .filter(|operand| match operand {
1597 Operand::DirectIndex(idx) | Operand::CellIndex(idx, _) => *idx == old_index,
1598 })
1599 .cloned()
1600 .collect();
1601
1602 for operand in outputs {
1603 self.outputs.borrow_mut().remove(&operand);
1604 }
1605
1606 Ok(netref.unwrap().borrow().get().clone())
1607 }
1608
1609 pub fn replace_net_uses(
1617 &self,
1618 of: DrivenNet<I>,
1619 with: &DrivenNet<I>,
1620 ) -> Result<DrivenNet<I>, Error> {
1621 {
1622 self.belongs(&of.clone().unwrap());
1623 self.belongs(&with.clone().unwrap());
1624 }
1625 let unwrapped = of.clone().unwrap().unwrap();
1626 let i = of.get_output_index();
1627 let k = with.get_output_index();
1628
1629 if of.clone().unwrap() == with.clone().unwrap() {
1630 if i == k {
1631 return Ok(of);
1632 }
1633
1634 if Rc::strong_count(&unwrapped) > 4 {
1635 return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1636 }
1637 } else if Rc::strong_count(&unwrapped) > 3 {
1638 return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1639 }
1640
1641 let old_index = of.get_operand();
1642
1643 if let Some(nets) = self.outputs.borrow().get(&old_index)
1644 && nets.contains(&of.as_net())
1645 {
1646 if of.is_an_input() {
1647 return Err(Error::NonuniqueNets(nets.iter().cloned().collect()));
1648 } else {
1649 let id = of.as_net().get_identifier().clone() + "_replaced".into();
1650 of.as_net_mut().set_identifier(id);
1651 }
1652 }
1653
1654 let new_index = with.get_operand();
1655 let objects = self.objects.borrow();
1656 for oref in objects.iter() {
1657 let operands = &mut oref.borrow_mut().operands;
1658 for operand in operands.iter_mut() {
1659 if let Some(op) = operand
1660 && *op == old_index
1661 {
1662 *operand = Some(new_index);
1663 }
1664 }
1665 }
1666
1667 let outs = self.outputs.borrow_mut().remove(&old_index);
1669 if let Some(outs) = outs {
1670 self.outputs
1671 .borrow_mut()
1672 .entry(new_index)
1673 .or_default()
1674 .extend(outs);
1675 }
1676
1677 Ok(of)
1678 }
1679}
1680
1681impl<I> Netlist<I>
1682where
1683 I: Instantiable,
1684{
1685 pub fn get_name(&self) -> Ref<'_, String> {
1687 self.name.borrow()
1688 }
1689
1690 pub fn set_name(&self, name: String) {
1695 *self.name.borrow_mut() = name;
1696 }
1697
1698 pub fn get_input_ports(&self) -> impl Iterator<Item = Net> {
1700 self.objects().filter_map(|oref| {
1701 if oref.is_an_input() {
1702 Some(oref.as_net().clone())
1703 } else {
1704 None
1705 }
1706 })
1707 }
1708
1709 pub fn get_output_ports(&self) -> Vec<Net> {
1711 self.outputs
1712 .borrow()
1713 .values()
1714 .flat_map(|nets| nets.iter().cloned())
1715 .collect()
1716 }
1717
1718 pub fn get_analysis<'a, A: Analysis<'a, I>>(&'a self) -> Result<A, Error> {
1720 A::build(self)
1721 }
1722
1723 pub fn find_net(&self, net: &Net) -> Option<DrivenNet<I>> {
1726 for obj in self.objects() {
1727 for o in obj.outputs() {
1728 if *o.as_net() == *net {
1729 return Some(o);
1730 }
1731 }
1732 }
1733 None
1734 }
1735
1736 pub fn first(&self) -> Option<NetRef<I>> {
1738 self.objects
1739 .borrow()
1740 .first()
1741 .map(|nr| NetRef::wrap(nr.clone()))
1742 }
1743
1744 pub fn last(&self) -> Option<NetRef<I>> {
1746 self.objects
1747 .borrow()
1748 .last()
1749 .map(|nr| NetRef::wrap(nr.clone()))
1750 }
1751
1752 pub fn len(&self) -> usize {
1754 self.objects.borrow().len()
1755 }
1756
1757 pub fn is_empty(&self) -> bool {
1759 self.objects.borrow().is_empty()
1760 }
1761
1762 pub fn drives_an_output(&self, netref: NetRef<I>) -> bool {
1767 self.belongs(&netref);
1768 let my_index = netref.unwrap().borrow().get_index();
1769 for key in self.outputs.borrow().keys() {
1770 if key.root() == my_index {
1771 return true;
1772 }
1773 }
1774 false
1775 }
1776
1777 pub fn rename_nets<F: Fn(&Identifier, usize) -> Identifier>(&self, f: F) -> Result<(), Error> {
1795 let mut i: usize = 0;
1796 for nr in self.objects() {
1797 if nr.is_an_input() {
1798 continue;
1799 }
1800 for mut net in nr.nets_mut() {
1801 let rename = f(net.get_identifier(), i);
1802 net.set_identifier(rename);
1803 i += 1;
1804 }
1805 }
1806
1807 for nr in self.objects() {
1808 if nr.is_an_input() {
1809 continue;
1810 }
1811
1812 let rename = f(&nr.get_instance_name().unwrap(), i);
1813 nr.set_instance_name(rename);
1814 i += 1;
1815 }
1816
1817 self.verify()
1818 }
1819
1820 pub fn retain_once(&self, set: &mut HashSet<DrivenNet<I>>) -> Result<Vec<Object<I>>, Error> {
1822 let mut dead_objs = HashSet::new();
1823 {
1824 let fan_out = self.get_analysis::<FanOutTable<I>>()?;
1825 for obj in self.objects() {
1826 let mut is_dead = true;
1827 for net in obj.outputs() {
1828 if fan_out.net_has_uses(&net.as_net()) {
1830 is_dead = false;
1831 } else {
1832 set.remove(&net);
1833 }
1834 }
1835 if is_dead && !obj.is_an_input() {
1836 dead_objs.insert(obj.unwrap().borrow().index);
1837 }
1838 }
1839 }
1840
1841 if dead_objs.is_empty() {
1842 return Ok(vec![]);
1843 }
1844
1845 let old_objects = self.objects.take();
1846
1847 for i in dead_objs.iter() {
1849 let rc = &old_objects[*i];
1850 if Rc::strong_count(rc) > 1 {
1851 self.objects.replace(old_objects.clone());
1852 return Err(Error::DanglingReference(
1853 rc.borrow().get().get_nets().to_vec(),
1854 ));
1855 }
1856 }
1857
1858 let mut removed = Vec::new();
1859 let mut remap: HashMap<usize, usize> = HashMap::new();
1860 for (old_index, obj) in old_objects.into_iter().enumerate() {
1861 if dead_objs.contains(&old_index) {
1862 removed.push(obj.borrow().get().clone());
1863 continue;
1864 }
1865
1866 let new_index = self.objects.borrow().len();
1867 remap.insert(old_index, new_index);
1868 obj.borrow_mut().index = new_index;
1869 self.objects.borrow_mut().push(obj);
1870 }
1871
1872 for obj in self.objects.borrow().iter() {
1873 for operand in obj.borrow_mut().inds_mut() {
1874 let root = operand.root();
1875 let root = *remap.get(&root).unwrap_or(&root);
1876 *operand = operand.remap(root);
1877 }
1878 }
1879
1880 let pairs: Vec<_> = self.outputs.take().into_iter().collect();
1881 for (operand, net) in pairs {
1882 let root = operand.root();
1883 let root = *remap.get(&root).unwrap_or(&root);
1884 let new_operand = operand.remap(root);
1885 self.outputs.borrow_mut().insert(new_operand, net);
1886 }
1887
1888 Ok(removed)
1889 }
1890
1891 pub fn clean(&self) -> Result<Vec<Object<I>>, Error> {
1894 let mut removed = Vec::new();
1895 let mut r = self.retain_once(&mut HashSet::new())?;
1896 while !r.is_empty() {
1897 removed.extend(r);
1898 r = self.retain_once(&mut HashSet::new())?;
1899 }
1900 Ok(removed)
1901 }
1902
1903 pub fn retain(&self, set: &mut HashSet<DrivenNet<I>>) -> Result<Vec<Object<I>>, Error> {
1905 let mut removed = Vec::new();
1906 let mut r = self.retain_once(set)?;
1907 while !r.is_empty() {
1908 removed.extend(r);
1909 r = self.retain_once(set)?;
1910 }
1911 Ok(removed)
1912 }
1913
1914 fn nets_insts_unique(&self) -> Result<(), Error> {
1916 let mut nets = HashSet::new();
1917 for net in self {
1918 if !nets.insert(net.clone().take_identifier()) {
1919 return Err(Error::NonuniqueNets(vec![net]));
1920 }
1921 }
1922 for inst in self.objects() {
1923 if let Some(name) = inst.get_instance_name()
1924 && !nets.insert(name.clone())
1925 {
1926 return Err(Error::NonuniqueInsts(vec![name]));
1927 }
1928 }
1929 Ok(())
1930 }
1931
1932 fn connections_type_check(&self) -> Result<(), Error> {
1933 for conn in self.connections() {
1934 let target = *conn.target().get_port().get_type();
1935 let source = *conn.src().as_net().get_type();
1936 if target != source {
1937 return Err(Error::TypeError(conn.src().as_net().clone()));
1938 }
1939 }
1940 Ok(())
1941 }
1942
1943 pub fn verify(&self) -> Result<(), Error> {
1945 if self.outputs.borrow().is_empty() {
1946 return Err(Error::NoOutputs);
1947 }
1948
1949 self.nets_insts_unique()?;
1950 self.connections_type_check()?;
1951
1952 Ok(())
1953 }
1954}
1955
1956#[derive(Debug, Clone)]
1958pub struct Connection<I: Instantiable> {
1959 driver: DrivenNet<I>,
1960 input: InputPort<I>,
1961}
1962
1963impl<I> Connection<I>
1964where
1965 I: Instantiable,
1966{
1967 fn new(driver: DrivenNet<I>, input: InputPort<I>) -> Self {
1968 Self { driver, input }
1969 }
1970
1971 pub fn src(&self) -> DrivenNet<I> {
1973 self.driver.clone()
1974 }
1975
1976 pub fn net(&self) -> Net {
1978 self.driver.as_net().clone()
1979 }
1980
1981 pub fn target(&self) -> InputPort<I> {
1983 self.input.clone()
1984 }
1985}
1986
1987impl<I> std::fmt::Display for Connection<I>
1988where
1989 I: Instantiable,
1990{
1991 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1992 self.net().fmt(f)
1993 }
1994}
1995
1996pub mod rewriter {
1998 use super::{DrivenNet, Error, Instantiable, NetRef, Netlist, Operand};
1999 use crate::graph::FanOutTable;
2000 use std::collections::HashMap;
2001 use std::rc::Rc;
2002
2003 pub struct NetMapper<'a, I: Instantiable> {
2007 parent: HashMap<DrivenNet<I>, DrivenNet<I>>,
2008 netlist: &'a Netlist<I>,
2009 fanout: FanOutTable<'a, I>,
2010 }
2011
2012 impl<'a, I: Instantiable> NetMapper<'a, I> {
2013 pub fn new(netlist: &'a Netlist<I>) -> Result<Self, Error> {
2015 Ok(Self {
2016 parent: HashMap::new(),
2017 netlist,
2018 fanout: netlist.get_analysis::<FanOutTable<I>>()?,
2019 })
2020 }
2021
2022 pub fn find(&self, x: DrivenNet<I>) -> DrivenNet<I> {
2024 let mut root = x;
2025 while let Some(p) = self.parent.get(&root) {
2026 root = p.clone();
2027 }
2028 root
2029 }
2030
2031 pub fn replace(&mut self, of: DrivenNet<I>, with: DrivenNet<I>) -> DrivenNet<I> {
2036 let of_root = self.find(of.clone());
2037 let with_root = self.find(with);
2038 if of_root == with_root {
2039 panic!("Already mapped by NetMapper: {of}");
2040 }
2041 self.parent.insert(of_root, with_root);
2042 of
2043 }
2044
2045 pub fn apply(self) -> Result<Vec<DrivenNet<I>>, Error> {
2048 let mut map: HashMap<Operand, Operand> = HashMap::new();
2050 for k in self.parent.keys().cloned() {
2051 let v = self.find(k.clone());
2052 if k != v {
2053 map.insert(k.get_operand(), v.get_operand());
2054 }
2055 }
2056
2057 drop(self.parent);
2058
2059 for (of, with) in map.iter() {
2061 let unwrapped = self.netlist.objects.borrow()[of.root()].clone();
2062 let i = of.secondary();
2063 let k = of.secondary();
2064 let nr = NetRef::wrap(unwrapped.clone());
2065
2066 if of.root() == with.root() {
2067 if i == k {
2068 continue;
2069 }
2070
2071 if Rc::strong_count(&unwrapped) - self.fanout.get_ref_count(&nr) > 4 {
2072 return Err(Error::DanglingReference(nr.nets().collect()));
2073 }
2074 } else if Rc::strong_count(&unwrapped) - self.fanout.get_ref_count(&nr) > 3 {
2075 return Err(Error::DanglingReference(nr.nets().collect()));
2076 }
2077
2078 let old_index = of;
2079 let of = DrivenNet::new(i, nr);
2080
2081 if let Some(nets) = self.netlist.outputs.borrow().get(old_index)
2082 && nets.contains(&of.as_net())
2083 {
2084 if of.is_an_input() {
2085 return Err(Error::NonuniqueNets(nets.iter().cloned().collect()));
2086 } else {
2087 let id = of.as_net().get_identifier().clone() + "_replaced".into();
2088 of.as_net_mut().set_identifier(id);
2089 }
2090 }
2091 }
2092
2093 let objects = self.netlist.objects.borrow();
2094 for (of, &with) in map.iter() {
2095 let of = DrivenNet::new(of.secondary(), NetRef::wrap(objects[of.root()].clone()));
2096 for u in self.fanout.get_users(&of) {
2097 let place = u.pos;
2098 let u = u.unwrap().unwrap();
2099 let operands = &mut u.borrow_mut().operands;
2100 operands[place] = Some(with);
2101 }
2102 }
2103
2104 for (of, &with) in map.iter() {
2105 let outs = self.netlist.outputs.borrow_mut().remove(of);
2107 if let Some(outs) = outs {
2108 self.netlist
2109 .outputs
2110 .borrow_mut()
2111 .entry(with)
2112 .or_default()
2113 .extend(outs);
2114 }
2115 }
2116
2117 let res: Vec<_> = map
2118 .into_keys()
2119 .map(|operand| {
2120 DrivenNet::new(
2121 operand.secondary(),
2122 NetRef::wrap(self.netlist.objects.borrow()[operand.root()].clone()),
2123 )
2124 })
2125 .collect();
2126
2127 Ok(res)
2128 }
2129 }
2130}
2131
2132pub mod iter {
2134
2135 use super::{
2136 Connection, DrivenNet, InputPort, Instantiable, Net, NetRef, Netlist, Operand, WeakIndex,
2137 };
2138 use std::collections::{HashMap, HashSet};
2139 pub struct NetIterator<'a, I: Instantiable> {
2141 netlist: &'a Netlist<I>,
2142 index: usize,
2143 subindex: usize,
2144 }
2145
2146 impl<'a, I> NetIterator<'a, I>
2147 where
2148 I: Instantiable,
2149 {
2150 pub fn new(netlist: &'a Netlist<I>) -> Self {
2152 Self {
2153 netlist,
2154 index: 0,
2155 subindex: 0,
2156 }
2157 }
2158 }
2159
2160 impl<I> Iterator for NetIterator<'_, I>
2161 where
2162 I: Instantiable,
2163 {
2164 type Item = Net;
2165
2166 fn next(&mut self) -> Option<Self::Item> {
2167 while self.index < self.netlist.objects.borrow().len() {
2168 let objects = self.netlist.objects.borrow();
2169 let object = objects[self.index].borrow();
2170 if self.subindex < object.get().get_nets().len() {
2171 let net = object.get().get_nets()[self.subindex].clone();
2172 self.subindex += 1;
2173 return Some(net);
2174 }
2175 self.subindex = 0;
2176 self.index += 1;
2177 }
2178 None
2179 }
2180 }
2181
2182 pub struct ObjectIterator<'a, I: Instantiable> {
2184 netlist: &'a Netlist<I>,
2185 index: usize,
2186 }
2187
2188 impl<'a, I> ObjectIterator<'a, I>
2189 where
2190 I: Instantiable,
2191 {
2192 pub fn new(netlist: &'a Netlist<I>) -> Self {
2194 Self { netlist, index: 0 }
2195 }
2196 }
2197
2198 impl<I> Iterator for ObjectIterator<'_, I>
2199 where
2200 I: Instantiable,
2201 {
2202 type Item = NetRef<I>;
2203
2204 fn next(&mut self) -> Option<Self::Item> {
2205 if self.index < self.netlist.objects.borrow().len() {
2206 let objects = self.netlist.objects.borrow();
2207 let object = &objects[self.index];
2208 self.index += 1;
2209 return Some(NetRef::wrap(object.clone()));
2210 }
2211 None
2212 }
2213 }
2214
2215 pub struct ConnectionIterator<'a, I: Instantiable> {
2217 netlist: &'a Netlist<I>,
2218 index: usize,
2219 subindex: usize,
2220 }
2221
2222 impl<'a, I> ConnectionIterator<'a, I>
2223 where
2224 I: Instantiable,
2225 {
2226 pub fn new(netlist: &'a Netlist<I>) -> Self {
2228 Self {
2229 netlist,
2230 index: 0,
2231 subindex: 0,
2232 }
2233 }
2234 }
2235
2236 impl<I> Iterator for ConnectionIterator<'_, I>
2237 where
2238 I: Instantiable,
2239 {
2240 type Item = super::Connection<I>;
2241
2242 fn next(&mut self) -> Option<Self::Item> {
2243 while self.index < self.netlist.objects.borrow().len() {
2244 let objects = self.netlist.objects.borrow();
2245 let object = objects[self.index].borrow();
2246 let noperands = object.operands.len();
2247 while self.subindex < noperands {
2248 if let Some(operand) = &object.operands[self.subindex] {
2249 let driver = match operand {
2250 Operand::DirectIndex(idx) => {
2251 DrivenNet::new(0, NetRef::wrap(objects[*idx].clone()))
2252 }
2253 Operand::CellIndex(idx, j) => {
2254 DrivenNet::new(*j, NetRef::wrap(objects[*idx].clone()))
2255 }
2256 };
2257 let input = InputPort::new(
2258 self.subindex,
2259 NetRef::wrap(objects[self.index].clone()),
2260 );
2261 self.subindex += 1;
2262 return Some(Connection::new(driver, input));
2263 }
2264 self.subindex += 1;
2265 }
2266 self.subindex = 0;
2267 self.index += 1;
2268 }
2269 None
2270 }
2271 }
2272
2273 #[derive(Clone)]
2275 struct Walk<T: std::hash::Hash + PartialEq + Eq + Clone> {
2276 stack: Vec<T>,
2277 counter: HashMap<T, usize>,
2278 }
2279
2280 impl<T> Walk<T>
2281 where
2282 T: std::hash::Hash + PartialEq + Eq + Clone,
2283 {
2284 fn new() -> Self {
2286 Self {
2287 stack: Vec::new(),
2288 counter: HashMap::new(),
2289 }
2290 }
2291
2292 fn push(&mut self, item: T) {
2294 self.stack.push(item.clone());
2295 *self.counter.entry(item).or_insert(0) += 1;
2296 }
2297
2298 fn contains_cycle(&self) -> bool {
2300 self.counter.values().any(|&count| count > 1)
2301 }
2302
2303 fn root_cycle(&self) -> bool {
2305 if self.stack.is_empty() {
2306 return false;
2307 }
2308 self.counter[&self.stack[0]] > 1
2309 }
2310
2311 fn last(&self) -> Option<&T> {
2313 self.stack.last()
2314 }
2315 }
2316
2317 pub struct DFSIterator<'a, I: Instantiable> {
2336 dfs: NetDFSIterator<'a, I>,
2337 seen: HashSet<NetRef<I>>,
2338 }
2339
2340 impl<'a, I> DFSIterator<'a, I>
2341 where
2342 I: Instantiable,
2343 {
2344 pub fn new(netlist: &'a Netlist<I>, from: NetRef<I>) -> Self {
2346 Self {
2347 dfs: NetDFSIterator::new(netlist, DrivenNet::new(0, from)),
2348 seen: HashSet::new(),
2349 }
2350 }
2351 }
2352
2353 impl<I> DFSIterator<'_, I>
2354 where
2355 I: Instantiable,
2356 {
2357 pub fn check_cycles(&self) -> bool {
2359 self.dfs.check_cycles()
2360 }
2361
2362 pub fn detect_cycles(self) -> bool {
2364 self.dfs.detect_cycles()
2365 }
2366
2367 pub fn check_self_loop(&self) -> bool {
2369 self.dfs.check_self_loop()
2370 }
2371
2372 pub fn detect_self_loop(self) -> bool {
2374 self.dfs.detect_self_loop()
2375 }
2376 }
2377
2378 impl<I> Iterator for DFSIterator<'_, I>
2379 where
2380 I: Instantiable,
2381 {
2382 type Item = NetRef<I>;
2383
2384 fn next(&mut self) -> Option<Self::Item> {
2385 let d = self.dfs.next()?;
2386 if self.seen.insert(d.clone().unwrap()) {
2387 Some(d.unwrap())
2388 } else {
2389 self.next()
2390 }
2391 }
2392 }
2393
2394 type TermFn<I> = Box<dyn Fn(&DrivenNet<I>) -> bool + 'static>;
2395
2396 pub struct NetDFSIterator<'a, I: Instantiable> {
2398 netlist: &'a Netlist<I>,
2399 stacks: Vec<Walk<DrivenNet<I>>>,
2400 visited: HashSet<usize>,
2401 visited_net: HashSet<(usize, usize)>,
2402 any_cycle: bool,
2403 root_cycle: bool,
2404 terminate: TermFn<I>,
2405 }
2406
2407 impl<'a, I> NetDFSIterator<'a, I>
2408 where
2409 I: Instantiable,
2410 {
2411 pub fn new_filtered<F: Fn(&DrivenNet<I>) -> bool + 'static>(
2414 netlist: &'a Netlist<I>,
2415 from: DrivenNet<I>,
2416 terminate: F,
2417 ) -> Self {
2418 let mut s = Walk::new();
2419 s.push(from);
2420 Self {
2421 netlist,
2422 stacks: vec![s],
2423 visited: HashSet::new(),
2424 visited_net: HashSet::new(),
2425 any_cycle: false,
2426 root_cycle: false,
2427 terminate: Box::new(terminate),
2428 }
2429 }
2430
2431 pub fn new(netlist: &'a Netlist<I>, from: DrivenNet<I>) -> Self {
2433 Self::new_filtered(netlist, from, |_| false)
2434 }
2435 }
2436
2437 impl<I> NetDFSIterator<'_, I>
2438 where
2439 I: Instantiable,
2440 {
2441 pub fn check_cycles(&self) -> bool {
2443 self.any_cycle
2444 }
2445
2446 pub fn detect_cycles(mut self) -> bool {
2448 if self.any_cycle {
2449 return true;
2450 }
2451
2452 while let Some(_) = self.next() {
2453 if self.any_cycle {
2454 return true;
2455 }
2456 }
2457
2458 self.any_cycle
2459 }
2460
2461 pub fn check_self_loop(&self) -> bool {
2463 self.root_cycle
2464 }
2465
2466 pub fn detect_self_loop(mut self) -> bool {
2468 if self.root_cycle {
2469 return true;
2470 }
2471
2472 while let Some(_) = self.next() {
2473 if self.root_cycle {
2474 return true;
2475 }
2476 }
2477
2478 self.root_cycle
2479 }
2480 }
2481
2482 impl<I> Iterator for NetDFSIterator<'_, I>
2483 where
2484 I: Instantiable,
2485 {
2486 type Item = DrivenNet<I>;
2487
2488 fn next(&mut self) -> Option<Self::Item> {
2489 if let Some(walk) = self.stacks.pop() {
2490 self.any_cycle |= walk.contains_cycle();
2491 self.root_cycle |= walk.root_cycle();
2492 let item = walk.last().cloned();
2493 let uw = item.clone().unwrap().unwrap().unwrap();
2494 let index = uw.borrow().get_index();
2495 let secondary = item.as_ref().unwrap().pos;
2496 if self.visited.insert(index) {
2497 if !(self.terminate)(item.as_ref().unwrap()) {
2498 let operands = &uw.borrow().operands;
2499 for operand in operands.iter().flatten() {
2500 let mut new_walk = walk.clone();
2501 new_walk.push(DrivenNet::new(
2502 operand.secondary(),
2503 NetRef::wrap(self.netlist.index_weak(&operand.root())),
2504 ));
2505 self.stacks.push(new_walk);
2506 }
2507 }
2508 self.visited_net.insert((index, secondary));
2509 return item;
2510 }
2511
2512 if self.visited_net.insert((index, secondary)) {
2513 return item;
2514 }
2515
2516 return self.next();
2517 }
2518
2519 None
2520 }
2521 }
2522}
2523
2524impl<'a, I> IntoIterator for &'a Netlist<I>
2525where
2526 I: Instantiable,
2527{
2528 type Item = Net;
2529 type IntoIter = iter::NetIterator<'a, I>;
2530
2531 fn into_iter(self) -> Self::IntoIter {
2532 iter::NetIterator::new(self)
2533 }
2534}
2535
2536#[macro_export]
2539macro_rules! filter_nodes {
2540 ($netlist:ident, $pattern:pat $(if $guard:expr)? $(,)?) => {
2541 $netlist.matches(|f| match f {
2542 $pattern $(if $guard)? => true,
2543 _ => false
2544 })
2545 };
2546}
2547
2548impl<I> Netlist<I>
2549where
2550 I: Instantiable,
2551{
2552 pub fn objects(&self) -> impl Iterator<Item = NetRef<I>> {
2554 iter::ObjectIterator::new(self)
2555 }
2556
2557 pub fn matches<F>(&self, filter: F) -> impl Iterator<Item = NetRef<I>>
2559 where
2560 F: Fn(&I) -> bool,
2561 {
2562 self.objects().filter(move |f| {
2563 if let Some(inst_type) = f.get_instance_type() {
2564 filter(&inst_type)
2565 } else {
2566 false
2567 }
2568 })
2569 }
2570
2571 pub fn inputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
2573 self.objects()
2574 .filter(|n| n.is_an_input())
2575 .map(|n| DrivenNet::new(0, n))
2576 }
2577
2578 pub fn outputs(&self) -> Vec<(DrivenNet<I>, Net)> {
2580 self.outputs
2581 .borrow()
2582 .iter()
2583 .flat_map(|(k, nets)| {
2584 nets.iter().map(|n| {
2585 (
2586 DrivenNet::new(k.secondary(), NetRef::wrap(self.index_weak(&k.root()))),
2587 n.clone(),
2588 )
2589 })
2590 })
2591 .collect()
2592 }
2593
2594 pub fn connections(&self) -> impl Iterator<Item = Connection<I>> {
2596 iter::ConnectionIterator::new(self)
2597 }
2598
2599 pub fn node_dfs(&self, from: NetRef<I>) -> impl Iterator<Item = NetRef<I>> {
2604 self.belongs(&from);
2605 iter::DFSIterator::new(self, from)
2606 }
2607
2608 pub fn net_dfs(&self, from: DrivenNet<I>) -> impl Iterator<Item = DrivenNet<I>> {
2613 self.belongs(&from.clone().unwrap());
2614 iter::NetDFSIterator::new(self, from)
2615 }
2616
2617 #[cfg(feature = "serde")]
2618 pub fn serialize(self, writer: impl std::io::Write) -> Result<(), serde_json::Error>
2620 where
2621 I: ::serde::Serialize,
2622 {
2623 serde::netlist_serialize(self, writer)
2624 }
2625
2626 #[cfg(feature = "graph")]
2627 pub fn dot_string(&self) -> Result<String, Error> {
2629 use super::graph::{Edge, MultiDiGraph, Node};
2630 use petgraph::dot::{Config, Dot};
2631 use petgraph::graph::{DiGraph, EdgeReference, NodeIndex};
2632 let analysis = self.get_analysis::<MultiDiGraph<_>>()?;
2633 let graph = analysis.get_graph();
2634
2635 fn node_impl<I: Instantiable>(
2636 _graph: &DiGraph<Node<I, String>, Edge<I, Net>>,
2637 node: (NodeIndex, &Node<I, String>),
2638 ) -> String {
2639 let n = node.1;
2640 let mut attr = String::new();
2641
2642 match n {
2643 Node::NetRef(nr) if nr.get_instance_type().is_some() => attr += "shape=record, ",
2644 _ => attr += "shape=ellipse, ",
2645 }
2646
2647 match n {
2648 Node::NetRef(nr)
2649 if let Some(inst_type) = nr.get_instance_type()
2650 && !inst_type.is_driverless() =>
2651 {
2652 let mut record = "{ { ".to_string();
2653
2654 let l = nr.get_num_input_ports();
2655 for (i, port) in nr.inputs().enumerate() {
2656 let id = port.get_port().get_identifier().clone();
2657 record += &format!("{{ <{}> {} }}", id, id);
2658
2659 if i != l - 1 {
2660 record += " | ";
2661 }
2662 }
2663
2664 record += &format!(
2665 " }} | {}({}) }}",
2666 inst_type.get_name(),
2667 nr.get_instance_name().unwrap()
2668 );
2669 attr += &format!("label=\"{record}\"");
2670 }
2671 _ => attr += &format!("label=\"{n}\""),
2672 }
2673
2674 attr
2675 }
2676
2677 fn edge_impl<I: Instantiable>(
2678 _graph: &DiGraph<Node<I, String>, Edge<I, Net>>,
2679 edge: EdgeReference<Edge<I, Net>>,
2680 ) -> String {
2681 match edge.weight() {
2682 Edge::Connection(c) => {
2683 format!(", port=\"{}\"", c.target().get_port().get_identifier())
2684 }
2685 _ => String::new(),
2686 }
2687 }
2688
2689 let dot = Dot::with_attr_getters(
2690 graph,
2691 &[Config::NodeNoLabel],
2692 &edge_impl::<I>,
2693 &node_impl::<I>,
2694 );
2695
2696 let mut result = String::new();
2698 for line in dot.to_string().lines() {
2699 if line.contains("->") && line.contains("port=") {
2700 let port = line
2701 .split("port=\"")
2702 .nth(1)
2703 .unwrap()
2704 .split('"')
2705 .next()
2706 .unwrap();
2707 let (l, r) = line.split_once("->").unwrap();
2708 let (l, r) = (l, r.trim());
2709 let (d, r) = r.split_once(" ").unwrap();
2710 result += &format!("{l}-> {d}:{port} {r}\n");
2711 } else {
2712 result += line;
2713 result += "\n";
2714 }
2715 }
2716
2717 Ok(result)
2718 }
2719
2720 #[cfg(feature = "graph")]
2721 pub fn dump_dot(&self) -> std::io::Result<()> {
2723 use std::io::Write;
2724 let mut dir = std::env::current_dir()?;
2725 let mod_name = format!("{}.dot", self.get_name());
2726 dir.push(mod_name);
2727 let mut file = std::fs::File::create(dir)?;
2728 if let Err(e) = self.verify() {
2729 write!(file, "Netlist verification failed: {e}")
2730 } else {
2731 let dot = self.dot_string().unwrap();
2732 write!(file, "{dot}")
2733 }
2734 }
2735}
2736
2737impl<I> std::fmt::Display for Netlist<I>
2738where
2739 I: Instantiable,
2740{
2741 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2742 let objects = self.objects.borrow();
2744 let outputs = self.outputs.borrow();
2745
2746 writeln!(f, "module {} (", self.get_name())?;
2747
2748 let level = 2;
2750 let indent = " ".repeat(level);
2751 for oref in objects.iter() {
2752 let owned = oref.borrow();
2753 let obj = owned.get();
2754 if let Object::Input(net) = obj {
2755 writeln!(f, "{}{},", indent, net.get_identifier().emit_name())?;
2756 }
2757 }
2758
2759 let all_outputs: Vec<_> = outputs.values().flat_map(|nets| nets.iter()).collect();
2761 for (i, net) in all_outputs.iter().enumerate() {
2762 if i == all_outputs.len() - 1 {
2763 writeln!(f, "{}{}", indent, net.get_identifier().emit_name())?;
2764 } else {
2765 writeln!(f, "{}{},", indent, net.get_identifier().emit_name())?;
2766 }
2767 }
2768 writeln!(f, ");")?;
2769
2770 let mut already_decl = HashSet::new();
2772 for oref in objects.iter() {
2773 let owned = oref.borrow();
2774 let obj = owned.get();
2775 if let Object::Input(net) = obj {
2776 writeln!(f, "{}input {};", indent, net.get_identifier().emit_name())?;
2777 writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2778 already_decl.insert(net.clone());
2779 }
2780 }
2781 for nets in outputs.values() {
2782 for net in nets {
2783 if !already_decl.contains(net) {
2784 writeln!(f, "{}output {};", indent, net.get_identifier().emit_name())?;
2785 writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2786 already_decl.insert(net.clone());
2787 }
2788 }
2789 }
2790 for oref in objects.iter() {
2791 let owned = oref.borrow();
2792 let obj = owned.get();
2793 if let Object::Instance(nets, _, inst_type) = obj
2794 && inst_type.get_constant().is_none()
2795 {
2796 for net in nets.iter() {
2797 if !already_decl.contains(net) {
2798 writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2799 already_decl.insert(net.clone());
2800 }
2801 }
2802 }
2803 }
2804
2805 for oref in objects.iter() {
2806 let owned = oref.borrow();
2807 let obj = owned.get();
2808
2809 if let Some(inst_type) = obj.get_instance_type()
2811 && inst_type.get_constant().is_some()
2812 {
2813 continue;
2814 }
2815
2816 if let Object::Instance(nets, inst_name, inst_type) = obj {
2817 for (k, v) in owned.attributes.iter() {
2818 if let Some(value) = v {
2819 writeln!(f, "{indent}(* {k} = \"{value}\" *)")?;
2820 } else {
2821 writeln!(f, "{indent}(* {k} *)")?;
2822 }
2823 }
2824
2825 write!(f, "{}{} ", indent, inst_type.get_name())?;
2826 if inst_type.is_parameterized() {
2827 writeln!(f, "#(")?;
2828 let level = 4;
2829 let indent = " ".repeat(level);
2830 let params: Vec<_> = inst_type.parameters().collect();
2831 for (i, (k, v)) in params.iter().enumerate() {
2832 if i == params.len() - 1 {
2833 writeln!(f, "{indent}.{k}({v})")?;
2834 } else {
2835 writeln!(f, "{indent}.{k}({v}),")?;
2836 }
2837 }
2838 let level = 2;
2839 let indent = " ".repeat(level);
2840 write!(f, "{indent}) ")?;
2841 }
2842 writeln!(f, "{} (", inst_name.emit_name())?;
2843 let level = 4;
2844 let indent = " ".repeat(level);
2845 for (idx, port) in inst_type.get_input_ports().into_iter().enumerate() {
2846 let port_name = port.get_identifier().emit_name();
2847 if let Some(operand) = owned.operands[idx].as_ref() {
2848 let operand_net = match operand {
2849 Operand::DirectIndex(idx) => objects[*idx].borrow().as_net().clone(),
2850 Operand::CellIndex(idx, j) => {
2851 objects[*idx].borrow().get_net(*j).clone()
2852 }
2853 };
2854
2855 let operand_str = if let Some(inst_type) =
2856 objects[operand.root()].borrow().get().get_instance_type()
2857 && let Some(logic) = inst_type.get_constant()
2858 {
2859 logic.to_string()
2860 } else {
2861 operand_net.get_identifier().emit_name()
2862 };
2863
2864 writeln!(f, "{}.{}({}),", indent, port_name, operand_str)?;
2865 }
2866 }
2867
2868 for (idx, net) in nets.iter().enumerate() {
2869 let port_name = inst_type.get_output_port(idx).get_identifier().emit_name();
2870 if idx == nets.len() - 1 {
2871 writeln!(
2872 f,
2873 "{}.{}({})",
2874 indent,
2875 port_name,
2876 net.get_identifier().emit_name()
2877 )?;
2878 } else {
2879 writeln!(
2880 f,
2881 "{}.{}({}),",
2882 indent,
2883 port_name,
2884 net.get_identifier().emit_name()
2885 )?;
2886 }
2887 }
2888
2889 let level = 2;
2890 let indent = " ".repeat(level);
2891 writeln!(f, "{indent});")?;
2892 }
2893 }
2894
2895 for (driver, nets) in outputs.iter() {
2896 for net in nets {
2897 let driver_net = match driver {
2898 Operand::DirectIndex(idx) => self.index_weak(idx).borrow().as_net().clone(),
2899 Operand::CellIndex(idx, j) => self.index_weak(idx).borrow().get_net(*j).clone(),
2900 };
2901
2902 let driver_str = if let Some(inst_type) = self
2903 .index_weak(&driver.root())
2904 .borrow()
2905 .get()
2906 .get_instance_type()
2907 && let Some(logic) = inst_type.get_constant()
2908 {
2909 logic.to_string()
2910 } else {
2911 driver_net.get_identifier().emit_name()
2912 };
2913
2914 if net.get_identifier() != driver_net.get_identifier() {
2915 writeln!(
2916 f,
2917 "{}assign {} = {};",
2918 indent,
2919 net.get_identifier().emit_name(),
2920 driver_str
2921 )?;
2922 }
2923 }
2924 }
2925
2926 writeln!(f, "endmodule")
2927 }
2928}
2929
2930pub type GateNetlist = Netlist<Gate>;
2932pub type GateRef = NetRef<Gate>;
2934
2935#[cfg(test)]
2936mod tests {
2937 use super::iter::{DFSIterator, NetDFSIterator};
2938 use super::*;
2939 #[test]
2940 fn test_delete_netlist() {
2941 let netlist = Netlist::new("simple_example".to_string());
2942
2943 let input1 = netlist.insert_input("input1".into());
2945 let input2 = netlist.insert_input("input2".into());
2946
2947 let instance = netlist
2949 .insert_gate(
2950 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
2951 "my_and".into(),
2952 &[input1.clone(), input2.clone()],
2953 )
2954 .unwrap();
2955
2956 let instance = instance.expose_as_output().unwrap();
2958 instance.delete_uses().unwrap();
2959 assert!(netlist.clean().is_ok());
2961 input1.expose_with_name("an_output".into());
2962 assert!(netlist.clean().is_ok());
2963 }
2964
2965 #[test]
2966 #[should_panic(expected = "Attempted to create a gate with a sliced identifier")]
2967 fn gate_w_slice_panics() {
2968 Gate::new_logical("AND[1]".into(), vec!["A".into(), "B".into()], "Y".into());
2969 }
2970
2971 #[test]
2972 fn gates_dont_have_params() {
2973 let gate = Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into());
2975 assert!(!gate.has_parameter(&"id".into()));
2976 assert!(gate.get_parameter(&"id".into()).is_none());
2977 assert_eq!(*gate.get_gate_name(), "AND".into());
2978 }
2979
2980 #[test]
2981 fn operand_conversions() {
2982 let operand = Operand::CellIndex(3, 2);
2983 assert_eq!(operand.to_string(), "3.2");
2984 let parsed = "3.2".parse::<Operand>();
2985 assert!(parsed.is_ok());
2986 let parsed = parsed.unwrap();
2987 assert_eq!(operand, parsed);
2988 }
2989
2990 #[test]
2991 #[should_panic(expected = "out of bounds for netref")]
2992 fn test_bad_output() {
2993 let netlist = GateNetlist::new("min_module".to_string());
2994 let a = netlist.insert_input("a".into());
2995 DrivenNet::new(1, a.unwrap());
2996 }
2997
2998 #[test]
2999 fn test_netdfsiterator() {
3000 let netlist = Netlist::new("dfs_netlist".to_string());
3001
3002 let a = netlist.insert_input("a".into());
3004 let b = netlist.insert_input("b".into());
3005 let c = netlist.insert_input("c".into());
3006 let d = netlist.insert_input("d".into());
3007 let e = netlist.insert_input("e".into());
3008
3009 let n1 = netlist
3011 .insert_gate(
3012 Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into()),
3013 "n1".into(),
3014 &[a.clone(), b.clone()],
3015 )
3016 .unwrap()
3017 .get_output(0);
3018 let n2 = netlist
3019 .insert_gate(
3020 Gate::new_logical("NOR".into(), vec!["A".into(), "B".into()], "Y".into()),
3021 "n2".into(),
3022 &[d.clone(), e.clone()],
3023 )
3024 .unwrap()
3025 .get_output(0);
3026 let n3 = netlist
3027 .insert_gate(
3028 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3029 "n3".into(),
3030 &[n1.clone(), c.clone()],
3031 )
3032 .unwrap()
3033 .get_output(0);
3034 let n4 = netlist
3035 .insert_gate(
3036 Gate::new_logical("NAND".into(), vec!["A".into(), "B".into()], "Y".into()),
3037 "n4".into(),
3038 &[n3.clone(), n2.clone()],
3039 )
3040 .unwrap()
3041 .get_output(0);
3042 n4.clone().expose_with_name("y".into());
3043
3044 let mut dfs = NetDFSIterator::new(&netlist, n4.clone());
3046 assert_eq!(dfs.next(), Some(n4));
3047 assert_eq!(dfs.next(), Some(n2));
3048 assert_eq!(dfs.next(), Some(e));
3049 assert_eq!(dfs.next(), Some(d));
3050 assert_eq!(dfs.next(), Some(n3));
3051 assert_eq!(dfs.next(), Some(c));
3052 assert_eq!(dfs.next(), Some(n1));
3053 assert_eq!(dfs.next(), Some(b));
3054 assert_eq!(dfs.next(), Some(a));
3055 assert_eq!(dfs.next(), None);
3056 }
3057
3058 #[test]
3059 fn test_dfs_cycles() {
3060 let netlist = Netlist::new("dfs_cycles".to_string());
3061
3062 let a = netlist.insert_input("a".into());
3064
3065 let and = netlist.insert_gate_disconnected(
3067 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3068 "and".into(),
3069 );
3070
3071 a.connect(and.get_input(0));
3073 and.get_output(0).connect(and.get_input(1));
3074
3075 let dfs = DFSIterator::new(&netlist, and.clone());
3077 let driven_dfs = NetDFSIterator::new(&netlist, and.get_output(0));
3078
3079 assert!(dfs.detect_cycles());
3080 assert!(driven_dfs.detect_cycles());
3081 }
3082
3083 #[test]
3084 fn test_netdfsiterator_with_boundary() {
3085 let netlist = Netlist::new("dfs_netlist".to_string());
3086
3087 let a = netlist.insert_input("a".into());
3089 let b = netlist.insert_input("b".into());
3090 let c = netlist.insert_input("c".into());
3091 let d = netlist.insert_input("d".into());
3092 let e = netlist.insert_input("e".into());
3093
3094 let n1 = netlist
3096 .insert_gate(
3097 Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into()),
3098 "n1".into(),
3099 &[a.clone(), b.clone()],
3100 )
3101 .unwrap()
3102 .get_output(0);
3103 let n2 = netlist
3104 .insert_gate(
3105 Gate::new_logical("NOR".into(), vec!["A".into(), "B".into()], "Y".into()),
3106 "n2".into(),
3107 &[d.clone(), e.clone()],
3108 )
3109 .unwrap()
3110 .get_output(0);
3111 let n3 = netlist
3112 .insert_gate(
3113 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3114 "n3".into(),
3115 &[n1.clone(), c.clone()],
3116 )
3117 .unwrap()
3118 .get_output(0);
3119 let n4 = netlist
3120 .insert_gate(
3121 Gate::new_logical("NAND".into(), vec!["A".into(), "B".into()], "Y".into()),
3122 "n4".into(),
3123 &[n3.clone(), n2.clone()],
3124 )
3125 .unwrap()
3126 .get_output(0);
3127
3128 let n3_boundary = n3.clone();
3130 let mut dfs =
3131 NetDFSIterator::new_filtered(&netlist, n4.clone(), move |n| *n == n3_boundary);
3132 assert_eq!(dfs.next(), Some(n4));
3133 assert_eq!(dfs.next(), Some(n2));
3134 assert_eq!(dfs.next(), Some(e));
3135 assert_eq!(dfs.next(), Some(d));
3136 assert_eq!(dfs.next(), Some(n3));
3137 assert_eq!(dfs.next(), None);
3138 }
3139
3140 #[test]
3141 fn test_dfs_convergence() {
3142 let netlist = GateNetlist::new("example".to_string());
3143 let gate = Gate::new_logical_multi(
3144 "FA".into(),
3145 vec!["A".into(), "B".into()],
3146 vec!["S".into(), "COUT".into()],
3147 );
3148 let a = netlist.insert_input("a".into());
3149 let b = netlist.insert_input("b".into());
3150 let gate = netlist.insert_gate(gate, "g".into(), &[a, b]).unwrap();
3151 let s = gate.get_output(0);
3152 let c = gate.get_output(1);
3153 let gate = Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into());
3154 let d = netlist.insert_gate(gate, "h".into(), &[s, c]).unwrap();
3155
3156 let dfs = NetDFSIterator::new(&netlist, d.get_output(0));
3157 let c = dfs.count();
3158 assert_eq!(c, 5);
3159
3160 let dfs = DFSIterator::new(&netlist, d.clone());
3161 let c = dfs.count();
3162 assert_eq!(c, 4);
3163 }
3164}
3165#[cfg(feature = "serde")]
3166pub mod serde {
3168 use super::{Netlist, Operand, OwnedObject, WeakIndex};
3169 use crate::{
3170 attribute::{AttributeKey, AttributeValue},
3171 circuit::{Instantiable, Net, Object},
3172 };
3173 use serde::{Deserialize, Serialize, de::DeserializeOwned};
3174 use std::cell::RefCell;
3175 use std::{
3176 collections::{BTreeSet, HashMap},
3177 rc::Rc,
3178 };
3179
3180 #[derive(Debug, Serialize, Deserialize)]
3181 struct SerdeObject<I>
3182 where
3183 I: Instantiable + Serialize,
3184 {
3185 object: Object<I>,
3187 operands: Vec<Option<Operand>>,
3189 attributes: HashMap<AttributeKey, AttributeValue>,
3191 }
3192
3193 impl<I, O> From<OwnedObject<I, O>> for SerdeObject<I>
3194 where
3195 I: Instantiable + Serialize,
3196 O: WeakIndex<usize, Output = OwnedObject<I, O>>,
3197 {
3198 fn from(value: OwnedObject<I, O>) -> Self {
3199 SerdeObject {
3200 object: value.object,
3201 operands: value.operands,
3202 attributes: value.attributes,
3203 }
3204 }
3205 }
3206
3207 impl<I> SerdeObject<I>
3208 where
3209 I: Instantiable + Serialize,
3210 {
3211 fn into_owned_object<O>(self, owner: &Rc<O>, index: usize) -> OwnedObject<I, O>
3212 where
3213 O: WeakIndex<usize, Output = OwnedObject<I, O>>,
3214 {
3215 OwnedObject {
3216 object: self.object,
3217 owner: Rc::downgrade(owner),
3218 operands: self.operands,
3219 attributes: self.attributes,
3220 index,
3221 }
3222 }
3223 }
3224
3225 #[derive(Debug, Serialize, Deserialize)]
3226 struct SerdeNetlist<I>
3227 where
3228 I: Instantiable + Serialize,
3229 {
3230 name: String,
3232 objects: Vec<SerdeObject<I>>,
3234 outputs: HashMap<String, BTreeSet<Net>>,
3238 }
3239
3240 impl<I> From<Netlist<I>> for SerdeNetlist<I>
3241 where
3242 I: Instantiable + Serialize,
3243 {
3244 fn from(value: Netlist<I>) -> Self {
3245 SerdeNetlist {
3246 name: value.name.into_inner(),
3247 objects: value
3248 .objects
3249 .into_inner()
3250 .into_iter()
3251 .map(|o| {
3252 Rc::try_unwrap(o)
3253 .ok()
3254 .expect("Cannot serialize with live references")
3255 .into_inner()
3256 .into()
3257 })
3258 .collect(),
3259 outputs: value
3260 .outputs
3261 .into_inner()
3262 .into_iter()
3263 .map(|(o, nets)| (o.to_string(), nets.into_iter().collect()))
3265 .collect(),
3266 }
3267 }
3268 }
3269
3270 impl<I> SerdeNetlist<I>
3271 where
3272 I: Instantiable + Serialize,
3273 {
3274 fn into_netlist(self) -> Rc<Netlist<I>> {
3276 let netlist = Netlist::new(self.name);
3277 let outputs: HashMap<Operand, BTreeSet<Net>> = self
3278 .outputs
3279 .into_iter()
3280 .map(|(k, v)| {
3281 let operand = k.parse::<Operand>().expect("Invalid index");
3282 (operand, v.into_iter().collect())
3283 })
3284 .collect();
3285 let objects = self
3286 .objects
3287 .into_iter()
3288 .enumerate()
3289 .map(|(i, o)| {
3290 let owned_object = o.into_owned_object(&netlist, i);
3291 Rc::new(RefCell::new(owned_object))
3292 })
3293 .collect::<Vec<_>>();
3294 {
3295 let mut objs_mut = netlist.objects.borrow_mut();
3296 *objs_mut = objects;
3297 let mut outputs_mut = netlist.outputs.borrow_mut();
3298 *outputs_mut = outputs;
3299 }
3300 netlist
3301 }
3302 }
3303
3304 pub fn netlist_serialize<I: Instantiable + Serialize>(
3306 netlist: Netlist<I>,
3307 writer: impl std::io::Write,
3308 ) -> Result<(), serde_json::Error> {
3309 let sobj: SerdeNetlist<I> = netlist.into();
3310 serde_json::to_writer_pretty(writer, &sobj)
3311 }
3312
3313 pub fn netlist_deserialize<I: Instantiable + Serialize + DeserializeOwned>(
3315 reader: impl std::io::Read,
3316 ) -> Result<Rc<Netlist<I>>, serde_json::Error> {
3317 let sobj: SerdeNetlist<I> = serde_json::from_reader(reader)?;
3318 Ok(sobj.into_netlist())
3319 }
3320}