1use rustdv_gpi as gpi;
7pub use rustdv_gpi::{HandleError, Logic, LogicArray, ValueError};
8
9use crate::phase;
10use crate::triggers::{Edge, EdgeKind};
11
12#[derive(Copy, Clone)]
14pub struct HierarchyHandle {
15 raw: gpi::HierarchyHandle,
16}
17impl HierarchyHandle {
18 pub fn null_for_test() -> HierarchyHandle {
24 HierarchyHandle { raw: gpi::HierarchyHandle::null_for_test() }
25 }
26}
27
28
29impl HierarchyHandle {
30 pub fn child(&self, name: &str) -> Result<AnyHandle, HandleError> {
31 Ok(AnyHandle::wrap(self.raw.child(name)?))
32 }
33
34 pub fn signal(&self, name: &str) -> Result<LogicHandle, HandleError> {
36 Ok(LogicHandle { raw: self.raw.child(name)?.as_logic()? })
37 }
38
39 pub fn name(&self) -> String {
40 self.raw.name()
41 }
42 pub fn full_name(&self) -> String {
43 self.raw.full_name()
44 }
45
46 pub fn children(&self) -> Vec<AnyHandle> {
47 self.raw.children().into_iter().map(AnyHandle::wrap).collect()
48 }
49}
50
51#[derive(Copy, Clone)]
52pub enum AnyHandle {
53 Hierarchy(HierarchyHandle),
54 Logic(LogicHandle),
55 Other,
56}
57
58impl AnyHandle {
59 fn wrap(h: gpi::AnyHandle) -> AnyHandle {
60 match h {
61 gpi::AnyHandle::Hierarchy(h) => AnyHandle::Hierarchy(HierarchyHandle { raw: h }),
62 gpi::AnyHandle::Logic(l) => AnyHandle::Logic(LogicHandle { raw: l }),
63 gpi::AnyHandle::Other(_) => AnyHandle::Other,
64 }
65 }
66
67 pub fn as_logic(self) -> Option<LogicHandle> {
68 match self {
69 AnyHandle::Logic(l) => Some(l),
70 _ => None,
71 }
72 }
73 pub fn as_hierarchy(self) -> Option<HierarchyHandle> {
74 match self {
75 AnyHandle::Hierarchy(h) => Some(h),
76 _ => None,
77 }
78 }
79}
80
81#[derive(Copy, Clone, PartialEq, Eq)]
84pub struct LogicHandle {
85 raw: gpi::LogicHandle,
86}
87
88impl std::fmt::Debug for LogicHandle {
89 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90 write!(f, "LogicHandle(\"{}\")", self.full_name())
91 }
92}
93
94impl std::fmt::Debug for HierarchyHandle {
95 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96 write!(f, "HierarchyHandle(\"{}\")", self.full_name())
97 }
98}
99
100impl LogicHandle {
101 pub fn name(&self) -> String {
102 self.raw.name()
103 }
104 pub fn full_name(&self) -> String {
105 self.raw.full_name()
106 }
107 pub fn size(&self) -> u32 {
108 self.raw.size()
109 }
110
111 pub fn get(&self) -> LogicArray {
113 self.raw.get()
114 }
115 pub fn get_binstr(&self) -> String {
116 self.raw.get_binstr()
117 }
118 pub fn get_u64(&self) -> Result<u64, ValueError> {
119 self.raw.get_u64()
120 }
121 pub fn is_high(&self) -> bool {
123 self.raw.get_binstr() == "1"
124 }
125 pub fn is_low(&self) -> bool {
126 self.raw.get_binstr() == "0"
127 }
128
129 pub fn set_u64(&self, v: u64) {
131 phase::schedule_write_u64(self.raw, v);
132 }
133 pub fn set(&self, v: &LogicArray) {
134 phase::schedule_write_arr(self.raw, v.clone());
135 }
136
137 pub fn set_u64_now(&self, v: u64) {
148 phase::deny_write_in_read_only(self.raw);
149 self.raw.set_u64_now(v);
150 }
151 pub fn set_now(&self, v: &LogicArray) {
152 phase::deny_write_in_read_only(self.raw);
153 self.raw.set_now(v);
154 }
155
156 pub fn rising_edge(&self) -> Edge {
158 Edge::new(self.raw, EdgeKind::Rising)
159 }
160 pub fn falling_edge(&self) -> Edge {
161 Edge::new(self.raw, EdgeKind::Falling)
162 }
163 pub fn value_change(&self) -> Edge {
164 Edge::new(self.raw, EdgeKind::AnyChange)
165 }
166}
167
168pub fn top_module() -> Result<HierarchyHandle, HandleError> {
170 Ok(HierarchyHandle { raw: gpi::top_module()? })
171}