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) -> &[Net] {
48 &self.inputs
49 }
50
51 fn get_output_ports(&self) -> &[Net] {
52 &self.outputs
53 }
54
55 fn get_parameter(&self, _id: &Identifier) -> Option<Parameter> {
56 None
57 }
58
59 fn set_parameter(&mut self, _id: &Identifier, _val: Parameter) -> Option<Parameter> {
60 panic!("Gate does not support parameters");
61 }
62
63 fn clear_parameter(&mut self, _id: &Identifier) -> Option<Parameter> {
64 None
65 }
66
67 fn parameters(&self) -> Vec<(Identifier, Parameter)> {
68 Vec::new()
69 }
70
71 fn from_constant(val: Logic) -> Option<Self> {
72 match val {
73 Logic::True => Some(Gate::new_logical("VDD".into(), vec![], "Y".into())),
74 Logic::False => Some(Gate::new_logical("GND".into(), vec![], "Y".into())),
75 _ => None,
76 }
77 }
78
79 fn get_constant(&self) -> Option<Logic> {
80 match self.name.to_string().as_str() {
81 "VDD" => Some(Logic::True),
82 "GND" => Some(Logic::False),
83 _ => None,
84 }
85 }
86
87 fn is_seq(&self) -> bool {
88 false
89 }
90}
91
92impl Gate {
93 pub fn new_logical(name: Identifier, inputs: Vec<Identifier>, output: Identifier) -> Self {
95 if name.is_sliced() {
96 panic!("Attempted to create a gate with a sliced identifier: {name}");
97 }
98
99 let outputs = vec![Net::new_logic(output)];
100 let inputs = inputs.into_iter().map(Net::new_logic).collect::<Vec<_>>();
101 Self {
102 name,
103 inputs,
104 outputs,
105 }
106 }
107
108 pub fn new_logical_multi(
110 name: Identifier,
111 inputs: Vec<Identifier>,
112 outputs: Vec<Identifier>,
113 ) -> Self {
114 if name.is_sliced() {
115 panic!("Attempted to create a gate with a sliced identifier: {name}");
116 }
117
118 let outputs = outputs.into_iter().map(Net::new_logic).collect::<Vec<_>>();
119 let inputs = inputs.into_iter().map(Net::new_logic).collect::<Vec<_>>();
120 Self {
121 name,
122 inputs,
123 outputs,
124 }
125 }
126
127 pub fn get_single_output_port(&self) -> &Net {
129 if self.outputs.len() > 1 {
130 panic!("Attempted to grab output port of a multi-output gate");
131 }
132 self.outputs
133 .first()
134 .expect("Gate is missing an output port")
135 }
136
137 pub fn set_gate_name(&mut self, new_name: Identifier) {
139 self.name = new_name;
140 }
141
142 pub fn get_gate_name(&self) -> &Identifier {
144 &self.name
145 }
146}
147
148#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
150#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
151enum Operand {
152 DirectIndex(usize),
154 CellIndex(usize, usize),
156}
157
158impl Ord for Operand {
159 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
160 match (self, other) {
161 (Operand::DirectIndex(a), Operand::DirectIndex(b)) => a.cmp(b),
162 (Operand::CellIndex(a, b), Operand::CellIndex(c, d)) => (a, b).cmp(&(c, d)),
163 (Operand::DirectIndex(a), Operand::CellIndex(c, d)) => {
164 if a == c && *d == 0 {
165 std::cmp::Ordering::Less
166 } else {
167 (a, &0).cmp(&(c, d))
168 }
169 }
170 (Operand::CellIndex(a, b), Operand::DirectIndex(c)) => {
171 if a == c && *b == 0 {
172 std::cmp::Ordering::Greater
173 } else {
174 (a, b).cmp(&(c, &0))
175 }
176 }
177 }
178 }
179}
180
181impl PartialOrd for Operand {
182 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
183 Some(self.cmp(other))
184 }
185}
186
187impl Operand {
188 fn remap(self, x: usize) -> Self {
190 match self {
191 Operand::DirectIndex(_idx) => Operand::DirectIndex(x),
192 Operand::CellIndex(_idx, j) => Operand::CellIndex(x, j),
193 }
194 }
195
196 fn root(&self) -> usize {
198 match self {
199 Operand::DirectIndex(idx) => *idx,
200 Operand::CellIndex(idx, _) => *idx,
201 }
202 }
203
204 fn secondary(&self) -> usize {
206 match self {
207 Operand::DirectIndex(_) => 0,
208 Operand::CellIndex(_, j) => *j,
209 }
210 }
211}
212
213impl std::fmt::Display for Operand {
214 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
215 match self {
216 Operand::DirectIndex(idx) => write!(f, "{idx}"),
217 Operand::CellIndex(idx, j) => write!(f, "{idx}.{j}"),
218 }
219 }
220}
221
222impl std::str::FromStr for Operand {
223 type Err = ParseIntError;
224
225 fn from_str(s: &str) -> Result<Self, Self::Err> {
226 match s.split_once('.') {
227 Some((idx, j)) => {
228 let idx = idx.parse::<usize>()?;
229 let j = j.parse::<usize>()?;
230 Ok(Operand::CellIndex(idx, j))
231 }
232 None => {
233 let idx = s.parse::<usize>()?;
234 Ok(Operand::DirectIndex(idx))
235 }
236 }
237 }
238}
239
240#[derive(Debug)]
242struct OwnedObject<I, O>
243where
244 I: Instantiable,
245 O: WeakIndex<usize, Output = Self>,
246{
247 object: Object<I>,
249 owner: Weak<O>,
251 operands: Vec<Option<Operand>>,
253 attributes: BTreeMap<AttributeKey, AttributeValue>,
255 index: usize,
257}
258
259impl<I, O> OwnedObject<I, O>
260where
261 I: Instantiable,
262 O: WeakIndex<usize, Output = Self>,
263{
264 fn inds_mut(&mut self) -> impl Iterator<Item = &mut Operand> {
266 self.operands
267 .iter_mut()
268 .filter_map(|operand| operand.as_mut())
269 }
270
271 fn get_driver(&self, index: usize) -> Option<Rc<RefCell<Self>>> {
273 self.operands[index].as_ref().map(|operand| {
274 self.owner
275 .upgrade()
276 .expect("Object is unlinked from netlist")
277 .index_weak(&operand.root())
278 })
279 }
280
281 fn drivers(&self) -> impl Iterator<Item = Option<Rc<RefCell<Self>>>> {
283 self.operands.iter().map(|operand| {
284 operand.as_ref().map(|operand| {
285 self.owner
286 .upgrade()
287 .expect("Object is unlinked from netlist")
288 .index_weak(&operand.root())
289 })
290 })
291 }
292
293 fn driver_nets(&self) -> impl Iterator<Item = Option<Net>> {
295 self.operands.iter().map(|operand| {
296 operand.as_ref().map(|operand| match operand {
297 Operand::DirectIndex(idx) => self
298 .owner
299 .upgrade()
300 .expect("Object is unlinked from netlist")
301 .index_weak(idx)
302 .borrow()
303 .as_net()
304 .clone(),
305 Operand::CellIndex(idx, j) => self
306 .owner
307 .upgrade()
308 .expect("Object is unlinked from netlist")
309 .index_weak(idx)
310 .borrow()
311 .get_net(*j)
312 .clone(),
313 })
314 })
315 }
316
317 fn get(&self) -> &Object<I> {
319 &self.object
320 }
321
322 fn get_mut(&mut self) -> &mut Object<I> {
324 &mut self.object
325 }
326
327 fn get_index(&self) -> usize {
329 self.index
330 }
331
332 fn as_net(&self) -> &Net {
334 match &self.object {
335 Object::Input(net) => net,
336 Object::Instance(nets, _, _) => {
337 if nets.len() > 1 {
338 panic!("Attempt to grab the net of a multi-output instance");
339 } else {
340 nets.first().expect("Instance is missing a net to drive")
341 }
342 }
343 }
344 }
345
346 fn as_net_mut(&mut self) -> &mut Net {
348 match &mut self.object {
349 Object::Input(net) => net,
350 Object::Instance(nets, _, _) => {
351 if nets.len() > 1 {
352 panic!("Attempt to grab the net of a multi-output instance");
353 } else {
354 nets.first_mut()
355 .expect("Instance is missing a net to drive")
356 }
357 }
358 }
359 }
360
361 fn get_net(&self, idx: usize) -> &Net {
363 match &self.object {
364 Object::Input(net) => {
365 if idx != 0 {
366 panic!("Nonzero index on an input object");
367 }
368 net
369 }
370 Object::Instance(nets, _, _) => &nets[idx],
371 }
372 }
373
374 fn get_net_mut(&mut self, idx: usize) -> &mut Net {
376 match &mut self.object {
377 Object::Input(net) => {
378 if idx != 0 {
379 panic!("Nonzero index on an input object");
380 }
381 net
382 }
383 Object::Instance(nets, _, _) => &mut nets[idx],
384 }
385 }
386
387 fn find_net(&self, net: &Net) -> Option<usize> {
389 match &self.object {
390 Object::Input(input_net) => {
391 if input_net == net {
392 Some(0)
393 } else {
394 None
395 }
396 }
397 Object::Instance(nets, _, _) => nets.iter().position(|n| n == net),
398 }
399 }
400
401 fn find_net_mut(&mut self, net: &Net) -> Option<&mut Net> {
403 match &mut self.object {
404 Object::Input(input_net) => {
405 if input_net == net {
406 Some(input_net)
407 } else {
408 None
409 }
410 }
411 Object::Instance(nets, _, _) => nets.iter_mut().find(|n| *n == net),
412 }
413 }
414
415 fn get_driver_net(&self, index: usize) -> Option<Net> {
421 let operand = &self.operands[index];
422 match operand {
423 Some(op) => match op {
424 Operand::DirectIndex(idx) => self
425 .owner
426 .upgrade()
427 .expect("Object is unlinked from netlist")
428 .index_weak(idx)
429 .borrow()
430 .as_net()
431 .clone()
432 .into(),
433 Operand::CellIndex(idx, j) => self
434 .owner
435 .upgrade()
436 .expect("Object is unlinked from netlist")
437 .index_weak(idx)
438 .borrow()
439 .get_net(*j)
440 .clone()
441 .into(),
442 },
443 None => None,
444 }
445 }
446
447 fn clear_attribute(&mut self, k: &AttributeKey) -> Option<AttributeValue> {
448 self.attributes.remove(k)
449 }
450
451 fn set_attribute(&mut self, k: AttributeKey) {
452 self.attributes.insert(k, None);
453 }
454
455 fn insert_attribute(&mut self, k: AttributeKey, v: Parameter) -> Option<AttributeValue> {
456 self.attributes.insert(k, Some(v))
457 }
458
459 fn attributes(&self) -> impl Iterator<Item = Attribute> {
460 Attribute::from_pairs(self.attributes.clone().into_iter())
461 }
462}
463
464type NetRefT<I> = Rc<RefCell<OwnedObject<I, Netlist<I>>>>;
466
467#[derive(Clone)]
470pub struct NetRef<I>
471where
472 I: Instantiable,
473{
474 netref: NetRefT<I>,
475}
476
477impl<I> std::fmt::Debug for NetRef<I>
478where
479 I: Instantiable,
480{
481 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
482 let b = self.netref.borrow();
483 let o = b.get();
484 let i = b.index;
485 let owner = &b.owner;
486 match owner.upgrade() {
487 Some(owner) => {
488 let n = owner.get_name();
489 write!(f, "{{ owner: \"{n}\", index: {i}, val: \"{o}\" }}")
490 }
491 None => write!(f, "{{ owner: None, index: {i}, val: \"{o}\" }}"),
492 }
493 }
494}
495
496impl<I> PartialEq for NetRef<I>
497where
498 I: Instantiable,
499{
500 fn eq(&self, other: &Self) -> bool {
501 Rc::ptr_eq(&self.netref, &other.netref)
502 }
503}
504
505impl<I> Eq for NetRef<I> where I: Instantiable {}
506
507impl<I> Ord for NetRef<I>
508where
509 I: Instantiable,
510{
511 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
512 Rc::as_ptr(&self.netref).cmp(&Rc::as_ptr(&other.netref))
513 }
514}
515
516impl<I> PartialOrd for NetRef<I>
517where
518 I: Instantiable,
519{
520 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
521 Some(self.cmp(other))
522 }
523}
524
525impl<I> std::hash::Hash for NetRef<I>
526where
527 I: Instantiable,
528{
529 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
530 Rc::as_ptr(&self.netref).hash(state);
531 }
532}
533
534impl<I> NetRef<I>
535where
536 I: Instantiable,
537{
538 fn wrap(netref: NetRefT<I>) -> Self {
540 Self { netref }
541 }
542
543 fn unwrap(self) -> NetRefT<I> {
545 self.netref
546 }
547
548 fn owner(&self) -> Rc<Netlist<I>> {
550 self.netref
551 .borrow()
552 .owner
553 .upgrade()
554 .expect("NetRef is unlinked from netlist")
555 }
556
557 pub fn as_net(&self) -> Ref<'_, Net> {
563 Ref::map(self.netref.borrow(), |f| f.as_net())
564 }
565
566 pub fn as_net_mut(&self) -> RefMut<'_, Net> {
572 RefMut::map(self.netref.borrow_mut(), |f| f.as_net_mut())
573 }
574
575 pub fn get_net(&self, idx: usize) -> Ref<'_, Net> {
577 Ref::map(self.netref.borrow(), |f| f.get_net(idx))
578 }
579
580 pub fn get_net_mut(&self, idx: usize) -> RefMut<'_, Net> {
582 RefMut::map(self.netref.borrow_mut(), |f| f.get_net_mut(idx))
583 }
584
585 pub fn get_output(&self, idx: usize) -> DrivenNet<I> {
591 let len = self.netref.borrow().get().get_nets().len();
592 if idx >= len {
593 panic!("Output index {idx} is out of bounds for circuit node with {len} outputs");
594 }
595 DrivenNet::new(idx, self.clone())
596 }
597
598 pub fn find_output(&self, id: &Identifier) -> Option<DrivenNet<I>> {
600 let ind = self.get_instance_type()?.find_output(id)?;
601 Some(self.get_output(ind))
602 }
603
604 pub fn get_input(&self, idx: usize) -> InputPort<I> {
610 if self.is_an_input() {
611 panic!("Principal inputs do not have inputs");
612 }
613 let len = self.netref.borrow().operands.len();
614 if idx >= len {
615 panic!("Input index {idx} is out of bounds for circuit node with {len} inputs");
616 }
617 InputPort::new(idx, self.clone())
618 }
619
620 pub fn find_input(&self, id: &Identifier) -> Option<InputPort<I>> {
622 let ind = self.get_instance_type()?.find_input(id)?;
623 Some(self.get_input(ind))
624 }
625
626 pub fn get_identifier(&self) -> Identifier {
632 self.as_net().get_identifier().clone()
633 }
634
635 pub fn set_identifier(&self, identifier: Identifier) {
641 self.as_net_mut().set_identifier(identifier)
642 }
643
644 pub fn is_an_input(&self) -> bool {
646 matches!(self.netref.borrow().get(), Object::Input(_))
647 }
648
649 pub fn get_obj(&self) -> Ref<'_, Object<I>> {
651 Ref::map(self.netref.borrow(), |f| f.get())
652 }
653
654 pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
656 Ref::filter_map(self.netref.borrow(), |f| f.get().get_instance_type()).ok()
657 }
658
659 pub fn get_instance_type_mut(&self) -> Option<RefMut<'_, I>> {
661 RefMut::filter_map(self.netref.borrow_mut(), |f| {
662 f.get_mut().get_instance_type_mut()
663 })
664 .ok()
665 }
666
667 pub fn get_instance_name(&self) -> Option<Identifier> {
669 match self.netref.borrow().get() {
670 Object::Instance(_, inst_name, _) => Some(inst_name.clone()),
671 _ => None,
672 }
673 }
674
675 pub fn set_instance_name(&self, name: Identifier) {
681 match self.netref.borrow_mut().get_mut() {
682 Object::Instance(_, inst_name, _) => *inst_name = name,
683 _ => panic!("Attempted to set instance name on a non-instance object"),
684 }
685 }
686
687 pub fn expose_as_output(self) -> Result<Self, Error> {
695 let netlist = self.owner();
696 netlist.expose_net(self.clone().into())?;
697 Ok(self)
698 }
699
700 pub fn expose_with_name(self, name: Identifier) -> Self {
708 let netlist = self.owner();
709 netlist.expose_net_with_name(self.clone().into(), name);
710 self
711 }
712
713 pub fn expose_net(&self, net: &Net) -> Result<(), Error> {
719 let netlist = self.owner();
720 let net_index = self
721 .netref
722 .borrow()
723 .find_net(net)
724 .ok_or(Error::NetNotFound(net.clone()))?;
725 let dr = DrivenNet::new(net_index, self.clone());
726 netlist.expose_net(dr)?;
727 Ok(())
728 }
729
730 pub fn remove_output(&self, net_name: &Identifier) -> bool {
738 let netlist = self.owner();
739 netlist.remove_output(&self.into(), net_name)
740 }
741
742 pub fn remove_all_outputs(&self) -> usize {
750 let netlist = self.owner();
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 get_num_input_ports(&self) -> usize {
770 if let Some(inst_type) = self.get_instance_type() {
771 inst_type.get_input_ports().iter().count()
772 } else {
773 0
774 }
775 }
776
777 pub fn is_fully_connected(&self) -> bool {
779 assert_eq!(
780 self.netref.borrow().operands.len(),
781 self.get_num_input_ports()
782 );
783 self.netref.borrow().operands.iter().all(|o| o.is_some())
784 }
785
786 pub fn drivers(&self) -> impl Iterator<Item = Option<Self>> {
788 let drivers: Vec<Option<Self>> = self
789 .netref
790 .borrow()
791 .drivers()
792 .map(|o| o.map(NetRef::wrap))
793 .collect();
794 drivers.into_iter()
795 }
796
797 pub fn driver_nets(&self) -> impl Iterator<Item = Option<Net>> {
799 let vec: Vec<Option<Net>> = self.netref.borrow().driver_nets().collect();
800 vec.into_iter()
801 }
802
803 #[allow(clippy::unnecessary_to_owned)]
805 pub fn nets(&self) -> impl Iterator<Item = Net> {
806 self.netref.borrow().get().get_nets().to_vec().into_iter()
807 }
808
809 pub fn inputs(&self) -> impl Iterator<Item = InputPort<I>> {
811 let len = self.netref.borrow().operands.len();
812 (0..len).map(move |i| InputPort::new(i, self.clone()))
813 }
814
815 pub fn outputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
817 let len = self.netref.borrow().get().get_nets().len();
818 (0..len).map(move |i| DrivenNet::new(i, self.clone()))
819 }
820
821 pub fn nets_mut(&self) -> impl Iterator<Item = RefMut<'_, Net>> {
823 let nnets = self.netref.borrow().get().get_nets().len();
824 (0..nnets).map(|i| self.get_net_mut(i))
825 }
826
827 pub fn drives_net(&self, net: &Net) -> bool {
829 self.netref.borrow().find_net(net).is_some()
830 }
831
832 pub fn drives_a_top_output(&self) -> bool {
837 let netlist = self.owner();
838 netlist.drives_an_output(self.clone())
839 }
840
841 pub fn find_net_mut(&self, net: &Net) -> Option<RefMut<'_, Net>> {
843 RefMut::filter_map(self.netref.borrow_mut(), |f| f.find_net_mut(net)).ok()
844 }
845
846 pub fn is_multi_output(&self) -> bool {
848 self.netref.borrow().get().get_nets().len() > 1
849 }
850
851 pub fn delete_uses(self) -> Result<Object<I>, Error> {
857 let netlist = self.owner();
858 netlist.delete_net_uses(self)
859 }
860
861 pub fn replace_uses_with(self, other: &DrivenNet<I>) -> Result<NetRef<I>, Error> {
871 let netlist = self.owner();
872 netlist
873 .replace_net_uses(self.into(), other)
874 .map(|d| d.unwrap())
875 }
876
877 pub fn clear_attribute(&self, k: &AttributeKey) -> Option<AttributeValue> {
879 self.netref.borrow_mut().clear_attribute(k)
880 }
881
882 pub fn set_attribute(&self, k: AttributeKey) {
884 self.netref.borrow_mut().set_attribute(k);
885 }
886
887 pub fn insert_attribute(&self, k: AttributeKey, v: Parameter) -> Option<AttributeValue> {
889 self.netref.borrow_mut().insert_attribute(k, v)
890 }
891
892 pub fn attributes(&self) -> impl Iterator<Item = Attribute> {
894 let v: Vec<_> = self.netref.borrow().attributes().collect();
895 v.into_iter()
896 }
897}
898
899impl<I> std::fmt::Display for NetRef<I>
900where
901 I: Instantiable,
902{
903 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
904 self.netref.borrow().object.fmt(f)
905 }
906}
907
908impl<I> From<NetRef<I>> for DrivenNet<I>
909where
910 I: Instantiable,
911{
912 fn from(val: NetRef<I>) -> Self {
913 if val.is_multi_output() {
914 panic!("Cannot convert a multi-output netref to an output port");
915 }
916 DrivenNet::new(0, val)
917 }
918}
919
920impl<I> From<&NetRef<I>> for DrivenNet<I>
921where
922 I: Instantiable,
923{
924 fn from(val: &NetRef<I>) -> Self {
925 if val.is_multi_output() {
926 panic!("Cannot convert a multi-output netref to an output port");
927 }
928 DrivenNet::new(0, val.clone())
929 }
930}
931
932#[derive(Debug)]
934pub struct Netlist<I>
935where
936 I: Instantiable,
937{
938 name: RefCell<Identifier>,
940 objects: RefCell<Vec<NetRefT<I>>>,
942 outputs: RefCell<BTreeMap<Operand, BTreeSet<Net>>>,
944}
945
946#[derive(Debug, Clone)]
948pub struct InputPort<I: Instantiable> {
949 pos: usize,
950 netref: NetRef<I>,
951}
952
953impl<I> InputPort<I>
954where
955 I: Instantiable,
956{
957 fn new(pos: usize, netref: NetRef<I>) -> Self {
958 if pos >= netref.clone().unwrap().borrow().operands.len() {
959 panic!(
960 "Position {} out of bounds for netref with {} input nets",
961 pos,
962 netref.unwrap().borrow().get().get_nets().len()
963 );
964 }
965 Self { pos, netref }
966 }
967
968 pub fn get_driver(&self) -> Option<DrivenNet<I>> {
970 if self.netref.is_an_input() {
971 panic!("Input port is not driven by a primitive");
972 }
973 if let Some(prev_operand) = self.netref.clone().unwrap().borrow().operands[self.pos] {
974 let netlist = self
975 .netref
976 .clone()
977 .unwrap()
978 .borrow()
979 .owner
980 .upgrade()
981 .expect("Input port is unlinked from netlist");
982 let driver_nr = netlist.index_weak(&prev_operand.root());
983 let nr = NetRef::wrap(driver_nr);
984 let pos = prev_operand.secondary();
985 Some(DrivenNet::new(pos, nr))
986 } else {
987 None
988 }
989 }
990
991 pub fn disconnect(&self) -> Option<DrivenNet<I>> {
993 let val = self.get_driver();
994 self.netref.clone().unwrap().borrow_mut().operands[self.pos] = None;
995 val
996 }
997
998 pub fn get_port(&self) -> Net {
1000 if self.netref.is_an_input() {
1001 panic!("Net is not driven by a primitive");
1002 }
1003 self.netref
1004 .get_instance_type()
1005 .unwrap()
1006 .get_input_port(self.pos)
1007 .clone()
1008 }
1009
1010 pub fn connect(self, output: DrivenNet<I>) {
1012 output.connect(self);
1013 }
1014
1015 pub fn unwrap(self) -> NetRef<I> {
1017 self.netref
1018 }
1019
1020 pub fn get_input_num(&self) -> usize {
1022 self.pos
1023 }
1024}
1025
1026impl<I> std::fmt::Display for InputPort<I>
1027where
1028 I: Instantiable,
1029{
1030 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1031 self.get_port().fmt(f)
1032 }
1033}
1034
1035#[derive(Debug, Clone)]
1037pub struct DrivenNet<I: Instantiable> {
1038 pos: usize,
1039 netref: NetRef<I>,
1040}
1041
1042impl<I> DrivenNet<I>
1043where
1044 I: Instantiable,
1045{
1046 fn new(pos: usize, netref: NetRef<I>) -> Self {
1047 if pos >= netref.clone().unwrap().borrow().get().get_nets().len() {
1048 panic!(
1049 "Position {} out of bounds for netref with {} outputted nets",
1050 pos,
1051 netref.unwrap().borrow().get().get_nets().len()
1052 );
1053 }
1054 Self { pos, netref }
1055 }
1056
1057 fn get_operand(&self) -> Operand {
1059 if self.netref.is_multi_output() {
1060 Operand::CellIndex(self.netref.clone().unwrap().borrow().get_index(), self.pos)
1061 } else {
1062 Operand::DirectIndex(self.netref.clone().unwrap().borrow().get_index())
1063 }
1064 }
1065
1066 pub fn as_net(&self) -> Ref<'_, Net> {
1068 self.netref.get_net(self.pos)
1069 }
1070
1071 pub fn as_net_mut(&self) -> RefMut<'_, Net> {
1073 self.netref.get_net_mut(self.pos)
1074 }
1075
1076 pub fn is_an_input(&self) -> bool {
1078 self.netref.is_an_input()
1079 }
1080
1081 pub fn get_port(&self) -> Net {
1083 if self.netref.is_an_input() {
1084 panic!("Net is not driven by a primitive");
1085 }
1086 self.netref
1087 .get_instance_type()
1088 .unwrap()
1089 .get_output_port(self.pos)
1090 .clone()
1091 }
1092
1093 pub fn connect(&self, input: InputPort<I>) {
1095 let operand = self.get_operand();
1096 let index = input.netref.unwrap().borrow().get_index();
1097 let netlist = self
1098 .netref
1099 .clone()
1100 .unwrap()
1101 .borrow()
1102 .owner
1103 .upgrade()
1104 .expect("Output port is unlinked from netlist");
1105 let obj = netlist.index_weak(&index);
1106 obj.borrow_mut().operands[input.pos] = Some(operand);
1107 }
1108
1109 pub fn is_top_level_output(&self) -> bool {
1111 let netlist = self
1112 .netref
1113 .clone()
1114 .unwrap()
1115 .borrow()
1116 .owner
1117 .upgrade()
1118 .expect("DrivenNet is unlinked from netlist");
1119 let outputs = netlist.outputs.borrow();
1120 outputs.contains_key(&self.get_operand())
1121 }
1122
1123 pub fn unwrap(self) -> NetRef<I> {
1125 self.netref
1126 }
1127
1128 pub fn get_identifier(&self) -> Identifier {
1130 self.as_net().get_identifier().clone()
1131 }
1132
1133 pub fn expose_with_name(self, name: Identifier) -> Self {
1140 let netlist = self
1141 .netref
1142 .clone()
1143 .unwrap()
1144 .borrow()
1145 .owner
1146 .upgrade()
1147 .expect("DrivenNet is unlinked from netlist");
1148 netlist.expose_net_with_name(self.clone(), name);
1149 self
1150 }
1151
1152 pub fn remove_output(&self, net_name: &Identifier) -> bool {
1159 let netlist = self
1160 .netref
1161 .clone()
1162 .unwrap()
1163 .borrow()
1164 .owner
1165 .upgrade()
1166 .expect("DrivenNet is unlinked from netlist");
1167 netlist.remove_output(self, net_name)
1168 }
1169
1170 pub fn remove_all_outputs(&self) -> usize {
1177 let netlist = self
1178 .netref
1179 .clone()
1180 .unwrap()
1181 .borrow()
1182 .owner
1183 .upgrade()
1184 .expect("DrivenNet is unlinked from netlist");
1185 netlist.remove_outputs(self)
1186 }
1187
1188 pub fn get_output_index(&self) -> Option<usize> {
1190 if self.netref.is_an_input() {
1191 None
1192 } else {
1193 Some(self.pos)
1194 }
1195 }
1196
1197 pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
1199 self.netref.get_instance_type()
1200 }
1201}
1202
1203impl<I> std::fmt::Display for DrivenNet<I>
1204where
1205 I: Instantiable,
1206{
1207 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1208 self.as_net().fmt(f)
1209 }
1210}
1211
1212impl<I> PartialEq for DrivenNet<I>
1213where
1214 I: Instantiable,
1215{
1216 fn eq(&self, other: &Self) -> bool {
1217 self.netref == other.netref && self.pos == other.pos
1218 }
1219}
1220
1221impl<I> Eq for DrivenNet<I> where I: Instantiable {}
1222
1223impl<I> std::hash::Hash for DrivenNet<I>
1224where
1225 I: Instantiable,
1226{
1227 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1228 self.netref.hash(state);
1229 self.pos.hash(state);
1230 }
1231}
1232
1233impl<I> Ord for DrivenNet<I>
1234where
1235 I: Instantiable,
1236{
1237 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
1238 match self.netref.cmp(&other.netref) {
1239 std::cmp::Ordering::Equal => self.pos.cmp(&other.pos),
1240 ord => ord,
1241 }
1242 }
1243}
1244
1245impl<I> PartialOrd for DrivenNet<I>
1246where
1247 I: Instantiable,
1248{
1249 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1250 Some(self.cmp(other))
1251 }
1252}
1253
1254impl<I> WeakIndex<usize> for Netlist<I>
1255where
1256 I: Instantiable,
1257{
1258 type Output = OwnedObject<I, Self>;
1259
1260 fn index_weak(&self, index: &usize) -> Rc<RefCell<Self::Output>> {
1261 self.objects.borrow()[*index].clone()
1262 }
1263}
1264
1265impl<I> Netlist<I>
1266where
1267 I: Instantiable,
1268{
1269 pub fn new(name: Identifier) -> Rc<Self> {
1271 Rc::new(Self {
1272 name: RefCell::new(name),
1273 objects: RefCell::new(Vec::new()),
1274 outputs: RefCell::new(BTreeMap::new()),
1275 })
1276 }
1277
1278 pub fn try_unlink(self: Rc<Self>) -> Result<Self, Rc<Self>> {
1280 Rc::try_unwrap(self)
1281 }
1282
1283 pub fn deep_clone(&self) -> Rc<Self> {
1285 let dc = Rc::new(Self {
1286 name: self.name.clone(),
1287 objects: RefCell::new(Vec::new()),
1288 outputs: self.outputs.clone(),
1289 });
1290
1291 let objects_linked: Vec<NetRefT<I>> = self
1292 .objects
1293 .borrow()
1294 .iter()
1295 .map(|obj| {
1296 let b = obj.borrow();
1297 Rc::new(RefCell::new(OwnedObject {
1298 object: b.object.clone(),
1299 owner: Rc::downgrade(&dc),
1300 operands: b.operands.clone(),
1301 attributes: b.attributes.clone(),
1302 index: b.index,
1303 }))
1304 })
1305 .collect();
1306
1307 *dc.objects.borrow_mut() = objects_linked;
1308
1309 dc
1310 }
1311
1312 fn insert_object(
1317 self: &Rc<Self>,
1318 object: Object<I>,
1319 operands: &[DrivenNet<I>],
1320 ) -> Result<NetRef<I>, Error> {
1321 for operand in operands {
1322 self.belongs(&operand.clone().unwrap());
1323 }
1324 let index = self.objects.borrow().len();
1325 let weak = Rc::downgrade(self);
1326 let operands = operands
1327 .iter()
1328 .map(|net| Some(net.get_operand()))
1329 .collect::<Vec<_>>();
1330 let owned_object = Rc::new(RefCell::new(OwnedObject {
1331 object,
1332 owner: weak,
1333 operands,
1334 attributes: BTreeMap::new(),
1335 index,
1336 }));
1337 self.objects.borrow_mut().push(owned_object.clone());
1338 Ok(NetRef::wrap(owned_object))
1339 }
1340
1341 pub fn insert_input(self: &Rc<Self>, net: Net) -> DrivenNet<I> {
1343 let obj = Object::Input(net);
1344 self.insert_object(obj, &[]).unwrap().into()
1345 }
1346
1347 pub fn insert_input_logic_bus(self: &Rc<Self>, net: String, bw: usize) -> Vec<DrivenNet<I>> {
1349 Net::new_logic_bus(net, bw)
1350 .into_iter()
1351 .map(|n| self.insert_input(n))
1352 .collect()
1353 }
1354
1355 pub fn insert_gate(
1357 self: &Rc<Self>,
1358 inst_type: I,
1359 inst_name: Identifier,
1360 operands: &[DrivenNet<I>],
1361 ) -> Result<NetRef<I>, Error> {
1362 let nets = inst_type
1363 .get_output_ports()
1364 .iter()
1365 .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1366 .collect::<Vec<_>>();
1367 let input_count = inst_type.get_input_ports().iter().count();
1368 if operands.len() != input_count {
1369 return Err(Error::ArgumentMismatch(input_count, operands.len()));
1370 }
1371 let obj = Object::Instance(nets, inst_name, inst_type);
1372 self.insert_object(obj, operands)
1373 }
1374
1375 pub fn insert_gate_disconnected(
1377 self: &Rc<Self>,
1378 inst_type: I,
1379 inst_name: Identifier,
1380 ) -> NetRef<I> {
1381 let nets = inst_type
1382 .get_output_ports()
1383 .iter()
1384 .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1385 .collect::<Vec<_>>();
1386 let object = Object::Instance(nets, inst_name, inst_type);
1387 let index = self.objects.borrow().len();
1388 let weak = Rc::downgrade(self);
1389 let input_count = object
1390 .get_instance_type()
1391 .unwrap()
1392 .get_input_ports()
1393 .iter()
1394 .count();
1395 let operands = vec![None; input_count];
1396 let owned_object = Rc::new(RefCell::new(OwnedObject {
1397 object,
1398 owner: weak,
1399 operands,
1400 attributes: BTreeMap::new(),
1401 index,
1402 }));
1403 self.objects.borrow_mut().push(owned_object.clone());
1404 NetRef::wrap(owned_object)
1405 }
1406
1407 pub fn insert_constant(
1409 self: &Rc<Self>,
1410 value: Logic,
1411 inst_name: Identifier,
1412 ) -> Result<DrivenNet<I>, Error> {
1413 let obj = I::from_constant(value).ok_or(Error::InstantiableError(format!(
1414 "Instantiable type does not support constant value {}",
1415 value
1416 )))?;
1417 Ok(self.insert_gate_disconnected(obj, inst_name).into())
1418 }
1419
1420 fn belongs(&self, netref: &NetRef<I>) {
1424 if let Some(nl) = netref.netref.borrow().owner.upgrade() {
1425 if self.objects.borrow().len() != nl.objects.borrow().len() {
1426 panic!("NetRef does not belong to this netlist");
1427 }
1428
1429 if let Some(p) = self.objects.borrow().first()
1430 && let Some(np) = nl.objects.borrow().first()
1431 && !Rc::ptr_eq(p, np)
1432 {
1433 panic!("NetRef does not belong to this netlist");
1434 }
1435 }
1436
1437 if netref.netref.borrow().index >= self.objects.borrow().len() {
1438 panic!("NetRef does not belong to this netlist");
1439 }
1440 }
1441
1442 pub fn get_driver(&self, netref: NetRef<I>, index: usize) -> Option<DrivenNet<I>> {
1449 self.belongs(&netref);
1450 let op = netref.unwrap().borrow().operands[index]?;
1451 Some(DrivenNet::new(
1452 op.secondary(),
1453 NetRef::wrap(self.index_weak(&op.root()).clone()),
1454 ))
1455 }
1456
1457 pub fn expose_net_with_name(&self, net: DrivenNet<I>, name: Identifier) -> DrivenNet<I> {
1463 self.belongs(&net.clone().unwrap());
1464 let mut outputs = self.outputs.borrow_mut();
1465 let named_net = net.as_net().with_name(name);
1466 outputs
1467 .entry(net.get_operand())
1468 .or_default()
1469 .insert(named_net);
1470 net
1471 }
1472
1473 pub fn expose_net(&self, net: DrivenNet<I>) -> Result<DrivenNet<I>, Error> {
1478 self.belongs(&net.clone().unwrap());
1479 if net.is_an_input() {
1480 return Err(Error::InputNeedsAlias(net.as_net().clone()));
1481 }
1482 let mut outputs = self.outputs.borrow_mut();
1483 outputs
1484 .entry(net.get_operand())
1485 .or_default()
1486 .insert(net.as_net().clone());
1487 Ok(net)
1488 }
1489
1490 pub fn remove_output(&self, operand: &DrivenNet<I>, net_name: &Identifier) -> bool {
1496 self.belongs(&operand.clone().unwrap());
1497 let mut outputs = self.outputs.borrow_mut();
1498 if let Some(nets) = outputs.get_mut(&operand.get_operand()) {
1499 let net_to_remove = Net::new(net_name.clone(), crate::circuit::DataType::logic());
1501 if nets.remove(&net_to_remove) {
1502 if nets.is_empty() {
1504 outputs.remove(&operand.get_operand());
1505 }
1506 return true;
1507 }
1508 }
1509 false
1510 }
1511
1512 pub fn remove_outputs(&self, operand: &DrivenNet<I>) -> usize {
1515 self.outputs
1517 .borrow_mut()
1518 .remove(&operand.get_operand())
1519 .map(|nets| nets.len())
1520 .unwrap_or(0)
1521 }
1522
1523 pub fn clear_outputs(&self) {
1525 self.outputs.borrow_mut().clear();
1526 }
1527
1528 pub fn clone_into<O: Instantiable + Into<I>>(
1533 self: &Rc<Self>,
1534 netref: &NetRef<O>,
1535 prefix: Option<Identifier>,
1536 map: &mut HashMap<DrivenNet<O>, DrivenNet<I>>,
1537 ) -> NetRef<I> {
1538 let mut object = netref.get_obj().clone();
1539 let attributes = BTreeMap::from_iter(netref.attributes().map(|a| a.split()));
1540 if let Some(prefix) = &prefix
1541 && let Object::Instance(_, name, _) = &mut object
1542 {
1543 let update = prefix + name;
1544 *name = update;
1545 }
1546
1547 let mut object = match object {
1548 Object::Input(a) => Object::Input(a),
1549 Object::Instance(nets, name, inst_type) => {
1550 Object::Instance(nets, name, inst_type.into())
1551 }
1552 };
1553
1554 if let Some(prefix) = &prefix {
1555 for net in object.get_nets_mut() {
1556 let update = prefix + net.get_identifier();
1557 net.set_identifier(update);
1558 }
1559 }
1560
1561 let mapped: Vec<Option<DrivenNet<I>>> = netref
1562 .inputs()
1563 .map(|x| map.get(&x.get_driver()?).cloned())
1564 .collect();
1565
1566 let mut operands = Vec::new();
1567
1568 for operand in mapped {
1569 let op = match operand {
1570 None => None,
1571 Some(d) => {
1572 let op = d.get_operand();
1573 self.belongs(&d.unwrap());
1574 Some(op)
1575 }
1576 };
1577 operands.push(op);
1578 }
1579
1580 let index = self.objects.borrow().len();
1581 let weak = Rc::downgrade(self);
1582 let owned_object = Rc::new(RefCell::new(OwnedObject {
1583 object,
1584 owner: weak,
1585 operands,
1586 attributes,
1587 index,
1588 }));
1589 self.objects.borrow_mut().push(owned_object.clone());
1590 let clone = NetRef::wrap(owned_object);
1591
1592 for (k, v) in netref.outputs().zip(clone.outputs()) {
1593 map.insert(k, v);
1594 }
1595
1596 clone
1597 }
1598
1599 pub fn delete_net_uses(&self, netref: NetRef<I>) -> Result<Object<I>, Error> {
1604 self.belongs(&netref);
1605 let unwrapped = netref.clone().unwrap();
1606 if Rc::strong_count(&unwrapped) > 3 {
1607 return Err(Error::DanglingReference(netref.nets().collect()));
1608 }
1609 let old_index = unwrapped.borrow().get_index();
1610 let objects = self.objects.borrow();
1611 for oref in objects.iter() {
1612 let operands = &mut oref.borrow_mut().operands;
1613 for operand in operands.iter_mut() {
1614 if let Some(op) = operand {
1615 match op {
1616 Operand::DirectIndex(idx) | Operand::CellIndex(idx, _)
1617 if *idx == old_index =>
1618 {
1619 *operand = None;
1620 }
1621 _ => (),
1622 }
1623 }
1624 }
1625 }
1626
1627 let outputs: Vec<Operand> = self
1628 .outputs
1629 .borrow()
1630 .keys()
1631 .filter(|operand| match operand {
1632 Operand::DirectIndex(idx) | Operand::CellIndex(idx, _) => *idx == old_index,
1633 })
1634 .cloned()
1635 .collect();
1636
1637 for operand in outputs {
1638 self.outputs.borrow_mut().remove(&operand);
1639 }
1640
1641 Ok(netref.unwrap().borrow().get().clone())
1642 }
1643
1644 pub fn replace_net_uses(
1652 &self,
1653 of: DrivenNet<I>,
1654 with: &DrivenNet<I>,
1655 ) -> Result<DrivenNet<I>, Error> {
1656 {
1657 self.belongs(&of.clone().unwrap());
1658 self.belongs(&with.clone().unwrap());
1659 }
1660 let unwrapped = of.clone().unwrap().unwrap();
1661 let i = of.get_output_index();
1662 let k = with.get_output_index();
1663
1664 if of.clone().unwrap() == with.clone().unwrap() {
1665 if i == k {
1666 return Ok(of);
1667 }
1668
1669 if Rc::strong_count(&unwrapped) > 4 {
1670 return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1671 }
1672 } else if Rc::strong_count(&unwrapped) > 3 {
1673 return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1674 }
1675
1676 let old_index = of.get_operand();
1677
1678 if let Some(nets) = self.outputs.borrow().get(&old_index)
1679 && nets.contains(&of.as_net())
1680 {
1681 if of.is_an_input() {
1682 return Err(Error::NonuniqueNets(nets.iter().cloned().collect()));
1683 } else {
1684 let id = of.as_net().get_identifier().clone() + "_replaced".into();
1685 of.as_net_mut().set_identifier(id);
1686 }
1687 }
1688
1689 let new_index = with.get_operand();
1690 let objects = self.objects.borrow();
1691 for oref in objects.iter() {
1692 let operands = &mut oref.borrow_mut().operands;
1693 for operand in operands.iter_mut() {
1694 if let Some(op) = operand
1695 && *op == old_index
1696 {
1697 *operand = Some(new_index);
1698 }
1699 }
1700 }
1701
1702 let outs = self.outputs.borrow_mut().remove(&old_index);
1704 if let Some(outs) = outs {
1705 self.outputs
1706 .borrow_mut()
1707 .entry(new_index)
1708 .or_default()
1709 .extend(outs);
1710 }
1711
1712 Ok(of)
1713 }
1714}
1715
1716impl<I> Netlist<I>
1717where
1718 I: Instantiable,
1719{
1720 pub fn get_name(&self) -> Ref<'_, Identifier> {
1722 self.name.borrow()
1723 }
1724
1725 pub fn set_name(&self, name: Identifier) {
1730 *self.name.borrow_mut() = name;
1731 }
1732
1733 pub fn get_input_ports(&self) -> impl Iterator<Item = Net> {
1735 self.objects().filter_map(|oref| {
1736 if oref.is_an_input() {
1737 Some(oref.as_net().clone())
1738 } else {
1739 None
1740 }
1741 })
1742 }
1743
1744 pub fn get_output_ports(&self) -> Vec<Net> {
1746 self.outputs
1747 .borrow()
1748 .values()
1749 .flat_map(|nets| nets.iter().cloned())
1750 .collect()
1751 }
1752
1753 pub fn get_analysis<'a, A: Analysis<'a, I>>(&'a self) -> Result<A, Error> {
1755 A::build(self)
1756 }
1757
1758 pub fn find_net(&self, net: &Net) -> Option<DrivenNet<I>> {
1761 for obj in self.objects() {
1762 for o in obj.outputs() {
1763 if *o.as_net() == *net {
1764 return Some(o);
1765 }
1766 }
1767 }
1768 None
1769 }
1770
1771 pub fn first(&self) -> Option<NetRef<I>> {
1773 self.objects
1774 .borrow()
1775 .first()
1776 .map(|nr| NetRef::wrap(nr.clone()))
1777 }
1778
1779 pub fn last(&self) -> Option<NetRef<I>> {
1781 self.objects
1782 .borrow()
1783 .last()
1784 .map(|nr| NetRef::wrap(nr.clone()))
1785 }
1786
1787 pub fn len(&self) -> usize {
1789 self.objects.borrow().len()
1790 }
1791
1792 pub fn is_empty(&self) -> bool {
1794 self.objects.borrow().is_empty()
1795 }
1796
1797 pub fn drives_an_output(&self, netref: NetRef<I>) -> bool {
1802 self.belongs(&netref);
1803 let my_index = netref.unwrap().borrow().get_index();
1804 for key in self.outputs.borrow().keys() {
1805 if key.root() == my_index {
1806 return true;
1807 }
1808 }
1809 false
1810 }
1811
1812 pub fn rename_nets<F: Fn(&Identifier, usize) -> Identifier>(&self, f: F) -> Result<(), Error> {
1830 let mut i: usize = 0;
1831 let mut set = HashSet::new();
1832 let mut vec = Vec::new();
1833 for nr in self.objects() {
1835 if nr.is_an_input() {
1836 continue;
1837 }
1838 for net in nr.nets() {
1839 let id = net.get_identifier().clone();
1840 let rename = f(&id, i);
1841 if !set.insert(rename.clone()) {
1842 return Err(Error::NonuniqueNets(vec![net]));
1843 }
1844 vec.push(rename);
1845 i += 1;
1846 }
1847 }
1848
1849 for nr in self.objects() {
1850 if nr.is_an_input() {
1851 continue;
1852 }
1853
1854 let id = nr.get_instance_name().unwrap();
1855 let rename = f(&id, i);
1856 if !set.insert(rename.clone()) {
1857 return Err(Error::NonuniqueInsts(vec![id]));
1858 }
1859 vec.push(rename);
1860 i += 1;
1861 }
1862
1863 i = 0;
1864 for nr in self.objects() {
1865 if nr.is_an_input() {
1866 continue;
1867 }
1868 for mut net in nr.nets_mut() {
1869 net.set_identifier(vec[i].clone());
1870 i += 1;
1871 }
1872 }
1873
1874 for nr in self.objects() {
1875 if nr.is_an_input() {
1876 continue;
1877 }
1878
1879 nr.set_instance_name(vec[i].clone());
1880 i += 1;
1881 }
1882
1883 Ok(())
1884 }
1885
1886 pub fn retain_once(&self, set: &mut HashSet<DrivenNet<I>>) -> Result<Vec<Object<I>>, Error> {
1888 let mut dead_objs = HashSet::new();
1889 {
1890 let fan_out = self.get_analysis::<FanOutTable<I>>()?;
1891 for obj in self.objects() {
1892 let mut is_dead = true;
1893 for net in obj.outputs() {
1894 if fan_out.net_has_uses(&net.as_net()) {
1896 is_dead = false;
1897 } else {
1898 set.remove(&net);
1899 }
1900 }
1901 if is_dead && !obj.is_an_input() {
1902 dead_objs.insert(obj.unwrap().borrow().index);
1903 }
1904 }
1905 }
1906
1907 if dead_objs.is_empty() {
1908 return Ok(vec![]);
1909 }
1910
1911 let old_objects = self.objects.take();
1912
1913 for i in dead_objs.iter() {
1915 let rc = &old_objects[*i];
1916 if Rc::strong_count(rc) > 1 {
1917 self.objects.replace(old_objects.clone());
1918 return Err(Error::DanglingReference(
1919 rc.borrow().get().get_nets().to_vec(),
1920 ));
1921 }
1922 }
1923
1924 let mut removed = Vec::new();
1925 let mut remap: HashMap<usize, usize> = HashMap::new();
1926 for (old_index, obj) in old_objects.into_iter().enumerate() {
1927 if dead_objs.contains(&old_index) {
1928 removed.push(obj.borrow().get().clone());
1929 continue;
1930 }
1931
1932 let new_index = self.objects.borrow().len();
1933 remap.insert(old_index, new_index);
1934 obj.borrow_mut().index = new_index;
1935 self.objects.borrow_mut().push(obj);
1936 }
1937
1938 for obj in self.objects.borrow().iter() {
1939 for operand in obj.borrow_mut().inds_mut() {
1940 let root = operand.root();
1941 let root = *remap.get(&root).unwrap_or(&root);
1942 *operand = operand.remap(root);
1943 }
1944 }
1945
1946 let pairs: Vec<_> = self.outputs.take().into_iter().collect();
1947 for (operand, net) in pairs {
1948 let root = operand.root();
1949 let root = *remap.get(&root).unwrap_or(&root);
1950 let new_operand = operand.remap(root);
1951 self.outputs.borrow_mut().insert(new_operand, net);
1952 }
1953
1954 Ok(removed)
1955 }
1956
1957 pub fn clean(&self) -> Result<Vec<Object<I>>, Error> {
1960 let mut removed = Vec::new();
1961 let mut r = self.retain_once(&mut HashSet::new())?;
1962 while !r.is_empty() {
1963 removed.extend(r);
1964 r = self.retain_once(&mut HashSet::new())?;
1965 }
1966 Ok(removed)
1967 }
1968
1969 pub fn retain(&self, set: &mut HashSet<DrivenNet<I>>) -> Result<Vec<Object<I>>, Error> {
1971 let mut removed = Vec::new();
1972 let mut r = self.retain_once(set)?;
1973 while !r.is_empty() {
1974 removed.extend(r);
1975 r = self.retain_once(set)?;
1976 }
1977 Ok(removed)
1978 }
1979
1980 fn nets_insts_unique(&self) -> Result<(), Error> {
1982 let mut nets = HashSet::new();
1983 let mut stems = HashSet::new();
1984 for net in self {
1985 if !nets.insert(net.clone().take_identifier()) {
1986 return Err(Error::NonuniqueNets(vec![net]));
1987 }
1988 if !stems.insert(net.get_identifier().get_stem().to_string())
1989 && net.get_identifier().get_bit_index().is_none()
1990 {
1991 return Err(Error::NonuniqueNets(vec![net]));
1992 }
1993 }
1994 for inst in self.objects() {
1995 if let Some(name) = inst.get_instance_name()
1996 && !stems.insert(name.get_stem().to_string())
1997 {
1998 return Err(Error::NonuniqueInsts(vec![name]));
1999 }
2000 if let Some(name) = inst.get_instance_name()
2001 && name.get_bit_index().is_some()
2002 {
2003 return Err(Error::InstantiableError(format!(
2004 "Instance identifier {name} cannot be indexed"
2005 )));
2006 }
2007 }
2008 Ok(())
2009 }
2010
2011 fn check_io(&self) -> Result<(), Error> {
2013 for inst in self.objects() {
2014 let unwrapped = inst.unwrap();
2015
2016 let olen = unwrapped.borrow().operands.len();
2017 let nlen = unwrapped.borrow().get().get_nets().len();
2018
2019 if let Some(inst) = unwrapped.borrow().get().get_instance_type() {
2020 let inlen = inst.get_input_ports().iter().count();
2021 let outlen = inst.get_output_ports().iter().count();
2022 if olen != inlen {
2023 return Err(Error::ArgumentMismatch(inlen, olen));
2024 }
2025
2026 if nlen != outlen {
2027 return Err(Error::InstantiableError(format!(
2028 "Instantiable type has incorrect number of outputs. Expected {outlen}, found {nlen}"
2029 )));
2030 }
2031 }
2032 }
2033 Ok(())
2034 }
2035
2036 fn connections_type_check(&self) -> Result<(), Error> {
2037 for conn in self.connections() {
2038 let target = *conn.target().get_port().get_type();
2039 let source = *conn.src().as_net().get_type();
2040 if target != source {
2041 return Err(Error::TypeError(conn.src().as_net().clone()));
2042 }
2043 }
2044 Ok(())
2045 }
2046
2047 fn cells_check(&self) -> Result<(), Error> {
2048 for inst in self.objects() {
2049 if let Some(inst_type) = inst.get_instance_type()
2050 && let Err(rsn) = inst_type.verify()
2051 {
2052 return Err(Error::InstantiableError(format!(
2053 "Instantiable {} invalid: {}",
2054 inst_type.get_name(),
2055 rsn
2056 )));
2057 }
2058 }
2059 Ok(())
2060 }
2061
2062 pub fn verify(&self) -> Result<(), Error> {
2064 if self.outputs.borrow().is_empty() {
2065 return Err(Error::NoOutputs);
2066 }
2067
2068 self.check_io()?;
2069 self.nets_insts_unique()?;
2070 self.connections_type_check()?;
2071 self.cells_check()?;
2072
2073 Ok(())
2074 }
2075}
2076
2077#[derive(Debug, Clone)]
2079pub struct Connection<I: Instantiable> {
2080 driver: DrivenNet<I>,
2081 input: InputPort<I>,
2082}
2083
2084impl<I> Connection<I>
2085where
2086 I: Instantiable,
2087{
2088 fn new(driver: DrivenNet<I>, input: InputPort<I>) -> Self {
2089 Self { driver, input }
2090 }
2091
2092 pub fn src(&self) -> DrivenNet<I> {
2094 self.driver.clone()
2095 }
2096
2097 pub fn net(&self) -> Net {
2099 self.driver.as_net().clone()
2100 }
2101
2102 pub fn target(&self) -> InputPort<I> {
2104 self.input.clone()
2105 }
2106}
2107
2108impl<I> std::fmt::Display for Connection<I>
2109where
2110 I: Instantiable,
2111{
2112 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2113 self.net().fmt(f)
2114 }
2115}
2116
2117pub mod emitter {
2119 #[cfg(feature = "graph")]
2120 use super::NetRef;
2121 use super::{Analysis, Error, Identifier, Instantiable, Netlist};
2122 #[cfg(feature = "graph")]
2123 use std::collections::HashMap;
2124 use std::collections::{BTreeMap, HashSet};
2125
2126 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2128 pub struct VerilogEmitterConfig {
2129 pub indent_char: char,
2131 pub indent_width: usize,
2133 pub ansi_style: bool,
2135 pub emit_const_cells: bool,
2137 }
2138
2139 impl VerilogEmitterConfig {
2140 pub fn legacy() -> Self {
2142 Self {
2143 indent_char: ' ',
2144 indent_width: 2,
2145 ansi_style: false,
2146 emit_const_cells: false,
2147 }
2148 }
2149 }
2150
2151 impl Default for VerilogEmitterConfig {
2152 fn default() -> Self {
2153 Self {
2154 indent_char: ' ',
2155 indent_width: 2,
2156 ansi_style: true,
2157 emit_const_cells: false,
2158 }
2159 }
2160 }
2161
2162 enum VerilogNet {
2163 Net(Identifier),
2164 Bus(Identifier, (usize, usize)),
2165 }
2166
2167 impl VerilogNet {
2168 fn id(&self) -> &Identifier {
2169 match self {
2170 VerilogNet::Net(id) => id,
2171 VerilogNet::Bus(id, _) => id,
2172 }
2173 }
2174 }
2175
2176 impl std::fmt::Display for VerilogNet {
2177 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2178 write!(f, "wire ")?;
2179 match self {
2180 VerilogNet::Net(net) => write!(f, "{}", net.get_stem()),
2181 VerilogNet::Bus(net, (h, l)) => write!(f, "[{}:{}] {}", h, l, net.get_stem()),
2182 }
2183 }
2184 }
2185
2186 pub struct VerilogEmitter<'a, I: Instantiable> {
2188 netlist: &'a Netlist<I>,
2189 config: VerilogEmitterConfig,
2190 inputs: Vec<VerilogNet>,
2191 outputs: Vec<VerilogNet>,
2192 others: Vec<VerilogNet>,
2193 }
2194
2195 impl<'a, I: Instantiable> VerilogEmitter<'a, I> {
2196 fn get_nets(
2197 nl: &'a Netlist<I>,
2198 emit_consts: bool,
2199 ) -> (Vec<VerilogNet>, Vec<VerilogNet>, Vec<VerilogNet>) {
2200 let mut seen: HashSet<Identifier> = HashSet::new();
2201 let mut inputs: BTreeMap<Identifier, (usize, usize)> = BTreeMap::new();
2202 let mut outputs: BTreeMap<Identifier, (usize, usize)> = BTreeMap::new();
2203 let mut others: BTreeMap<Identifier, (usize, usize)> = BTreeMap::new();
2204
2205 for (_, output) in nl.outputs() {
2206 let output = output.take_identifier();
2207 let stem = output.get_stem();
2208 seen.insert(stem.clone());
2209 let entry = outputs.entry(stem.clone()).or_default();
2210 if let Some(idx) = output.get_bit_index() {
2211 entry.1 = entry.1.min(idx);
2212 entry.0 = entry.0.max(idx);
2213 }
2214 }
2215
2216 for input in nl.inputs() {
2217 let input = input.get_identifier();
2218 let stem = input.get_stem();
2219 seen.insert(stem.clone());
2220 let entry = inputs.entry(stem.clone()).or_default();
2221 if let Some(idx) = input.get_bit_index() {
2222 entry.1 = entry.1.min(idx);
2223 entry.0 = entry.0.max(idx);
2224 }
2225 }
2226
2227 for obj in nl.objects() {
2228 if !emit_consts
2229 && obj
2230 .get_instance_type()
2231 .and_then(|i| i.get_constant())
2232 .is_some()
2233 {
2234 continue;
2235 }
2236
2237 for net in obj.nets() {
2238 let id = net.get_identifier();
2239 let stem = id.get_stem();
2240 if !seen.contains(&stem) {
2241 let entry = others.entry(stem.clone()).or_default();
2242 if let Some(idx) = id.get_bit_index() {
2243 entry.1 = entry.1.min(idx);
2244 entry.0 = entry.0.max(idx);
2245 }
2246 }
2247 }
2248 }
2249
2250 let inputs = inputs
2251 .into_iter()
2252 .map(|(id, (h, l))| {
2253 if h == l {
2254 VerilogNet::Net(id)
2255 } else {
2256 VerilogNet::Bus(id, (h, l))
2257 }
2258 })
2259 .collect::<Vec<_>>();
2260
2261 let outputs = outputs
2262 .into_iter()
2263 .map(|(id, (h, l))| {
2264 if h == l {
2265 VerilogNet::Net(id)
2266 } else {
2267 VerilogNet::Bus(id, (h, l))
2268 }
2269 })
2270 .collect::<Vec<_>>();
2271
2272 let others = others
2273 .into_iter()
2274 .map(|(id, (h, l))| {
2275 if h == l {
2276 VerilogNet::Net(id)
2277 } else {
2278 VerilogNet::Bus(id, (h, l))
2279 }
2280 })
2281 .collect::<Vec<_>>();
2282
2283 (inputs, outputs, others)
2284 }
2285
2286 pub fn new(netlist: &'a Netlist<I>, config: VerilogEmitterConfig) -> Self {
2288 let (inputs, outputs, others) = Self::get_nets(netlist, config.emit_const_cells);
2289 Self {
2290 netlist,
2291 config,
2292 inputs,
2293 outputs,
2294 others,
2295 }
2296 }
2297
2298 pub fn new_default(netlist: &'a Netlist<I>) -> Self {
2300 Self::new(netlist, VerilogEmitterConfig::default())
2301 }
2302
2303 pub fn with_spaces(self) -> Self {
2305 Self {
2306 config: VerilogEmitterConfig {
2307 indent_char: ' ',
2308 ..self.config
2309 },
2310 ..self
2311 }
2312 }
2313
2314 pub fn with_tabs(self) -> Self {
2316 Self {
2317 config: VerilogEmitterConfig {
2318 indent_char: '\t',
2319 ..self.config
2320 },
2321 ..self
2322 }
2323 }
2324
2325 pub fn with_indent(self, width: usize) -> Self {
2327 Self {
2328 config: VerilogEmitterConfig {
2329 indent_width: width,
2330 ..self.config
2331 },
2332 ..self
2333 }
2334 }
2335
2336 pub fn with_ansi_style(self) -> Self {
2338 Self {
2339 config: VerilogEmitterConfig {
2340 ansi_style: true,
2341 ..self.config
2342 },
2343 ..self
2344 }
2345 }
2346
2347 pub fn with_nonansi_style(self) -> Self {
2349 Self {
2350 config: VerilogEmitterConfig {
2351 ansi_style: false,
2352 ..self.config
2353 },
2354 ..self
2355 }
2356 }
2357
2358 pub fn with_emitted_constants(self) -> Self {
2360 Self {
2361 config: VerilogEmitterConfig {
2362 emit_const_cells: true,
2363 ..self.config
2364 },
2365 ..self
2366 }
2367 }
2368 }
2369
2370 impl<'a, I: Instantiable> Analysis<'a, I> for VerilogEmitter<'a, I> {
2371 fn build(netlist: &'a Netlist<I>) -> Result<Self, Error> {
2372 Ok(Self::new_default(netlist))
2373 }
2374 }
2375
2376 impl<'a, I: Instantiable> VerilogEmitter<'a, I> {
2377 fn get_indent(&self, level: usize) -> String {
2378 self.config
2379 .indent_char
2380 .to_string()
2381 .repeat(self.config.indent_width * level)
2382 }
2383
2384 fn emit_ansi_header(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2385 assert!(self.config.ansi_style);
2386
2387 writeln!(f, "module {} (", self.netlist.get_name())?;
2388 let indent = self.get_indent(1);
2389 for input in &self.inputs {
2390 writeln!(f, "{}input {},", indent, input)?;
2391 }
2392 let l = self.outputs.len();
2393 for (i, output) in self.outputs.iter().enumerate() {
2394 write!(f, "{}output {}", indent, output)?;
2395 if i != l - 1 {
2396 writeln!(f, ",")?;
2397 }
2398 }
2399 writeln!(f)?;
2400 writeln!(f, ");")
2401 }
2402
2403 fn emit_nonansi_header(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2404 assert!(!self.config.ansi_style);
2405
2406 writeln!(f, "module {} (", self.netlist.get_name())?;
2407 let indent = self.get_indent(1);
2408 for input in &self.inputs {
2409 writeln!(f, "{}{},", indent, input.id())?;
2410 }
2411 let l = self.outputs.len();
2412 for (i, output) in self.outputs.iter().enumerate() {
2413 write!(f, "{}{}", indent, output.id())?;
2414 if i != l - 1 {
2415 writeln!(f, ",")?;
2416 }
2417 }
2418 writeln!(f)?;
2419 writeln!(f, ");")
2420 }
2421
2422 fn emit_net_decls(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2423 let indent = self.get_indent(1);
2424 if !self.config.ansi_style {
2425 for net in &self.inputs {
2426 writeln!(f, "{}input {};", indent, net)?;
2427 }
2428 for net in &self.outputs {
2429 writeln!(f, "{}output {};", indent, net)?;
2430 }
2431 }
2432
2433 for net in &self.others {
2434 writeln!(f, "{}{};", indent, net)?;
2435 }
2436 writeln!(f)
2437 }
2438
2439 fn emit_instances(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2440 let indent = self.get_indent(1);
2441 for nr in self
2442 .netlist
2443 .matches(|i| self.config.emit_const_cells || i.get_constant().is_none())
2444 {
2445 for attribute in nr.attributes() {
2446 if let Some(value) = attribute.value() {
2447 writeln!(f, "{}(* {} = {} *)", indent, attribute.key(), value)?;
2448 } else {
2449 writeln!(f, "{}(* {} *)", indent, attribute.key())?;
2450 }
2451 }
2452 let inst = nr.get_instance_type().unwrap().clone();
2453 write!(f, "{}{} ", indent, inst.get_name())?;
2454 let params = inst.parameters();
2455 if !params.is_empty() {
2456 writeln!(f, "#(")?;
2457 let indent = self.get_indent(2);
2458 let l = params.len();
2459 for (i, (k, v)) in params.into_iter().enumerate() {
2460 write!(f, "{}.{}({})", indent, k, v)?;
2461 if i != l - 1 {
2462 writeln!(f, ",")?;
2463 }
2464 }
2465 writeln!(f)?;
2466 let indent = self.get_indent(1);
2467 write!(f, "{}) ", indent)?;
2468 }
2469 writeln!(f, "{} (", nr.get_instance_name().unwrap())?;
2470 let indent = self.get_indent(2);
2471 for input in nr.inputs() {
2472 if let Some(driver) = self.netlist.get_driver(nr.clone(), input.get_input_num())
2473 {
2474 let rhs = if !self.config.emit_const_cells
2475 && let Some(logic) =
2476 driver.get_instance_type().and_then(|i| i.get_constant())
2477 {
2478 logic.to_string()
2479 } else {
2480 driver.get_identifier().to_string()
2481 };
2482
2483 writeln!(f, "{}.{}({}),", indent, input.get_port(), rhs)?;
2484 }
2485 }
2486 let outputs = nr.outputs().collect::<Vec<_>>();
2487 let l = outputs.len();
2488 for (i, output) in outputs.into_iter().enumerate() {
2489 write!(
2490 f,
2491 "{}.{}({})",
2492 indent,
2493 output.get_port(),
2494 output.get_identifier()
2495 )?;
2496 if i != l - 1 {
2497 writeln!(f, ",")?;
2498 }
2499 }
2500 let indent = self.get_indent(1);
2501 writeln!(f)?;
2502 writeln!(f, "{});", indent)?;
2503 }
2504 writeln!(f)
2505 }
2506
2507 fn emit_output_assignments(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2508 let indent = self.get_indent(1);
2509 for (operand, net) in self.netlist.outputs() {
2510 if operand.get_identifier() != *net.get_identifier() {
2511 let rhs = if !self.config.emit_const_cells
2512 && let Some(logic) =
2513 operand.get_instance_type().and_then(|i| i.get_constant())
2514 {
2515 logic.to_string()
2516 } else {
2517 operand.get_identifier().to_string()
2518 };
2519 writeln!(f, "{}assign {} = {};", indent, net.get_identifier(), rhs)?;
2520 }
2521 }
2522 writeln!(f)
2523 }
2524
2525 pub fn emit(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2527 if self.config.ansi_style {
2528 self.emit_ansi_header(f)?;
2529 } else {
2530 self.emit_nonansi_header(f)?;
2531 }
2532
2533 self.emit_net_decls(f)?;
2534 self.emit_instances(f)?;
2535 self.emit_output_assignments(f)?;
2536
2537 writeln!(f, "endmodule")
2538 }
2539
2540 pub fn emit_to_string(&self) -> String {
2542 self.to_string()
2543 }
2544 }
2545
2546 impl<'a, I: Instantiable> std::fmt::Display for VerilogEmitter<'a, I> {
2547 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2548 self.emit(f)
2549 }
2550 }
2551
2552 #[cfg(feature = "graph")]
2554 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2555 pub struct RGB {
2556 pub r: u8,
2558 pub g: u8,
2560 pub b: u8,
2562 }
2563
2564 #[cfg(feature = "graph")]
2565 impl std::fmt::Display for RGB {
2566 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2567 write!(f, "#{:02x}{:02x}{:02x}", self.r, self.g, self.b)
2568 }
2569 }
2570
2571 #[cfg(feature = "graph")]
2573 pub type ColorFunc<T> = dyn Fn(&T, Option<RGB>) -> Option<RGB>;
2574
2575 #[cfg(feature = "graph")]
2577 pub struct DotEmitter<'a, I: Instantiable> {
2578 netlist: &'a Netlist<I>,
2579 overrides_netref: HashMap<NetRef<I>, RGB>,
2580 color_netref: Box<ColorFunc<NetRef<I>>>,
2581 color_inst: Box<ColorFunc<I>>,
2582 }
2583
2584 #[cfg(feature = "graph")]
2585 impl<'a, I: Instantiable> DotEmitter<'a, I> {
2586 pub fn new(netlist: &'a Netlist<I>) -> Self {
2588 Self {
2589 netlist,
2590 overrides_netref: HashMap::new(),
2591 color_netref: Box::new(|_, _| None),
2592 color_inst: Box::new(|_, _| None),
2593 }
2594 }
2595
2596 pub fn override_color(&mut self, netref: NetRef<I>, color: RGB) {
2598 self.overrides_netref.insert(netref, color);
2599 }
2600
2601 pub fn with_net_coloring<F: Fn(&NetRef<I>, Option<RGB>) -> Option<RGB> + 'static>(
2603 self,
2604 f: F,
2605 ) -> Self {
2606 Self {
2607 color_netref: Box::new(f),
2608 ..self
2609 }
2610 }
2611
2612 pub fn with_instance_coloring<F: Fn(&I, Option<RGB>) -> Option<RGB> + 'static>(
2614 self,
2615 f: F,
2616 ) -> Self {
2617 Self {
2618 color_inst: Box::new(f),
2619 ..self
2620 }
2621 }
2622
2623 fn get_color(&self, netref: &NetRef<I>) -> Option<RGB> {
2624 if let Some(color) = self.overrides_netref.get(netref) {
2625 return Some(*color);
2626 }
2627 let color = match netref.get_instance_type() {
2628 Some(inst) => (self.color_inst)(&inst, None),
2629 None => None,
2630 };
2631 (self.color_netref)(netref, color)
2632 }
2633
2634 pub fn emit(&self) -> String {
2636 use super::super::graph::{Edge, MultiDiGraph, Node};
2637 use super::Net;
2638 use petgraph::dot::{Config, Dot};
2639 use petgraph::graph::{DiGraph, EdgeReference, NodeIndex};
2640 let analysis = MultiDiGraph::new(self.netlist);
2641 let graph = analysis.get_graph();
2642
2643 let node_impl = |_graph: &DiGraph<Node<I, String>, Edge<I, Net>>,
2644 node: (NodeIndex, &Node<I, String>)| {
2645 let n = node.1;
2646 let mut attr = String::new();
2647
2648 match n {
2649 Node::NetRef(nr) if nr.get_instance_type().is_some() => {
2650 attr += "shape=record, ";
2651 if let Some(color) = self.get_color(nr) {
2652 attr += &format!("style=filled, fillcolor=\"{color}\", ");
2653 }
2654 }
2655 _ => attr += "shape=ellipse, ",
2656 }
2657
2658 match n {
2659 Node::NetRef(nr)
2660 if let Some(inst_type) = nr.get_instance_type()
2661 && !inst_type.is_driverless() =>
2662 {
2663 let mut record = "{ { ".to_string();
2664
2665 let l = nr.get_num_input_ports();
2666 for (i, port) in nr.inputs().enumerate() {
2667 let id = port.get_port().get_identifier().clone();
2668 record += &format!("{{ <{}> {} }}", id, id);
2669
2670 if i != l - 1 {
2671 record += " | ";
2672 }
2673 }
2674
2675 record += &format!(
2676 " }} | {}({}) }}",
2677 inst_type.get_name(),
2678 nr.get_instance_name().unwrap()
2679 );
2680 attr += &format!("label=\"{record}\"");
2681 }
2682 _ => attr += &format!("label=\"{n}\""),
2683 }
2684
2685 attr
2686 };
2687
2688 fn edge_impl<I: Instantiable>(
2689 _graph: &DiGraph<Node<I, String>, Edge<I, Net>>,
2690 edge: EdgeReference<Edge<I, Net>>,
2691 ) -> String {
2692 match edge.weight() {
2693 Edge::Connection(c) => {
2694 format!(", port=\"{}\"", c.target().get_port().get_identifier())
2695 }
2696 _ => String::new(),
2697 }
2698 }
2699
2700 let dot =
2701 Dot::with_attr_getters(graph, &[Config::NodeNoLabel], &edge_impl::<I>, &node_impl);
2702
2703 let mut result = String::new();
2705 for line in dot.to_string().lines() {
2706 if line.contains("->") && line.contains("port=") {
2707 let port = line
2708 .split("port=\"")
2709 .nth(1)
2710 .unwrap()
2711 .split('"')
2712 .next()
2713 .unwrap();
2714 let (l, r) = line.split_once("->").unwrap();
2715 let (l, r) = (l, r.trim());
2716 let (d, r) = r.split_once(" ").unwrap();
2717 result += &format!("{l}-> {d}:{port} {r}\n");
2718 } else {
2719 result += line;
2720 result += "\n";
2721 }
2722 }
2723
2724 result
2725 }
2726 }
2727
2728 #[cfg(feature = "graph")]
2729 impl<'a, I: Instantiable> std::fmt::Display for DotEmitter<'a, I> {
2730 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2731 write!(f, "{}", self.emit())
2732 }
2733 }
2734}
2735
2736pub mod rewriter {
2738 use super::{DrivenNet, Error, Instantiable, NetRef, Netlist, Operand};
2739 use crate::graph::FanOutTable;
2740 use std::collections::HashMap;
2741 use std::rc::Rc;
2742
2743 pub struct NetMapper<'a, I: Instantiable> {
2747 parent: HashMap<DrivenNet<I>, DrivenNet<I>>,
2748 netlist: &'a Netlist<I>,
2749 fanout: FanOutTable<'a, I>,
2750 }
2751
2752 impl<'a, I: Instantiable> NetMapper<'a, I> {
2753 pub fn new(netlist: &'a Netlist<I>) -> Result<Self, Error> {
2755 Ok(Self {
2756 parent: HashMap::new(),
2757 netlist,
2758 fanout: netlist.get_analysis::<FanOutTable<I>>()?,
2759 })
2760 }
2761
2762 pub fn find(&self, x: DrivenNet<I>) -> DrivenNet<I> {
2764 let mut root = x;
2765 while let Some(p) = self.parent.get(&root) {
2766 root = p.clone();
2767 }
2768 root
2769 }
2770
2771 pub fn replace(&mut self, of: DrivenNet<I>, with: DrivenNet<I>) -> DrivenNet<I> {
2776 let of_root = self.find(of.clone());
2777 let with_root = self.find(with);
2778 if of_root == with_root {
2779 panic!("Already mapped by NetMapper: {of}");
2780 }
2781 self.parent.insert(of_root, with_root);
2782 of
2783 }
2784
2785 pub fn apply(self) -> Result<Vec<DrivenNet<I>>, Error> {
2788 let mut map: HashMap<Operand, Operand> = HashMap::new();
2790 for k in self.parent.keys().cloned() {
2791 let v = self.find(k.clone());
2792 if k != v {
2793 map.insert(k.get_operand(), v.get_operand());
2794 }
2795 }
2796
2797 drop(self.parent);
2798
2799 for (of, with) in map.iter() {
2801 let unwrapped = self.netlist.objects.borrow()[of.root()].clone();
2802 let i = of.secondary();
2803 let k = of.secondary();
2804 let nr = NetRef::wrap(unwrapped.clone());
2805
2806 if of.root() == with.root() {
2807 if i == k {
2808 continue;
2809 }
2810
2811 if Rc::strong_count(&unwrapped) - self.fanout.get_ref_count(&nr) > 4 {
2812 return Err(Error::DanglingReference(nr.nets().collect()));
2813 }
2814 } else if Rc::strong_count(&unwrapped) - self.fanout.get_ref_count(&nr) > 3 {
2815 return Err(Error::DanglingReference(nr.nets().collect()));
2816 }
2817
2818 let old_index = of;
2819 let of = DrivenNet::new(i, nr);
2820
2821 if let Some(nets) = self.netlist.outputs.borrow().get(old_index)
2822 && nets.contains(&of.as_net())
2823 {
2824 if of.is_an_input() {
2825 return Err(Error::NonuniqueNets(nets.iter().cloned().collect()));
2826 } else {
2827 let id = of.as_net().get_identifier().clone() + "_replaced".into();
2828 of.as_net_mut().set_identifier(id);
2829 }
2830 }
2831 }
2832
2833 let objects = self.netlist.objects.borrow();
2834 for (of, &with) in map.iter() {
2835 let of = DrivenNet::new(of.secondary(), NetRef::wrap(objects[of.root()].clone()));
2836 for u in self.fanout.get_users(&of) {
2837 let place = u.pos;
2838 let u = u.unwrap().unwrap();
2839 let operands = &mut u.borrow_mut().operands;
2840 operands[place] = Some(with);
2841 }
2842 }
2843
2844 for (of, &with) in map.iter() {
2845 let outs = self.netlist.outputs.borrow_mut().remove(of);
2847 if let Some(outs) = outs {
2848 self.netlist
2849 .outputs
2850 .borrow_mut()
2851 .entry(with)
2852 .or_default()
2853 .extend(outs);
2854 }
2855 }
2856
2857 let res: Vec<_> = map
2858 .into_keys()
2859 .map(|operand| {
2860 DrivenNet::new(
2861 operand.secondary(),
2862 NetRef::wrap(self.netlist.objects.borrow()[operand.root()].clone()),
2863 )
2864 })
2865 .collect();
2866
2867 Ok(res)
2868 }
2869 }
2870}
2871
2872pub mod iter {
2874
2875 use super::{
2876 Connection, DrivenNet, InputPort, Instantiable, Net, NetRef, Netlist, Operand, WeakIndex,
2877 };
2878 use std::collections::{HashMap, HashSet};
2879 pub struct NetIterator<'a, I: Instantiable> {
2881 netlist: &'a Netlist<I>,
2882 index: usize,
2883 subindex: usize,
2884 }
2885
2886 impl<'a, I> NetIterator<'a, I>
2887 where
2888 I: Instantiable,
2889 {
2890 pub fn new(netlist: &'a Netlist<I>) -> Self {
2892 Self {
2893 netlist,
2894 index: 0,
2895 subindex: 0,
2896 }
2897 }
2898 }
2899
2900 impl<I> Iterator for NetIterator<'_, I>
2901 where
2902 I: Instantiable,
2903 {
2904 type Item = Net;
2905
2906 fn next(&mut self) -> Option<Self::Item> {
2907 while self.index < self.netlist.objects.borrow().len() {
2908 let objects = self.netlist.objects.borrow();
2909 let object = objects[self.index].borrow();
2910 if self.subindex < object.get().get_nets().len() {
2911 let net = object.get().get_nets()[self.subindex].clone();
2912 self.subindex += 1;
2913 return Some(net);
2914 }
2915 self.subindex = 0;
2916 self.index += 1;
2917 }
2918 None
2919 }
2920 }
2921
2922 pub struct ObjectIterator<'a, I: Instantiable> {
2924 netlist: &'a Netlist<I>,
2925 index: usize,
2926 }
2927
2928 impl<'a, I> ObjectIterator<'a, I>
2929 where
2930 I: Instantiable,
2931 {
2932 pub fn new(netlist: &'a Netlist<I>) -> Self {
2934 Self { netlist, index: 0 }
2935 }
2936 }
2937
2938 impl<I> Iterator for ObjectIterator<'_, I>
2939 where
2940 I: Instantiable,
2941 {
2942 type Item = NetRef<I>;
2943
2944 fn next(&mut self) -> Option<Self::Item> {
2945 if self.index < self.netlist.objects.borrow().len() {
2946 let objects = self.netlist.objects.borrow();
2947 let object = &objects[self.index];
2948 self.index += 1;
2949 return Some(NetRef::wrap(object.clone()));
2950 }
2951 None
2952 }
2953 }
2954
2955 pub struct ConnectionIterator<'a, I: Instantiable> {
2957 netlist: &'a Netlist<I>,
2958 index: usize,
2959 subindex: usize,
2960 }
2961
2962 impl<'a, I> ConnectionIterator<'a, I>
2963 where
2964 I: Instantiable,
2965 {
2966 pub fn new(netlist: &'a Netlist<I>) -> Self {
2968 Self {
2969 netlist,
2970 index: 0,
2971 subindex: 0,
2972 }
2973 }
2974 }
2975
2976 impl<I> Iterator for ConnectionIterator<'_, I>
2977 where
2978 I: Instantiable,
2979 {
2980 type Item = super::Connection<I>;
2981
2982 fn next(&mut self) -> Option<Self::Item> {
2983 while self.index < self.netlist.objects.borrow().len() {
2984 let objects = self.netlist.objects.borrow();
2985 let object = objects[self.index].borrow();
2986 let noperands = object.operands.len();
2987 while self.subindex < noperands {
2988 if let Some(operand) = &object.operands[self.subindex] {
2989 let driver = match operand {
2990 Operand::DirectIndex(idx) => {
2991 DrivenNet::new(0, NetRef::wrap(objects[*idx].clone()))
2992 }
2993 Operand::CellIndex(idx, j) => {
2994 DrivenNet::new(*j, NetRef::wrap(objects[*idx].clone()))
2995 }
2996 };
2997 let input = InputPort::new(
2998 self.subindex,
2999 NetRef::wrap(objects[self.index].clone()),
3000 );
3001 self.subindex += 1;
3002 return Some(Connection::new(driver, input));
3003 }
3004 self.subindex += 1;
3005 }
3006 self.subindex = 0;
3007 self.index += 1;
3008 }
3009 None
3010 }
3011 }
3012
3013 #[derive(Clone)]
3015 struct Walk<T: std::hash::Hash + PartialEq + Eq + Clone> {
3016 stack: Vec<T>,
3017 counter: HashMap<T, usize>,
3018 }
3019
3020 impl<T> Walk<T>
3021 where
3022 T: std::hash::Hash + PartialEq + Eq + Clone,
3023 {
3024 fn new() -> Self {
3026 Self {
3027 stack: Vec::new(),
3028 counter: HashMap::new(),
3029 }
3030 }
3031
3032 fn push(&mut self, item: T) {
3034 self.stack.push(item.clone());
3035 *self.counter.entry(item).or_insert(0) += 1;
3036 }
3037
3038 fn contains_cycle(&self) -> bool {
3040 self.counter.values().any(|&count| count > 1)
3041 }
3042
3043 fn root_cycle(&self) -> bool {
3045 if self.stack.is_empty() {
3046 return false;
3047 }
3048 self.counter[&self.stack[0]] > 1
3049 }
3050
3051 fn last(&self) -> Option<&T> {
3053 self.stack.last()
3054 }
3055 }
3056
3057 pub struct DFSIterator<'a, I: Instantiable> {
3076 dfs: NetDFSIterator<'a, I>,
3077 seen: HashSet<NetRef<I>>,
3078 }
3079
3080 impl<'a, I> DFSIterator<'a, I>
3081 where
3082 I: Instantiable,
3083 {
3084 pub fn new(netlist: &'a Netlist<I>, from: NetRef<I>) -> Self {
3086 Self {
3087 dfs: NetDFSIterator::new(netlist, DrivenNet::new(0, from)),
3088 seen: HashSet::new(),
3089 }
3090 }
3091 }
3092
3093 impl<I> DFSIterator<'_, I>
3094 where
3095 I: Instantiable,
3096 {
3097 pub fn check_cycles(&self) -> bool {
3099 self.dfs.check_cycles()
3100 }
3101
3102 pub fn detect_cycles(self) -> bool {
3104 self.dfs.detect_cycles()
3105 }
3106
3107 pub fn check_self_loop(&self) -> bool {
3109 self.dfs.check_self_loop()
3110 }
3111
3112 pub fn detect_self_loop(self) -> bool {
3114 self.dfs.detect_self_loop()
3115 }
3116 }
3117
3118 impl<I> Iterator for DFSIterator<'_, I>
3119 where
3120 I: Instantiable,
3121 {
3122 type Item = NetRef<I>;
3123
3124 fn next(&mut self) -> Option<Self::Item> {
3125 let d = self.dfs.next()?;
3126 if self.seen.insert(d.clone().unwrap()) {
3127 Some(d.unwrap())
3128 } else {
3129 self.next()
3130 }
3131 }
3132 }
3133
3134 type TermFn<I> = Box<dyn Fn(&DrivenNet<I>) -> bool + 'static>;
3135
3136 pub struct NetDFSIterator<'a, I: Instantiable> {
3138 netlist: &'a Netlist<I>,
3139 stacks: Vec<Walk<DrivenNet<I>>>,
3140 visited: HashSet<usize>,
3141 visited_net: HashSet<(usize, usize)>,
3142 any_cycle: bool,
3143 root_cycle: bool,
3144 terminate: TermFn<I>,
3145 }
3146
3147 impl<'a, I> NetDFSIterator<'a, I>
3148 where
3149 I: Instantiable,
3150 {
3151 pub fn new_filtered<F: Fn(&DrivenNet<I>) -> bool + 'static>(
3154 netlist: &'a Netlist<I>,
3155 from: DrivenNet<I>,
3156 terminate: F,
3157 ) -> Self {
3158 let mut s = Walk::new();
3159 s.push(from);
3160 Self {
3161 netlist,
3162 stacks: vec![s],
3163 visited: HashSet::new(),
3164 visited_net: HashSet::new(),
3165 any_cycle: false,
3166 root_cycle: false,
3167 terminate: Box::new(terminate),
3168 }
3169 }
3170
3171 pub fn new(netlist: &'a Netlist<I>, from: DrivenNet<I>) -> Self {
3173 Self::new_filtered(netlist, from, |_| false)
3174 }
3175 }
3176
3177 impl<I> NetDFSIterator<'_, I>
3178 where
3179 I: Instantiable,
3180 {
3181 pub fn check_cycles(&self) -> bool {
3183 self.any_cycle
3184 }
3185
3186 pub fn detect_cycles(mut self) -> bool {
3188 if self.any_cycle {
3189 return true;
3190 }
3191
3192 while let Some(_) = self.next() {
3193 if self.any_cycle {
3194 return true;
3195 }
3196 }
3197
3198 self.any_cycle
3199 }
3200
3201 pub fn check_self_loop(&self) -> bool {
3203 self.root_cycle
3204 }
3205
3206 pub fn detect_self_loop(mut self) -> bool {
3208 if self.root_cycle {
3209 return true;
3210 }
3211
3212 while let Some(_) = self.next() {
3213 if self.root_cycle {
3214 return true;
3215 }
3216 }
3217
3218 self.root_cycle
3219 }
3220 }
3221
3222 impl<I> Iterator for NetDFSIterator<'_, I>
3223 where
3224 I: Instantiable,
3225 {
3226 type Item = DrivenNet<I>;
3227
3228 fn next(&mut self) -> Option<Self::Item> {
3229 if let Some(walk) = self.stacks.pop() {
3230 self.any_cycle |= walk.contains_cycle();
3231 self.root_cycle |= walk.root_cycle();
3232 let item = walk.last().cloned();
3233 let uw = item.clone().unwrap().unwrap().unwrap();
3234 let index = uw.borrow().get_index();
3235 let secondary = item.as_ref().unwrap().pos;
3236 if self.visited.insert(index) {
3237 if !(self.terminate)(item.as_ref().unwrap()) {
3238 let operands = &uw.borrow().operands;
3239 for operand in operands.iter().flatten() {
3240 let mut new_walk = walk.clone();
3241 new_walk.push(DrivenNet::new(
3242 operand.secondary(),
3243 NetRef::wrap(self.netlist.index_weak(&operand.root())),
3244 ));
3245 self.stacks.push(new_walk);
3246 }
3247 }
3248 self.visited_net.insert((index, secondary));
3249 return item;
3250 }
3251
3252 if self.visited_net.insert((index, secondary)) {
3253 return item;
3254 }
3255
3256 return self.next();
3257 }
3258
3259 None
3260 }
3261 }
3262}
3263
3264impl<'a, I> IntoIterator for &'a Netlist<I>
3265where
3266 I: Instantiable,
3267{
3268 type Item = Net;
3269 type IntoIter = iter::NetIterator<'a, I>;
3270
3271 fn into_iter(self) -> Self::IntoIter {
3272 iter::NetIterator::new(self)
3273 }
3274}
3275
3276#[macro_export]
3279macro_rules! filter_nodes {
3280 ($netlist:ident, $pattern:pat $(if $guard:expr)? $(,)?) => {
3281 $netlist.matches(|f| match f {
3282 $pattern $(if $guard)? => true,
3283 _ => false
3284 })
3285 };
3286}
3287
3288impl<I> Netlist<I>
3289where
3290 I: Instantiable,
3291{
3292 pub fn objects(&self) -> impl Iterator<Item = NetRef<I>> {
3294 iter::ObjectIterator::new(self)
3295 }
3296
3297 pub fn matches<F>(&self, filter: F) -> impl Iterator<Item = NetRef<I>>
3299 where
3300 F: Fn(&I) -> bool,
3301 {
3302 self.objects().filter(move |f| {
3303 if let Some(inst_type) = f.get_instance_type() {
3304 filter(&inst_type)
3305 } else {
3306 false
3307 }
3308 })
3309 }
3310
3311 pub fn inputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
3313 self.objects()
3314 .filter(|n| n.is_an_input())
3315 .map(|n| DrivenNet::new(0, n))
3316 }
3317
3318 pub fn outputs(&self) -> Vec<(DrivenNet<I>, Net)> {
3320 self.outputs
3321 .borrow()
3322 .iter()
3323 .flat_map(|(k, nets)| {
3324 nets.iter().map(|n| {
3325 (
3326 DrivenNet::new(k.secondary(), NetRef::wrap(self.index_weak(&k.root()))),
3327 n.clone(),
3328 )
3329 })
3330 })
3331 .collect()
3332 }
3333
3334 pub fn connections(&self) -> impl Iterator<Item = Connection<I>> {
3336 iter::ConnectionIterator::new(self)
3337 }
3338
3339 pub fn node_dfs(&self, from: NetRef<I>) -> impl Iterator<Item = NetRef<I>> {
3344 self.belongs(&from);
3345 iter::DFSIterator::new(self, from)
3346 }
3347
3348 pub fn net_dfs(&self, from: DrivenNet<I>) -> impl Iterator<Item = DrivenNet<I>> {
3353 self.belongs(&from.clone().unwrap());
3354 iter::NetDFSIterator::new(self, from)
3355 }
3356
3357 #[cfg(feature = "serde")]
3358 pub fn serialize(self, writer: impl std::io::Write) -> Result<(), serde_json::Error>
3360 where
3361 I: ::serde::Serialize,
3362 {
3363 serde::netlist_serialize(self, writer)
3364 }
3365
3366 #[cfg(feature = "graph")]
3367 pub fn dot_string(&self) -> String {
3369 use emitter::DotEmitter;
3370 let emitter = DotEmitter::new(self);
3371 emitter.emit()
3372 }
3373
3374 #[cfg(feature = "graph")]
3375 pub fn dump_dot(&self) -> std::io::Result<()> {
3377 use std::io::Write;
3378 let mut dir = std::env::current_dir()?;
3379 let mod_name = format!("{}.dot", self.get_name());
3380 dir.push(mod_name);
3381 let mut file = std::fs::File::create(dir)?;
3382 let dot = self.dot_string();
3383 write!(file, "{dot}")
3384 }
3385}
3386
3387impl<I> std::fmt::Display for Netlist<I>
3388where
3389 I: Instantiable,
3390{
3391 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3392 use emitter::{VerilogEmitter, VerilogEmitterConfig};
3393 let emitter = VerilogEmitter::new(self, VerilogEmitterConfig::legacy());
3394 emitter.fmt(f)
3395 }
3396}
3397
3398pub type GateNetlist = Netlist<Gate>;
3400pub type GateRef = NetRef<Gate>;
3402
3403#[cfg(test)]
3404mod tests {
3405 use super::iter::{DFSIterator, NetDFSIterator};
3406 use super::*;
3407 #[test]
3408 fn test_delete_netlist() {
3409 let netlist = Netlist::new("simple_example".into());
3410
3411 let input1 = netlist.insert_input("input1".into());
3413 let input2 = netlist.insert_input("input2".into());
3414
3415 let instance = netlist
3417 .insert_gate(
3418 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3419 "my_and".into(),
3420 &[input1.clone(), input2.clone()],
3421 )
3422 .unwrap();
3423
3424 let instance = instance.expose_as_output().unwrap();
3426 instance.delete_uses().unwrap();
3427 assert!(netlist.clean().is_ok());
3429 input1.expose_with_name("an_output".into());
3430 assert!(netlist.clean().is_ok());
3431 }
3432
3433 #[test]
3434 #[should_panic(expected = "Attempted to create a gate with a sliced identifier")]
3435 fn gate_w_slice_panics() {
3436 Gate::new_logical("AND[1]".into(), vec!["A".into(), "B".into()], "Y".into());
3437 }
3438
3439 #[test]
3440 fn gates_dont_have_params() {
3441 let gate = Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into());
3443 assert!(!gate.has_parameter(&"id".into()));
3444 assert!(gate.get_parameter(&"id".into()).is_none());
3445 assert_eq!(*gate.get_gate_name(), "AND".into());
3446 }
3447
3448 #[test]
3449 fn operand_conversions() {
3450 let operand = Operand::CellIndex(3, 2);
3451 assert_eq!(operand.to_string(), "3.2");
3452 let parsed = "3.2".parse::<Operand>();
3453 assert!(parsed.is_ok());
3454 let parsed = parsed.unwrap();
3455 assert_eq!(operand, parsed);
3456 }
3457
3458 #[test]
3459 #[should_panic(expected = "out of bounds for netref")]
3460 fn test_bad_output() {
3461 let netlist = GateNetlist::new("min_module".into());
3462 let a = netlist.insert_input("a".into());
3463 DrivenNet::new(1, a.unwrap());
3464 }
3465
3466 #[test]
3467 fn test_netdfsiterator() {
3468 let netlist = Netlist::new("dfs_netlist".into());
3469
3470 let a = netlist.insert_input("a".into());
3472 let b = netlist.insert_input("b".into());
3473 let c = netlist.insert_input("c".into());
3474 let d = netlist.insert_input("d".into());
3475 let e = netlist.insert_input("e".into());
3476
3477 let n1 = netlist
3479 .insert_gate(
3480 Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into()),
3481 "n1".into(),
3482 &[a.clone(), b.clone()],
3483 )
3484 .unwrap()
3485 .get_output(0);
3486 let n2 = netlist
3487 .insert_gate(
3488 Gate::new_logical("NOR".into(), vec!["A".into(), "B".into()], "Y".into()),
3489 "n2".into(),
3490 &[d.clone(), e.clone()],
3491 )
3492 .unwrap()
3493 .get_output(0);
3494 let n3 = netlist
3495 .insert_gate(
3496 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3497 "n3".into(),
3498 &[n1.clone(), c.clone()],
3499 )
3500 .unwrap()
3501 .get_output(0);
3502 let n4 = netlist
3503 .insert_gate(
3504 Gate::new_logical("NAND".into(), vec!["A".into(), "B".into()], "Y".into()),
3505 "n4".into(),
3506 &[n3.clone(), n2.clone()],
3507 )
3508 .unwrap()
3509 .get_output(0);
3510 n4.clone().expose_with_name("y".into());
3511
3512 let mut dfs = NetDFSIterator::new(&netlist, n4.clone());
3514 assert_eq!(dfs.next(), Some(n4));
3515 assert_eq!(dfs.next(), Some(n2));
3516 assert_eq!(dfs.next(), Some(e));
3517 assert_eq!(dfs.next(), Some(d));
3518 assert_eq!(dfs.next(), Some(n3));
3519 assert_eq!(dfs.next(), Some(c));
3520 assert_eq!(dfs.next(), Some(n1));
3521 assert_eq!(dfs.next(), Some(b));
3522 assert_eq!(dfs.next(), Some(a));
3523 assert_eq!(dfs.next(), None);
3524 }
3525
3526 #[test]
3527 fn test_dfs_cycles() {
3528 let netlist = Netlist::new("dfs_cycles".into());
3529
3530 let a = netlist.insert_input("a".into());
3532
3533 let and = netlist.insert_gate_disconnected(
3535 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3536 "and".into(),
3537 );
3538
3539 a.connect(and.get_input(0));
3541 and.get_output(0).connect(and.get_input(1));
3542
3543 let dfs = DFSIterator::new(&netlist, and.clone());
3545 let driven_dfs = NetDFSIterator::new(&netlist, and.get_output(0));
3546
3547 assert!(dfs.detect_cycles());
3548 assert!(driven_dfs.detect_cycles());
3549 }
3550
3551 #[test]
3552 fn test_netdfsiterator_with_boundary() {
3553 let netlist = Netlist::new("dfs_netlist".into());
3554
3555 let a = netlist.insert_input("a".into());
3557 let b = netlist.insert_input("b".into());
3558 let c = netlist.insert_input("c".into());
3559 let d = netlist.insert_input("d".into());
3560 let e = netlist.insert_input("e".into());
3561
3562 let n1 = netlist
3564 .insert_gate(
3565 Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into()),
3566 "n1".into(),
3567 &[a.clone(), b.clone()],
3568 )
3569 .unwrap()
3570 .get_output(0);
3571 let n2 = netlist
3572 .insert_gate(
3573 Gate::new_logical("NOR".into(), vec!["A".into(), "B".into()], "Y".into()),
3574 "n2".into(),
3575 &[d.clone(), e.clone()],
3576 )
3577 .unwrap()
3578 .get_output(0);
3579 let n3 = netlist
3580 .insert_gate(
3581 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
3582 "n3".into(),
3583 &[n1.clone(), c.clone()],
3584 )
3585 .unwrap()
3586 .get_output(0);
3587 let n4 = netlist
3588 .insert_gate(
3589 Gate::new_logical("NAND".into(), vec!["A".into(), "B".into()], "Y".into()),
3590 "n4".into(),
3591 &[n3.clone(), n2.clone()],
3592 )
3593 .unwrap()
3594 .get_output(0);
3595
3596 let n3_boundary = n3.clone();
3598 let mut dfs =
3599 NetDFSIterator::new_filtered(&netlist, n4.clone(), move |n| *n == n3_boundary);
3600 assert_eq!(dfs.next(), Some(n4));
3601 assert_eq!(dfs.next(), Some(n2));
3602 assert_eq!(dfs.next(), Some(e));
3603 assert_eq!(dfs.next(), Some(d));
3604 assert_eq!(dfs.next(), Some(n3));
3605 assert_eq!(dfs.next(), None);
3606 }
3607
3608 #[test]
3609 fn test_dfs_convergence() {
3610 let netlist = GateNetlist::new("example".into());
3611 let gate = Gate::new_logical_multi(
3612 "FA".into(),
3613 vec!["A".into(), "B".into()],
3614 vec!["S".into(), "COUT".into()],
3615 );
3616 let a = netlist.insert_input("a".into());
3617 let b = netlist.insert_input("b".into());
3618 let gate = netlist.insert_gate(gate, "g".into(), &[a, b]).unwrap();
3619 let s = gate.get_output(0);
3620 let c = gate.get_output(1);
3621 let gate = Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into());
3622 let d = netlist.insert_gate(gate, "h".into(), &[s, c]).unwrap();
3623
3624 let dfs = NetDFSIterator::new(&netlist, d.get_output(0));
3625 let c = dfs.count();
3626 assert_eq!(c, 5);
3627
3628 let dfs = DFSIterator::new(&netlist, d.clone());
3629 let c = dfs.count();
3630 assert_eq!(c, 4);
3631 }
3632
3633 #[test]
3634 fn test_operand_comparison() {
3635 let a = Operand::CellIndex(3, 0);
3636 let b = Operand::DirectIndex(3);
3637 assert_eq!(a.cmp(&b), std::cmp::Ordering::Greater);
3638 assert_eq!(b.cmp(&a), std::cmp::Ordering::Less);
3639 }
3640}
3641#[cfg(feature = "serde")]
3642pub mod serde {
3644 use super::{Identifier, Netlist, Operand, OwnedObject, WeakIndex};
3645 use crate::{
3646 attribute::{AttributeKey, AttributeValue},
3647 circuit::{Instantiable, Net, Object},
3648 };
3649 use serde::{Deserialize, Serialize, de::DeserializeOwned};
3650 use std::cell::RefCell;
3651 use std::{
3652 collections::{BTreeMap, BTreeSet},
3653 rc::Rc,
3654 };
3655
3656 #[derive(Debug, Serialize, Deserialize)]
3657 struct SerdeObject<I>
3658 where
3659 I: Instantiable + Serialize,
3660 {
3661 object: Object<I>,
3663 operands: Vec<Option<Operand>>,
3665 attributes: BTreeMap<AttributeKey, AttributeValue>,
3667 }
3668
3669 impl<I, O> From<OwnedObject<I, O>> for SerdeObject<I>
3670 where
3671 I: Instantiable + Serialize,
3672 O: WeakIndex<usize, Output = OwnedObject<I, O>>,
3673 {
3674 fn from(value: OwnedObject<I, O>) -> Self {
3675 SerdeObject {
3676 object: value.object,
3677 operands: value.operands,
3678 attributes: value.attributes,
3679 }
3680 }
3681 }
3682
3683 impl<I> SerdeObject<I>
3684 where
3685 I: Instantiable + Serialize,
3686 {
3687 fn into_owned_object<O>(self, owner: &Rc<O>, index: usize) -> OwnedObject<I, O>
3688 where
3689 O: WeakIndex<usize, Output = OwnedObject<I, O>>,
3690 {
3691 OwnedObject {
3692 object: self.object,
3693 owner: Rc::downgrade(owner),
3694 operands: self.operands,
3695 attributes: self.attributes,
3696 index,
3697 }
3698 }
3699 }
3700
3701 #[derive(Debug, Serialize, Deserialize)]
3702 struct SerdeNetlist<I>
3703 where
3704 I: Instantiable + Serialize,
3705 {
3706 name: Identifier,
3708 objects: Vec<SerdeObject<I>>,
3710 outputs: BTreeMap<String, BTreeSet<Net>>,
3714 }
3715
3716 impl<I> From<Netlist<I>> for SerdeNetlist<I>
3717 where
3718 I: Instantiable + Serialize,
3719 {
3720 fn from(value: Netlist<I>) -> Self {
3721 SerdeNetlist {
3722 name: value.name.into_inner(),
3723 objects: value
3724 .objects
3725 .into_inner()
3726 .into_iter()
3727 .map(|o| {
3728 Rc::try_unwrap(o)
3729 .ok()
3730 .expect("Cannot serialize with live references")
3731 .into_inner()
3732 .into()
3733 })
3734 .collect(),
3735 outputs: value
3736 .outputs
3737 .into_inner()
3738 .into_iter()
3739 .map(|(o, nets)| (o.to_string(), nets.into_iter().collect()))
3741 .collect(),
3742 }
3743 }
3744 }
3745
3746 impl<I> SerdeNetlist<I>
3747 where
3748 I: Instantiable + Serialize,
3749 {
3750 fn into_netlist(self) -> Rc<Netlist<I>> {
3752 let netlist = Netlist::new(self.name);
3753 let outputs: BTreeMap<Operand, BTreeSet<Net>> = self
3754 .outputs
3755 .into_iter()
3756 .map(|(k, v)| {
3757 let operand = k.parse::<Operand>().expect("Invalid index");
3758 (operand, v.into_iter().collect())
3759 })
3760 .collect();
3761 let objects = self
3762 .objects
3763 .into_iter()
3764 .enumerate()
3765 .map(|(i, o)| {
3766 let owned_object = o.into_owned_object(&netlist, i);
3767 Rc::new(RefCell::new(owned_object))
3768 })
3769 .collect::<Vec<_>>();
3770 {
3771 let mut objs_mut = netlist.objects.borrow_mut();
3772 *objs_mut = objects;
3773 let mut outputs_mut = netlist.outputs.borrow_mut();
3774 *outputs_mut = outputs;
3775 }
3776 netlist
3777 }
3778 }
3779
3780 pub fn netlist_serialize<I: Instantiable + Serialize>(
3782 netlist: Netlist<I>,
3783 writer: impl std::io::Write,
3784 ) -> Result<(), serde_json::Error> {
3785 let sobj: SerdeNetlist<I> = netlist.into();
3786 serde_json::to_writer_pretty(writer, &sobj)
3787 }
3788
3789 pub fn netlist_deserialize<I: Instantiable + Serialize + DeserializeOwned>(
3791 reader: impl std::io::Read,
3792 ) -> Result<Rc<Netlist<I>>, serde_json::Error> {
3793 let sobj: SerdeNetlist<I> = serde_json::from_reader(reader)?;
3794 Ok(sobj.into_netlist())
3795 }
3796}