use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::FromPrimitive;
use vpi_sys::PLI_INT32;
use crate::{Handle, ObjectType, Value, ValueType};
#[repr(i32)]
#[derive(FromPrimitive, ToPrimitive, Debug, Clone, PartialEq, Eq)]
pub enum Property {
Undefined = vpi_sys::vpiUndefined,
Type = vpi_sys::vpiType as i32,
Name = vpi_sys::vpiName as i32,
FullName = vpi_sys::vpiFullName as i32,
Size = vpi_sys::vpiSize as i32,
File = vpi_sys::vpiFile as i32,
LineNo = vpi_sys::vpiLineNo as i32,
TopModule = vpi_sys::vpiTopModule as i32,
CellInstance = vpi_sys::vpiCellInstance as i32,
DefName = vpi_sys::vpiDefName as i32,
Protected = vpi_sys::vpiProtected as i32,
TimeUnit = vpi_sys::vpiTimeUnit as i32,
TimePrecision = vpi_sys::vpiTimePrecision as i32,
DefNetType = vpi_sys::vpiDefNetType as i32,
UnconnDrive = vpi_sys::vpiUnconnDrive as i32,
DefFile = vpi_sys::vpiDefFile as i32,
DefLineNo = vpi_sys::vpiDefLineNo as i32,
Scalar = vpi_sys::vpiScalar as i32,
Vector = vpi_sys::vpiVector as i32,
ExplicitName = vpi_sys::vpiExplicitName as i32,
Direction = vpi_sys::vpiDirection as i32,
ConnByName = vpi_sys::vpiConnByName as i32,
NetType = vpi_sys::vpiNetType as i32,
ExplicitScalared = vpi_sys::vpiExplicitScalared as i32,
ExplicitVectored = vpi_sys::vpiExplicitVectored as i32,
Expanded = vpi_sys::vpiExpanded as i32,
ImplicitDecl = vpi_sys::vpiImplicitDecl as i32,
ChargeStrength = vpi_sys::vpiChargeStrength as i32,
Array = vpi_sys::vpiArray as i32,
PortIndex = vpi_sys::vpiPortIndex as i32,
TermIndex = vpi_sys::vpiTermIndex as i32,
Strength0 = vpi_sys::vpiStrength0 as i32,
Strength1 = vpi_sys::vpiStrength1 as i32,
PrimType = vpi_sys::vpiPrimType as i32,
Polarity = vpi_sys::vpiPolarity as i32,
DataPolarity = vpi_sys::vpiDataPolarity as i32,
Edge = vpi_sys::vpiEdge as i32,
PathType = vpi_sys::vpiPathType as i32,
TchkType = vpi_sys::vpiTchkType as i32,
OpType = vpi_sys::vpiOpType as i32,
ConstType = vpi_sys::vpiConstType as i32,
Blocking = vpi_sys::vpiBlocking as i32,
CaseType = vpi_sys::vpiCaseType as i32,
NetDeclAssign = vpi_sys::vpiNetDeclAssign as i32,
FuncType = vpi_sys::vpiFuncType as i32,
UserDefn = vpi_sys::vpiUserDefn as i32,
Scheduled = vpi_sys::vpiScheduled as i32,
DefDelayMode = vpi_sys::vpiDefDelayMode as i32,
DefDecayTime = vpi_sys::vpiDefDecayTime as i32,
Active = vpi_sys::vpiActive as i32,
Automatic = vpi_sys::vpiAutomatic as i32,
Cell = vpi_sys::vpiCell as i32,
Config = vpi_sys::vpiConfig as i32,
ConstantSelect = vpi_sys::vpiConstantSelect as i32,
Decompile = vpi_sys::vpiDecompile as i32,
DefAttribute = vpi_sys::vpiDefAttribute as i32,
DelayType = vpi_sys::vpiDelayType as i32,
IteratorType = vpi_sys::vpiIteratorType as i32,
Library = vpi_sys::vpiLibrary as i32,
MultiArray = vpi_sys::vpiMultiArray as i32,
Offset = vpi_sys::vpiOffset as i32,
Resolved = vpi_sys::vpiResolvedNetType as i32,
SaveRestartID = vpi_sys::vpiSaveRestartID as i32,
SaveRestartLocation = vpi_sys::vpiSaveRestartLocation as i32,
Valid = vpi_sys::vpiValid as i32,
Signed = vpi_sys::vpiSigned as i32,
Stop = vpi_sys::vpiStop as i32,
Finish = vpi_sys::vpiFinish as i32,
Reset = vpi_sys::vpiReset as i32,
SetInteractiveScope = vpi_sys::vpiSetInteractiveScope as i32,
LocalParam = vpi_sys::vpiLocalParam as i32,
ModPathHasIfNone = vpi_sys::vpiModPathHasIfNone as i32,
IndexedPartSelectType = vpi_sys::vpiIndexedPartSelectType as i32,
IsMemory = vpi_sys::vpiIsMemory as i32,
IsProtected = vpi_sys::vpiIsProtected as i32,
#[cfg(feature = "sv")]
Top = vpi_sys::vpiTop as i32,
#[cfg(feature = "sv")]
Unit = vpi_sys::vpiUnit as i32,
#[cfg(feature = "sv")]
JoinType = vpi_sys::vpiJoinType as i32,
#[cfg(feature = "sv")]
AccessType = vpi_sys::vpiAccessType as i32,
#[cfg(feature = "sv")]
ArrayType = vpi_sys::vpiArrayType as i32,
#[cfg(feature = "sv")]
ArrayMember = vpi_sys::vpiArrayMember as i32,
#[cfg(feature = "sv")]
IsRandomized = vpi_sys::vpiIsRandomized as i32,
#[cfg(feature = "sv")]
LocalVarDecls = vpi_sys::vpiLocalVarDecls as i32,
#[cfg(feature = "sv")]
RandType = vpi_sys::vpiRandType as i32,
#[cfg(feature = "sv")]
PortType = vpi_sys::vpiPortType as i32,
#[cfg(feature = "sv")]
ConstantVariable = vpi_sys::vpiConstantVariable as i32,
#[cfg(feature = "sv")]
StructUnionMember = vpi_sys::vpiStructUnionMember as i32,
#[cfg(feature = "sv")]
Visibility = vpi_sys::vpiVisibility as i32,
#[cfg(feature = "sv")]
AlwaysType = vpi_sys::vpiAlwaysType as i32,
#[cfg(feature = "sv")]
DistType = vpi_sys::vpiDistType as i32,
#[cfg(feature = "sv")]
Packed = vpi_sys::vpiPacked as i32,
#[cfg(feature = "sv")]
Tagged = vpi_sys::vpiTagged as i32,
#[cfg(feature = "sv")]
Virtual = vpi_sys::vpiVirtual as i32,
#[cfg(feature = "sv")]
HasActual = vpi_sys::vpiHasActual as i32,
#[cfg(feature = "sv")]
IsConstraintEnabled = vpi_sys::vpiIsConstraintEnabled as i32,
#[cfg(feature = "sv")]
Soft = vpi_sys::vpiSoft as i32,
#[cfg(feature = "sv")]
ClassType = vpi_sys::vpiClassType as i32,
#[cfg(feature = "sv")]
Method = vpi_sys::vpiMethod as i32,
#[cfg(feature = "sv")]
IsClockInferred = vpi_sys::vpiIsClockInferred as i32,
#[cfg(feature = "sv")]
Qualifier = vpi_sys::vpiQualifier as i32,
#[cfg(feature = "sv")]
InputEdge = vpi_sys::vpiInputEdge as i32,
#[cfg(feature = "sv")]
OutputEdge = vpi_sys::vpiOutputEdge as i32,
#[cfg(feature = "sv")]
Generic = vpi_sys::vpiGeneric as i32,
#[cfg(feature = "sv")]
CompatibilityMode = vpi_sys::vpiCompatibilityMode as i32,
#[cfg(feature = "sv")]
PackedArrayMember = vpi_sys::vpiPackedArrayMember as i32,
#[cfg(feature = "sv")]
OpStrong = vpi_sys::vpiOpStrong as i32,
#[cfg(feature = "sv")]
IsDeferred = vpi_sys::vpiIsDeferred as i32,
#[cfg(feature = "sv")]
AllocScheme = vpi_sys::vpiAllocScheme as i32,
#[cfg(feature = "sv")]
IsCoverSequence = vpi_sys::vpiIsCoverSequence as i32,
#[cfg(feature = "sv")]
ObjId = vpi_sys::vpiObjId as i32,
#[cfg(feature = "sv")]
StartLine = vpi_sys::vpiStartLine as i32,
#[cfg(feature = "sv")]
Column = vpi_sys::vpiColumn as i32,
#[cfg(feature = "sv")]
EndLine = vpi_sys::vpiEndLine as i32,
#[cfg(feature = "sv")]
EndColumn = vpi_sys::vpiEndColumn as i32,
#[cfg(feature = "sv")]
DPIPure = vpi_sys::vpiDPIPure as i32,
#[cfg(feature = "sv")]
DPIContext = vpi_sys::vpiDPIContext as i32,
#[cfg(feature = "sv")]
DPICStr = vpi_sys::vpiDPICStr as i32,
#[cfg(feature = "sv")]
DPICIdentifier = vpi_sys::vpiDPICIdentifier as i32,
#[cfg(feature = "sv")]
IsModPort = vpi_sys::vpiIsModPort as i32,
#[cfg(feature = "sv")]
IsFinal = vpi_sys::vpiIsFinal as i32,
}
impl Property {
#[allow(non_upper_case_globals)]
pub const SysFuncType: Self = Property::FuncType;
}
#[repr(u32)]
#[derive(FromPrimitive, ToPrimitive, Debug, Clone, PartialEq, Eq)]
pub enum Direction {
Input = vpi_sys::vpiInput,
Output = vpi_sys::vpiOutput,
Inout = vpi_sys::vpiInout,
MixedIO = vpi_sys::vpiMixedIO,
NoDirection = vpi_sys::vpiNoDirection,
}
impl std::fmt::Display for Direction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Direction::Input => write!(f, "Input"),
Direction::Output => write!(f, "Output"),
Direction::Inout => write!(f, "Inout"),
Direction::MixedIO => write!(f, "MixedIO"),
Direction::NoDirection => write!(f, "NoDirection"),
}
}
}
#[repr(u32)]
#[derive(FromPrimitive, ToPrimitive, Debug, Clone, PartialEq, Eq)]
pub enum NetType {
Wire = vpi_sys::vpiWire,
Wand = vpi_sys::vpiWand,
Wor = vpi_sys::vpiWor,
Tri = vpi_sys::vpiTri,
Tri0 = vpi_sys::vpiTri0,
Tri1 = vpi_sys::vpiTri1,
TriReg = vpi_sys::vpiTriReg,
TriAnd = vpi_sys::vpiTriAnd,
TriOr = vpi_sys::vpiTriOr,
Supply0 = vpi_sys::vpiSupply0,
Supply1 = vpi_sys::vpiSupply1,
None = vpi_sys::vpiNone,
UWire = vpi_sys::vpiUwire,
}
bitflags::bitflags! {
pub struct Edge: u32 {
const NoEdge = vpi_sys::vpiNoEdge;
const Edge01 = vpi_sys::vpiEdge01;
const Edge10 = vpi_sys::vpiEdge10;
const Edge0x = vpi_sys::vpiEdge0x;
const Edge1x = vpi_sys::vpiEdge1x;
const Edgex0 = vpi_sys::vpiEdgex0;
const Edgex1 = vpi_sys::vpiEdgex1;
const Posedge = vpi_sys::vpiPosedge;
const Negedge = vpi_sys::vpiNegedge;
const AnyEdge = vpi_sys::vpiAnyEdge;
}
}
#[repr(u32)]
#[derive(FromPrimitive, ToPrimitive, Debug, Clone, PartialEq, Eq)]
pub enum ConstType {
Dec = vpi_sys::vpiDecConst,
Binary = vpi_sys::vpiBinaryConst,
Oct = vpi_sys::vpiOctConst,
Hex = vpi_sys::vpiHexConst,
Int = vpi_sys::vpiIntConst,
Real = vpi_sys::vpiRealConst,
String = vpi_sys::vpiStringConst,
Time = vpi_sys::vpiTimeConst,
#[cfg(feature = "sv")]
OneStep = vpi_sys::vpiOneStepConst,
#[cfg(feature = "sv")]
Unbounded = vpi_sys::vpiUnboundedConst,
#[cfg(feature = "sv")]
Null = vpi_sys::vpiNullConst,
}
#[repr(u32)]
#[derive(FromPrimitive, ToPrimitive, Debug, Clone, PartialEq, Eq)]
pub enum FuncType {
Int = vpi_sys::vpiIntFunc,
Real = vpi_sys::vpiRealFunc,
Time = vpi_sys::vpiTimeFunc,
Sized = vpi_sys::vpiSizedFunc,
SizedSigned = vpi_sys::vpiSizedSignedFunc,
#[cfg(feature = "sv")]
Other = vpi_sys::vpiOtherFunc,
}
#[repr(u32)]
#[derive(FromPrimitive, ToPrimitive, Debug, Clone, PartialEq, Eq)]
pub enum SysFuncType {
Int = vpi_sys::vpiSysFuncInt,
Real = vpi_sys::vpiSysFuncReal,
Time = vpi_sys::vpiSysFuncTime,
Sized = vpi_sys::vpiSysFuncSized,
}
#[cfg(feature = "sv")]
#[repr(u32)]
#[derive(FromPrimitive, ToPrimitive, Copy, Clone, Debug, PartialEq, Eq)]
pub enum RandType {
NotRand = vpi_sys::vpiNotRand,
Rand = vpi_sys::vpiRand,
RandC = vpi_sys::vpiRandC,
}
#[cfg(feature = "sv")]
#[repr(u32)]
#[derive(FromPrimitive, ToPrimitive, Copy, Clone, Debug, PartialEq, Eq)]
pub enum DistType {
Equal = vpi_sys::vpiEqualDist,
Div = vpi_sys::vpiDivDist,
}
#[repr(u32)]
#[derive(FromPrimitive, ToPrimitive, Debug, Clone, PartialEq, Eq)]
pub enum PrimType {
And = vpi_sys::vpiAndPrim,
Nand = vpi_sys::vpiNandPrim,
Nor = vpi_sys::vpiNorPrim,
Or = vpi_sys::vpiOrPrim,
Xor = vpi_sys::vpiXorPrim,
Xnor = vpi_sys::vpiXnorPrim,
Buf = vpi_sys::vpiBufPrim,
Not = vpi_sys::vpiNotPrim,
Bufif0 = vpi_sys::vpiBufif0Prim,
Bufif1 = vpi_sys::vpiBufif1Prim,
Notif0 = vpi_sys::vpiNotif0Prim,
Notif1 = vpi_sys::vpiNotif1Prim,
Nmos = vpi_sys::vpiNmosPrim,
Pmos = vpi_sys::vpiPmosPrim,
Cmos = vpi_sys::vpiCmosPrim,
Rnmos = vpi_sys::vpiRnmosPrim,
Rpmos = vpi_sys::vpiRpmosPrim,
Rcmos = vpi_sys::vpiRcmosPrim,
Rtran = vpi_sys::vpiRtranPrim,
Rtranif0 = vpi_sys::vpiRtranif0Prim,
Rtranif1 = vpi_sys::vpiRtranif1Prim,
Tran = vpi_sys::vpiTranPrim,
Tranif0 = vpi_sys::vpiTranif0Prim,
Tranif1 = vpi_sys::vpiTranif1Prim,
Pullup = vpi_sys::vpiPullupPrim,
Pulldown = vpi_sys::vpiPulldownPrim,
Seq = vpi_sys::vpiSeqPrim,
Comb = vpi_sys::vpiCombPrim,
}
#[repr(u32)]
#[derive(FromPrimitive, ToPrimitive, Debug, Clone, PartialEq, Eq)]
pub enum TchkType {
Setup = vpi_sys::vpiSetup,
Hold = vpi_sys::vpiHold,
Period = vpi_sys::vpiPeriod,
Width = vpi_sys::vpiWidth,
Skew = vpi_sys::vpiSkew,
Recovery = vpi_sys::vpiRecovery,
NoChange = vpi_sys::vpiNoChange,
SetupHold = vpi_sys::vpiSetupHold,
Fullskew = vpi_sys::vpiFullskew,
Recrem = vpi_sys::vpiRecrem,
Removal = vpi_sys::vpiRemoval,
Timeskew = vpi_sys::vpiTimeskew,
}
#[repr(u32)]
#[derive(FromPrimitive, ToPrimitive, Debug, Clone, PartialEq, Eq)]
pub enum OpType {
Minus = vpi_sys::vpiMinusOp,
Plus = vpi_sys::vpiPlusOp,
Not = vpi_sys::vpiNotOp,
BitNeg = vpi_sys::vpiBitNegOp,
UnaryAnd = vpi_sys::vpiUnaryAndOp,
UnaryNand = vpi_sys::vpiUnaryNandOp,
UnaryOr = vpi_sys::vpiUnaryOrOp,
UnaryNor = vpi_sys::vpiUnaryNorOp,
UnaryXor = vpi_sys::vpiUnaryXorOp,
UnaryXNor = vpi_sys::vpiUnaryXNorOp,
Sub = vpi_sys::vpiSubOp,
Div = vpi_sys::vpiDivOp,
Mod = vpi_sys::vpiModOp,
Eq = vpi_sys::vpiEqOp,
Neq = vpi_sys::vpiNeqOp,
CaseEq = vpi_sys::vpiCaseEqOp,
CaseNeq = vpi_sys::vpiCaseNeqOp,
Gt = vpi_sys::vpiGtOp,
Ge = vpi_sys::vpiGeOp,
Lt = vpi_sys::vpiLtOp,
Le = vpi_sys::vpiLeOp,
LShift = vpi_sys::vpiLShiftOp,
RShift = vpi_sys::vpiRShiftOp,
Add = vpi_sys::vpiAddOp,
Mult = vpi_sys::vpiMultOp,
LogAnd = vpi_sys::vpiLogAndOp,
LogOr = vpi_sys::vpiLogOrOp,
BitAnd = vpi_sys::vpiBitAndOp,
BitOr = vpi_sys::vpiBitOrOp,
BitXor = vpi_sys::vpiBitXorOp,
BitXnor = vpi_sys::vpiBitXNorOp,
Condition = vpi_sys::vpiConditionOp,
Concat = vpi_sys::vpiConcatOp,
MultiConcat = vpi_sys::vpiMultiConcatOp,
EventOr = vpi_sys::vpiEventOrOp,
Null = vpi_sys::vpiNullOp,
List = vpi_sys::vpiListOp,
MinTypMax = vpi_sys::vpiMinTypMaxOp,
Posedge = vpi_sys::vpiPosedgeOp,
Negedge = vpi_sys::vpiNegedgeOp,
ArithLShift = vpi_sys::vpiArithLShiftOp,
ArithRShift = vpi_sys::vpiArithRShiftOp,
Power = vpi_sys::vpiPowerOp,
#[cfg(feature = "sv")]
Imply = vpi_sys::vpiImplyOp,
#[cfg(feature = "sv")]
NonOverlapImply = vpi_sys::vpiNonOverlapImplyOp,
#[cfg(feature = "sv")]
OverlapImply = vpi_sys::vpiOverlapImplyOp,
#[cfg(feature = "sv")]
UnaryCycleDelay = vpi_sys::vpiUnaryCycleDelayOp,
#[cfg(feature = "sv")]
CycleDelay = vpi_sys::vpiCycleDelayOp,
#[cfg(feature = "sv")]
Intersect = vpi_sys::vpiIntersectOp,
#[cfg(feature = "sv")]
FirstMatch = vpi_sys::vpiFirstMatchOp,
#[cfg(feature = "sv")]
Throughout = vpi_sys::vpiThroughoutOp,
#[cfg(feature = "sv")]
Within = vpi_sys::vpiWithinOp,
#[cfg(feature = "sv")]
Repeat = vpi_sys::vpiRepeatOp,
#[cfg(feature = "sv")]
ConsecutiveRepeat = vpi_sys::vpiConsecutiveRepeatOp,
#[cfg(feature = "sv")]
GotoRepeat = vpi_sys::vpiGotoRepeatOp,
#[cfg(feature = "sv")]
PostInc = vpi_sys::vpiPostIncOp,
#[cfg(feature = "sv")]
PreInc = vpi_sys::vpiPreIncOp,
#[cfg(feature = "sv")]
PostDec = vpi_sys::vpiPostDecOp,
#[cfg(feature = "sv")]
PreDec = vpi_sys::vpiPreDecOp,
#[cfg(feature = "sv")]
Match = vpi_sys::vpiMatchOp,
#[cfg(feature = "sv")]
Cast = vpi_sys::vpiCastOp,
#[cfg(feature = "sv")]
Iff = vpi_sys::vpiIffOp,
#[cfg(feature = "sv")]
WildEq = vpi_sys::vpiWildEqOp,
#[cfg(feature = "sv")]
WildNeq = vpi_sys::vpiWildNeqOp,
#[cfg(feature = "sv")]
StreamLR = vpi_sys::vpiStreamLROp,
#[cfg(feature = "sv")]
StreamRL = vpi_sys::vpiStreamRLOp,
#[cfg(feature = "sv")]
Matched = vpi_sys::vpiMatchedOp,
#[cfg(feature = "sv")]
Triggered = vpi_sys::vpiTriggeredOp,
#[cfg(feature = "sv")]
AssignmentPattern = vpi_sys::vpiAssignmentPatternOp,
#[cfg(feature = "sv")]
MultiAssignmentPattern = vpi_sys::vpiMultiAssignmentPatternOp,
#[cfg(feature = "sv")]
If = vpi_sys::vpiIfOp,
#[cfg(feature = "sv")]
IfElse = vpi_sys::vpiIfElseOp,
#[cfg(feature = "sv")]
CompAnd = vpi_sys::vpiCompAndOp,
#[cfg(feature = "sv")]
CompOr = vpi_sys::vpiCompOrOp,
#[cfg(feature = "sv")]
Type = vpi_sys::vpiTypeOp,
#[cfg(feature = "sv")]
Assignment = vpi_sys::vpiAssignmentOp,
#[cfg(feature = "sv")]
AcceptOn = vpi_sys::vpiAcceptOnOp,
#[cfg(feature = "sv")]
RejectOn = vpi_sys::vpiRejectOnOp,
#[cfg(feature = "sv")]
SyncAcceptOn = vpi_sys::vpiSyncAcceptOnOp,
#[cfg(feature = "sv")]
SyncRejectOn = vpi_sys::vpiSyncRejectOnOp,
#[cfg(feature = "sv")]
OverlapFollowedBy = vpi_sys::vpiOverlapFollowedByOp,
#[cfg(feature = "sv")]
NonOverlapFollowedBy = vpi_sys::vpiNonOverlapFollowedByOp,
#[cfg(feature = "sv")]
Nexttime = vpi_sys::vpiNexttimeOp,
#[cfg(feature = "sv")]
Always = vpi_sys::vpiAlwaysOp,
#[cfg(feature = "sv")]
Eventually = vpi_sys::vpiEventuallyOp,
#[cfg(feature = "sv")]
Until = vpi_sys::vpiUntilOp,
#[cfg(feature = "sv")]
UntilWith = vpi_sys::vpiUntilWithOp,
#[cfg(feature = "sv")]
Implies = vpi_sys::vpiImpliesOp,
#[cfg(feature = "sv")]
Inside = vpi_sys::vpiInsideOp,
}
impl OpType {
#[allow(non_upper_case_globals)]
pub const BitXNor: Self = OpType::BitXnor;
}
impl Handle {
#[must_use]
pub fn get_i64(&self, property: Property) -> Option<i64> {
if self.is_null() {
return None;
}
let value = unsafe { vpi_sys::vpi_get64(property as PLI_INT32, self.as_raw()) };
Some(value)
}
#[must_use]
pub fn get_u64(&self, property: Property) -> Option<u64> {
let value = self.get_i64(property)?;
u64::try_from(value).ok()
}
#[must_use]
pub fn get_u32(&self, property: Property) -> Option<u32> {
if self.is_null() {
return None;
}
match property {
Property::Size
| Property::LineNo
| Property::TimeUnit
| Property::TimePrecision
| Property::DefNetType
| Property::PortIndex
| Property::TermIndex => unsafe {
let value = vpi_sys::vpi_get(property as PLI_INT32, self.as_raw());
Some(value as u32)
},
#[cfg(feature = "sv")]
Property::RandType | Property::DistType => unsafe {
let value = vpi_sys::vpi_get(property as PLI_INT32, self.as_raw());
Some(value as u32)
},
_ => None, }
}
#[must_use]
pub fn get_str(&self, property: Property) -> Option<String> {
if self.is_null() {
return None;
}
match property {
Property::Name
| Property::FullName
| Property::DefName
| Property::File
| Property::DefFile
| Property::Type => unsafe {
let ptr = vpi_sys::vpi_get_str(property as PLI_INT32, self.as_raw());
if ptr.is_null() {
None
} else {
let c_str = std::ffi::CStr::from_ptr(ptr);
if let Ok(str_slice) = c_str.to_str() {
Some(str_slice.to_string())
} else {
None
}
}
},
_ => None, }
}
#[must_use]
pub fn get_bool(&self, property: Property) -> Option<bool> {
if self.is_null() {
return None;
}
match property {
Property::TopModule
| Property::CellInstance
| Property::Protected
| Property::Scalar
| Property::Vector
| Property::ExplicitName
| Property::ConnByName
| Property::ExplicitScalared
| Property::ExplicitVectored
| Property::Expanded
| Property::ImplicitDecl
| Property::Array
| Property::Blocking
| Property::UserDefn
| Property::Scheduled
| Property::Signed
| Property::LocalParam
| Property::ModPathHasIfNone
| Property::IsMemory
| Property::IsProtected => unsafe {
let value = vpi_sys::vpi_get(property as PLI_INT32, self.as_raw());
Some(value != 0)
},
#[cfg(feature = "sv")]
Property::IsRandomized | Property::IsConstraintEnabled | Property::Soft => unsafe {
let value = vpi_sys::vpi_get(property as PLI_INT32, self.as_raw());
Some(value != 0)
},
_ => None, }
}
#[must_use]
pub fn get_direction(&self) -> Option<Direction> {
if self.is_null() {
return None;
}
let value = unsafe { vpi_sys::vpi_get(Property::Direction as PLI_INT32, self.as_raw()) };
Direction::from_u32(value as u32)
}
#[must_use]
pub fn get_op_type(&self) -> Option<OpType> {
if self.is_null() {
return None;
}
let value = unsafe { vpi_sys::vpi_get(Property::OpType as PLI_INT32, self.as_raw()) };
OpType::from_u32(value as u32)
}
#[must_use]
pub fn get_prim_type(&self) -> Option<PrimType> {
if self.is_null() {
return None;
}
let value = unsafe { vpi_sys::vpi_get(Property::PrimType as PLI_INT32, self.as_raw()) };
PrimType::from_u32(value as u32)
}
#[must_use]
pub fn get_tchk_type(&self) -> Option<TchkType> {
if self.is_null() {
return None;
}
let value = unsafe { vpi_sys::vpi_get(Property::TchkType as PLI_INT32, self.as_raw()) };
TchkType::from_u32(value as u32)
}
#[must_use]
pub fn get_const_type(&self) -> Option<ConstType> {
if self.is_null() {
return None;
}
let value = unsafe { vpi_sys::vpi_get(Property::ConstType as PLI_INT32, self.as_raw()) };
ConstType::from_u32(value as u32)
}
#[must_use]
pub fn get_name(&self) -> Option<String> {
if self.is_null() {
return None;
}
self.get_str(Property::Name)
}
#[must_use]
pub fn get_full_name(&self) -> Option<String> {
if self.is_null() {
return None;
}
self.get_str(Property::FullName)
}
#[must_use]
pub fn get_func_type(&self) -> Option<FuncType> {
if self.is_null() {
return None;
}
let value = unsafe { vpi_sys::vpi_get(Property::FuncType as PLI_INT32, self.as_raw()) };
FuncType::from_u32(value as u32)
}
#[must_use]
pub fn get_sys_func_type(&self) -> Option<SysFuncType> {
if self.is_null() {
return None;
}
let value = unsafe { vpi_sys::vpi_get(Property::SysFuncType as PLI_INT32, self.as_raw()) };
SysFuncType::from_u32(value as u32)
}
#[must_use]
pub fn get_edge(&self) -> Option<Edge> {
if self.is_null() {
return None;
}
let value = unsafe { vpi_sys::vpi_get(Property::Edge as PLI_INT32, self.as_raw()) };
Edge::from_bits(value as u32)
}
#[must_use]
pub fn get_type(&self) -> Option<ObjectType> {
if self.is_null() {
return None;
}
let value = unsafe { vpi_sys::vpi_get(Property::Type as PLI_INT32, self.as_raw()) };
ObjectType::from_u32(value as u32)
}
#[must_use]
pub fn get_index(&self) -> Option<i32> {
if self.is_null() {
return None;
}
let raw_value = unsafe { vpi_sys::vpi_get(ObjectType::Index as PLI_INT32, self.as_raw()) };
Some(raw_value)
}
#[must_use]
pub fn get_left_range(&self) -> Option<i32> {
match self.get(ObjectType::LeftRange).get_value(ValueType::Int) {
Some(Value::Int(value)) => Some(value),
_ => None,
}
}
#[must_use]
pub fn get_right_range(&self) -> Option<i32> {
match self.get(ObjectType::RightRange).get_value(ValueType::Int) {
Some(Value::Int(value)) => Some(value),
_ => None,
}
}
#[cfg(feature = "sv")]
#[must_use]
pub fn get_packages(&self) -> Vec<Handle> {
if self.is_null() {
return Vec::new();
}
self.iterator(ObjectType::Package).collect()
}
#[cfg(feature = "sv")]
#[must_use]
pub fn get_interfaces(&self) -> Vec<Handle> {
if self.is_null() {
return Vec::new();
}
self.iterator(ObjectType::Interface).collect()
}
#[cfg(feature = "sv")]
#[must_use]
pub fn get_programs(&self) -> Vec<Handle> {
if self.is_null() {
return Vec::new();
}
self.iterator(ObjectType::Program).collect()
}
#[cfg(feature = "sv")]
#[must_use]
pub fn get_virtual_interfaces(&self) -> Vec<Handle> {
if self.is_null() {
return Vec::new();
}
self.iterator(ObjectType::VirtualInterfaceVar).collect()
}
#[cfg(feature = "sv")]
#[must_use]
pub fn is_randomized(&self) -> Option<bool> {
self.get_bool(Property::IsRandomized)
}
#[cfg(feature = "sv")]
#[must_use]
pub fn get_rand_type(&self) -> Option<RandType> {
if self.is_null() {
return None;
}
let raw = unsafe { vpi_sys::vpi_get(Property::RandType as PLI_INT32, self.as_raw()) };
RandType::from_u32(raw as u32)
}
#[cfg(feature = "sv")]
#[must_use]
pub fn is_constraint_enabled(&self) -> Option<bool> {
self.get_bool(Property::IsConstraintEnabled)
}
#[cfg(feature = "sv")]
#[must_use]
pub fn is_constraint_soft(&self) -> Option<bool> {
self.get_bool(Property::Soft)
}
#[cfg(feature = "sv")]
#[must_use]
pub fn get_dist_type(&self) -> Option<DistType> {
if self.is_null() {
return None;
}
let raw = unsafe { vpi_sys::vpi_get(Property::DistType as PLI_INT32, self.as_raw()) };
DistType::from_u32(raw as u32)
}
#[cfg(feature = "sv")]
#[must_use]
pub fn get_constraints(&self) -> Vec<Handle> {
if self.is_null() {
return Vec::new();
}
self.iterator(ObjectType::Constraint).collect()
}
#[cfg(feature = "sv")]
#[must_use]
pub fn get_constraint_ordering(&self) -> Vec<Handle> {
if self.is_null() {
return Vec::new();
}
self.iterator(ObjectType::ConstraintOrdering).collect()
}
#[cfg(feature = "sv")]
#[must_use]
pub fn get_constraint_items(&self) -> Vec<Handle> {
if self.is_null() {
return Vec::new();
}
self.iterator(ObjectType::ConstraintItem).collect()
}
#[cfg(feature = "sv")]
#[must_use]
pub fn get_solve_before(&self) -> Vec<Handle> {
if self.is_null() {
return Vec::new();
}
self.iterator(ObjectType::SolveBefore).collect()
}
#[cfg(feature = "sv")]
#[must_use]
pub fn get_solve_after(&self) -> Vec<Handle> {
if self.is_null() {
return Vec::new();
}
self.iterator(ObjectType::SolveAfter).collect()
}
#[cfg(feature = "sv")]
#[must_use]
pub fn get_distribution_items(&self) -> Vec<Handle> {
if self.is_null() {
return Vec::new();
}
self.iterator(ObjectType::DistItem).collect()
}
}
#[cfg(all(test, feature = "sv"))]
mod tests {
use super::{DistType, RandType};
use crate::Handle;
#[test]
fn sv_constraint_helpers_on_null_handle_are_safe() {
let h = Handle::null();
assert!(h.get_packages().is_empty());
assert!(h.get_interfaces().is_empty());
assert!(h.get_programs().is_empty());
assert!(h.get_virtual_interfaces().is_empty());
assert_eq!(h.is_randomized(), None);
assert_eq!(h.get_rand_type(), None);
assert_eq!(h.is_constraint_enabled(), None);
assert_eq!(h.is_constraint_soft(), None);
assert_eq!(h.get_dist_type(), None);
assert!(h.get_constraints().is_empty());
assert!(h.get_constraint_ordering().is_empty());
assert!(h.get_constraint_items().is_empty());
assert!(h.get_solve_before().is_empty());
assert!(h.get_solve_after().is_empty());
assert!(h.get_distribution_items().is_empty());
}
#[test]
fn sv_rand_and_dist_values_match_vpi_constants() {
assert_eq!(RandType::NotRand as u32, vpi_sys::vpiNotRand);
assert_eq!(RandType::Rand as u32, vpi_sys::vpiRand);
assert_eq!(RandType::RandC as u32, vpi_sys::vpiRandC);
assert_eq!(DistType::Equal as u32, vpi_sys::vpiEqualDist);
assert_eq!(DistType::Div as u32, vpi_sys::vpiDivDist);
}
}