use rustdv_gpi as gpi;
pub use rustdv_gpi::{BigUint, HandleError, Logic, LogicArray, ValueError};
pub mod aggregate;
pub mod hierarchy;
pub mod logic;
pub mod real;
pub mod string;
pub use aggregate::AggregateHandle;
pub use hierarchy::{HierarchyHandle, top_module};
pub use logic::LogicHandle;
pub use real::RealHandle;
pub use string::StringHandle;
use crate::triggers::Edge;
#[derive(Copy, Clone)]
pub enum SimHandle {
Hierarchy(HierarchyHandle),
Logic(LogicHandle),
Real(RealHandle),
String(StringHandle),
Struct(AggregateHandle),
Union(AggregateHandle),
Other,
}
impl SimHandle {
fn wrap(h: gpi::AnyHandle) -> SimHandle {
match h {
gpi::AnyHandle::Hierarchy(raw) => SimHandle::Hierarchy(HierarchyHandle { raw }),
gpi::AnyHandle::Logic(raw) => SimHandle::Logic(LogicHandle { raw }),
gpi::AnyHandle::Real(raw) => SimHandle::Real(RealHandle { raw }),
gpi::AnyHandle::String(raw) => SimHandle::String(StringHandle { raw }),
gpi::AnyHandle::Struct(raw) => SimHandle::Struct(AggregateHandle { raw }),
gpi::AnyHandle::Union(raw) => SimHandle::Union(AggregateHandle { raw }),
gpi::AnyHandle::Other(_) => SimHandle::Other,
}
}
fn wrong_kind(self, expected: &'static str) -> HandleError {
let (name, actual) = match self {
Self::Hierarchy(h) => (h.full_name(), "module"),
Self::Logic(h) => (h.full_name(), "signal"),
Self::Real(h) => (h.full_name(), "real"),
Self::String(h) => (h.full_name(), "string"),
Self::Struct(h) => (h.full_name(), "struct"),
Self::Union(h) => (h.full_name(), "union"),
Self::Other => ("<unknown>".into(), "unsupported simulator object"),
};
HandleError::WrongKind {
name,
expected,
actual: actual.into(),
}
}
pub fn as_hierarchy(self) -> Result<HierarchyHandle, HandleError> {
match self {
SimHandle::Hierarchy(h) => Ok(h),
other => Err(other.wrong_kind("module")),
}
}
pub fn as_signal(self) -> Result<LogicHandle, HandleError> {
match self {
SimHandle::Logic(l) => Ok(l),
other => Err(other.wrong_kind("signal")),
}
}
pub fn as_real(self) -> Result<RealHandle, HandleError> {
match self {
Self::Real(h) => Ok(h),
other => Err(other.wrong_kind("real")),
}
}
pub fn as_string(self) -> Result<StringHandle, HandleError> {
match self {
Self::String(h) => Ok(h),
other => Err(other.wrong_kind("string")),
}
}
pub fn as_aggregate(self) -> Result<AggregateHandle, HandleError> {
match self {
Self::Struct(h) | Self::Union(h) => Ok(h),
other => Err(other.wrong_kind("struct or union")),
}
}
pub fn is_other(self) -> bool {
matches!(self, SimHandle::Other)
}
}
pub trait HandleBase {
fn name(&self) -> String;
fn full_name(&self) -> String;
}
pub trait HandleChildren {
fn child(&self, name: &str) -> Result<SimHandle, HandleError>;
fn children(&self) -> Vec<SimHandle>;
fn signal(&self, name: &str) -> Result<LogicHandle, HandleError> {
self.child(name)?.as_signal()
}
fn real(&self, name: &str) -> Result<RealHandle, HandleError> {
self.child(name)?.as_real()
}
fn string(&self, name: &str) -> Result<StringHandle, HandleError> {
self.child(name)?.as_string()
}
fn hierarchy(&self, name: &str) -> Result<HierarchyHandle, HandleError> {
self.child(name)?.as_hierarchy()
}
fn aggregate(&self, name: &str) -> Result<AggregateHandle, HandleError> {
self.child(name)?.as_aggregate()
}
}
pub trait HandleEvent {
fn rising_edge(&self) -> Edge;
fn falling_edge(&self) -> Edge;
fn value_change(&self) -> Edge;
}