use rustdv_gpi as gpi;
pub use rustdv_gpi::{HandleError, Logic, LogicArray, ValueError};
use crate::phase;
use crate::triggers::{Edge, EdgeKind};
#[derive(Copy, Clone)]
pub struct HierarchyHandle {
raw: gpi::HierarchyHandle,
}
impl HierarchyHandle {
pub fn null_for_test() -> HierarchyHandle {
HierarchyHandle { raw: gpi::HierarchyHandle::null_for_test() }
}
}
impl HierarchyHandle {
pub fn child(&self, name: &str) -> Result<AnyHandle, HandleError> {
Ok(AnyHandle::wrap(self.raw.child(name)?))
}
pub fn signal(&self, name: &str) -> Result<LogicHandle, HandleError> {
Ok(LogicHandle { raw: self.raw.child(name)?.as_logic()? })
}
pub fn name(&self) -> String {
self.raw.name()
}
pub fn full_name(&self) -> String {
self.raw.full_name()
}
pub fn children(&self) -> Vec<AnyHandle> {
self.raw.children().into_iter().map(AnyHandle::wrap).collect()
}
}
#[derive(Copy, Clone)]
pub enum AnyHandle {
Hierarchy(HierarchyHandle),
Logic(LogicHandle),
Other,
}
impl AnyHandle {
fn wrap(h: gpi::AnyHandle) -> AnyHandle {
match h {
gpi::AnyHandle::Hierarchy(h) => AnyHandle::Hierarchy(HierarchyHandle { raw: h }),
gpi::AnyHandle::Logic(l) => AnyHandle::Logic(LogicHandle { raw: l }),
gpi::AnyHandle::Other(_) => AnyHandle::Other,
}
}
pub fn as_logic(self) -> Option<LogicHandle> {
match self {
AnyHandle::Logic(l) => Some(l),
_ => None,
}
}
pub fn as_hierarchy(self) -> Option<HierarchyHandle> {
match self {
AnyHandle::Hierarchy(h) => Some(h),
_ => None,
}
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct LogicHandle {
raw: gpi::LogicHandle,
}
impl std::fmt::Debug for LogicHandle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "LogicHandle(\"{}\")", self.full_name())
}
}
impl std::fmt::Debug for HierarchyHandle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "HierarchyHandle(\"{}\")", self.full_name())
}
}
impl LogicHandle {
pub fn name(&self) -> String {
self.raw.name()
}
pub fn full_name(&self) -> String {
self.raw.full_name()
}
pub fn size(&self) -> u32 {
self.raw.size()
}
pub fn get(&self) -> LogicArray {
self.raw.get()
}
pub fn get_binstr(&self) -> String {
self.raw.get_binstr()
}
pub fn get_u64(&self) -> Result<u64, ValueError> {
self.raw.get_u64()
}
pub fn is_high(&self) -> bool {
self.raw.get_binstr() == "1"
}
pub fn is_low(&self) -> bool {
self.raw.get_binstr() == "0"
}
pub fn set_u64(&self, v: u64) {
phase::schedule_write_u64(self.raw, v);
}
pub fn set(&self, v: &LogicArray) {
phase::schedule_write_arr(self.raw, v.clone());
}
pub fn set_u64_now(&self, v: u64) {
phase::deny_write_in_read_only(self.raw);
self.raw.set_u64_now(v);
}
pub fn set_now(&self, v: &LogicArray) {
phase::deny_write_in_read_only(self.raw);
self.raw.set_now(v);
}
pub fn rising_edge(&self) -> Edge {
Edge::new(self.raw, EdgeKind::Rising)
}
pub fn falling_edge(&self) -> Edge {
Edge::new(self.raw, EdgeKind::Falling)
}
pub fn value_change(&self) -> Edge {
Edge::new(self.raw, EdgeKind::AnyChange)
}
}
pub fn top_module() -> Result<HierarchyHandle, HandleError> {
Ok(HierarchyHandle { raw: gpi::top_module()? })
}