Class: VPI::Handle
- Inherits:
-
Object
- Object
- VPI::Handle
- Includes:
- VPI
- Defined in:
- lib/ruby-vpi/core/handle.rb,
lib/ruby-vpi/core/edge.rb,
lib/ruby-vpi/core/callback.rb
Overview
A handle is an object inside a Verilog simulation (see vpiHandle in IEEE Std. 1364-2005 for details).
Nearly all methods of this class, such as put_value() and get_value(), you allow you to specify VPI types and properties (which are listed in ext/vpi_user.h) by their names (strings or symbols) or integer constants.
For example, the vpiIntVal property can be specified as a string ("vpiIntVal"), a symbol (:vpiIntVal), or as an integer (VpiIntVal or VPI::vpiIntVal).
Defined Under Namespace
Classes: Property
Constant Summary collapse
- @@propCache =
Hash.new {|h,k| h[k] = Property.new(k)}
Constants included from VPI
INTEGER_BITS, INTEGER_LIMIT, INTEGER_MASK
Instance Method Summary collapse
-
#/(aRelativePath) ⇒ Object
Returns the child handle at the given relative VPI path.
-
#<=>(other) ⇒ Object
Sort by absolute VPI path.
-
#[](aProp) ⇒ Object
Returns the value of the given VPI property (name or integer constant) of this handle.
-
#cbValueChange(aOptions = {}, &aHandler) ⇒ Object
Registers a callback that is invoked whenever the value of this object changes.
-
#change? ⇒ Boolean
Tests if the logic value of this handle has changed since the last simulation time step.
-
#edge? ⇒ Boolean
Tests if either a positive or negative edge has occurred.
-
#force? ⇒ Boolean
Tests if there is currently a value forced onto this handle.
-
#force_value(*args) ⇒ Object
Forces the given value (see arguments for #put_value) onto this handle.
-
#get_value(aFormat = VpiIntVal) ⇒ Object
Reads the value using the given format (name or integer constant) and returns it.
-
#get_value_wrapper(aFormat) ⇒ Object
Reads the value using the given format (name or integer constant) and returns a
S_vpi_valueobject. -
#inspect(*aPropNames) ⇒ Object
(also: #to_s)
Inspects the given VPI property names, in addition to those common to all handles.
-
#method_missing(aMeth, *aArgs, &aBlock) ⇒ Object
Provides access to this handle’s (1) child handles and (2) VPI properties through method calls.
-
#put_value(aValue, aFormat = nil, aTime = nil, aDelay = VpiNoDelay) ⇒ Object
Writes the given value using the given format (name or integer constant), time, and delay, and then returns the written value.
-
#release_value ⇒ Object
Releases all forced values on this handle (if any).
-
#to_a(*aChildTypes) ⇒ Object
Returns an array of child handles which have the given types (names or integer constants).
-
#vpi0! ⇒ Object
(also: #f!)
Sets the integer value of this handle to 0.
-
#vpi0? ⇒ Boolean
(also: #f?)
Tests if the integer value of this handle is 0.
-
#vpi1! ⇒ Object
(also: #t!)
Sets the integer value of this handle to 1.
-
#vpi1? ⇒ Boolean
(also: #t?)
Tests if the integer value of this handle is 1.
-
#vpiH! ⇒ Object
(also: #h!)
Sets the strength value of this handle to high.
-
#vpiH? ⇒ Boolean
(also: #h?)
Tests if the strength value of this handle is high.
-
#vpiL! ⇒ Object
(also: #l!)
Sets the strength value of this handle to low.
-
#vpiL? ⇒ Boolean
(also: #l?)
Tests if the strength value of this handle is low.
-
#vpiX! ⇒ Object
(also: #x!)
Sets the logic value of this handle to unknown (x).
-
#vpiX? ⇒ Boolean
(also: #x?)
Tests if the logic value of this handle is unknown (x).
-
#vpiZ! ⇒ Object
(also: #z!)
Sets the logic value of this handle to high impedance (z).
-
#vpiZ? ⇒ Boolean
(also: #z?)
Tests if the logic value of this handle is high impedance (z).
Methods included from VPI
__callback__vpi_register_cb, __callback__vpi_remove_cb, __scheduler__vpi_put_value, #advance_time, #always, #current_time, #process, #vpi_put_value, #vpi_register_cb, #vpi_remove_cb
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(aMeth, *aArgs, &aBlock) ⇒ Object
Provides access to this handle’s (1) child handles and (2) VPI properties through method calls. In the case that a child handle has the same name as a VPI property, the child handle will be accessed instead of the VPI property. However, you can still access the VPI property using the square brackets #[] method.
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/ruby-vpi/core/handle.rb', line 298 def method_missing aMeth, *aArgs, &aBlock # cache the result for future accesses, in order # to cut down number of calls to method_missing() eigen_class = (class << self; self; end) if child = vpi_handle_by_name(aMeth.to_s, self) eigen_class.class_eval do define_method aMeth do child end end child else # XXX: using a string because define_method() does # not support a block argument until Ruby 1.9 eigen_class.class_eval %{ def #{aMeth}(*a, &b) access_prop(#{aMeth.inspect}, *a, &b) end }, __FILE__, __LINE__ __send__(aMeth, *aArgs, &aBlock) end end |
Instance Method Details
#/(aRelativePath) ⇒ Object
Returns the child handle at the given relative VPI path.
223 224 225 |
# File 'lib/ruby-vpi/core/handle.rb', line 223 def / aRelativePath access_child(aRelativePath) end |
#<=>(other) ⇒ Object
Sort by absolute VPI path.
273 274 275 |
# File 'lib/ruby-vpi/core/handle.rb', line 273 def <=> other get_value(VpiFullName) <=> other.get_value(VpiFullName) end |
#[](aProp) ⇒ Object
Returns the value of the given VPI property (name or integer constant) of this handle.
284 285 286 |
# File 'lib/ruby-vpi/core/handle.rb', line 284 def [] aProp access_prop(aProp) end |
#cbValueChange(aOptions = {}, &aHandler) ⇒ Object
Registers a callback that is invoked whenever the value of this object changes.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/ruby-vpi/core/callback.rb', line 92 def cbValueChange aOptions = {}, &aHandler raise ArgumentError unless block_given? aOptions[:time] ||= S_vpi_time.new(:type => VpiSuppressTime) aOptions[:value] ||= S_vpi_value.new(:format => VpiSuppressVal) alarm = S_cb_data.new( :reason => CbValueChange, :obj => self, :time => aOptions[:time], :value => aOptions[:value], :index => 0 ) vpi_register_cb alarm, &aHandler end |
#change? ⇒ Boolean
Tests if the logic value of this handle has changed since the last simulation time step.
68 69 70 71 72 73 |
# File 'lib/ruby-vpi/core/edge.rb', line 68 def change? old = @__edge__prev_val new = get_value(VpiScalarVal) old != new end |
#edge? ⇒ Boolean
Tests if either a positive or negative edge has occurred.
62 63 64 |
# File 'lib/ruby-vpi/core/edge.rb', line 62 def edge? posedge? or negedge? end |
#force? ⇒ Boolean
Tests if there is currently a value forced onto this handle.
213 214 215 |
# File 'lib/ruby-vpi/core/handle.rb', line 213 def force? self.to_a(VpiDriver).any? {|d| vpi_get(VpiType, d) == VpiForce} end |
#force_value(*args) ⇒ Object
Forces the given value (see arguments for #put_value) onto this handle.
201 202 203 204 |
# File 'lib/ruby-vpi/core/handle.rb', line 201 def force_value *args args[3] = VpiForceFlag put_value(*args) end |
#get_value(aFormat = VpiIntVal) ⇒ Object
Reads the value using the given format (name or integer constant) and returns it. If a format is not given, then it is assumed to be VpiIntVal.
144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/ruby-vpi/core/handle.rb', line 144 def get_value aFormat = VpiIntVal fmt = resolve_prop_type(aFormat) @size ||= vpi_get(VpiSize, self) if fmt == VpiIntVal and @size > INTEGER_BITS fmt = VpiBinStrVal val = get_value_wrapper(fmt) val.read(fmt).gsub(/[^01]/, '0').to_i(2) else val = get_value_wrapper(fmt) val.read(fmt) end end |
#get_value_wrapper(aFormat) ⇒ Object
Reads the value using the given format (name or integer constant) and returns a S_vpi_value object.
135 136 137 138 139 140 |
# File 'lib/ruby-vpi/core/handle.rb', line 135 def get_value_wrapper aFormat fmt = resolve_prop_type(aFormat) val = S_vpi_value.new(:format => fmt) vpi_get_value(self, val) val end |
#inspect(*aPropNames) ⇒ Object Also known as: to_s
Inspects the given VPI property names, in addition to those common to all handles.
116 117 118 119 120 121 122 123 124 |
# File 'lib/ruby-vpi/core/handle.rb', line 116 def inspect *aPropNames aPropNames.unshift :name, :fullName, :size, :file, :lineNo, :hexStrVal aPropNames.map! do |name| "#{name}=#{__send__(name).inspect}" end "#<VPI::Handle #{vpi_get_str(VpiType, self)} #{aPropNames.join(', ')}>" end |
#put_value(aValue, aFormat = nil, aTime = nil, aDelay = VpiNoDelay) ⇒ Object
Writes the given value using the given format (name or integer constant), time, and delay, and then returns the written value.
-
If you do not specify the format, then the Verilog simulator will attempt to determine the correct format.
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/ruby-vpi/core/handle.rb', line 164 def put_value aValue, aFormat = nil, aTime = nil, aDelay = VpiNoDelay if vpi_get(VpiType, self) == VpiNet aDelay = VpiForceFlag if driver = self.to_a(VpiDriver).find {|d| vpi_get(VpiType, d) != VpiForce} warn "forcing value #{aValue.inspect} onto wire #{self} that is already driven by #{driver.inspect}" end end aFormat = if aFormat resolve_prop_type(aFormat) else S_vpi_value.detect_format(aValue) || get_value_wrapper(VpiObjTypeVal).format # let the simulator detect end if aFormat == VpiIntVal @size ||= vpi_get(VpiSize, self) unless @size < INTEGER_BITS aFormat = VpiHexStrVal aValue = aValue.to_i.to_s(16) end end aTime ||= S_vpi_time.new(:type => VpiSimTime, :integer => 0) wrapper = S_vpi_value.new(:format => aFormat) result = wrapper.write(aValue, aFormat) vpi_put_value(self, wrapper, aTime, aDelay) result end |
#release_value ⇒ Object
Releases all forced values on this handle (if any).
207 208 209 210 |
# File 'lib/ruby-vpi/core/handle.rb', line 207 def release_value # this doesn't really change the value, it only removes the force flag put_value(0, VpiIntVal, nil, VpiReleaseFlag) end |
#to_a(*aChildTypes) ⇒ Object
Returns an array of child handles which have the given types (names or integer constants).
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'lib/ruby-vpi/core/handle.rb', line 229 def to_a *aChildTypes handles = [] aChildTypes.each do |arg| t = resolve_prop_type(arg) if itr = vpi_iterate(t, self) while h = vpi_scan(itr) handles << h end end end handles end |
#vpi0! ⇒ Object Also known as: f!
Sets the integer value of this handle to 0.
50 51 52 |
# File 'lib/ruby-vpi/core/handle.rb', line 50 def vpi0! put_value(Vpi0, VpiScalarVal) end |
#vpi0? ⇒ Boolean Also known as: f?
Tests if the integer value of this handle is 0.
45 46 47 |
# File 'lib/ruby-vpi/core/handle.rb', line 45 def vpi0? get_value(VpiScalarVal) == Vpi0 end |
#vpi1! ⇒ Object Also known as: t!
Sets the integer value of this handle to 1.
36 37 38 |
# File 'lib/ruby-vpi/core/handle.rb', line 36 def vpi1! put_value(Vpi1, VpiScalarVal) end |
#vpi1? ⇒ Boolean Also known as: t?
Tests if the integer value of this handle is 1.
31 32 33 |
# File 'lib/ruby-vpi/core/handle.rb', line 31 def vpi1? get_value(VpiScalarVal) == Vpi1 end |
#vpiH! ⇒ Object Also known as: h!
Sets the strength value of this handle to high.
92 93 94 |
# File 'lib/ruby-vpi/core/handle.rb', line 92 def vpiH! put_value(VpiH, VpiScalarVal) end |
#vpiH? ⇒ Boolean Also known as: h?
Tests if the strength value of this handle is high.
87 88 89 |
# File 'lib/ruby-vpi/core/handle.rb', line 87 def vpiH? get_value(VpiScalarVal) == VpiH end |
#vpiL! ⇒ Object Also known as: l!
Sets the strength value of this handle to low.
106 107 108 |
# File 'lib/ruby-vpi/core/handle.rb', line 106 def vpiL! put_value(VpiL, VpiScalarVal) end |
#vpiL? ⇒ Boolean Also known as: l?
Tests if the strength value of this handle is low.
101 102 103 |
# File 'lib/ruby-vpi/core/handle.rb', line 101 def vpiL? get_value(VpiScalarVal) == VpiL end |
#vpiX! ⇒ Object Also known as: x!
Sets the logic value of this handle to unknown (x).
64 65 66 |
# File 'lib/ruby-vpi/core/handle.rb', line 64 def vpiX! put_value(VpiX, VpiScalarVal) end |
#vpiX? ⇒ Boolean Also known as: x?
Tests if the logic value of this handle is unknown (x).
59 60 61 |
# File 'lib/ruby-vpi/core/handle.rb', line 59 def vpiX? get_value(VpiScalarVal) == VpiX end |
#vpiZ! ⇒ Object Also known as: z!
Sets the logic value of this handle to high impedance (z).
78 79 80 |
# File 'lib/ruby-vpi/core/handle.rb', line 78 def vpiZ! put_value(VpiZ, VpiScalarVal) end |
#vpiZ? ⇒ Boolean Also known as: z?
Tests if the logic value of this handle is high impedance (z).
73 74 75 |
# File 'lib/ruby-vpi/core/handle.rb', line 73 def vpiZ? get_value(VpiScalarVal) == VpiZ end |