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: String) -> 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> {
578 DrivenNet::new(idx, self.clone())
579 }
580
581 pub fn find_output(&self, id: &Identifier) -> Option<DrivenNet<I>> {
583 let ind = self.get_instance_type()?.find_output(id)?;
584 Some(self.get_output(ind))
585 }
586
587 pub fn get_input(&self, idx: usize) -> InputPort<I> {
589 if self.is_an_input() {
590 panic!("Principal inputs do not have inputs");
591 }
592 InputPort::new(idx, self.clone())
593 }
594
595 pub fn find_input(&self, id: &Identifier) -> Option<InputPort<I>> {
597 let ind = self.get_instance_type()?.find_input(id)?;
598 Some(self.get_input(ind))
599 }
600
601 pub fn get_identifier(&self) -> Identifier {
607 self.as_net().get_identifier().clone()
608 }
609
610 pub fn set_identifier(&self, identifier: Identifier) {
616 self.as_net_mut().set_identifier(identifier)
617 }
618
619 pub fn is_an_input(&self) -> bool {
621 matches!(self.netref.borrow().get(), Object::Input(_))
622 }
623
624 pub fn get_obj(&self) -> Ref<'_, Object<I>> {
626 Ref::map(self.netref.borrow(), |f| f.get())
627 }
628
629 pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
631 Ref::filter_map(self.netref.borrow(), |f| f.get().get_instance_type()).ok()
632 }
633
634 pub fn get_instance_type_mut(&self) -> Option<RefMut<'_, I>> {
636 RefMut::filter_map(self.netref.borrow_mut(), |f| {
637 f.get_mut().get_instance_type_mut()
638 })
639 .ok()
640 }
641
642 pub fn get_instance_name(&self) -> Option<Identifier> {
644 match self.netref.borrow().get() {
645 Object::Instance(_, inst_name, _) => Some(inst_name.clone()),
646 _ => None,
647 }
648 }
649
650 pub fn set_instance_name(&self, name: Identifier) {
656 match self.netref.borrow_mut().get_mut() {
657 Object::Instance(_, inst_name, _) => *inst_name = name,
658 _ => panic!("Attempted to set instance name on a non-instance object"),
659 }
660 }
661
662 pub fn expose_as_output(self) -> Result<Self, Error> {
670 let netlist = self
671 .netref
672 .borrow()
673 .owner
674 .upgrade()
675 .expect("NetRef is unlinked from netlist");
676 netlist.expose_net(self.clone().into())?;
677 Ok(self)
678 }
679
680 pub fn expose_with_name(self, name: Identifier) -> Self {
688 let netlist = self
689 .netref
690 .borrow()
691 .owner
692 .upgrade()
693 .expect("NetRef is unlinked from netlist");
694 netlist.expose_net_with_name(self.clone().into(), name);
695 self
696 }
697
698 pub fn expose_net(&self, net: &Net) -> Result<(), Error> {
704 let netlist = self
705 .netref
706 .borrow()
707 .owner
708 .upgrade()
709 .expect("NetRef is unlinked from netlist");
710 let net_index = self
711 .netref
712 .borrow()
713 .find_net(net)
714 .ok_or(Error::NetNotFound(net.clone()))?;
715 let dr = DrivenNet::new(net_index, self.clone());
716 netlist.expose_net(dr)?;
717 Ok(())
718 }
719
720 pub fn remove_output(&self, net_name: &Identifier) -> bool {
728 let netlist = self
729 .netref
730 .borrow()
731 .owner
732 .upgrade()
733 .expect("NetRef is unlinked from netlist");
734 netlist.remove_output(&self.into(), net_name)
735 }
736
737 pub fn remove_all_outputs(&self) -> usize {
745 let netlist = self
746 .netref
747 .borrow()
748 .owner
749 .upgrade()
750 .expect("NetRef is unlinked from netlist");
751 netlist.remove_outputs(&self.into())
752 }
753
754 pub fn get_driver(&self, index: usize) -> Option<Self> {
756 self.netref.borrow().get_driver(index).map(NetRef::wrap)
757 }
758
759 pub fn get_driver_net(&self, index: usize) -> Option<Net> {
765 self.netref.borrow().get_driver_net(index)
766 }
767
768 pub fn req_driver_net(&self, index: usize) -> Option<MutBorrowReq<I>> {
775 let net = self.get_driver_net(index)?;
776 let operand = self.get_driver(index).unwrap();
777 Some(MutBorrowReq::new(operand, net))
778 }
779
780 pub fn get_num_input_ports(&self) -> usize {
782 if let Some(inst_type) = self.get_instance_type() {
783 inst_type.get_input_ports().into_iter().count()
784 } else {
785 0
786 }
787 }
788
789 pub fn is_fully_connected(&self) -> bool {
791 assert_eq!(
792 self.netref.borrow().operands.len(),
793 self.get_num_input_ports()
794 );
795 self.netref.borrow().operands.iter().all(|o| o.is_some())
796 }
797
798 pub fn drivers(&self) -> impl Iterator<Item = Option<Self>> {
800 let drivers: Vec<Option<Self>> = self
801 .netref
802 .borrow()
803 .drivers()
804 .map(|o| o.map(NetRef::wrap))
805 .collect();
806 drivers.into_iter()
807 }
808
809 pub fn driver_nets(&self) -> impl Iterator<Item = Option<Net>> {
811 let vec: Vec<Option<Net>> = self.netref.borrow().driver_nets().collect();
812 vec.into_iter()
813 }
814
815 #[allow(clippy::unnecessary_to_owned)]
817 pub fn nets(&self) -> impl Iterator<Item = Net> {
818 self.netref.borrow().get().get_nets().to_vec().into_iter()
819 }
820
821 pub fn inputs(&self) -> impl Iterator<Item = InputPort<I>> {
823 let len = self.netref.borrow().operands.len();
824 (0..len).map(move |i| InputPort::new(i, self.clone()))
825 }
826
827 pub fn outputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
829 let len = self.netref.borrow().get().get_nets().len();
830 (0..len).map(move |i| DrivenNet::new(i, self.clone()))
831 }
832
833 pub fn nets_mut(&self) -> impl Iterator<Item = RefMut<'_, Net>> {
835 let nnets = self.netref.borrow().get().get_nets().len();
836 (0..nnets).map(|i| self.get_net_mut(i))
837 }
838
839 pub fn drives_net(&self, net: &Net) -> bool {
841 self.netref.borrow().find_net(net).is_some()
842 }
843
844 pub fn drives_a_top_output(&self) -> bool {
849 let netlist = self
850 .netref
851 .borrow()
852 .owner
853 .upgrade()
854 .expect("NetRef is unlinked from netlist");
855 netlist.drives_an_output(self.clone())
856 }
857
858 pub fn find_net_mut(&self, net: &Net) -> Option<RefMut<'_, Net>> {
860 RefMut::filter_map(self.netref.borrow_mut(), |f| f.find_net_mut(net)).ok()
861 }
862
863 pub fn is_multi_output(&self) -> bool {
865 self.netref.borrow().get().get_nets().len() > 1
866 }
867
868 pub fn delete_uses(self) -> Result<Object<I>, Error> {
874 let netlist = self
875 .netref
876 .borrow()
877 .owner
878 .upgrade()
879 .expect("NetRef is unlinked from netlist");
880 netlist.delete_net_uses(self)
881 }
882
883 pub fn replace_uses_with(self, other: &DrivenNet<I>) -> Result<NetRef<I>, Error> {
893 let netlist = self
894 .netref
895 .borrow()
896 .owner
897 .upgrade()
898 .expect("NetRef is unlinked from netlist");
899 netlist
900 .replace_net_uses(self.into(), other)
901 .map(|d| d.unwrap())
902 }
903
904 pub fn clear_attribute(&self, k: &AttributeKey) -> Option<AttributeValue> {
906 self.netref.borrow_mut().clear_attribute(k)
907 }
908
909 pub fn set_attribute(&self, k: AttributeKey) {
911 self.netref.borrow_mut().set_attribute(k);
912 }
913
914 pub fn insert_attribute(&self, k: AttributeKey, v: String) -> Option<AttributeValue> {
916 self.netref.borrow_mut().insert_attribute(k, v)
917 }
918
919 pub fn attributes(&self) -> impl Iterator<Item = Attribute> {
921 let v: Vec<_> = self.netref.borrow().attributes().collect();
922 v.into_iter()
923 }
924}
925
926impl<I> std::fmt::Display for NetRef<I>
927where
928 I: Instantiable,
929{
930 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
931 self.netref.borrow().object.fmt(f)
932 }
933}
934
935impl<I> From<NetRef<I>> for DrivenNet<I>
936where
937 I: Instantiable,
938{
939 fn from(val: NetRef<I>) -> Self {
940 if val.is_multi_output() {
941 panic!("Cannot convert a multi-output netref to an output port");
942 }
943 DrivenNet::new(0, val)
944 }
945}
946
947impl<I> From<&NetRef<I>> for DrivenNet<I>
948where
949 I: Instantiable,
950{
951 fn from(val: &NetRef<I>) -> Self {
952 if val.is_multi_output() {
953 panic!("Cannot convert a multi-output netref to an output port");
954 }
955 DrivenNet::new(0, val.clone())
956 }
957}
958
959pub struct MutBorrowReq<I: Instantiable> {
961 from: NetRef<I>,
962 ind: Net,
963}
964
965impl<I> MutBorrowReq<I>
966where
967 I: Instantiable,
968{
969 fn new(from: NetRef<I>, ind: Net) -> Self {
971 Self { from, ind }
972 }
973
974 pub fn borrow_mut(&self) -> RefMut<'_, Net> {
976 self.from.find_net_mut(&self.ind).unwrap()
977 }
978
979 pub fn is_an_input(&self) -> bool {
981 self.from.is_an_input()
982 }
983
984 pub fn borrow_mut_if(&self, f: impl Fn(&NetRef<I>) -> bool) -> Option<RefMut<'_, Net>> {
986 if f(&self.from) {
987 Some(self.borrow_mut())
988 } else {
989 None
990 }
991 }
992}
993
994#[derive(Debug)]
996pub struct Netlist<I>
997where
998 I: Instantiable,
999{
1000 name: RefCell<String>,
1002 objects: RefCell<Vec<NetRefT<I>>>,
1004 outputs: RefCell<BTreeMap<Operand, BTreeSet<Net>>>,
1006}
1007
1008#[derive(Debug, Clone)]
1010pub struct InputPort<I: Instantiable> {
1011 pos: usize,
1012 netref: NetRef<I>,
1013}
1014
1015impl<I> InputPort<I>
1016where
1017 I: Instantiable,
1018{
1019 fn new(pos: usize, netref: NetRef<I>) -> Self {
1020 if pos >= netref.clone().unwrap().borrow().operands.len() {
1021 panic!(
1022 "Position {} out of bounds for netref with {} input nets",
1023 pos,
1024 netref.unwrap().borrow().get().get_nets().len()
1025 );
1026 }
1027 Self { pos, netref }
1028 }
1029
1030 pub fn get_driver(&self) -> Option<DrivenNet<I>> {
1032 if self.netref.is_an_input() {
1033 panic!("Input port is not driven by a primitive");
1034 }
1035 if let Some(prev_operand) = self.netref.clone().unwrap().borrow().operands[self.pos] {
1036 let netlist = self
1037 .netref
1038 .clone()
1039 .unwrap()
1040 .borrow()
1041 .owner
1042 .upgrade()
1043 .expect("Input port is unlinked from netlist");
1044 let driver_nr = netlist.index_weak(&prev_operand.root());
1045 let nr = NetRef::wrap(driver_nr);
1046 let pos = prev_operand.secondary();
1047 Some(DrivenNet::new(pos, nr))
1048 } else {
1049 None
1050 }
1051 }
1052
1053 pub fn disconnect(&self) -> Option<DrivenNet<I>> {
1055 let val = self.get_driver();
1056 self.netref.clone().unwrap().borrow_mut().operands[self.pos] = None;
1057 val
1058 }
1059
1060 pub fn get_port(&self) -> Net {
1062 if self.netref.is_an_input() {
1063 panic!("Net is not driven by a primitive");
1064 }
1065 self.netref
1066 .get_instance_type()
1067 .unwrap()
1068 .get_input_port(self.pos)
1069 .clone()
1070 }
1071
1072 pub fn connect(self, output: DrivenNet<I>) {
1074 output.connect(self);
1075 }
1076
1077 pub fn unwrap(self) -> NetRef<I> {
1079 self.netref
1080 }
1081
1082 pub fn get_input_num(&self) -> usize {
1084 self.pos
1085 }
1086}
1087
1088impl<I> std::fmt::Display for InputPort<I>
1089where
1090 I: Instantiable,
1091{
1092 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1093 self.get_port().fmt(f)
1094 }
1095}
1096
1097#[derive(Debug, Clone)]
1099pub struct DrivenNet<I: Instantiable> {
1100 pos: usize,
1101 netref: NetRef<I>,
1102}
1103
1104impl<I> DrivenNet<I>
1105where
1106 I: Instantiable,
1107{
1108 fn new(pos: usize, netref: NetRef<I>) -> Self {
1109 if pos >= netref.clone().unwrap().borrow().get().get_nets().len() {
1110 panic!(
1111 "Position {} out of bounds for netref with {} outputted nets",
1112 pos,
1113 netref.unwrap().borrow().get().get_nets().len()
1114 );
1115 }
1116 Self { pos, netref }
1117 }
1118
1119 fn get_operand(&self) -> Operand {
1121 if self.netref.is_multi_output() {
1122 Operand::CellIndex(self.netref.clone().unwrap().borrow().get_index(), self.pos)
1123 } else {
1124 Operand::DirectIndex(self.netref.clone().unwrap().borrow().get_index())
1125 }
1126 }
1127
1128 pub fn as_net(&self) -> Ref<'_, Net> {
1130 self.netref.get_net(self.pos)
1131 }
1132
1133 pub fn as_net_mut(&self) -> RefMut<'_, Net> {
1135 self.netref.get_net_mut(self.pos)
1136 }
1137
1138 pub fn is_an_input(&self) -> bool {
1140 self.netref.is_an_input()
1141 }
1142
1143 pub fn get_port(&self) -> Net {
1145 if self.netref.is_an_input() {
1146 panic!("Net is not driven by a primitive");
1147 }
1148 self.netref
1149 .get_instance_type()
1150 .unwrap()
1151 .get_output_port(self.pos)
1152 .clone()
1153 }
1154
1155 pub fn connect(&self, input: InputPort<I>) {
1157 let operand = self.get_operand();
1158 let index = input.netref.unwrap().borrow().get_index();
1159 let netlist = self
1160 .netref
1161 .clone()
1162 .unwrap()
1163 .borrow()
1164 .owner
1165 .upgrade()
1166 .expect("Output port is unlinked from netlist");
1167 let obj = netlist.index_weak(&index);
1168 obj.borrow_mut().operands[input.pos] = Some(operand);
1169 }
1170
1171 pub fn is_top_level_output(&self) -> bool {
1173 let netlist = self
1174 .netref
1175 .clone()
1176 .unwrap()
1177 .borrow()
1178 .owner
1179 .upgrade()
1180 .expect("DrivenNet is unlinked from netlist");
1181 let outputs = netlist.outputs.borrow();
1182 outputs.contains_key(&self.get_operand())
1183 }
1184
1185 pub fn unwrap(self) -> NetRef<I> {
1187 self.netref
1188 }
1189
1190 pub fn get_identifier(&self) -> Identifier {
1192 self.as_net().get_identifier().clone()
1193 }
1194
1195 pub fn expose_with_name(self, name: Identifier) -> Self {
1202 let netlist = self
1203 .netref
1204 .clone()
1205 .unwrap()
1206 .borrow()
1207 .owner
1208 .upgrade()
1209 .expect("DrivenNet is unlinked from netlist");
1210 netlist.expose_net_with_name(self.clone(), name);
1211 self
1212 }
1213
1214 pub fn remove_output(&self, net_name: &Identifier) -> bool {
1221 let netlist = self
1222 .netref
1223 .clone()
1224 .unwrap()
1225 .borrow()
1226 .owner
1227 .upgrade()
1228 .expect("DrivenNet is unlinked from netlist");
1229 netlist.remove_output(self, net_name)
1230 }
1231
1232 pub fn remove_all_outputs(&self) -> usize {
1239 let netlist = self
1240 .netref
1241 .clone()
1242 .unwrap()
1243 .borrow()
1244 .owner
1245 .upgrade()
1246 .expect("DrivenNet is unlinked from netlist");
1247 netlist.remove_outputs(self)
1248 }
1249
1250 pub fn get_output_index(&self) -> Option<usize> {
1252 if self.netref.is_an_input() {
1253 None
1254 } else {
1255 Some(self.pos)
1256 }
1257 }
1258
1259 pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
1261 self.netref.get_instance_type()
1262 }
1263}
1264
1265impl<I> std::fmt::Display for DrivenNet<I>
1266where
1267 I: Instantiable,
1268{
1269 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1270 self.as_net().fmt(f)
1271 }
1272}
1273
1274impl<I> PartialEq for DrivenNet<I>
1275where
1276 I: Instantiable,
1277{
1278 fn eq(&self, other: &Self) -> bool {
1279 self.netref == other.netref && self.pos == other.pos
1280 }
1281}
1282
1283impl<I> Eq for DrivenNet<I> where I: Instantiable {}
1284
1285impl<I> std::hash::Hash for DrivenNet<I>
1286where
1287 I: Instantiable,
1288{
1289 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1290 self.netref.hash(state);
1291 self.pos.hash(state);
1292 }
1293}
1294
1295impl<I> Ord for DrivenNet<I>
1296where
1297 I: Instantiable,
1298{
1299 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
1300 match self.netref.cmp(&other.netref) {
1301 std::cmp::Ordering::Equal => self.pos.cmp(&other.pos),
1302 ord => ord,
1303 }
1304 }
1305}
1306
1307impl<I> PartialOrd for DrivenNet<I>
1308where
1309 I: Instantiable,
1310{
1311 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1312 Some(self.cmp(other))
1313 }
1314}
1315
1316impl<I> WeakIndex<usize> for Netlist<I>
1317where
1318 I: Instantiable,
1319{
1320 type Output = OwnedObject<I, Self>;
1321
1322 fn index_weak(&self, index: &usize) -> Rc<RefCell<Self::Output>> {
1323 self.objects.borrow()[*index].clone()
1324 }
1325}
1326
1327impl<I> Netlist<I>
1328where
1329 I: Instantiable,
1330{
1331 pub fn new(name: String) -> Rc<Self> {
1333 Rc::new(Self {
1334 name: RefCell::new(name),
1335 objects: RefCell::new(Vec::new()),
1336 outputs: RefCell::new(BTreeMap::new()),
1337 })
1338 }
1339
1340 pub fn reclaim(self: Rc<Self>) -> Option<Self> {
1342 Rc::try_unwrap(self).ok()
1343 }
1344
1345 pub fn deep_clone(self: &Rc<Self>) -> Rc<Self> {
1347 let dc = Rc::new(Self {
1348 name: self.name.clone(),
1349 objects: RefCell::new(Vec::new()),
1350 outputs: self.outputs.clone(),
1351 });
1352
1353 let objects_linked: Vec<NetRefT<I>> = self
1354 .objects
1355 .borrow()
1356 .iter()
1357 .map(|obj| {
1358 Rc::new(RefCell::new(OwnedObject {
1359 object: obj.borrow().object.clone(),
1360 owner: Rc::downgrade(&dc),
1361 operands: obj.borrow().operands.clone(),
1362 attributes: obj.borrow().attributes.clone(),
1363 index: obj.borrow().index,
1364 }))
1365 })
1366 .collect();
1367
1368 *dc.objects.borrow_mut() = objects_linked;
1369
1370 dc
1371 }
1372
1373 fn insert_object(
1378 self: &Rc<Self>,
1379 object: Object<I>,
1380 operands: &[DrivenNet<I>],
1381 ) -> Result<NetRef<I>, Error> {
1382 for operand in operands {
1383 self.belongs(&operand.clone().unwrap());
1384 }
1385 let index = self.objects.borrow().len();
1386 let weak = Rc::downgrade(self);
1387 let operands = operands
1388 .iter()
1389 .map(|net| Some(net.get_operand()))
1390 .collect::<Vec<_>>();
1391 let owned_object = Rc::new(RefCell::new(OwnedObject {
1392 object,
1393 owner: weak,
1394 operands,
1395 attributes: BTreeMap::new(),
1396 index,
1397 }));
1398 self.objects.borrow_mut().push(owned_object.clone());
1399 Ok(NetRef::wrap(owned_object))
1400 }
1401
1402 pub fn insert_input(self: &Rc<Self>, net: Net) -> DrivenNet<I> {
1404 let obj = Object::Input(net);
1405 self.insert_object(obj, &[]).unwrap().into()
1406 }
1407
1408 pub fn insert_input_logic_bus(self: &Rc<Self>, net: String, bw: usize) -> Vec<DrivenNet<I>> {
1410 Net::new_logic_bus(net, bw)
1411 .into_iter()
1412 .map(|n| self.insert_input(n))
1413 .collect()
1414 }
1415
1416 pub fn insert_gate(
1418 self: &Rc<Self>,
1419 inst_type: I,
1420 inst_name: Identifier,
1421 operands: &[DrivenNet<I>],
1422 ) -> Result<NetRef<I>, Error> {
1423 let nets = inst_type
1424 .get_output_ports()
1425 .into_iter()
1426 .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1427 .collect::<Vec<_>>();
1428 let input_count = inst_type.get_input_ports().into_iter().count();
1429 if operands.len() != input_count {
1430 return Err(Error::ArgumentMismatch(input_count, operands.len()));
1431 }
1432 let obj = Object::Instance(nets, inst_name, inst_type);
1433 self.insert_object(obj, operands)
1434 }
1435
1436 pub fn insert_gate_disconnected(
1438 self: &Rc<Self>,
1439 inst_type: I,
1440 inst_name: Identifier,
1441 ) -> NetRef<I> {
1442 let nets = inst_type
1443 .get_output_ports()
1444 .into_iter()
1445 .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1446 .collect::<Vec<_>>();
1447 let object = Object::Instance(nets, inst_name, inst_type);
1448 let index = self.objects.borrow().len();
1449 let weak = Rc::downgrade(self);
1450 let input_count = object
1451 .get_instance_type()
1452 .unwrap()
1453 .get_input_ports()
1454 .into_iter()
1455 .count();
1456 let operands = vec![None; input_count];
1457 let owned_object = Rc::new(RefCell::new(OwnedObject {
1458 object,
1459 owner: weak,
1460 operands,
1461 attributes: BTreeMap::new(),
1462 index,
1463 }));
1464 self.objects.borrow_mut().push(owned_object.clone());
1465 NetRef::wrap(owned_object)
1466 }
1467
1468 pub fn insert_constant(
1470 self: &Rc<Self>,
1471 value: Logic,
1472 inst_name: Identifier,
1473 ) -> Result<DrivenNet<I>, Error> {
1474 let obj = I::from_constant(value).ok_or(Error::InstantiableError(format!(
1475 "Instantiable type does not support constant value {}",
1476 value
1477 )))?;
1478 Ok(self.insert_gate_disconnected(obj, inst_name).into())
1479 }
1480
1481 fn belongs(&self, netref: &NetRef<I>) {
1485 if let Some(nl) = netref.netref.borrow().owner.upgrade() {
1486 if self.objects.borrow().len() != nl.objects.borrow().len() {
1487 panic!("NetRef does not belong to this netlist");
1488 }
1489
1490 if let Some(p) = self.objects.borrow().first()
1491 && let Some(np) = nl.objects.borrow().first()
1492 && !Rc::ptr_eq(p, np)
1493 {
1494 panic!("NetRef does not belong to this netlist");
1495 }
1496 }
1497
1498 if netref.netref.borrow().index >= self.objects.borrow().len() {
1499 panic!("NetRef does not belong to this netlist");
1500 }
1501 }
1502
1503 pub fn get_driver(&self, netref: NetRef<I>, index: usize) -> Option<DrivenNet<I>> {
1510 self.belongs(&netref);
1511 let op = netref.unwrap().borrow().operands[index]?;
1512 Some(DrivenNet::new(
1513 op.secondary(),
1514 NetRef::wrap(self.index_weak(&op.root()).clone()),
1515 ))
1516 }
1517
1518 pub fn expose_net_with_name(&self, net: DrivenNet<I>, name: Identifier) -> DrivenNet<I> {
1524 self.belongs(&net.clone().unwrap());
1525 let mut outputs = self.outputs.borrow_mut();
1526 let named_net = net.as_net().with_name(name);
1527 outputs
1528 .entry(net.get_operand())
1529 .or_default()
1530 .insert(named_net);
1531 net
1532 }
1533
1534 pub fn expose_net(&self, net: DrivenNet<I>) -> Result<DrivenNet<I>, Error> {
1539 self.belongs(&net.clone().unwrap());
1540 if net.is_an_input() {
1541 return Err(Error::InputNeedsAlias(net.as_net().clone()));
1542 }
1543 let mut outputs = self.outputs.borrow_mut();
1544 outputs
1545 .entry(net.get_operand())
1546 .or_default()
1547 .insert(net.as_net().clone());
1548 Ok(net)
1549 }
1550
1551 pub fn remove_output(&self, operand: &DrivenNet<I>, net_name: &Identifier) -> bool {
1557 self.belongs(&operand.clone().unwrap());
1558 let mut outputs = self.outputs.borrow_mut();
1559 if let Some(nets) = outputs.get_mut(&operand.get_operand()) {
1560 let net_to_remove = Net::new(net_name.clone(), crate::circuit::DataType::logic());
1562 if nets.remove(&net_to_remove) {
1563 if nets.is_empty() {
1565 outputs.remove(&operand.get_operand());
1566 }
1567 return true;
1568 }
1569 }
1570 false
1571 }
1572
1573 pub fn remove_outputs(&self, operand: &DrivenNet<I>) -> usize {
1576 self.outputs
1578 .borrow_mut()
1579 .remove(&operand.get_operand())
1580 .map(|nets| nets.len())
1581 .unwrap_or(0)
1582 }
1583
1584 pub fn clear_outputs(&self) {
1586 self.outputs.borrow_mut().clear();
1587 }
1588
1589 pub fn delete_net_uses(&self, netref: NetRef<I>) -> Result<Object<I>, Error> {
1594 self.belongs(&netref);
1595 let unwrapped = netref.clone().unwrap();
1596 if Rc::strong_count(&unwrapped) > 3 {
1597 return Err(Error::DanglingReference(netref.nets().collect()));
1598 }
1599 let old_index = unwrapped.borrow().get_index();
1600 let objects = self.objects.borrow();
1601 for oref in objects.iter() {
1602 let operands = &mut oref.borrow_mut().operands;
1603 for operand in operands.iter_mut() {
1604 if let Some(op) = operand {
1605 match op {
1606 Operand::DirectIndex(idx) | Operand::CellIndex(idx, _)
1607 if *idx == old_index =>
1608 {
1609 *operand = None;
1610 }
1611 _ => (),
1612 }
1613 }
1614 }
1615 }
1616
1617 let outputs: Vec<Operand> = self
1618 .outputs
1619 .borrow()
1620 .keys()
1621 .filter(|operand| match operand {
1622 Operand::DirectIndex(idx) | Operand::CellIndex(idx, _) => *idx == old_index,
1623 })
1624 .cloned()
1625 .collect();
1626
1627 for operand in outputs {
1628 self.outputs.borrow_mut().remove(&operand);
1629 }
1630
1631 Ok(netref.unwrap().borrow().get().clone())
1632 }
1633
1634 pub fn replace_net_uses(
1642 &self,
1643 of: DrivenNet<I>,
1644 with: &DrivenNet<I>,
1645 ) -> Result<DrivenNet<I>, Error> {
1646 {
1647 self.belongs(&of.clone().unwrap());
1648 self.belongs(&with.clone().unwrap());
1649 }
1650 let unwrapped = of.clone().unwrap().unwrap();
1651 let i = of.get_output_index();
1652 let k = with.get_output_index();
1653
1654 if of.clone().unwrap() == with.clone().unwrap() {
1655 if i == k {
1656 return Ok(of);
1657 }
1658
1659 if Rc::strong_count(&unwrapped) > 4 {
1660 return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1661 }
1662 } else if Rc::strong_count(&unwrapped) > 3 {
1663 return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1664 }
1665
1666 let old_index = of.get_operand();
1667
1668 if let Some(nets) = self.outputs.borrow().get(&old_index)
1669 && nets.contains(&of.as_net())
1670 {
1671 if of.is_an_input() {
1672 return Err(Error::NonuniqueNets(nets.iter().cloned().collect()));
1673 } else {
1674 let id = of.as_net().get_identifier().clone() + "_replaced".into();
1675 of.as_net_mut().set_identifier(id);
1676 }
1677 }
1678
1679 let new_index = with.get_operand();
1680 let objects = self.objects.borrow();
1681 for oref in objects.iter() {
1682 let operands = &mut oref.borrow_mut().operands;
1683 for operand in operands.iter_mut() {
1684 if let Some(op) = operand
1685 && *op == old_index
1686 {
1687 *operand = Some(new_index);
1688 }
1689 }
1690 }
1691
1692 let outs = self.outputs.borrow_mut().remove(&old_index);
1694 if let Some(outs) = outs {
1695 self.outputs
1696 .borrow_mut()
1697 .entry(new_index)
1698 .or_default()
1699 .extend(outs);
1700 }
1701
1702 Ok(of)
1703 }
1704}
1705
1706impl<I> Netlist<I>
1707where
1708 I: Instantiable,
1709{
1710 pub fn get_name(&self) -> Ref<'_, String> {
1712 self.name.borrow()
1713 }
1714
1715 pub fn set_name(&self, name: String) {
1720 *self.name.borrow_mut() = name;
1721 }
1722
1723 pub fn get_input_ports(&self) -> impl Iterator<Item = Net> {
1725 self.objects().filter_map(|oref| {
1726 if oref.is_an_input() {
1727 Some(oref.as_net().clone())
1728 } else {
1729 None
1730 }
1731 })
1732 }
1733
1734 pub fn get_output_ports(&self) -> Vec<Net> {
1736 self.outputs
1737 .borrow()
1738 .values()
1739 .flat_map(|nets| nets.iter().cloned())
1740 .collect()
1741 }
1742
1743 pub fn get_analysis<'a, A: Analysis<'a, I>>(&'a self) -> Result<A, Error> {
1745 A::build(self)
1746 }
1747
1748 pub fn find_net(&self, net: &Net) -> Option<DrivenNet<I>> {
1751 for obj in self.objects() {
1752 for o in obj.outputs() {
1753 if *o.as_net() == *net {
1754 return Some(o);
1755 }
1756 }
1757 }
1758 None
1759 }
1760
1761 pub fn first(&self) -> Option<NetRef<I>> {
1763 self.objects
1764 .borrow()
1765 .first()
1766 .map(|nr| NetRef::wrap(nr.clone()))
1767 }
1768
1769 pub fn last(&self) -> Option<NetRef<I>> {
1771 self.objects
1772 .borrow()
1773 .last()
1774 .map(|nr| NetRef::wrap(nr.clone()))
1775 }
1776
1777 pub fn len(&self) -> usize {
1779 self.objects.borrow().len()
1780 }
1781
1782 pub fn is_empty(&self) -> bool {
1784 self.objects.borrow().is_empty()
1785 }
1786
1787 pub fn drives_an_output(&self, netref: NetRef<I>) -> bool {
1792 self.belongs(&netref);
1793 let my_index = netref.unwrap().borrow().get_index();
1794 for key in self.outputs.borrow().keys() {
1795 if key.root() == my_index {
1796 return true;
1797 }
1798 }
1799 false
1800 }
1801
1802 pub fn rename_nets<F: Fn(&Identifier, usize) -> Identifier>(&self, f: F) -> Result<(), Error> {
1820 let mut i: usize = 0;
1821 for nr in self.objects() {
1822 if nr.is_an_input() {
1823 continue;
1824 }
1825 for mut net in nr.nets_mut() {
1826 let rename = f(net.get_identifier(), i);
1827 net.set_identifier(rename);
1828 i += 1;
1829 }
1830 }
1831
1832 for nr in self.objects() {
1833 if nr.is_an_input() {
1834 continue;
1835 }
1836
1837 let rename = f(&nr.get_instance_name().unwrap(), i);
1838 nr.set_instance_name(rename);
1839 i += 1;
1840 }
1841
1842 self.verify()
1843 }
1844
1845 pub fn retain_once(&self, set: &mut HashSet<DrivenNet<I>>) -> Result<Vec<Object<I>>, Error> {
1847 let mut dead_objs = HashSet::new();
1848 {
1849 let fan_out = self.get_analysis::<FanOutTable<I>>()?;
1850 for obj in self.objects() {
1851 let mut is_dead = true;
1852 for net in obj.outputs() {
1853 if fan_out.net_has_uses(&net.as_net()) {
1855 is_dead = false;
1856 } else {
1857 set.remove(&net);
1858 }
1859 }
1860 if is_dead && !obj.is_an_input() {
1861 dead_objs.insert(obj.unwrap().borrow().index);
1862 }
1863 }
1864 }
1865
1866 if dead_objs.is_empty() {
1867 return Ok(vec![]);
1868 }
1869
1870 let old_objects = self.objects.take();
1871
1872 for i in dead_objs.iter() {
1874 let rc = &old_objects[*i];
1875 if Rc::strong_count(rc) > 1 {
1876 self.objects.replace(old_objects.clone());
1877 return Err(Error::DanglingReference(
1878 rc.borrow().get().get_nets().to_vec(),
1879 ));
1880 }
1881 }
1882
1883 let mut removed = Vec::new();
1884 let mut remap: HashMap<usize, usize> = HashMap::new();
1885 for (old_index, obj) in old_objects.into_iter().enumerate() {
1886 if dead_objs.contains(&old_index) {
1887 removed.push(obj.borrow().get().clone());
1888 continue;
1889 }
1890
1891 let new_index = self.objects.borrow().len();
1892 remap.insert(old_index, new_index);
1893 obj.borrow_mut().index = new_index;
1894 self.objects.borrow_mut().push(obj);
1895 }
1896
1897 for obj in self.objects.borrow().iter() {
1898 for operand in obj.borrow_mut().inds_mut() {
1899 let root = operand.root();
1900 let root = *remap.get(&root).unwrap_or(&root);
1901 *operand = operand.remap(root);
1902 }
1903 }
1904
1905 let pairs: Vec<_> = self.outputs.take().into_iter().collect();
1906 for (operand, net) in pairs {
1907 let root = operand.root();
1908 let root = *remap.get(&root).unwrap_or(&root);
1909 let new_operand = operand.remap(root);
1910 self.outputs.borrow_mut().insert(new_operand, net);
1911 }
1912
1913 Ok(removed)
1914 }
1915
1916 pub fn clean(&self) -> Result<Vec<Object<I>>, Error> {
1919 let mut removed = Vec::new();
1920 let mut r = self.retain_once(&mut HashSet::new())?;
1921 while !r.is_empty() {
1922 removed.extend(r);
1923 r = self.retain_once(&mut HashSet::new())?;
1924 }
1925 Ok(removed)
1926 }
1927
1928 pub fn retain(&self, set: &mut HashSet<DrivenNet<I>>) -> Result<Vec<Object<I>>, Error> {
1930 let mut removed = Vec::new();
1931 let mut r = self.retain_once(set)?;
1932 while !r.is_empty() {
1933 removed.extend(r);
1934 r = self.retain_once(set)?;
1935 }
1936 Ok(removed)
1937 }
1938
1939 fn nets_insts_unique(&self) -> Result<(), Error> {
1941 let mut nets = HashSet::new();
1942 let mut stems = HashSet::new();
1943 for net in self {
1944 if !nets.insert(net.clone().take_identifier()) {
1945 return Err(Error::NonuniqueNets(vec![net]));
1946 }
1947 if !stems.insert(net.get_identifier().get_stem().to_string())
1948 && net.get_identifier().get_bit_index().is_none()
1949 {
1950 return Err(Error::NonuniqueNets(vec![net]));
1951 }
1952 }
1953 for inst in self.objects() {
1954 if let Some(name) = inst.get_instance_name()
1955 && !stems.insert(name.get_stem().to_string())
1956 {
1957 return Err(Error::NonuniqueInsts(vec![name]));
1958 }
1959 if let Some(name) = inst.get_instance_name()
1960 && name.get_bit_index().is_some()
1961 {
1962 return Err(Error::InstantiableError(format!(
1963 "Instance identifier {name} cannot be indexed"
1964 )));
1965 }
1966 }
1967 Ok(())
1968 }
1969
1970 fn connections_type_check(&self) -> Result<(), Error> {
1971 for conn in self.connections() {
1972 let target = *conn.target().get_port().get_type();
1973 let source = *conn.src().as_net().get_type();
1974 if target != source {
1975 return Err(Error::TypeError(conn.src().as_net().clone()));
1976 }
1977 }
1978 Ok(())
1979 }
1980
1981 pub fn verify(&self) -> Result<(), Error> {
1983 if self.outputs.borrow().is_empty() {
1984 return Err(Error::NoOutputs);
1985 }
1986
1987 self.nets_insts_unique()?;
1988 self.connections_type_check()?;
1989
1990 Ok(())
1991 }
1992}
1993
1994#[derive(Debug, Clone)]
1996pub struct Connection<I: Instantiable> {
1997 driver: DrivenNet<I>,
1998 input: InputPort<I>,
1999}
2000
2001impl<I> Connection<I>
2002where
2003 I: Instantiable,
2004{
2005 fn new(driver: DrivenNet<I>, input: InputPort<I>) -> Self {
2006 Self { driver, input }
2007 }
2008
2009 pub fn src(&self) -> DrivenNet<I> {
2011 self.driver.clone()
2012 }
2013
2014 pub fn net(&self) -> Net {
2016 self.driver.as_net().clone()
2017 }
2018
2019 pub fn target(&self) -> InputPort<I> {
2021 self.input.clone()
2022 }
2023}
2024
2025impl<I> std::fmt::Display for Connection<I>
2026where
2027 I: Instantiable,
2028{
2029 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2030 self.net().fmt(f)
2031 }
2032}
2033
2034pub mod rewriter {
2036 use super::{DrivenNet, Error, Instantiable, NetRef, Netlist, Operand};
2037 use crate::graph::FanOutTable;
2038 use std::collections::HashMap;
2039 use std::rc::Rc;
2040
2041 pub struct NetMapper<'a, I: Instantiable> {
2045 parent: HashMap<DrivenNet<I>, DrivenNet<I>>,
2046 netlist: &'a Netlist<I>,
2047 fanout: FanOutTable<'a, I>,
2048 }
2049
2050 impl<'a, I: Instantiable> NetMapper<'a, I> {
2051 pub fn new(netlist: &'a Netlist<I>) -> Result<Self, Error> {
2053 Ok(Self {
2054 parent: HashMap::new(),
2055 netlist,
2056 fanout: netlist.get_analysis::<FanOutTable<I>>()?,
2057 })
2058 }
2059
2060 pub fn find(&self, x: DrivenNet<I>) -> DrivenNet<I> {
2062 let mut root = x;
2063 while let Some(p) = self.parent.get(&root) {
2064 root = p.clone();
2065 }
2066 root
2067 }
2068
2069 pub fn replace(&mut self, of: DrivenNet<I>, with: DrivenNet<I>) -> DrivenNet<I> {
2074 let of_root = self.find(of.clone());
2075 let with_root = self.find(with);
2076 if of_root == with_root {
2077 panic!("Already mapped by NetMapper: {of}");
2078 }
2079 self.parent.insert(of_root, with_root);
2080 of
2081 }
2082
2083 pub fn apply(self) -> Result<Vec<DrivenNet<I>>, Error> {
2086 let mut map: HashMap<Operand, Operand> = HashMap::new();
2088 for k in self.parent.keys().cloned() {
2089 let v = self.find(k.clone());
2090 if k != v {
2091 map.insert(k.get_operand(), v.get_operand());
2092 }
2093 }
2094
2095 drop(self.parent);
2096
2097 for (of, with) in map.iter() {
2099 let unwrapped = self.netlist.objects.borrow()[of.root()].clone();
2100 let i = of.secondary();
2101 let k = of.secondary();
2102 let nr = NetRef::wrap(unwrapped.clone());
2103
2104 if of.root() == with.root() {
2105 if i == k {
2106 continue;
2107 }
2108
2109 if Rc::strong_count(&unwrapped) - self.fanout.get_ref_count(&nr) > 4 {
2110 return Err(Error::DanglingReference(nr.nets().collect()));
2111 }
2112 } else if Rc::strong_count(&unwrapped) - self.fanout.get_ref_count(&nr) > 3 {
2113 return Err(Error::DanglingReference(nr.nets().collect()));
2114 }
2115
2116 let old_index = of;
2117 let of = DrivenNet::new(i, nr);
2118
2119 if let Some(nets) = self.netlist.outputs.borrow().get(old_index)
2120 && nets.contains(&of.as_net())
2121 {
2122 if of.is_an_input() {
2123 return Err(Error::NonuniqueNets(nets.iter().cloned().collect()));
2124 } else {
2125 let id = of.as_net().get_identifier().clone() + "_replaced".into();
2126 of.as_net_mut().set_identifier(id);
2127 }
2128 }
2129 }
2130
2131 let objects = self.netlist.objects.borrow();
2132 for (of, &with) in map.iter() {
2133 let of = DrivenNet::new(of.secondary(), NetRef::wrap(objects[of.root()].clone()));
2134 for u in self.fanout.get_users(&of) {
2135 let place = u.pos;
2136 let u = u.unwrap().unwrap();
2137 let operands = &mut u.borrow_mut().operands;
2138 operands[place] = Some(with);
2139 }
2140 }
2141
2142 for (of, &with) in map.iter() {
2143 let outs = self.netlist.outputs.borrow_mut().remove(of);
2145 if let Some(outs) = outs {
2146 self.netlist
2147 .outputs
2148 .borrow_mut()
2149 .entry(with)
2150 .or_default()
2151 .extend(outs);
2152 }
2153 }
2154
2155 let res: Vec<_> = map
2156 .into_keys()
2157 .map(|operand| {
2158 DrivenNet::new(
2159 operand.secondary(),
2160 NetRef::wrap(self.netlist.objects.borrow()[operand.root()].clone()),
2161 )
2162 })
2163 .collect();
2164
2165 Ok(res)
2166 }
2167 }
2168}
2169
2170pub mod iter {
2172
2173 use super::{
2174 Connection, DrivenNet, InputPort, Instantiable, Net, NetRef, Netlist, Operand, WeakIndex,
2175 };
2176 use std::collections::{HashMap, HashSet};
2177 pub struct NetIterator<'a, I: Instantiable> {
2179 netlist: &'a Netlist<I>,
2180 index: usize,
2181 subindex: usize,
2182 }
2183
2184 impl<'a, I> NetIterator<'a, I>
2185 where
2186 I: Instantiable,
2187 {
2188 pub fn new(netlist: &'a Netlist<I>) -> Self {
2190 Self {
2191 netlist,
2192 index: 0,
2193 subindex: 0,
2194 }
2195 }
2196 }
2197
2198 impl<I> Iterator for NetIterator<'_, I>
2199 where
2200 I: Instantiable,
2201 {
2202 type Item = Net;
2203
2204 fn next(&mut self) -> Option<Self::Item> {
2205 while self.index < self.netlist.objects.borrow().len() {
2206 let objects = self.netlist.objects.borrow();
2207 let object = objects[self.index].borrow();
2208 if self.subindex < object.get().get_nets().len() {
2209 let net = object.get().get_nets()[self.subindex].clone();
2210 self.subindex += 1;
2211 return Some(net);
2212 }
2213 self.subindex = 0;
2214 self.index += 1;
2215 }
2216 None
2217 }
2218 }
2219
2220 pub struct ObjectIterator<'a, I: Instantiable> {
2222 netlist: &'a Netlist<I>,
2223 index: usize,
2224 }
2225
2226 impl<'a, I> ObjectIterator<'a, I>
2227 where
2228 I: Instantiable,
2229 {
2230 pub fn new(netlist: &'a Netlist<I>) -> Self {
2232 Self { netlist, index: 0 }
2233 }
2234 }
2235
2236 impl<I> Iterator for ObjectIterator<'_, I>
2237 where
2238 I: Instantiable,
2239 {
2240 type Item = NetRef<I>;
2241
2242 fn next(&mut self) -> Option<Self::Item> {
2243 if self.index < self.netlist.objects.borrow().len() {
2244 let objects = self.netlist.objects.borrow();
2245 let object = &objects[self.index];
2246 self.index += 1;
2247 return Some(NetRef::wrap(object.clone()));
2248 }
2249 None
2250 }
2251 }
2252
2253 pub struct ConnectionIterator<'a, I: Instantiable> {
2255 netlist: &'a Netlist<I>,
2256 index: usize,
2257 subindex: usize,
2258 }
2259
2260 impl<'a, I> ConnectionIterator<'a, I>
2261 where
2262 I: Instantiable,
2263 {
2264 pub fn new(netlist: &'a Netlist<I>) -> Self {
2266 Self {
2267 netlist,
2268 index: 0,
2269 subindex: 0,
2270 }
2271 }
2272 }
2273
2274 impl<I> Iterator for ConnectionIterator<'_, I>
2275 where
2276 I: Instantiable,
2277 {
2278 type Item = super::Connection<I>;
2279
2280 fn next(&mut self) -> Option<Self::Item> {
2281 while self.index < self.netlist.objects.borrow().len() {
2282 let objects = self.netlist.objects.borrow();
2283 let object = objects[self.index].borrow();
2284 let noperands = object.operands.len();
2285 while self.subindex < noperands {
2286 if let Some(operand) = &object.operands[self.subindex] {
2287 let driver = match operand {
2288 Operand::DirectIndex(idx) => {
2289 DrivenNet::new(0, NetRef::wrap(objects[*idx].clone()))
2290 }
2291 Operand::CellIndex(idx, j) => {
2292 DrivenNet::new(*j, NetRef::wrap(objects[*idx].clone()))
2293 }
2294 };
2295 let input = InputPort::new(
2296 self.subindex,
2297 NetRef::wrap(objects[self.index].clone()),
2298 );
2299 self.subindex += 1;
2300 return Some(Connection::new(driver, input));
2301 }
2302 self.subindex += 1;
2303 }
2304 self.subindex = 0;
2305 self.index += 1;
2306 }
2307 None
2308 }
2309 }
2310
2311 #[derive(Clone)]
2313 struct Walk<T: std::hash::Hash + PartialEq + Eq + Clone> {
2314 stack: Vec<T>,
2315 counter: HashMap<T, usize>,
2316 }
2317
2318 impl<T> Walk<T>
2319 where
2320 T: std::hash::Hash + PartialEq + Eq + Clone,
2321 {
2322 fn new() -> Self {
2324 Self {
2325 stack: Vec::new(),
2326 counter: HashMap::new(),
2327 }
2328 }
2329
2330 fn push(&mut self, item: T) {
2332 self.stack.push(item.clone());
2333 *self.counter.entry(item).or_insert(0) += 1;
2334 }
2335
2336 fn contains_cycle(&self) -> bool {
2338 self.counter.values().any(|&count| count > 1)
2339 }
2340
2341 fn root_cycle(&self) -> bool {
2343 if self.stack.is_empty() {
2344 return false;
2345 }
2346 self.counter[&self.stack[0]] > 1
2347 }
2348
2349 fn last(&self) -> Option<&T> {
2351 self.stack.last()
2352 }
2353 }
2354
2355 pub struct DFSIterator<'a, I: Instantiable> {
2374 dfs: NetDFSIterator<'a, I>,
2375 seen: HashSet<NetRef<I>>,
2376 }
2377
2378 impl<'a, I> DFSIterator<'a, I>
2379 where
2380 I: Instantiable,
2381 {
2382 pub fn new(netlist: &'a Netlist<I>, from: NetRef<I>) -> Self {
2384 Self {
2385 dfs: NetDFSIterator::new(netlist, DrivenNet::new(0, from)),
2386 seen: HashSet::new(),
2387 }
2388 }
2389 }
2390
2391 impl<I> DFSIterator<'_, I>
2392 where
2393 I: Instantiable,
2394 {
2395 pub fn check_cycles(&self) -> bool {
2397 self.dfs.check_cycles()
2398 }
2399
2400 pub fn detect_cycles(self) -> bool {
2402 self.dfs.detect_cycles()
2403 }
2404
2405 pub fn check_self_loop(&self) -> bool {
2407 self.dfs.check_self_loop()
2408 }
2409
2410 pub fn detect_self_loop(self) -> bool {
2412 self.dfs.detect_self_loop()
2413 }
2414 }
2415
2416 impl<I> Iterator for DFSIterator<'_, I>
2417 where
2418 I: Instantiable,
2419 {
2420 type Item = NetRef<I>;
2421
2422 fn next(&mut self) -> Option<Self::Item> {
2423 let d = self.dfs.next()?;
2424 if self.seen.insert(d.clone().unwrap()) {
2425 Some(d.unwrap())
2426 } else {
2427 self.next()
2428 }
2429 }
2430 }
2431
2432 type TermFn<I> = Box<dyn Fn(&DrivenNet<I>) -> bool + 'static>;
2433
2434 pub struct NetDFSIterator<'a, I: Instantiable> {
2436 netlist: &'a Netlist<I>,
2437 stacks: Vec<Walk<DrivenNet<I>>>,
2438 visited: HashSet<usize>,
2439 visited_net: HashSet<(usize, usize)>,
2440 any_cycle: bool,
2441 root_cycle: bool,
2442 terminate: TermFn<I>,
2443 }
2444
2445 impl<'a, I> NetDFSIterator<'a, I>
2446 where
2447 I: Instantiable,
2448 {
2449 pub fn new_filtered<F: Fn(&DrivenNet<I>) -> bool + 'static>(
2452 netlist: &'a Netlist<I>,
2453 from: DrivenNet<I>,
2454 terminate: F,
2455 ) -> Self {
2456 let mut s = Walk::new();
2457 s.push(from);
2458 Self {
2459 netlist,
2460 stacks: vec![s],
2461 visited: HashSet::new(),
2462 visited_net: HashSet::new(),
2463 any_cycle: false,
2464 root_cycle: false,
2465 terminate: Box::new(terminate),
2466 }
2467 }
2468
2469 pub fn new(netlist: &'a Netlist<I>, from: DrivenNet<I>) -> Self {
2471 Self::new_filtered(netlist, from, |_| false)
2472 }
2473 }
2474
2475 impl<I> NetDFSIterator<'_, I>
2476 where
2477 I: Instantiable,
2478 {
2479 pub fn check_cycles(&self) -> bool {
2481 self.any_cycle
2482 }
2483
2484 pub fn detect_cycles(mut self) -> bool {
2486 if self.any_cycle {
2487 return true;
2488 }
2489
2490 while let Some(_) = self.next() {
2491 if self.any_cycle {
2492 return true;
2493 }
2494 }
2495
2496 self.any_cycle
2497 }
2498
2499 pub fn check_self_loop(&self) -> bool {
2501 self.root_cycle
2502 }
2503
2504 pub fn detect_self_loop(mut self) -> bool {
2506 if self.root_cycle {
2507 return true;
2508 }
2509
2510 while let Some(_) = self.next() {
2511 if self.root_cycle {
2512 return true;
2513 }
2514 }
2515
2516 self.root_cycle
2517 }
2518 }
2519
2520 impl<I> Iterator for NetDFSIterator<'_, I>
2521 where
2522 I: Instantiable,
2523 {
2524 type Item = DrivenNet<I>;
2525
2526 fn next(&mut self) -> Option<Self::Item> {
2527 if let Some(walk) = self.stacks.pop() {
2528 self.any_cycle |= walk.contains_cycle();
2529 self.root_cycle |= walk.root_cycle();
2530 let item = walk.last().cloned();
2531 let uw = item.clone().unwrap().unwrap().unwrap();
2532 let index = uw.borrow().get_index();
2533 let secondary = item.as_ref().unwrap().pos;
2534 if self.visited.insert(index) {
2535 if !(self.terminate)(item.as_ref().unwrap()) {
2536 let operands = &uw.borrow().operands;
2537 for operand in operands.iter().flatten() {
2538 let mut new_walk = walk.clone();
2539 new_walk.push(DrivenNet::new(
2540 operand.secondary(),
2541 NetRef::wrap(self.netlist.index_weak(&operand.root())),
2542 ));
2543 self.stacks.push(new_walk);
2544 }
2545 }
2546 self.visited_net.insert((index, secondary));
2547 return item;
2548 }
2549
2550 if self.visited_net.insert((index, secondary)) {
2551 return item;
2552 }
2553
2554 return self.next();
2555 }
2556
2557 None
2558 }
2559 }
2560}
2561
2562impl<'a, I> IntoIterator for &'a Netlist<I>
2563where
2564 I: Instantiable,
2565{
2566 type Item = Net;
2567 type IntoIter = iter::NetIterator<'a, I>;
2568
2569 fn into_iter(self) -> Self::IntoIter {
2570 iter::NetIterator::new(self)
2571 }
2572}
2573
2574#[macro_export]
2577macro_rules! filter_nodes {
2578 ($netlist:ident, $pattern:pat $(if $guard:expr)? $(,)?) => {
2579 $netlist.matches(|f| match f {
2580 $pattern $(if $guard)? => true,
2581 _ => false
2582 })
2583 };
2584}
2585
2586impl<I> Netlist<I>
2587where
2588 I: Instantiable,
2589{
2590 pub fn objects(&self) -> impl Iterator<Item = NetRef<I>> {
2592 iter::ObjectIterator::new(self)
2593 }
2594
2595 pub fn matches<F>(&self, filter: F) -> impl Iterator<Item = NetRef<I>>
2597 where
2598 F: Fn(&I) -> bool,
2599 {
2600 self.objects().filter(move |f| {
2601 if let Some(inst_type) = f.get_instance_type() {
2602 filter(&inst_type)
2603 } else {
2604 false
2605 }
2606 })
2607 }
2608
2609 pub fn inputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
2611 self.objects()
2612 .filter(|n| n.is_an_input())
2613 .map(|n| DrivenNet::new(0, n))
2614 }
2615
2616 pub fn outputs(&self) -> Vec<(DrivenNet<I>, Net)> {
2618 self.outputs
2619 .borrow()
2620 .iter()
2621 .flat_map(|(k, nets)| {
2622 nets.iter().map(|n| {
2623 (
2624 DrivenNet::new(k.secondary(), NetRef::wrap(self.index_weak(&k.root()))),
2625 n.clone(),
2626 )
2627 })
2628 })
2629 .collect()
2630 }
2631
2632 pub fn connections(&self) -> impl Iterator<Item = Connection<I>> {
2634 iter::ConnectionIterator::new(self)
2635 }
2636
2637 pub fn node_dfs(&self, from: NetRef<I>) -> impl Iterator<Item = NetRef<I>> {
2642 self.belongs(&from);
2643 iter::DFSIterator::new(self, from)
2644 }
2645
2646 pub fn net_dfs(&self, from: DrivenNet<I>) -> impl Iterator<Item = DrivenNet<I>> {
2651 self.belongs(&from.clone().unwrap());
2652 iter::NetDFSIterator::new(self, from)
2653 }
2654
2655 #[cfg(feature = "serde")]
2656 pub fn serialize(self, writer: impl std::io::Write) -> Result<(), serde_json::Error>
2658 where
2659 I: ::serde::Serialize,
2660 {
2661 serde::netlist_serialize(self, writer)
2662 }
2663
2664 #[cfg(feature = "graph")]
2665 pub fn dot_string(&self) -> Result<String, Error> {
2667 use super::graph::{Edge, MultiDiGraph, Node};
2668 use petgraph::dot::{Config, Dot};
2669 use petgraph::graph::{DiGraph, EdgeReference, NodeIndex};
2670 let analysis = self.get_analysis::<MultiDiGraph<_>>()?;
2671 let graph = analysis.get_graph();
2672
2673 fn node_impl<I: Instantiable>(
2674 _graph: &DiGraph<Node<I, String>, Edge<I, Net>>,
2675 node: (NodeIndex, &Node<I, String>),
2676 ) -> String {
2677 let n = node.1;
2678 let mut attr = String::new();
2679
2680 match n {
2681 Node::NetRef(nr) if nr.get_instance_type().is_some() => attr += "shape=record, ",
2682 _ => attr += "shape=ellipse, ",
2683 }
2684
2685 match n {
2686 Node::NetRef(nr)
2687 if let Some(inst_type) = nr.get_instance_type()
2688 && !inst_type.is_driverless() =>
2689 {
2690 let mut record = "{ { ".to_string();
2691
2692 let l = nr.get_num_input_ports();
2693 for (i, port) in nr.inputs().enumerate() {
2694 let id = port.get_port().get_identifier().clone();
2695 record += &format!("{{ <{}> {} }}", id, id);
2696
2697 if i != l - 1 {
2698 record += " | ";
2699 }
2700 }
2701
2702 record += &format!(
2703 " }} | {}({}) }}",
2704 inst_type.get_name(),
2705 nr.get_instance_name().unwrap()
2706 );
2707 attr += &format!("label=\"{record}\"");
2708 }
2709 _ => attr += &format!("label=\"{n}\""),
2710 }
2711
2712 attr
2713 }
2714
2715 fn edge_impl<I: Instantiable>(
2716 _graph: &DiGraph<Node<I, String>, Edge<I, Net>>,
2717 edge: EdgeReference<Edge<I, Net>>,
2718 ) -> String {
2719 match edge.weight() {
2720 Edge::Connection(c) => {
2721 format!(", port=\"{}\"", c.target().get_port().get_identifier())
2722 }
2723 _ => String::new(),
2724 }
2725 }
2726
2727 let dot = Dot::with_attr_getters(
2728 graph,
2729 &[Config::NodeNoLabel],
2730 &edge_impl::<I>,
2731 &node_impl::<I>,
2732 );
2733
2734 let mut result = String::new();
2736 for line in dot.to_string().lines() {
2737 if line.contains("->") && line.contains("port=") {
2738 let port = line
2739 .split("port=\"")
2740 .nth(1)
2741 .unwrap()
2742 .split('"')
2743 .next()
2744 .unwrap();
2745 let (l, r) = line.split_once("->").unwrap();
2746 let (l, r) = (l, r.trim());
2747 let (d, r) = r.split_once(" ").unwrap();
2748 result += &format!("{l}-> {d}:{port} {r}\n");
2749 } else {
2750 result += line;
2751 result += "\n";
2752 }
2753 }
2754
2755 Ok(result)
2756 }
2757
2758 #[cfg(feature = "graph")]
2759 pub fn dump_dot(&self) -> std::io::Result<()> {
2761 use std::io::Write;
2762 let mut dir = std::env::current_dir()?;
2763 let mod_name = format!("{}.dot", self.get_name());
2764 dir.push(mod_name);
2765 let mut file = std::fs::File::create(dir)?;
2766 if let Err(e) = self.verify() {
2767 write!(file, "Netlist verification failed: {e}")
2768 } else {
2769 let dot = self.dot_string().unwrap();
2770 write!(file, "{dot}")
2771 }
2772 }
2773}
2774
2775impl<I> std::fmt::Display for Netlist<I>
2776where
2777 I: Instantiable,
2778{
2779 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2780 let objects = self.objects.borrow();
2782 let outputs = self.outputs.borrow();
2783
2784 writeln!(f, "module {} (", self.get_name())?;
2785
2786 let mut input_list: BTreeMap<(String, bool), (usize, usize)> = BTreeMap::new();
2788 let mut output_list: BTreeMap<(String, bool), (usize, usize)> = BTreeMap::new();
2789 let mut net_list: BTreeMap<(String, bool), (usize, usize)> = BTreeMap::new();
2790
2791 for oref in objects.iter() {
2792 let owned = oref.borrow();
2793 let obj = owned.get();
2794 if let Object::Input(net) = obj {
2795 let stem = net.get_identifier().get_stem();
2796 let entry = input_list
2797 .entry((stem.to_string(), net.get_identifier().is_escaped()))
2798 .or_default();
2799 if let Some(idx) = net.get_identifier().get_bit_index() {
2800 entry.0 = entry.0.min(idx);
2801 entry.1 = entry.1.max(idx);
2802 }
2803 }
2804 }
2805
2806 let all_outputs: Vec<_> = outputs.values().flat_map(|nets| nets.iter()).collect();
2808 for &net in &all_outputs {
2809 let stem = net.get_identifier().get_stem();
2810 if input_list.contains_key(&(stem.to_string(), net.get_identifier().is_escaped())) {
2811 continue;
2812 }
2813 let entry = output_list
2814 .entry((stem.to_string(), net.get_identifier().is_escaped()))
2815 .or_default();
2816 if let Some(idx) = net.get_identifier().get_bit_index() {
2817 entry.0 = entry.0.min(idx);
2818 entry.1 = entry.1.max(idx);
2819 }
2820 }
2821
2822 let level = 2;
2823 let indent = " ".repeat(level);
2824 for (id, escaped) in input_list.keys() {
2825 write!(f, "{}", indent)?;
2826 if *escaped {
2827 write!(f, "\\")?;
2828 }
2829 write!(f, "{}", id)?;
2830 if *escaped {
2831 write!(f, " ")?;
2832 }
2833 writeln!(f, ",")?;
2834 }
2835
2836 for (i, (id, escaped)) in output_list.keys().enumerate() {
2837 write!(f, "{}", indent)?;
2838 if *escaped {
2839 write!(f, "\\")?;
2840 }
2841 write!(f, "{}", id)?;
2842 if *escaped {
2843 write!(f, " ")?;
2844 }
2845 if i == output_list.len() - 1 {
2846 writeln!(f)?;
2847 } else {
2848 writeln!(f, ",")?;
2849 }
2850 }
2851
2852 writeln!(f, ");")?;
2853
2854 let mut already_decl = HashSet::new();
2856 for ((id, escaped), (lsb, msb)) in input_list {
2857 write!(f, "{}input wire ", indent)?;
2858 if lsb != msb {
2859 write!(f, "[{}:{}] ", msb, lsb)?;
2860 }
2861 if escaped {
2862 write!(f, "\\")?;
2863 }
2864 write!(f, "{}", id)?;
2865 if escaped {
2866 write!(f, " ")?;
2867 }
2868 writeln!(f, ";")?;
2869 already_decl.insert(id);
2870 }
2871
2872 for ((id, escaped), (lsb, msb)) in output_list {
2873 write!(f, "{}output wire ", indent)?;
2874 if lsb != msb {
2875 write!(f, "[{}:{}] ", msb, lsb)?;
2876 }
2877 if escaped {
2878 write!(f, "\\")?;
2879 }
2880 write!(f, "{}", id)?;
2881 if escaped {
2882 write!(f, " ")?;
2883 }
2884 writeln!(f, ";")?;
2885 already_decl.insert(id);
2886 }
2887
2888 for oref in objects.iter() {
2889 let owned = oref.borrow();
2890 let obj = owned.get();
2891 if let Object::Instance(nets, _, inst_type) = obj
2892 && inst_type.get_constant().is_none()
2893 {
2894 for net in nets.iter() {
2895 if already_decl.contains(net.get_identifier().get_stem()) {
2896 continue;
2897 }
2898 let stem = net.get_identifier().get_stem();
2899 let entry = net_list
2900 .entry((stem.to_string(), net.get_identifier().is_escaped()))
2901 .or_default();
2902 if let Some(idx) = net.get_identifier().get_bit_index() {
2903 entry.0 = entry.0.min(idx);
2904 entry.1 = entry.1.max(idx);
2905 }
2906 }
2907 }
2908 }
2909
2910 for ((id, escaped), (lsb, msb)) in net_list {
2911 write!(f, "{}wire ", indent)?;
2912 if lsb != msb {
2913 write!(f, "[{}:{}] ", msb, lsb)?;
2914 }
2915 if escaped {
2916 write!(f, "\\")?;
2917 }
2918 write!(f, "{}", id)?;
2919 if escaped {
2920 write!(f, " ")?;
2921 }
2922 writeln!(f, ";")?;
2923 }
2924
2925 for oref in objects.iter() {
2926 let owned = oref.borrow();
2927 let obj = owned.get();
2928
2929 if let Some(inst_type) = obj.get_instance_type()
2931 && inst_type.get_constant().is_some()
2932 {
2933 continue;
2934 }
2935
2936 if let Object::Instance(nets, inst_name, inst_type) = obj {
2937 for (k, v) in owned.attributes.iter() {
2938 if let Some(value) = v {
2939 writeln!(f, "{indent}(* {k} = \"{value}\" *)")?;
2940 } else {
2941 writeln!(f, "{indent}(* {k} *)")?;
2942 }
2943 }
2944
2945 write!(f, "{}{} ", indent, inst_type.get_name())?;
2946 if inst_type.is_parameterized() {
2947 writeln!(f, "#(")?;
2948 let level = 4;
2949 let indent = " ".repeat(level);
2950 let params: Vec<_> = inst_type.parameters().collect();
2951 for (i, (k, v)) in params.iter().enumerate() {
2952 if i == params.len() - 1 {
2953 writeln!(f, "{indent}.{k}({v})")?;
2954 } else {
2955 writeln!(f, "{indent}.{k}({v}),")?;
2956 }
2957 }
2958 let level = 2;
2959 let indent = " ".repeat(level);
2960 write!(f, "{indent}) ")?;
2961 }
2962 writeln!(f, "{} (", inst_name.emit_name())?;
2963 let level = 4;
2964 let indent = " ".repeat(level);
2965 for (idx, port) in inst_type.get_input_ports().into_iter().enumerate() {
2966 let port_name = port.get_identifier().emit_name();
2967 if let Some(operand) = owned.operands[idx].as_ref() {
2968 let operand_net = match operand {
2969 Operand::DirectIndex(idx) => objects[*idx].borrow().as_net().clone(),
2970 Operand::CellIndex(idx, j) => {
2971 objects[*idx].borrow().get_net(*j).clone()
2972 }
2973 };
2974
2975 let operand_str = if let Some(inst_type) =
2976 objects[operand.root()].borrow().get().get_instance_type()
2977 && let Some(logic) = inst_type.get_constant()
2978 {
2979 logic.to_string()
2980 } else {
2981 operand_net.get_identifier().emit_name()
2982 };
2983
2984 writeln!(f, "{}.{}({}),", indent, port_name, operand_str)?;
2985 }
2986 }
2987
2988 for (idx, net) in nets.iter().enumerate() {
2989 let port_name = inst_type.get_output_port(idx).get_identifier().emit_name();
2990 if idx == nets.len() - 1 {
2991 writeln!(
2992 f,
2993 "{}.{}({})",
2994 indent,
2995 port_name,
2996 net.get_identifier().emit_name()
2997 )?;
2998 } else {
2999 writeln!(
3000 f,
3001 "{}.{}({}),",
3002 indent,
3003 port_name,
3004 net.get_identifier().emit_name()
3005 )?;
3006 }
3007 }
3008
3009 let level = 2;
3010 let indent = " ".repeat(level);
3011 writeln!(f, "{indent});")?;
3012 }
3013 }
3014
3015 for (driver, nets) in outputs.iter() {
3016 for net in nets {
3017 let driver_net = match driver {
3018 Operand::DirectIndex(idx) => self.index_weak(idx).borrow().as_net().clone(),
3019 Operand::CellIndex(idx, j) => self.index_weak(idx).borrow().get_net(*j).clone(),
3020 };
3021
3022 let driver_str = if let Some(inst_type) = self
3023 .index_weak(&driver.root())
3024 .borrow()
3025 .get()
3026 .get_instance_type()
3027 && let Some(logic) = inst_type.get_constant()
3028 {
3029 logic.to_string()
3030 } else {
3031 driver_net.get_identifier().emit_name()
3032 };
3033
3034 if net.get_identifier() != driver_net.get_identifier() {
3035 writeln!(
3036 f,
3037 "{}assign {} = {};",
3038 indent,
3039 net.get_identifier().emit_name(),
3040 driver_str
3041 )?;
3042 }
3043 }
3044 }
3045
3046 writeln!(f, "endmodule")
3047 }
3048}
3049
3050pub type GateNetlist = Netlist<Gate>;
3052pub type GateRef = NetRef<Gate>;
3054
3055#[cfg(test)]
3056mod tests {
3057 use super::iter::{DFSIterator, NetDFSIterator};
3058 use super::*;
3059 #[test]
3060 fn test_delete_netlist() {
3061 let netlist = Netlist::new("simple_example".to_string());
3062
3063 let input1 = netlist.insert_input("input1".into());
3065 let input2 = netlist.insert_input("input2".into());
3066
3067 let instance = netlist
3069 .insert_gate(
3070 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3071 "my_and".into(),
3072 &[input1.clone(), input2.clone()],
3073 )
3074 .unwrap();
3075
3076 let instance = instance.expose_as_output().unwrap();
3078 instance.delete_uses().unwrap();
3079 assert!(netlist.clean().is_ok());
3081 input1.expose_with_name("an_output".into());
3082 assert!(netlist.clean().is_ok());
3083 }
3084
3085 #[test]
3086 #[should_panic(expected = "Attempted to create a gate with a sliced identifier")]
3087 fn gate_w_slice_panics() {
3088 Gate::new_logical("AND[1]".into(), vec!["A".into(), "B".into()], "Y".into());
3089 }
3090
3091 #[test]
3092 fn gates_dont_have_params() {
3093 let gate = Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into());
3095 assert!(!gate.has_parameter(&"id".into()));
3096 assert!(gate.get_parameter(&"id".into()).is_none());
3097 assert_eq!(*gate.get_gate_name(), "AND".into());
3098 }
3099
3100 #[test]
3101 fn operand_conversions() {
3102 let operand = Operand::CellIndex(3, 2);
3103 assert_eq!(operand.to_string(), "3.2");
3104 let parsed = "3.2".parse::<Operand>();
3105 assert!(parsed.is_ok());
3106 let parsed = parsed.unwrap();
3107 assert_eq!(operand, parsed);
3108 }
3109
3110 #[test]
3111 #[should_panic(expected = "out of bounds for netref")]
3112 fn test_bad_output() {
3113 let netlist = GateNetlist::new("min_module".to_string());
3114 let a = netlist.insert_input("a".into());
3115 DrivenNet::new(1, a.unwrap());
3116 }
3117
3118 #[test]
3119 fn test_netdfsiterator() {
3120 let netlist = Netlist::new("dfs_netlist".to_string());
3121
3122 let a = netlist.insert_input("a".into());
3124 let b = netlist.insert_input("b".into());
3125 let c = netlist.insert_input("c".into());
3126 let d = netlist.insert_input("d".into());
3127 let e = netlist.insert_input("e".into());
3128
3129 let n1 = netlist
3131 .insert_gate(
3132 Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into()),
3133 "n1".into(),
3134 &[a.clone(), b.clone()],
3135 )
3136 .unwrap()
3137 .get_output(0);
3138 let n2 = netlist
3139 .insert_gate(
3140 Gate::new_logical("NOR".into(), vec!["A".into(), "B".into()], "Y".into()),
3141 "n2".into(),
3142 &[d.clone(), e.clone()],
3143 )
3144 .unwrap()
3145 .get_output(0);
3146 let n3 = netlist
3147 .insert_gate(
3148 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3149 "n3".into(),
3150 &[n1.clone(), c.clone()],
3151 )
3152 .unwrap()
3153 .get_output(0);
3154 let n4 = netlist
3155 .insert_gate(
3156 Gate::new_logical("NAND".into(), vec!["A".into(), "B".into()], "Y".into()),
3157 "n4".into(),
3158 &[n3.clone(), n2.clone()],
3159 )
3160 .unwrap()
3161 .get_output(0);
3162 n4.clone().expose_with_name("y".into());
3163
3164 let mut dfs = NetDFSIterator::new(&netlist, n4.clone());
3166 assert_eq!(dfs.next(), Some(n4));
3167 assert_eq!(dfs.next(), Some(n2));
3168 assert_eq!(dfs.next(), Some(e));
3169 assert_eq!(dfs.next(), Some(d));
3170 assert_eq!(dfs.next(), Some(n3));
3171 assert_eq!(dfs.next(), Some(c));
3172 assert_eq!(dfs.next(), Some(n1));
3173 assert_eq!(dfs.next(), Some(b));
3174 assert_eq!(dfs.next(), Some(a));
3175 assert_eq!(dfs.next(), None);
3176 }
3177
3178 #[test]
3179 fn test_dfs_cycles() {
3180 let netlist = Netlist::new("dfs_cycles".to_string());
3181
3182 let a = netlist.insert_input("a".into());
3184
3185 let and = netlist.insert_gate_disconnected(
3187 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3188 "and".into(),
3189 );
3190
3191 a.connect(and.get_input(0));
3193 and.get_output(0).connect(and.get_input(1));
3194
3195 let dfs = DFSIterator::new(&netlist, and.clone());
3197 let driven_dfs = NetDFSIterator::new(&netlist, and.get_output(0));
3198
3199 assert!(dfs.detect_cycles());
3200 assert!(driven_dfs.detect_cycles());
3201 }
3202
3203 #[test]
3204 fn test_netdfsiterator_with_boundary() {
3205 let netlist = Netlist::new("dfs_netlist".to_string());
3206
3207 let a = netlist.insert_input("a".into());
3209 let b = netlist.insert_input("b".into());
3210 let c = netlist.insert_input("c".into());
3211 let d = netlist.insert_input("d".into());
3212 let e = netlist.insert_input("e".into());
3213
3214 let n1 = netlist
3216 .insert_gate(
3217 Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into()),
3218 "n1".into(),
3219 &[a.clone(), b.clone()],
3220 )
3221 .unwrap()
3222 .get_output(0);
3223 let n2 = netlist
3224 .insert_gate(
3225 Gate::new_logical("NOR".into(), vec!["A".into(), "B".into()], "Y".into()),
3226 "n2".into(),
3227 &[d.clone(), e.clone()],
3228 )
3229 .unwrap()
3230 .get_output(0);
3231 let n3 = netlist
3232 .insert_gate(
3233 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3234 "n3".into(),
3235 &[n1.clone(), c.clone()],
3236 )
3237 .unwrap()
3238 .get_output(0);
3239 let n4 = netlist
3240 .insert_gate(
3241 Gate::new_logical("NAND".into(), vec!["A".into(), "B".into()], "Y".into()),
3242 "n4".into(),
3243 &[n3.clone(), n2.clone()],
3244 )
3245 .unwrap()
3246 .get_output(0);
3247
3248 let n3_boundary = n3.clone();
3250 let mut dfs =
3251 NetDFSIterator::new_filtered(&netlist, n4.clone(), move |n| *n == n3_boundary);
3252 assert_eq!(dfs.next(), Some(n4));
3253 assert_eq!(dfs.next(), Some(n2));
3254 assert_eq!(dfs.next(), Some(e));
3255 assert_eq!(dfs.next(), Some(d));
3256 assert_eq!(dfs.next(), Some(n3));
3257 assert_eq!(dfs.next(), None);
3258 }
3259
3260 #[test]
3261 fn test_dfs_convergence() {
3262 let netlist = GateNetlist::new("example".to_string());
3263 let gate = Gate::new_logical_multi(
3264 "FA".into(),
3265 vec!["A".into(), "B".into()],
3266 vec!["S".into(), "COUT".into()],
3267 );
3268 let a = netlist.insert_input("a".into());
3269 let b = netlist.insert_input("b".into());
3270 let gate = netlist.insert_gate(gate, "g".into(), &[a, b]).unwrap();
3271 let s = gate.get_output(0);
3272 let c = gate.get_output(1);
3273 let gate = Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into());
3274 let d = netlist.insert_gate(gate, "h".into(), &[s, c]).unwrap();
3275
3276 let dfs = NetDFSIterator::new(&netlist, d.get_output(0));
3277 let c = dfs.count();
3278 assert_eq!(c, 5);
3279
3280 let dfs = DFSIterator::new(&netlist, d.clone());
3281 let c = dfs.count();
3282 assert_eq!(c, 4);
3283 }
3284
3285 #[test]
3286 fn test_operand_comparison() {
3287 let a = Operand::CellIndex(3, 0);
3288 let b = Operand::DirectIndex(3);
3289 assert_eq!(a.cmp(&b), std::cmp::Ordering::Greater);
3290 assert_eq!(b.cmp(&a), std::cmp::Ordering::Less);
3291 }
3292}
3293#[cfg(feature = "serde")]
3294pub mod serde {
3296 use super::{Netlist, Operand, OwnedObject, WeakIndex};
3297 use crate::{
3298 attribute::{AttributeKey, AttributeValue},
3299 circuit::{Instantiable, Net, Object},
3300 };
3301 use serde::{Deserialize, Serialize, de::DeserializeOwned};
3302 use std::cell::RefCell;
3303 use std::{
3304 collections::{BTreeMap, BTreeSet},
3305 rc::Rc,
3306 };
3307
3308 #[derive(Debug, Serialize, Deserialize)]
3309 struct SerdeObject<I>
3310 where
3311 I: Instantiable + Serialize,
3312 {
3313 object: Object<I>,
3315 operands: Vec<Option<Operand>>,
3317 attributes: BTreeMap<AttributeKey, AttributeValue>,
3319 }
3320
3321 impl<I, O> From<OwnedObject<I, O>> for SerdeObject<I>
3322 where
3323 I: Instantiable + Serialize,
3324 O: WeakIndex<usize, Output = OwnedObject<I, O>>,
3325 {
3326 fn from(value: OwnedObject<I, O>) -> Self {
3327 SerdeObject {
3328 object: value.object,
3329 operands: value.operands,
3330 attributes: value.attributes,
3331 }
3332 }
3333 }
3334
3335 impl<I> SerdeObject<I>
3336 where
3337 I: Instantiable + Serialize,
3338 {
3339 fn into_owned_object<O>(self, owner: &Rc<O>, index: usize) -> OwnedObject<I, O>
3340 where
3341 O: WeakIndex<usize, Output = OwnedObject<I, O>>,
3342 {
3343 OwnedObject {
3344 object: self.object,
3345 owner: Rc::downgrade(owner),
3346 operands: self.operands,
3347 attributes: self.attributes,
3348 index,
3349 }
3350 }
3351 }
3352
3353 #[derive(Debug, Serialize, Deserialize)]
3354 struct SerdeNetlist<I>
3355 where
3356 I: Instantiable + Serialize,
3357 {
3358 name: String,
3360 objects: Vec<SerdeObject<I>>,
3362 outputs: BTreeMap<String, BTreeSet<Net>>,
3366 }
3367
3368 impl<I> From<Netlist<I>> for SerdeNetlist<I>
3369 where
3370 I: Instantiable + Serialize,
3371 {
3372 fn from(value: Netlist<I>) -> Self {
3373 SerdeNetlist {
3374 name: value.name.into_inner(),
3375 objects: value
3376 .objects
3377 .into_inner()
3378 .into_iter()
3379 .map(|o| {
3380 Rc::try_unwrap(o)
3381 .ok()
3382 .expect("Cannot serialize with live references")
3383 .into_inner()
3384 .into()
3385 })
3386 .collect(),
3387 outputs: value
3388 .outputs
3389 .into_inner()
3390 .into_iter()
3391 .map(|(o, nets)| (o.to_string(), nets.into_iter().collect()))
3393 .collect(),
3394 }
3395 }
3396 }
3397
3398 impl<I> SerdeNetlist<I>
3399 where
3400 I: Instantiable + Serialize,
3401 {
3402 fn into_netlist(self) -> Rc<Netlist<I>> {
3404 let netlist = Netlist::new(self.name);
3405 let outputs: BTreeMap<Operand, BTreeSet<Net>> = self
3406 .outputs
3407 .into_iter()
3408 .map(|(k, v)| {
3409 let operand = k.parse::<Operand>().expect("Invalid index");
3410 (operand, v.into_iter().collect())
3411 })
3412 .collect();
3413 let objects = self
3414 .objects
3415 .into_iter()
3416 .enumerate()
3417 .map(|(i, o)| {
3418 let owned_object = o.into_owned_object(&netlist, i);
3419 Rc::new(RefCell::new(owned_object))
3420 })
3421 .collect::<Vec<_>>();
3422 {
3423 let mut objs_mut = netlist.objects.borrow_mut();
3424 *objs_mut = objects;
3425 let mut outputs_mut = netlist.outputs.borrow_mut();
3426 *outputs_mut = outputs;
3427 }
3428 netlist
3429 }
3430 }
3431
3432 pub fn netlist_serialize<I: Instantiable + Serialize>(
3434 netlist: Netlist<I>,
3435 writer: impl std::io::Write,
3436 ) -> Result<(), serde_json::Error> {
3437 let sobj: SerdeNetlist<I> = netlist.into();
3438 serde_json::to_writer_pretty(writer, &sobj)
3439 }
3440
3441 pub fn netlist_deserialize<I: Instantiable + Serialize + DeserializeOwned>(
3443 reader: impl std::io::Read,
3444 ) -> Result<Rc<Netlist<I>>, serde_json::Error> {
3445 let sobj: SerdeNetlist<I> = serde_json::from_reader(reader)?;
3446 Ok(sobj.into_netlist())
3447 }
3448}