1mod check;
2mod mlir;
3
4use super::*;
5use std::collections::BTreeSet;
6use std::sync::Arc;
7
8#[derive(Debug, Clone)]
11pub struct Circuit(pub(crate) Package, pub(crate) Arc<Component>);
12
13impl Circuit {
14 pub fn package(&self) -> &Package {
15 &self.0
16 }
17
18 pub fn top(&self) -> Arc<Component> {
20 self.1.clone()
21 }
22
23 pub fn component(&self, path: Path) -> Option<Arc<Component>> {
26 if path == "top".into() {
27 return Some(self.top());
28 }
29 let root_prefix = format!("top.");
30 if !path.starts_with(&root_prefix) {
31 return None;
32 }
33 let path: Path = path[root_prefix.len()..].into();
34 self.component_from(self.top(), path)
35 }
36
37 fn component_from(&self, component: Arc<Component>, path: Path) -> Option<Arc<Component>> {
38 let mut result: Arc<Component> = component;
39 for part in path.split(".") {
40 if let Some(child) = result.child(part) {
41 if let Component::ModInst(_loc, _name, moddef) = &*child {
42 result = moddef.clone();
43 } else {
44 result = child.clone();
45 }
46 }
47 }
48 Some(result)
49 }
50
51 pub fn wires(&self) -> Vec<(Path, Wire)> {
53 let mut results = vec![];
54 for (path, component) in self.walk_instances() {
55 for wire in component.wires() {
56 results.push((path.clone(), wire));
58 }
59 }
60 results
61 }
62
63 pub fn exts(&self) -> Vec<Path> {
64 let mut results = vec![];
65 for (path, component) in self.walk_instances() {
66 if let Component::Ext(_loc, _name, _children) = &*component {
67 results.push(path);
68 }
69 }
70 results
71 }
72
73 pub fn regs(&self) -> Vec<Path> {
75 let mut results = vec![];
76 for (path, component) in self.walk_instances() {
77 if let Component::Reg(_loc, _name, _typ, _reset) = &*component {
78 results.push(path);
79 }
80 }
81 results
82 }
83
84 pub fn paths(&self) -> Vec<Path> {
86 self.top().paths_rec("top".into())
87 }
88
89 pub fn reset_for_reg(&self, path: Path) -> Option<Arc<Expr>> {
91 if let Component::Reg(_loc, _name, _typ, reset) = &*self.component(path)? {
92 reset.clone()
93 } else {
94 None
95 }
96 }
97
98 fn walk_instances(&self) -> Vec<(Path, Arc<Component>)> {
99 self.walk_instances_rec(self.top(), "top".into())
100 }
101
102 fn walk_instances_rec(
103 &self,
104 component: Arc<Component>,
105 path: Path,
106 ) -> Vec<(Path, Arc<Component>)> {
107 let mut results = vec![(path.clone(), component.clone())];
108 for child in component.children() {
109 if let Component::ModInst(_loc, name, reference) = &*child {
110 if let Some(moddef) = self.package().moddef(reference.name()) {
111 results.extend(
112 self.walk_instances_rec(moddef.clone(), path.join(child.name().into())),
113 );
114 } else {
115 panic!("Undefined reference to ext: {name}")
116 }
117 } else {
118 results
119 .extend(self.walk_instances_rec(child.clone(), path.join(child.name().into())));
120 }
121 }
122 results
123 }
124}