rust_hdl_core/
check_connected.rs1use crate::atom::Atom;
2use crate::atom::AtomKind;
3use crate::block::Block;
4use crate::check_error::{CheckError, OpenMap, PathedName};
5use crate::named_path::NamedPath;
6use crate::probe::Probe;
7
8#[derive(Default)]
9struct CheckConnected {
10 path: NamedPath,
11 namespace: NamedPath,
12 failures: OpenMap,
13}
14
15impl Probe for CheckConnected {
16 fn visit_start_scope(&mut self, name: &str, _node: &dyn Block) {
17 self.path.push(name);
18 self.namespace.reset();
19 }
20
21 fn visit_start_namespace(&mut self, name: &str, _node: &dyn Block) {
22 self.namespace.push(name);
23 }
24
25 fn visit_atom(&mut self, name: &str, signal: &dyn Atom) {
26 let is_top_scope = self.path.to_string().eq("uut");
27 let signal_is_connected = signal.connected();
28 let signal_is_input =
29 [AtomKind::InputParameter, AtomKind::InOutParameter].contains(&signal.kind());
30 if !(signal_is_connected | (signal_is_input && is_top_scope)) {
31 dbg!(&signal.kind());
32 self.failures.insert(
33 signal.id(),
34 dbg!(PathedName {
35 path: self.path.to_string(),
36 name: if self.namespace.is_empty() {
37 name.to_string()
38 } else {
39 format!("{}${name}", self.namespace.to_string())
40 }
41 }),
42 );
43 }
44 }
45
46 fn visit_end_namespace(&mut self, _name: &str, _node: &dyn Block) {
47 self.namespace.pop();
48 }
49
50 fn visit_end_scope(&mut self, _name: &str, _node: &dyn Block) {
51 self.path.pop();
52 }
53}
54
55pub fn check_connected(uut: &dyn Block) -> Result<(), CheckError> {
79 let mut visitor = CheckConnected::default();
80 uut.accept("uut", &mut visitor);
81 if visitor.failures.is_empty() {
82 Ok(())
83 } else {
84 Err(CheckError::OpenSignal(visitor.failures))
85 }
86}