1use crate::{
8 attribute::{Attribute, AttributeKey, AttributeValue, Parameter},
9 circuit::{Identifier, Instantiable, Net, Object},
10 error::Error,
11 graph::{Analysis, FanOutTable},
12 logic::Logic,
13};
14use std::{
15 cell::{Ref, RefCell, RefMut},
16 collections::{BTreeSet, HashMap, HashSet},
17 num::ParseIntError,
18 rc::{Rc, Weak},
19};
20
21trait WeakIndex<Idx: ?Sized> {
23 type Output: ?Sized;
25 fn index_weak(&self, index: &Idx) -> Rc<RefCell<Self::Output>>;
27}
28
29#[derive(Debug, Clone)]
32#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
33pub struct Gate {
34 name: Identifier,
36 inputs: Vec<Net>,
38 outputs: Vec<Net>,
40}
41
42impl Instantiable for Gate {
43 fn get_name(&self) -> &Identifier {
44 &self.name
45 }
46
47 fn get_input_ports(&self) -> impl IntoIterator<Item = &Net> {
48 &self.inputs
49 }
50
51 fn get_output_ports(&self) -> impl IntoIterator<Item = &Net> {
52 &self.outputs
53 }
54
55 fn has_parameter(&self, _id: &Identifier) -> bool {
56 false
57 }
58
59 fn get_parameter(&self, _id: &Identifier) -> Option<Parameter> {
60 None
61 }
62
63 fn set_parameter(&mut self, _id: &Identifier, _val: Parameter) -> Option<Parameter> {
64 None
65 }
66
67 fn parameters(&self) -> impl Iterator<Item = (Identifier, Parameter)> {
68 std::iter::empty()
69 }
70
71 fn from_constant(val: Logic) -> Option<Self> {
72 match val {
73 Logic::True => Some(Gate::new_logical("VDD".into(), vec![], "Y".into())),
74 Logic::False => Some(Gate::new_logical("GND".into(), vec![], "Y".into())),
75 _ => None,
76 }
77 }
78
79 fn get_constant(&self) -> Option<Logic> {
80 match self.name.to_string().as_str() {
81 "VDD" => Some(Logic::True),
82 "GND" => Some(Logic::False),
83 _ => None,
84 }
85 }
86
87 fn is_seq(&self) -> bool {
88 false
89 }
90}
91
92impl Gate {
93 pub fn new_logical(name: Identifier, inputs: Vec<Identifier>, output: Identifier) -> Self {
95 if name.is_sliced() {
96 panic!("Attempted to create a gate with a sliced identifier: {name}");
97 }
98
99 let outputs = vec![Net::new_logic(output)];
100 let inputs = inputs.into_iter().map(Net::new_logic).collect::<Vec<_>>();
101 Self {
102 name,
103 inputs,
104 outputs,
105 }
106 }
107
108 pub fn new_logical_multi(
110 name: Identifier,
111 inputs: Vec<Identifier>,
112 outputs: Vec<Identifier>,
113 ) -> Self {
114 if name.is_sliced() {
115 panic!("Attempted to create a gate with a sliced identifier: {name}");
116 }
117
118 let outputs = outputs.into_iter().map(Net::new_logic).collect::<Vec<_>>();
119 let inputs = inputs.into_iter().map(Net::new_logic).collect::<Vec<_>>();
120 Self {
121 name,
122 inputs,
123 outputs,
124 }
125 }
126
127 pub fn get_single_output_port(&self) -> &Net {
129 if self.outputs.len() > 1 {
130 panic!("Attempted to grab output port of a multi-output gate");
131 }
132 self.outputs
133 .first()
134 .expect("Gate is missing an output port")
135 }
136
137 pub fn set_gate_name(&mut self, new_name: Identifier) {
139 self.name = new_name;
140 }
141
142 pub fn get_gate_name(&self) -> &Identifier {
144 &self.name
145 }
146}
147
148#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
150#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
151enum Operand {
152 DirectIndex(usize),
154 CellIndex(usize, usize),
156}
157
158impl Operand {
159 fn remap(self, x: usize) -> Self {
161 match self {
162 Operand::DirectIndex(_idx) => Operand::DirectIndex(x),
163 Operand::CellIndex(_idx, j) => Operand::CellIndex(x, j),
164 }
165 }
166
167 fn root(&self) -> usize {
169 match self {
170 Operand::DirectIndex(idx) => *idx,
171 Operand::CellIndex(idx, _) => *idx,
172 }
173 }
174
175 fn secondary(&self) -> usize {
177 match self {
178 Operand::DirectIndex(_) => 0,
179 Operand::CellIndex(_, j) => *j,
180 }
181 }
182}
183
184impl std::fmt::Display for Operand {
185 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
186 match self {
187 Operand::DirectIndex(idx) => write!(f, "{idx}"),
188 Operand::CellIndex(idx, j) => write!(f, "{idx}.{j}"),
189 }
190 }
191}
192
193impl std::str::FromStr for Operand {
194 type Err = ParseIntError;
195
196 fn from_str(s: &str) -> Result<Self, Self::Err> {
197 match s.split_once('.') {
198 Some((idx, j)) => {
199 let idx = idx.parse::<usize>()?;
200 let j = j.parse::<usize>()?;
201 Ok(Operand::CellIndex(idx, j))
202 }
203 None => {
204 let idx = s.parse::<usize>()?;
205 Ok(Operand::DirectIndex(idx))
206 }
207 }
208 }
209}
210
211#[derive(Debug)]
213struct OwnedObject<I, O>
214where
215 I: Instantiable,
216 O: WeakIndex<usize, Output = Self>,
217{
218 object: Object<I>,
220 owner: Weak<O>,
222 operands: Vec<Option<Operand>>,
224 attributes: HashMap<AttributeKey, AttributeValue>,
226 index: usize,
228}
229
230impl<I, O> OwnedObject<I, O>
231where
232 I: Instantiable,
233 O: WeakIndex<usize, Output = Self>,
234{
235 fn inds_mut(&mut self) -> impl Iterator<Item = &mut Operand> {
237 self.operands
238 .iter_mut()
239 .filter_map(|operand| operand.as_mut())
240 }
241
242 fn get_driver(&self, index: usize) -> Option<Rc<RefCell<Self>>> {
244 self.operands[index].as_ref().map(|operand| {
245 self.owner
246 .upgrade()
247 .expect("Object is unlinked from netlist")
248 .index_weak(&operand.root())
249 })
250 }
251
252 fn drivers(&self) -> impl Iterator<Item = Option<Rc<RefCell<Self>>>> {
254 self.operands.iter().map(|operand| {
255 operand.as_ref().map(|operand| {
256 self.owner
257 .upgrade()
258 .expect("Object is unlinked from netlist")
259 .index_weak(&operand.root())
260 })
261 })
262 }
263
264 fn driver_nets(&self) -> impl Iterator<Item = Option<Net>> {
266 self.operands.iter().map(|operand| {
267 operand.as_ref().map(|operand| match operand {
268 Operand::DirectIndex(idx) => self
269 .owner
270 .upgrade()
271 .expect("Object is unlinked from netlist")
272 .index_weak(idx)
273 .borrow()
274 .as_net()
275 .clone(),
276 Operand::CellIndex(idx, j) => self
277 .owner
278 .upgrade()
279 .expect("Object is unlinked from netlist")
280 .index_weak(idx)
281 .borrow()
282 .get_net(*j)
283 .clone(),
284 })
285 })
286 }
287
288 fn get(&self) -> &Object<I> {
290 &self.object
291 }
292
293 fn get_mut(&mut self) -> &mut Object<I> {
295 &mut self.object
296 }
297
298 fn get_index(&self) -> usize {
300 self.index
301 }
302
303 fn as_net(&self) -> &Net {
305 match &self.object {
306 Object::Input(net) => net,
307 Object::Instance(nets, _, _) => {
308 if nets.len() > 1 {
309 panic!("Attempt to grab the net of a multi-output instance");
310 } else {
311 nets.first().expect("Instance is missing a net to drive")
312 }
313 }
314 }
315 }
316
317 fn as_net_mut(&mut self) -> &mut Net {
319 match &mut self.object {
320 Object::Input(net) => net,
321 Object::Instance(nets, _, _) => {
322 if nets.len() > 1 {
323 panic!("Attempt to grab the net of a multi-output instance");
324 } else {
325 nets.first_mut()
326 .expect("Instance is missing a net to drive")
327 }
328 }
329 }
330 }
331
332 fn get_net(&self, idx: usize) -> &Net {
334 match &self.object {
335 Object::Input(net) => {
336 if idx != 0 {
337 panic!("Nonzero index on an input object");
338 }
339 net
340 }
341 Object::Instance(nets, _, _) => &nets[idx],
342 }
343 }
344
345 fn get_net_mut(&mut self, idx: usize) -> &mut Net {
347 match &mut self.object {
348 Object::Input(net) => {
349 if idx != 0 {
350 panic!("Nonzero index on an input object");
351 }
352 net
353 }
354 Object::Instance(nets, _, _) => &mut nets[idx],
355 }
356 }
357
358 fn find_net(&self, net: &Net) -> Option<usize> {
360 match &self.object {
361 Object::Input(input_net) => {
362 if input_net == net {
363 Some(0)
364 } else {
365 None
366 }
367 }
368 Object::Instance(nets, _, _) => nets.iter().position(|n| n == net),
369 }
370 }
371
372 fn find_net_mut(&mut self, net: &Net) -> Option<&mut Net> {
374 match &mut self.object {
375 Object::Input(input_net) => {
376 if input_net == net {
377 Some(input_net)
378 } else {
379 None
380 }
381 }
382 Object::Instance(nets, _, _) => nets.iter_mut().find(|n| *n == net),
383 }
384 }
385
386 fn get_driver_net(&self, index: usize) -> Option<Net> {
392 let operand = &self.operands[index];
393 match operand {
394 Some(op) => match op {
395 Operand::DirectIndex(idx) => self
396 .owner
397 .upgrade()
398 .expect("Object is unlinked from netlist")
399 .index_weak(idx)
400 .borrow()
401 .as_net()
402 .clone()
403 .into(),
404 Operand::CellIndex(idx, j) => self
405 .owner
406 .upgrade()
407 .expect("Object is unlinked from netlist")
408 .index_weak(idx)
409 .borrow()
410 .get_net(*j)
411 .clone()
412 .into(),
413 },
414 None => None,
415 }
416 }
417
418 fn clear_attribute(&mut self, k: &AttributeKey) -> Option<AttributeValue> {
419 self.attributes.remove(k)
420 }
421
422 fn set_attribute(&mut self, k: AttributeKey) {
423 self.attributes.insert(k, None);
424 }
425
426 fn insert_attribute(&mut self, k: AttributeKey, v: String) -> Option<AttributeValue> {
427 self.attributes.insert(k, Some(v))
428 }
429
430 fn attributes(&self) -> impl Iterator<Item = Attribute> {
431 Attribute::from_pairs(self.attributes.clone().into_iter())
432 }
433}
434
435type NetRefT<I> = Rc<RefCell<OwnedObject<I, Netlist<I>>>>;
437
438#[derive(Clone)]
441pub struct NetRef<I>
442where
443 I: Instantiable,
444{
445 netref: NetRefT<I>,
446}
447
448impl<I> std::fmt::Debug for NetRef<I>
449where
450 I: Instantiable,
451{
452 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
453 let b = self.netref.borrow();
454 let o = b.get();
455 let i = b.index;
456 let owner = &b.owner;
457 match owner.upgrade() {
458 Some(owner) => {
459 let n = owner.get_name();
460 write!(f, "{{ owner: \"{n}\", index: {i}, val: \"{o}\" }}")
461 }
462 None => write!(f, "{{ owner: None, index: {i}, val: \"{o}\" }}"),
463 }
464 }
465}
466
467impl<I> PartialEq for NetRef<I>
468where
469 I: Instantiable,
470{
471 fn eq(&self, other: &Self) -> bool {
472 Rc::ptr_eq(&self.netref, &other.netref)
473 }
474}
475
476impl<I> Eq for NetRef<I> where I: Instantiable {}
477
478impl<I> Ord for NetRef<I>
479where
480 I: Instantiable,
481{
482 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
483 Rc::as_ptr(&self.netref).cmp(&Rc::as_ptr(&other.netref))
484 }
485}
486
487impl<I> PartialOrd for NetRef<I>
488where
489 I: Instantiable,
490{
491 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
492 Some(self.cmp(other))
493 }
494}
495
496impl<I> std::hash::Hash for NetRef<I>
497where
498 I: Instantiable,
499{
500 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
501 Rc::as_ptr(&self.netref).hash(state);
502 }
503}
504
505impl<I> NetRef<I>
506where
507 I: Instantiable,
508{
509 fn wrap(netref: NetRefT<I>) -> Self {
511 Self { netref }
512 }
513
514 fn unwrap(self) -> NetRefT<I> {
516 self.netref
517 }
518
519 pub fn as_net(&self) -> Ref<'_, Net> {
525 Ref::map(self.netref.borrow(), |f| f.as_net())
526 }
527
528 pub fn as_net_mut(&self) -> RefMut<'_, Net> {
534 RefMut::map(self.netref.borrow_mut(), |f| f.as_net_mut())
535 }
536
537 pub fn get_net(&self, idx: usize) -> Ref<'_, Net> {
539 Ref::map(self.netref.borrow(), |f| f.get_net(idx))
540 }
541
542 pub fn get_net_mut(&self, idx: usize) -> RefMut<'_, Net> {
544 RefMut::map(self.netref.borrow_mut(), |f| f.get_net_mut(idx))
545 }
546
547 pub fn get_output(&self, idx: usize) -> DrivenNet<I> {
549 DrivenNet::new(idx, self.clone())
550 }
551
552 pub fn find_output(&self, id: &Identifier) -> Option<DrivenNet<I>> {
554 let ind = self.get_instance_type()?.find_output(id)?;
555 Some(self.get_output(ind))
556 }
557
558 pub fn get_input(&self, idx: usize) -> InputPort<I> {
560 if self.is_an_input() {
561 panic!("Principal inputs do not have inputs");
562 }
563 InputPort::new(idx, self.clone())
564 }
565
566 pub fn find_input(&self, id: &Identifier) -> Option<InputPort<I>> {
568 let ind = self.get_instance_type()?.find_input(id)?;
569 Some(self.get_input(ind))
570 }
571
572 pub fn get_identifier(&self) -> Identifier {
578 self.as_net().get_identifier().clone()
579 }
580
581 pub fn set_identifier(&self, identifier: Identifier) {
587 self.as_net_mut().set_identifier(identifier)
588 }
589
590 pub fn is_an_input(&self) -> bool {
592 matches!(self.netref.borrow().get(), Object::Input(_))
593 }
594
595 pub fn get_obj(&self) -> Ref<'_, Object<I>> {
597 Ref::map(self.netref.borrow(), |f| f.get())
598 }
599
600 pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
602 Ref::filter_map(self.netref.borrow(), |f| f.get().get_instance_type()).ok()
603 }
604
605 pub fn get_instance_type_mut(&self) -> Option<RefMut<'_, I>> {
607 RefMut::filter_map(self.netref.borrow_mut(), |f| {
608 f.get_mut().get_instance_type_mut()
609 })
610 .ok()
611 }
612
613 pub fn get_instance_name(&self) -> Option<Identifier> {
615 match self.netref.borrow().get() {
616 Object::Instance(_, inst_name, _) => Some(inst_name.clone()),
617 _ => None,
618 }
619 }
620
621 pub fn set_instance_name(&self, name: Identifier) {
627 match self.netref.borrow_mut().get_mut() {
628 Object::Instance(_, inst_name, _) => *inst_name = name,
629 _ => panic!("Attempted to set instance name on a non-instance object"),
630 }
631 }
632
633 pub fn expose_as_output(self) -> Result<Self, Error> {
641 let netlist = self
642 .netref
643 .borrow()
644 .owner
645 .upgrade()
646 .expect("NetRef is unlinked from netlist");
647 netlist.expose_net(self.clone().into())?;
648 Ok(self)
649 }
650
651 pub fn expose_with_name(self, name: Identifier) -> Self {
659 let netlist = self
660 .netref
661 .borrow()
662 .owner
663 .upgrade()
664 .expect("NetRef is unlinked from netlist");
665 netlist.expose_net_with_name(self.clone().into(), name);
666 self
667 }
668
669 pub fn expose_net(&self, net: &Net) -> Result<(), Error> {
675 let netlist = self
676 .netref
677 .borrow()
678 .owner
679 .upgrade()
680 .expect("NetRef is unlinked from netlist");
681 let net_index = self
682 .netref
683 .borrow()
684 .find_net(net)
685 .ok_or(Error::NetNotFound(net.clone()))?;
686 let dr = DrivenNet::new(net_index, self.clone());
687 netlist.expose_net(dr)?;
688 Ok(())
689 }
690
691 pub fn remove_output(&self, net_name: &Identifier) -> bool {
699 let netlist = self
700 .netref
701 .borrow()
702 .owner
703 .upgrade()
704 .expect("NetRef is unlinked from netlist");
705 netlist.remove_output(&self.into(), net_name)
706 }
707
708 pub fn remove_all_outputs(&self) -> usize {
716 let netlist = self
717 .netref
718 .borrow()
719 .owner
720 .upgrade()
721 .expect("NetRef is unlinked from netlist");
722 netlist.remove_outputs(&self.into())
723 }
724
725 pub fn get_driver(&self, index: usize) -> Option<Self> {
727 self.netref.borrow().get_driver(index).map(NetRef::wrap)
728 }
729
730 pub fn get_driver_net(&self, index: usize) -> Option<Net> {
736 self.netref.borrow().get_driver_net(index)
737 }
738
739 pub fn req_driver_net(&self, index: usize) -> Option<MutBorrowReq<I>> {
746 let net = self.get_driver_net(index)?;
747 let operand = self.get_driver(index).unwrap();
748 Some(MutBorrowReq::new(operand, net))
749 }
750
751 pub fn get_num_input_ports(&self) -> usize {
753 if let Some(inst_type) = self.get_instance_type() {
754 inst_type.get_input_ports().into_iter().count()
755 } else {
756 0
757 }
758 }
759
760 pub fn is_fully_connected(&self) -> bool {
762 assert_eq!(
763 self.netref.borrow().operands.len(),
764 self.get_num_input_ports()
765 );
766 self.netref.borrow().operands.iter().all(|o| o.is_some())
767 }
768
769 pub fn drivers(&self) -> impl Iterator<Item = Option<Self>> {
771 let drivers: Vec<Option<Self>> = self
772 .netref
773 .borrow()
774 .drivers()
775 .map(|o| o.map(NetRef::wrap))
776 .collect();
777 drivers.into_iter()
778 }
779
780 pub fn driver_nets(&self) -> impl Iterator<Item = Option<Net>> {
782 let vec: Vec<Option<Net>> = self.netref.borrow().driver_nets().collect();
783 vec.into_iter()
784 }
785
786 #[allow(clippy::unnecessary_to_owned)]
788 pub fn nets(&self) -> impl Iterator<Item = Net> {
789 self.netref.borrow().get().get_nets().to_vec().into_iter()
790 }
791
792 pub fn inputs(&self) -> impl Iterator<Item = InputPort<I>> {
794 let len = self.netref.borrow().operands.len();
795 (0..len).map(move |i| InputPort::new(i, self.clone()))
796 }
797
798 pub fn outputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
800 let len = self.netref.borrow().get().get_nets().len();
801 (0..len).map(move |i| DrivenNet::new(i, self.clone()))
802 }
803
804 pub fn nets_mut(&self) -> impl Iterator<Item = RefMut<'_, Net>> {
806 let nnets = self.netref.borrow().get().get_nets().len();
807 (0..nnets).map(|i| self.get_net_mut(i))
808 }
809
810 pub fn drives_net(&self, net: &Net) -> bool {
812 self.netref.borrow().find_net(net).is_some()
813 }
814
815 pub fn drives_a_top_output(&self) -> bool {
820 let netlist = self
821 .netref
822 .borrow()
823 .owner
824 .upgrade()
825 .expect("NetRef is unlinked from netlist");
826 netlist.drives_an_output(self.clone())
827 }
828
829 pub fn find_net_mut(&self, net: &Net) -> Option<RefMut<'_, Net>> {
831 RefMut::filter_map(self.netref.borrow_mut(), |f| f.find_net_mut(net)).ok()
832 }
833
834 pub fn is_multi_output(&self) -> bool {
836 self.netref.borrow().get().get_nets().len() > 1
837 }
838
839 pub fn delete_uses(self) -> Result<Object<I>, Error> {
845 let netlist = self
846 .netref
847 .borrow()
848 .owner
849 .upgrade()
850 .expect("NetRef is unlinked from netlist");
851 netlist.delete_net_uses(self)
852 }
853
854 pub fn replace_uses_with(self, other: &DrivenNet<I>) -> Result<Object<I>, Error> {
861 let netlist = self
862 .netref
863 .borrow()
864 .owner
865 .upgrade()
866 .expect("NetRef is unlinked from netlist");
867 netlist.replace_net_uses(self.into(), other)
868 }
869
870 pub fn clear_attribute(&self, k: &AttributeKey) -> Option<AttributeValue> {
872 self.netref.borrow_mut().clear_attribute(k)
873 }
874
875 pub fn set_attribute(&self, k: AttributeKey) {
877 self.netref.borrow_mut().set_attribute(k);
878 }
879
880 pub fn insert_attribute(&self, k: AttributeKey, v: String) -> Option<AttributeValue> {
882 self.netref.borrow_mut().insert_attribute(k, v)
883 }
884
885 pub fn attributes(&self) -> impl Iterator<Item = Attribute> {
887 let v: Vec<_> = self.netref.borrow().attributes().collect();
888 v.into_iter()
889 }
890}
891
892impl<I> std::fmt::Display for NetRef<I>
893where
894 I: Instantiable,
895{
896 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
897 self.netref.borrow().object.fmt(f)
898 }
899}
900
901impl<I> From<NetRef<I>> for DrivenNet<I>
902where
903 I: Instantiable,
904{
905 fn from(val: NetRef<I>) -> Self {
906 if val.is_multi_output() {
907 panic!("Cannot convert a multi-output netref to an output port");
908 }
909 DrivenNet::new(0, val)
910 }
911}
912
913impl<I> From<&NetRef<I>> for DrivenNet<I>
914where
915 I: Instantiable,
916{
917 fn from(val: &NetRef<I>) -> Self {
918 if val.is_multi_output() {
919 panic!("Cannot convert a multi-output netref to an output port");
920 }
921 DrivenNet::new(0, val.clone())
922 }
923}
924
925pub struct MutBorrowReq<I: Instantiable> {
927 from: NetRef<I>,
928 ind: Net,
929}
930
931impl<I> MutBorrowReq<I>
932where
933 I: Instantiable,
934{
935 fn new(from: NetRef<I>, ind: Net) -> Self {
937 Self { from, ind }
938 }
939
940 pub fn borrow_mut(&self) -> RefMut<'_, Net> {
942 self.from.find_net_mut(&self.ind).unwrap()
943 }
944
945 pub fn is_an_input(&self) -> bool {
947 self.from.is_an_input()
948 }
949
950 pub fn borrow_mut_if(&self, f: impl Fn(&NetRef<I>) -> bool) -> Option<RefMut<'_, Net>> {
952 if f(&self.from) {
953 Some(self.borrow_mut())
954 } else {
955 None
956 }
957 }
958}
959
960#[derive(Debug)]
962pub struct Netlist<I>
963where
964 I: Instantiable,
965{
966 name: RefCell<String>,
968 objects: RefCell<Vec<NetRefT<I>>>,
970 outputs: RefCell<HashMap<Operand, BTreeSet<Net>>>,
972}
973
974#[derive(Debug, Clone)]
976pub struct InputPort<I: Instantiable> {
977 pos: usize,
978 netref: NetRef<I>,
979}
980
981impl<I> InputPort<I>
982where
983 I: Instantiable,
984{
985 fn new(pos: usize, netref: NetRef<I>) -> Self {
986 if pos >= netref.clone().unwrap().borrow().operands.len() {
987 panic!(
988 "Position {} out of bounds for netref with {} input nets",
989 pos,
990 netref.unwrap().borrow().get().get_nets().len()
991 );
992 }
993 Self { pos, netref }
994 }
995
996 pub fn get_driver(&self) -> Option<DrivenNet<I>> {
998 if self.netref.is_an_input() {
999 panic!("Input port is not driven by a primitive");
1000 }
1001 if let Some(prev_operand) = self.netref.clone().unwrap().borrow().operands[self.pos] {
1002 let netlist = self
1003 .netref
1004 .clone()
1005 .unwrap()
1006 .borrow()
1007 .owner
1008 .upgrade()
1009 .expect("Input port is unlinked from netlist");
1010 let driver_nr = netlist.index_weak(&prev_operand.root());
1011 let nr = NetRef::wrap(driver_nr);
1012 let pos = prev_operand.secondary();
1013 Some(DrivenNet::new(pos, nr))
1014 } else {
1015 None
1016 }
1017 }
1018
1019 pub fn disconnect(&self) -> Option<DrivenNet<I>> {
1021 let val = self.get_driver();
1022 self.netref.clone().unwrap().borrow_mut().operands[self.pos] = None;
1023 val
1024 }
1025
1026 pub fn get_port(&self) -> Net {
1028 if self.netref.is_an_input() {
1029 panic!("Net is not driven by a primitive");
1030 }
1031 self.netref
1032 .get_instance_type()
1033 .unwrap()
1034 .get_input_port(self.pos)
1035 .clone()
1036 }
1037
1038 pub fn connect(self, output: DrivenNet<I>) {
1040 output.connect(self);
1041 }
1042
1043 pub fn unwrap(self) -> NetRef<I> {
1045 self.netref
1046 }
1047}
1048
1049impl<I> std::fmt::Display for InputPort<I>
1050where
1051 I: Instantiable,
1052{
1053 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1054 self.get_port().fmt(f)
1055 }
1056}
1057
1058#[derive(Debug, Clone)]
1060pub struct DrivenNet<I: Instantiable> {
1061 pos: usize,
1062 netref: NetRef<I>,
1063}
1064
1065impl<I> DrivenNet<I>
1066where
1067 I: Instantiable,
1068{
1069 fn new(pos: usize, netref: NetRef<I>) -> Self {
1070 if pos >= netref.clone().unwrap().borrow().get().get_nets().len() {
1071 panic!(
1072 "Position {} out of bounds for netref with {} outputted nets",
1073 pos,
1074 netref.unwrap().borrow().get().get_nets().len()
1075 );
1076 }
1077 Self { pos, netref }
1078 }
1079
1080 fn get_operand(&self) -> Operand {
1082 if self.netref.is_multi_output() {
1083 Operand::CellIndex(self.netref.clone().unwrap().borrow().get_index(), self.pos)
1084 } else {
1085 Operand::DirectIndex(self.netref.clone().unwrap().borrow().get_index())
1086 }
1087 }
1088
1089 pub fn as_net(&self) -> Ref<'_, Net> {
1091 self.netref.get_net(self.pos)
1092 }
1093
1094 pub fn as_net_mut(&self) -> RefMut<'_, Net> {
1096 self.netref.get_net_mut(self.pos)
1097 }
1098
1099 pub fn is_an_input(&self) -> bool {
1101 self.netref.is_an_input()
1102 }
1103
1104 pub fn get_port(&self) -> Net {
1106 if self.netref.is_an_input() {
1107 panic!("Net is not driven by a primitive");
1108 }
1109 self.netref
1110 .get_instance_type()
1111 .unwrap()
1112 .get_output_port(self.pos)
1113 .clone()
1114 }
1115
1116 pub fn connect(&self, input: InputPort<I>) {
1118 let operand = self.get_operand();
1119 let index = input.netref.unwrap().borrow().get_index();
1120 let netlist = self
1121 .netref
1122 .clone()
1123 .unwrap()
1124 .borrow()
1125 .owner
1126 .upgrade()
1127 .expect("Output port is unlinked from netlist");
1128 let obj = netlist.index_weak(&index);
1129 obj.borrow_mut().operands[input.pos] = Some(operand);
1130 }
1131
1132 pub fn is_top_level_output(&self) -> bool {
1134 let netlist = self
1135 .netref
1136 .clone()
1137 .unwrap()
1138 .borrow()
1139 .owner
1140 .upgrade()
1141 .expect("DrivenNet is unlinked from netlist");
1142 let outputs = netlist.outputs.borrow();
1143 outputs.contains_key(&self.get_operand())
1144 }
1145
1146 pub fn unwrap(self) -> NetRef<I> {
1148 self.netref
1149 }
1150
1151 pub fn get_identifier(&self) -> Identifier {
1153 self.as_net().get_identifier().clone()
1154 }
1155
1156 pub fn expose_with_name(self, name: Identifier) -> Self {
1163 let netlist = self
1164 .netref
1165 .clone()
1166 .unwrap()
1167 .borrow()
1168 .owner
1169 .upgrade()
1170 .expect("DrivenNet is unlinked from netlist");
1171 netlist.expose_net_with_name(self.clone(), name);
1172 self
1173 }
1174
1175 pub fn remove_output(&self, net_name: &Identifier) -> bool {
1182 let netlist = self
1183 .netref
1184 .clone()
1185 .unwrap()
1186 .borrow()
1187 .owner
1188 .upgrade()
1189 .expect("DrivenNet is unlinked from netlist");
1190 netlist.remove_output(self, net_name)
1191 }
1192
1193 pub fn remove_all_outputs(&self) -> usize {
1200 let netlist = self
1201 .netref
1202 .clone()
1203 .unwrap()
1204 .borrow()
1205 .owner
1206 .upgrade()
1207 .expect("DrivenNet is unlinked from netlist");
1208 netlist.remove_outputs(self)
1209 }
1210
1211 pub fn get_output_index(&self) -> Option<usize> {
1213 if self.netref.is_an_input() {
1214 None
1215 } else {
1216 Some(self.pos)
1217 }
1218 }
1219
1220 pub fn get_instance_type(&self) -> Option<Ref<'_, I>> {
1222 self.netref.get_instance_type()
1223 }
1224}
1225
1226impl<I> std::fmt::Display for DrivenNet<I>
1227where
1228 I: Instantiable,
1229{
1230 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1231 self.as_net().fmt(f)
1232 }
1233}
1234
1235impl<I> PartialEq for DrivenNet<I>
1236where
1237 I: Instantiable,
1238{
1239 fn eq(&self, other: &Self) -> bool {
1240 self.netref == other.netref && self.pos == other.pos
1241 }
1242}
1243
1244impl<I> Eq for DrivenNet<I> where I: Instantiable {}
1245
1246impl<I> std::hash::Hash for DrivenNet<I>
1247where
1248 I: Instantiable,
1249{
1250 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1251 self.netref.hash(state);
1252 self.pos.hash(state);
1253 }
1254}
1255
1256impl<I> Ord for DrivenNet<I>
1257where
1258 I: Instantiable,
1259{
1260 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
1261 match self.netref.cmp(&other.netref) {
1262 std::cmp::Ordering::Equal => self.pos.cmp(&other.pos),
1263 ord => ord,
1264 }
1265 }
1266}
1267
1268impl<I> PartialOrd for DrivenNet<I>
1269where
1270 I: Instantiable,
1271{
1272 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1273 Some(self.cmp(other))
1274 }
1275}
1276
1277impl<I> WeakIndex<usize> for Netlist<I>
1278where
1279 I: Instantiable,
1280{
1281 type Output = OwnedObject<I, Self>;
1282
1283 fn index_weak(&self, index: &usize) -> Rc<RefCell<Self::Output>> {
1284 self.objects.borrow()[*index].clone()
1285 }
1286}
1287
1288impl<I> Netlist<I>
1289where
1290 I: Instantiable,
1291{
1292 pub fn new(name: String) -> Rc<Self> {
1294 Rc::new(Self {
1295 name: RefCell::new(name),
1296 objects: RefCell::new(Vec::new()),
1297 outputs: RefCell::new(HashMap::new()),
1298 })
1299 }
1300
1301 pub fn reclaim(self: Rc<Self>) -> Option<Self> {
1303 Rc::try_unwrap(self).ok()
1304 }
1305
1306 fn insert_object(
1308 self: &Rc<Self>,
1309 object: Object<I>,
1310 operands: &[DrivenNet<I>],
1311 ) -> Result<NetRef<I>, Error> {
1312 let index = self.objects.borrow().len();
1313 let weak = Rc::downgrade(self);
1314 let operands = operands
1315 .iter()
1316 .map(|net| Some(net.get_operand()))
1317 .collect::<Vec<_>>();
1318 let owned_object = Rc::new(RefCell::new(OwnedObject {
1319 object,
1320 owner: weak,
1321 operands,
1322 attributes: HashMap::new(),
1323 index,
1324 }));
1325 self.objects.borrow_mut().push(owned_object.clone());
1326 Ok(NetRef::wrap(owned_object))
1327 }
1328
1329 pub fn insert_input(self: &Rc<Self>, net: Net) -> DrivenNet<I> {
1331 let obj = Object::Input(net);
1332 self.insert_object(obj, &[]).unwrap().into()
1333 }
1334
1335 pub fn insert_input_escaped_logic_bus(
1337 self: &Rc<Self>,
1338 net: String,
1339 bw: usize,
1340 ) -> Vec<DrivenNet<I>> {
1341 Net::new_escaped_logic_bus(net, bw)
1342 .into_iter()
1343 .map(|n| self.insert_input(n))
1344 .collect()
1345 }
1346
1347 pub fn insert_gate(
1349 self: &Rc<Self>,
1350 inst_type: I,
1351 inst_name: Identifier,
1352 operands: &[DrivenNet<I>],
1353 ) -> Result<NetRef<I>, Error> {
1354 let nets = inst_type
1355 .get_output_ports()
1356 .into_iter()
1357 .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1358 .collect::<Vec<_>>();
1359 let input_count = inst_type.get_input_ports().into_iter().count();
1360 if operands.len() != input_count {
1361 return Err(Error::ArgumentMismatch(input_count, operands.len()));
1362 }
1363 let obj = Object::Instance(nets, inst_name, inst_type);
1364 self.insert_object(obj, operands)
1365 }
1366
1367 pub fn insert_gate_disconnected(
1369 self: &Rc<Self>,
1370 inst_type: I,
1371 inst_name: Identifier,
1372 ) -> NetRef<I> {
1373 let nets = inst_type
1374 .get_output_ports()
1375 .into_iter()
1376 .map(|pnet| pnet.with_name(&inst_name + pnet.get_identifier()))
1377 .collect::<Vec<_>>();
1378 let object = Object::Instance(nets, inst_name, inst_type);
1379 let index = self.objects.borrow().len();
1380 let weak = Rc::downgrade(self);
1381 let input_count = object
1382 .get_instance_type()
1383 .unwrap()
1384 .get_input_ports()
1385 .into_iter()
1386 .count();
1387 let operands = vec![None; input_count];
1388 let owned_object = Rc::new(RefCell::new(OwnedObject {
1389 object,
1390 owner: weak,
1391 operands,
1392 attributes: HashMap::new(),
1393 index,
1394 }));
1395 self.objects.borrow_mut().push(owned_object.clone());
1396 NetRef::wrap(owned_object)
1397 }
1398
1399 pub fn insert_constant(
1401 self: &Rc<Self>,
1402 value: Logic,
1403 inst_name: Identifier,
1404 ) -> Result<DrivenNet<I>, Error> {
1405 let obj = I::from_constant(value).ok_or(Error::InstantiableError(format!(
1406 "Instantiable type does not support constant value {}",
1407 value
1408 )))?;
1409 Ok(self.insert_gate_disconnected(obj, inst_name).into())
1410 }
1411
1412 pub fn get_driver(&self, netref: NetRef<I>, index: usize) -> Option<NetRef<I>> {
1418 let op = netref.unwrap().borrow().operands[index]?;
1419 Some(NetRef::wrap(self.index_weak(&op.root()).clone()))
1420 }
1421
1422 pub fn expose_net_with_name(&self, net: DrivenNet<I>, name: Identifier) -> DrivenNet<I> {
1425 let mut outputs = self.outputs.borrow_mut();
1426 let named_net = net.as_net().with_name(name);
1427 outputs
1428 .entry(net.get_operand())
1429 .or_default()
1430 .insert(named_net);
1431 net
1432 }
1433
1434 pub fn expose_net(&self, net: DrivenNet<I>) -> Result<DrivenNet<I>, Error> {
1436 if net.is_an_input() {
1437 return Err(Error::InputNeedsAlias(net.as_net().clone()));
1438 }
1439 let mut outputs = self.outputs.borrow_mut();
1440 outputs
1441 .entry(net.get_operand())
1442 .or_default()
1443 .insert(net.as_net().clone());
1444 Ok(net)
1445 }
1446
1447 pub fn remove_output(&self, operand: &DrivenNet<I>, net_name: &Identifier) -> bool {
1450 let mut outputs = self.outputs.borrow_mut();
1451 if let Some(nets) = outputs.get_mut(&operand.get_operand()) {
1452 let net_to_remove = Net::new(net_name.clone(), crate::circuit::DataType::logic());
1454 if nets.remove(&net_to_remove) {
1455 if nets.is_empty() {
1457 outputs.remove(&operand.get_operand());
1458 }
1459 return true;
1460 }
1461 }
1462 false
1463 }
1464
1465 pub fn remove_outputs(&self, operand: &DrivenNet<I>) -> usize {
1468 self.outputs
1470 .borrow_mut()
1471 .remove(&operand.get_operand())
1472 .map(|nets| nets.len())
1473 .unwrap_or(0)
1474 }
1475
1476 pub fn clear_outputs(&self) {
1478 self.outputs.borrow_mut().clear();
1479 }
1480
1481 pub fn delete_net_uses(&self, netref: NetRef<I>) -> Result<Object<I>, Error> {
1483 let unwrapped = netref.clone().unwrap();
1484 if Rc::strong_count(&unwrapped) > 3 {
1485 return Err(Error::DanglingReference(netref.nets().collect()));
1486 }
1487 let old_index = unwrapped.borrow().get_index();
1488 let objects = self.objects.borrow();
1489 for oref in objects.iter() {
1490 let operands = &mut oref.borrow_mut().operands;
1491 for operand in operands.iter_mut() {
1492 if let Some(op) = operand {
1493 match op {
1494 Operand::DirectIndex(idx) | Operand::CellIndex(idx, _)
1495 if *idx == old_index =>
1496 {
1497 *operand = None;
1498 }
1499 _ => (),
1500 }
1501 }
1502 }
1503 }
1504
1505 let outputs: Vec<Operand> = self
1506 .outputs
1507 .borrow()
1508 .keys()
1509 .filter(|operand| match operand {
1510 Operand::DirectIndex(idx) | Operand::CellIndex(idx, _) => *idx == old_index,
1511 })
1512 .cloned()
1513 .collect();
1514
1515 for operand in outputs {
1516 self.outputs.borrow_mut().remove(&operand);
1517 }
1518
1519 Ok(netref.unwrap().borrow().get().clone())
1520 }
1521
1522 pub fn replace_net_uses(
1524 &self,
1525 of: DrivenNet<I>,
1526 with: &DrivenNet<I>,
1527 ) -> Result<Object<I>, Error> {
1528 let unwrapped = of.clone().unwrap().unwrap();
1529 let i = of.get_output_index();
1530 let k = with.get_output_index();
1531
1532 if of.clone().unwrap() == with.clone().unwrap() {
1533 if i == k {
1534 return Ok(of.unwrap().unwrap().borrow().get().clone());
1535 }
1536
1537 if Rc::strong_count(&unwrapped) > 4 {
1538 return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1539 }
1540 } else if Rc::strong_count(&unwrapped) > 3 {
1541 return Err(Error::DanglingReference(of.unwrap().nets().collect()));
1542 }
1543
1544 let old_index = of.get_operand();
1545
1546 if let Some(nets) = self.outputs.borrow().get(&old_index)
1547 && nets.contains(&*of.as_net())
1548 {
1549 return Err(Error::NonuniqueNets(nets.iter().cloned().collect()));
1550 }
1551
1552 let new_index = with.get_operand();
1553 let objects = self.objects.borrow();
1554 for oref in objects.iter() {
1555 let operands = &mut oref.borrow_mut().operands;
1556 for operand in operands.iter_mut() {
1557 if let Some(op) = operand
1558 && *op == old_index
1559 {
1560 *operand = Some(new_index);
1561 }
1562 }
1563 }
1564
1565 let outs = self.outputs.borrow_mut().remove(&old_index);
1567 if let Some(outs) = outs {
1568 self.outputs
1569 .borrow_mut()
1570 .entry(new_index)
1571 .or_default()
1572 .extend(outs);
1573 }
1574
1575 Ok(of.unwrap().unwrap().borrow().get().clone())
1576 }
1577}
1578
1579impl<I> Netlist<I>
1580where
1581 I: Instantiable,
1582{
1583 pub fn get_name(&self) -> Ref<'_, String> {
1585 self.name.borrow()
1586 }
1587
1588 pub fn set_name(&self, name: String) {
1593 *self.name.borrow_mut() = name;
1594 }
1595
1596 pub fn get_input_ports(&self) -> impl Iterator<Item = Net> {
1598 self.objects().filter_map(|oref| {
1599 if oref.is_an_input() {
1600 Some(oref.as_net().clone())
1601 } else {
1602 None
1603 }
1604 })
1605 }
1606
1607 pub fn get_output_ports(&self) -> Vec<Net> {
1609 self.outputs
1610 .borrow()
1611 .values()
1612 .flat_map(|nets| nets.iter().cloned())
1613 .collect()
1614 }
1615
1616 pub fn get_analysis<'a, A: Analysis<'a, I>>(&'a self) -> Result<A, Error> {
1618 A::build(self)
1619 }
1620
1621 pub fn find_net(&self, net: &Net) -> Option<DrivenNet<I>> {
1624 for obj in self.objects() {
1625 for o in obj.outputs() {
1626 if *o.as_net() == *net {
1627 return Some(o);
1628 }
1629 }
1630 }
1631 None
1632 }
1633
1634 pub fn first(&self) -> Option<NetRef<I>> {
1636 self.objects
1637 .borrow()
1638 .first()
1639 .map(|nr| NetRef::wrap(nr.clone()))
1640 }
1641
1642 pub fn last(&self) -> Option<NetRef<I>> {
1644 self.objects
1645 .borrow()
1646 .last()
1647 .map(|nr| NetRef::wrap(nr.clone()))
1648 }
1649
1650 pub fn len(&self) -> usize {
1652 self.objects.borrow().len()
1653 }
1654
1655 pub fn is_empty(&self) -> bool {
1657 self.objects.borrow().is_empty()
1658 }
1659
1660 pub fn drives_an_output(&self, netref: NetRef<I>) -> bool {
1662 let my_index = netref.unwrap().borrow().get_index();
1663 for key in self.outputs.borrow().keys() {
1664 if key.root() == my_index {
1665 return true;
1666 }
1667 }
1668 false
1669 }
1670
1671 pub fn rename_nets<F: Fn(usize) -> Identifier>(&self, f: F) -> Result<(), Error> {
1674 let mut i: usize = 0;
1675 for nr in self.objects() {
1676 if nr.is_an_input() {
1677 continue;
1678 }
1679 for mut net in nr.nets_mut() {
1680 net.set_identifier(f(i));
1681 i += 1;
1682 }
1683 }
1684
1685 for nr in self.objects() {
1686 if nr.is_an_input() {
1687 continue;
1688 }
1689
1690 nr.set_instance_name(f(i));
1691 i += 1;
1692 }
1693
1694 self.verify()
1695 }
1696
1697 pub fn clean_once(&self) -> Result<bool, Error> {
1699 let mut dead_objs = HashSet::new();
1700 {
1701 let fan_out = self.get_analysis::<FanOutTable<I>>()?;
1702 for obj in self.objects() {
1703 let mut is_dead = true;
1704 for net in obj.nets() {
1705 if fan_out.net_has_uses(&net) {
1707 is_dead = false;
1708 break;
1709 }
1710 }
1711 if is_dead && !obj.is_an_input() {
1712 dead_objs.insert(obj.unwrap().borrow().index);
1713 }
1714 }
1715 }
1716
1717 if dead_objs.is_empty() {
1718 return Ok(false);
1719 }
1720
1721 let old_objects = self.objects.take();
1722
1723 for i in dead_objs.iter() {
1725 let rc = &old_objects[*i];
1726 if Rc::strong_count(rc) > 1 {
1727 self.objects.replace(old_objects.clone());
1728 return Err(Error::DanglingReference(
1729 rc.borrow().get().get_nets().to_vec(),
1730 ));
1731 }
1732 }
1733
1734 let mut remap: HashMap<usize, usize> = HashMap::new();
1735 for (old_index, obj) in old_objects.into_iter().enumerate() {
1736 if dead_objs.contains(&old_index) {
1737 continue;
1738 }
1739
1740 let new_index = self.objects.borrow().len();
1741 remap.insert(old_index, new_index);
1742 obj.borrow_mut().index = new_index;
1743 self.objects.borrow_mut().push(obj);
1744 }
1745
1746 for obj in self.objects.borrow().iter() {
1747 for operand in obj.borrow_mut().inds_mut() {
1748 let root = operand.root();
1749 let root = *remap.get(&root).unwrap_or(&root);
1750 *operand = operand.remap(root);
1751 }
1752 }
1753
1754 let pairs: Vec<_> = self.outputs.take().into_iter().collect();
1755 for (operand, net) in pairs {
1756 let root = operand.root();
1757 let root = *remap.get(&root).unwrap_or(&root);
1758 let new_operand = operand.remap(root);
1759 self.outputs.borrow_mut().insert(new_operand, net);
1760 }
1761
1762 Ok(true)
1763 }
1764
1765 pub fn clean(&self) -> Result<bool, Error> {
1768 if !self.clean_once()? {
1769 Ok(false)
1770 } else {
1771 let mut changed = true;
1772 while changed {
1773 changed = self.clean_once()?;
1774 }
1775 Ok(true)
1776 }
1777 }
1778
1779 fn nets_unique(&self) -> Result<(), Error> {
1781 let mut nets = HashSet::new();
1782 for net in self.into_iter() {
1783 if !nets.insert(net.clone().take_identifier()) {
1784 return Err(Error::NonuniqueNets(vec![net]));
1785 }
1786 }
1787 Ok(())
1788 }
1789
1790 fn insts_unique(&self) -> Result<(), Error> {
1792 let mut insts = HashSet::new();
1793 for inst in self.objects() {
1794 if let Some(name) = inst.get_instance_name()
1795 && !insts.insert(name.clone())
1796 {
1797 return Err(Error::NonuniqueInsts(vec![name]));
1798 }
1799 }
1800 Ok(())
1801 }
1802
1803 pub fn verify(&self) -> Result<(), Error> {
1805 if self.outputs.borrow().is_empty() {
1806 return Err(Error::NoOutputs);
1807 }
1808
1809 self.nets_unique()?;
1810
1811 self.insts_unique()?;
1812
1813 Ok(())
1814 }
1815}
1816
1817#[derive(Debug, Clone)]
1819pub struct Connection<I: Instantiable> {
1820 driver: DrivenNet<I>,
1821 input: InputPort<I>,
1822}
1823
1824impl<I> Connection<I>
1825where
1826 I: Instantiable,
1827{
1828 fn new(driver: DrivenNet<I>, input: InputPort<I>) -> Self {
1829 Self { driver, input }
1830 }
1831
1832 pub fn src(&self) -> DrivenNet<I> {
1834 self.driver.clone()
1835 }
1836
1837 pub fn net(&self) -> Net {
1839 self.driver.as_net().clone()
1840 }
1841
1842 pub fn target(&self) -> InputPort<I> {
1844 self.input.clone()
1845 }
1846}
1847
1848impl<I> std::fmt::Display for Connection<I>
1849where
1850 I: Instantiable,
1851{
1852 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1853 self.net().fmt(f)
1854 }
1855}
1856
1857pub mod iter {
1859
1860 use super::{
1861 Connection, DrivenNet, InputPort, Instantiable, Net, NetRef, Netlist, Operand, WeakIndex,
1862 };
1863 use std::collections::{HashMap, HashSet};
1864 pub struct NetIterator<'a, I: Instantiable> {
1866 netlist: &'a Netlist<I>,
1867 index: usize,
1868 subindex: usize,
1869 }
1870
1871 impl<'a, I> NetIterator<'a, I>
1872 where
1873 I: Instantiable,
1874 {
1875 pub fn new(netlist: &'a Netlist<I>) -> Self {
1877 Self {
1878 netlist,
1879 index: 0,
1880 subindex: 0,
1881 }
1882 }
1883 }
1884
1885 impl<I> Iterator for NetIterator<'_, I>
1886 where
1887 I: Instantiable,
1888 {
1889 type Item = Net;
1890
1891 fn next(&mut self) -> Option<Self::Item> {
1892 while self.index < self.netlist.objects.borrow().len() {
1893 let objects = self.netlist.objects.borrow();
1894 let object = objects[self.index].borrow();
1895 if self.subindex < object.get().get_nets().len() {
1896 let net = object.get().get_nets()[self.subindex].clone();
1897 self.subindex += 1;
1898 return Some(net);
1899 }
1900 self.subindex = 0;
1901 self.index += 1;
1902 }
1903 None
1904 }
1905 }
1906
1907 pub struct ObjectIterator<'a, I: Instantiable> {
1909 netlist: &'a Netlist<I>,
1910 index: usize,
1911 }
1912
1913 impl<'a, I> ObjectIterator<'a, I>
1914 where
1915 I: Instantiable,
1916 {
1917 pub fn new(netlist: &'a Netlist<I>) -> Self {
1919 Self { netlist, index: 0 }
1920 }
1921 }
1922
1923 impl<I> Iterator for ObjectIterator<'_, I>
1924 where
1925 I: Instantiable,
1926 {
1927 type Item = NetRef<I>;
1928
1929 fn next(&mut self) -> Option<Self::Item> {
1930 if self.index < self.netlist.objects.borrow().len() {
1931 let objects = self.netlist.objects.borrow();
1932 let object = &objects[self.index];
1933 self.index += 1;
1934 return Some(NetRef::wrap(object.clone()));
1935 }
1936 None
1937 }
1938 }
1939
1940 pub struct ConnectionIterator<'a, I: Instantiable> {
1942 netlist: &'a Netlist<I>,
1943 index: usize,
1944 subindex: usize,
1945 }
1946
1947 impl<'a, I> ConnectionIterator<'a, I>
1948 where
1949 I: Instantiable,
1950 {
1951 pub fn new(netlist: &'a Netlist<I>) -> Self {
1953 Self {
1954 netlist,
1955 index: 0,
1956 subindex: 0,
1957 }
1958 }
1959 }
1960
1961 impl<I> Iterator for ConnectionIterator<'_, I>
1962 where
1963 I: Instantiable,
1964 {
1965 type Item = super::Connection<I>;
1966
1967 fn next(&mut self) -> Option<Self::Item> {
1968 while self.index < self.netlist.objects.borrow().len() {
1969 let objects = self.netlist.objects.borrow();
1970 let object = objects[self.index].borrow();
1971 let noperands = object.operands.len();
1972 while self.subindex < noperands {
1973 if let Some(operand) = &object.operands[self.subindex] {
1974 let driver = match operand {
1975 Operand::DirectIndex(idx) => {
1976 DrivenNet::new(0, NetRef::wrap(objects[*idx].clone()))
1977 }
1978 Operand::CellIndex(idx, j) => {
1979 DrivenNet::new(*j, NetRef::wrap(objects[*idx].clone()))
1980 }
1981 };
1982 let input = InputPort::new(
1983 self.subindex,
1984 NetRef::wrap(objects[self.index].clone()),
1985 );
1986 self.subindex += 1;
1987 return Some(Connection::new(driver, input));
1988 }
1989 self.subindex += 1;
1990 }
1991 self.subindex = 0;
1992 self.index += 1;
1993 }
1994 None
1995 }
1996 }
1997
1998 #[derive(Clone)]
2000 struct Walk<T: std::hash::Hash + PartialEq + Eq + Clone> {
2001 stack: Vec<T>,
2002 counter: HashMap<T, usize>,
2003 }
2004
2005 impl<T> Walk<T>
2006 where
2007 T: std::hash::Hash + PartialEq + Eq + Clone,
2008 {
2009 fn new() -> Self {
2011 Self {
2012 stack: Vec::new(),
2013 counter: HashMap::new(),
2014 }
2015 }
2016
2017 fn push(&mut self, item: T) {
2019 self.stack.push(item.clone());
2020 *self.counter.entry(item).or_insert(0) += 1;
2021 }
2022
2023 fn contains_cycle(&self) -> bool {
2025 self.counter.values().any(|&count| count > 1)
2026 }
2027
2028 fn last(&self) -> Option<&T> {
2030 self.stack.last()
2031 }
2032 }
2033
2034 pub struct DFSIterator<'a, I: Instantiable> {
2053 netlist: &'a Netlist<I>,
2054 stacks: Vec<Walk<NetRef<I>>>,
2055 visited: HashSet<usize>,
2056 cycles: bool,
2057 }
2058
2059 impl<'a, I> DFSIterator<'a, I>
2060 where
2061 I: Instantiable,
2062 {
2063 pub fn new(netlist: &'a Netlist<I>, from: NetRef<I>) -> Self {
2065 let mut s = Walk::new();
2066 s.push(from);
2067 Self {
2068 netlist,
2069 stacks: vec![s],
2070 visited: HashSet::new(),
2071 cycles: false,
2072 }
2073 }
2074 }
2075
2076 impl<I> DFSIterator<'_, I>
2077 where
2078 I: Instantiable,
2079 {
2080 pub fn check_cycles(&self) -> bool {
2082 self.cycles
2083 }
2084
2085 pub fn detect_cycles(mut self) -> bool {
2087 if self.cycles {
2088 return true;
2089 }
2090
2091 while let Some(_) = self.next() {
2092 if self.cycles {
2093 return true;
2094 }
2095 }
2096
2097 self.cycles
2098 }
2099 }
2100
2101 impl<I> Iterator for DFSIterator<'_, I>
2102 where
2103 I: Instantiable,
2104 {
2105 type Item = NetRef<I>;
2106
2107 fn next(&mut self) -> Option<Self::Item> {
2108 if let Some(walk) = self.stacks.pop() {
2109 let item = walk.last().cloned();
2110 let uw = item.clone().unwrap().unwrap();
2111 let index = uw.borrow().get_index();
2112 if self.visited.insert(index) {
2113 let operands = &uw.borrow().operands;
2114 for operand in operands.iter().flatten() {
2115 let mut new_walk = walk.clone();
2116 new_walk.push(NetRef::wrap(self.netlist.index_weak(&operand.root())));
2117 if !new_walk.contains_cycle() {
2118 self.stacks.push(new_walk);
2119 } else {
2120 self.cycles = true;
2121 }
2122 }
2123 return item;
2124 }
2125
2126 return self.next();
2127 }
2128
2129 None
2130 }
2131 }
2132}
2133
2134impl<'a, I> IntoIterator for &'a Netlist<I>
2135where
2136 I: Instantiable,
2137{
2138 type Item = Net;
2139 type IntoIter = iter::NetIterator<'a, I>;
2140
2141 fn into_iter(self) -> Self::IntoIter {
2142 iter::NetIterator::new(self)
2143 }
2144}
2145
2146#[macro_export]
2149macro_rules! filter_nodes {
2150 ($netlist:ident, $pattern:pat $(if $guard:expr)? $(,)?) => {
2151 $netlist.matches(|f| match f {
2152 $pattern $(if $guard)? => true,
2153 _ => false
2154 })
2155 };
2156}
2157
2158impl<I> Netlist<I>
2159where
2160 I: Instantiable,
2161{
2162 pub fn objects(&self) -> impl Iterator<Item = NetRef<I>> {
2164 iter::ObjectIterator::new(self)
2165 }
2166
2167 pub fn matches<F>(&self, filter: F) -> impl Iterator<Item = NetRef<I>>
2169 where
2170 F: Fn(&I) -> bool,
2171 {
2172 self.objects().filter(move |f| {
2173 if let Some(inst_type) = f.get_instance_type() {
2174 filter(&inst_type)
2175 } else {
2176 false
2177 }
2178 })
2179 }
2180
2181 pub fn inputs(&self) -> impl Iterator<Item = DrivenNet<I>> {
2183 self.objects()
2184 .filter(|n| n.is_an_input())
2185 .map(|n| DrivenNet::new(0, n))
2186 }
2187
2188 pub fn outputs(&self) -> Vec<(DrivenNet<I>, Net)> {
2190 self.outputs
2191 .borrow()
2192 .iter()
2193 .flat_map(|(k, nets)| {
2194 nets.iter().map(|n| {
2195 (
2196 DrivenNet::new(k.secondary(), NetRef::wrap(self.index_weak(&k.root()))),
2197 n.clone(),
2198 )
2199 })
2200 })
2201 .collect()
2202 }
2203
2204 pub fn connections(&self) -> impl Iterator<Item = Connection<I>> {
2206 iter::ConnectionIterator::new(self)
2207 }
2208
2209 pub fn dfs(&self, from: NetRef<I>) -> impl Iterator<Item = NetRef<I>> {
2211 iter::DFSIterator::new(self, from)
2212 }
2213
2214 #[cfg(feature = "serde")]
2215 pub fn serialize(self, writer: impl std::io::Write) -> Result<(), serde_json::Error>
2217 where
2218 I: ::serde::Serialize,
2219 {
2220 serde::netlist_serialize(self, writer)
2221 }
2222}
2223
2224impl<I> std::fmt::Display for Netlist<I>
2225where
2226 I: Instantiable,
2227{
2228 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2229 let objects = self.objects.borrow();
2231 let outputs = self.outputs.borrow();
2232
2233 writeln!(f, "module {} (", self.get_name())?;
2234
2235 let level = 2;
2237 let indent = " ".repeat(level);
2238 for oref in objects.iter() {
2239 let owned = oref.borrow();
2240 let obj = owned.get();
2241 if let Object::Input(net) = obj {
2242 writeln!(f, "{}{},", indent, net.get_identifier().emit_name())?;
2243 }
2244 }
2245
2246 let all_outputs: Vec<_> = outputs.iter().flat_map(|(_, nets)| nets.iter()).collect();
2248 for (i, net) in all_outputs.iter().enumerate() {
2249 if i == all_outputs.len() - 1 {
2250 writeln!(f, "{}{}", indent, net.get_identifier().emit_name())?;
2251 } else {
2252 writeln!(f, "{}{},", indent, net.get_identifier().emit_name())?;
2253 }
2254 }
2255 writeln!(f, ");")?;
2256
2257 let mut already_decl = HashSet::new();
2259 for oref in objects.iter() {
2260 let owned = oref.borrow();
2261 let obj = owned.get();
2262 if let Object::Input(net) = obj {
2263 writeln!(f, "{}input {};", indent, net.get_identifier().emit_name())?;
2264 writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2265 already_decl.insert(net.clone());
2266 }
2267 }
2268 for nets in outputs.values() {
2269 for net in nets {
2270 if !already_decl.contains(net) {
2271 writeln!(f, "{}output {};", indent, net.get_identifier().emit_name())?;
2272 writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2273 already_decl.insert(net.clone());
2274 }
2275 }
2276 }
2277 for oref in objects.iter() {
2278 let owned = oref.borrow();
2279 let obj = owned.get();
2280 if let Object::Instance(nets, _, inst_type) = obj
2281 && inst_type.get_constant().is_none()
2282 {
2283 for net in nets.iter() {
2284 if !already_decl.contains(net) {
2285 writeln!(f, "{}wire {};", indent, net.get_identifier().emit_name())?;
2286 already_decl.insert(net.clone());
2287 }
2288 }
2289 }
2290 }
2291
2292 for oref in objects.iter() {
2293 let owned = oref.borrow();
2294 let obj = owned.get();
2295
2296 if let Some(inst_type) = obj.get_instance_type()
2298 && inst_type.get_constant().is_some()
2299 {
2300 continue;
2301 }
2302
2303 if let Object::Instance(nets, inst_name, inst_type) = obj {
2304 for (k, v) in owned.attributes.iter() {
2305 if let Some(value) = v {
2306 writeln!(f, "{indent}(* {k} = \"{value}\" *)")?;
2307 } else {
2308 writeln!(f, "{indent}(* {k} *)")?;
2309 }
2310 }
2311
2312 write!(f, "{}{} ", indent, inst_type.get_name())?;
2313 if inst_type.is_parameterized() {
2314 writeln!(f, "#(")?;
2315 let level = 4;
2316 let indent = " ".repeat(level);
2317 let params: Vec<_> = inst_type.parameters().collect();
2318 for (i, (k, v)) in params.iter().enumerate() {
2319 if i == params.len() - 1 {
2320 writeln!(f, "{indent}.{k}({v})")?;
2321 } else {
2322 writeln!(f, "{indent}.{k}({v}),")?;
2323 }
2324 }
2325 let level = 2;
2326 let indent = " ".repeat(level);
2327 write!(f, "{indent}) ")?;
2328 }
2329 writeln!(f, "{} (", inst_name.emit_name())?;
2330 let level = 4;
2331 let indent = " ".repeat(level);
2332 for (idx, port) in inst_type.get_input_ports().into_iter().enumerate() {
2333 let port_name = port.get_identifier().emit_name();
2334 if let Some(operand) = owned.operands[idx].as_ref() {
2335 let operand_net = match operand {
2336 Operand::DirectIndex(idx) => objects[*idx].borrow().as_net().clone(),
2337 Operand::CellIndex(idx, j) => {
2338 objects[*idx].borrow().get_net(*j).clone()
2339 }
2340 };
2341
2342 let operand_str = if let Some(inst_type) =
2343 objects[operand.root()].borrow().get().get_instance_type()
2344 && let Some(logic) = inst_type.get_constant()
2345 {
2346 logic.to_string()
2347 } else {
2348 operand_net.get_identifier().emit_name()
2349 };
2350
2351 writeln!(f, "{}.{}({}),", indent, port_name, operand_str)?;
2352 }
2353 }
2354
2355 for (idx, net) in nets.iter().enumerate() {
2356 let port_name = inst_type.get_output_port(idx).get_identifier().emit_name();
2357 if idx == nets.len() - 1 {
2358 writeln!(
2359 f,
2360 "{}.{}({})",
2361 indent,
2362 port_name,
2363 net.get_identifier().emit_name()
2364 )?;
2365 } else {
2366 writeln!(
2367 f,
2368 "{}.{}({}),",
2369 indent,
2370 port_name,
2371 net.get_identifier().emit_name()
2372 )?;
2373 }
2374 }
2375
2376 let level = 2;
2377 let indent = " ".repeat(level);
2378 writeln!(f, "{indent});")?;
2379 }
2380 }
2381
2382 for (driver, nets) in outputs.iter() {
2383 for net in nets {
2384 let driver_net = match driver {
2385 Operand::DirectIndex(idx) => self.index_weak(idx).borrow().as_net().clone(),
2386 Operand::CellIndex(idx, j) => self.index_weak(idx).borrow().get_net(*j).clone(),
2387 };
2388
2389 let driver_str = if let Some(inst_type) = self
2390 .index_weak(&driver.root())
2391 .borrow()
2392 .get()
2393 .get_instance_type()
2394 && let Some(logic) = inst_type.get_constant()
2395 {
2396 logic.to_string()
2397 } else {
2398 driver_net.get_identifier().emit_name()
2399 };
2400
2401 if net.get_identifier() != driver_net.get_identifier() {
2402 writeln!(
2403 f,
2404 "{}assign {} = {};",
2405 indent,
2406 net.get_identifier().emit_name(),
2407 driver_str
2408 )?;
2409 }
2410 }
2411 }
2412
2413 writeln!(f, "endmodule")
2414 }
2415}
2416
2417pub type GateNetlist = Netlist<Gate>;
2419pub type GateRef = NetRef<Gate>;
2421
2422#[cfg(test)]
2423mod tests {
2424 use super::*;
2425 #[test]
2426 fn test_delete_netlist() {
2427 let netlist = Netlist::new("simple_example".to_string());
2428
2429 let input1 = netlist.insert_input("input1".into());
2431 let input2 = netlist.insert_input("input2".into());
2432
2433 let instance = netlist
2435 .insert_gate(
2436 Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into()),
2437 "my_and".into(),
2438 &[input1.clone(), input2.clone()],
2439 )
2440 .unwrap();
2441
2442 let instance = instance.expose_as_output().unwrap();
2444 instance.delete_uses().unwrap();
2445 assert!(netlist.clean().is_err());
2447 input1.expose_with_name("an_output".into());
2448 assert!(netlist.clean().is_ok());
2449 }
2450
2451 #[test]
2452 #[should_panic(expected = "Attempted to create a gate with a sliced identifier")]
2453 fn gate_w_slice_panics() {
2454 Gate::new_logical("AND[1]".into(), vec!["A".into(), "B".into()], "Y".into());
2455 }
2456
2457 #[test]
2458 fn gates_dont_have_params() {
2459 let gate = Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into());
2461 assert!(!gate.has_parameter(&"id".into()));
2462 assert!(gate.get_parameter(&"id".into()).is_none());
2463 assert_eq!(*gate.get_gate_name(), "AND".into());
2464 }
2465
2466 #[test]
2467 fn operand_conversions() {
2468 let operand = Operand::CellIndex(3, 2);
2469 assert_eq!(operand.to_string(), "3.2");
2470 let parsed = "3.2".parse::<Operand>();
2471 assert!(parsed.is_ok());
2472 let parsed = parsed.unwrap();
2473 assert_eq!(operand, parsed);
2474 }
2475
2476 #[test]
2477 #[should_panic(expected = "out of bounds for netref")]
2478 fn test_bad_output() {
2479 let netlist = GateNetlist::new("min_module".to_string());
2480 let a = netlist.insert_input("a".into());
2481 DrivenNet::new(1, a.unwrap());
2482 }
2483}
2484#[cfg(feature = "serde")]
2485pub mod serde {
2487 use super::{Netlist, Operand, OwnedObject, WeakIndex};
2488 use crate::{
2489 attribute::{AttributeKey, AttributeValue},
2490 circuit::{Instantiable, Net, Object},
2491 };
2492 use serde::{Deserialize, Serialize, de::DeserializeOwned};
2493 use std::cell::RefCell;
2494 use std::{
2495 collections::{BTreeSet, HashMap},
2496 rc::Rc,
2497 };
2498
2499 #[derive(Debug, Serialize, Deserialize)]
2500 struct SerdeObject<I>
2501 where
2502 I: Instantiable + Serialize,
2503 {
2504 object: Object<I>,
2506 operands: Vec<Option<Operand>>,
2508 attributes: HashMap<AttributeKey, AttributeValue>,
2510 }
2511
2512 impl<I, O> From<OwnedObject<I, O>> for SerdeObject<I>
2513 where
2514 I: Instantiable + Serialize,
2515 O: WeakIndex<usize, Output = OwnedObject<I, O>>,
2516 {
2517 fn from(value: OwnedObject<I, O>) -> Self {
2518 SerdeObject {
2519 object: value.object,
2520 operands: value.operands,
2521 attributes: value.attributes,
2522 }
2523 }
2524 }
2525
2526 impl<I> SerdeObject<I>
2527 where
2528 I: Instantiable + Serialize,
2529 {
2530 fn into_owned_object<O>(self, owner: &Rc<O>, index: usize) -> OwnedObject<I, O>
2531 where
2532 O: WeakIndex<usize, Output = OwnedObject<I, O>>,
2533 {
2534 OwnedObject {
2535 object: self.object,
2536 owner: Rc::downgrade(owner),
2537 operands: self.operands,
2538 attributes: self.attributes,
2539 index,
2540 }
2541 }
2542 }
2543
2544 #[derive(Debug, Serialize, Deserialize)]
2545 struct SerdeNetlist<I>
2546 where
2547 I: Instantiable + Serialize,
2548 {
2549 name: String,
2551 objects: Vec<SerdeObject<I>>,
2553 outputs: HashMap<String, BTreeSet<Net>>,
2557 }
2558
2559 impl<I> From<Netlist<I>> for SerdeNetlist<I>
2560 where
2561 I: Instantiable + Serialize,
2562 {
2563 fn from(value: Netlist<I>) -> Self {
2564 SerdeNetlist {
2565 name: value.name.into_inner(),
2566 objects: value
2567 .objects
2568 .into_inner()
2569 .into_iter()
2570 .map(|o| {
2571 Rc::try_unwrap(o)
2572 .ok()
2573 .expect("Cannot serialize with live references")
2574 .into_inner()
2575 .into()
2576 })
2577 .collect(),
2578 outputs: value
2579 .outputs
2580 .into_inner()
2581 .into_iter()
2582 .map(|(o, nets)| (o.to_string(), nets.into_iter().collect()))
2584 .collect(),
2585 }
2586 }
2587 }
2588
2589 impl<I> SerdeNetlist<I>
2590 where
2591 I: Instantiable + Serialize,
2592 {
2593 fn into_netlist(self) -> Rc<Netlist<I>> {
2595 let netlist = Netlist::new(self.name);
2596 let outputs: HashMap<Operand, BTreeSet<Net>> = self
2597 .outputs
2598 .into_iter()
2599 .map(|(k, v)| {
2600 let operand = k.parse::<Operand>().expect("Invalid index");
2601 (operand, v.into_iter().collect())
2602 })
2603 .collect();
2604 let objects = self
2605 .objects
2606 .into_iter()
2607 .enumerate()
2608 .map(|(i, o)| {
2609 let owned_object = o.into_owned_object(&netlist, i);
2610 Rc::new(RefCell::new(owned_object))
2611 })
2612 .collect::<Vec<_>>();
2613 {
2614 let mut objs_mut = netlist.objects.borrow_mut();
2615 *objs_mut = objects;
2616 let mut outputs_mut = netlist.outputs.borrow_mut();
2617 *outputs_mut = outputs;
2618 }
2619 netlist
2620 }
2621 }
2622
2623 pub fn netlist_serialize<I: Instantiable + Serialize>(
2625 netlist: Netlist<I>,
2626 writer: impl std::io::Write,
2627 ) -> Result<(), serde_json::Error> {
2628 let sobj: SerdeNetlist<I> = netlist.into();
2629 serde_json::to_writer_pretty(writer, &sobj)
2630 }
2631
2632 pub fn netlist_deserialize<I: Instantiable + Serialize + DeserializeOwned>(
2634 reader: impl std::io::Read,
2635 ) -> Result<Rc<Netlist<I>>, serde_json::Error> {
2636 let sobj: SerdeNetlist<I> = serde_json::from_reader(reader)?;
2637 Ok(sobj.into_netlist())
2638 }
2639}