ruby-vpi 15.0.2 → 16.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +23 -340
- data/Rakefile +169 -192
- data/bin/generate_test.rb +26 -25
- data/bin/generate_test_tpl/runner.rake +4 -10
- data/bin/header_to_ruby.rb +3 -20
- data/doc/README +11 -0
- data/doc/Rakefile +8 -21
- data/doc/common.css +44 -10
- data/doc/common.tpl +5 -10
- data/doc/history.doc +8 -7
- data/doc/history.html +228 -560
- data/doc/history.rb +7 -11
- data/doc/{history.yml → history.yaml} +325 -128
- data/doc/images/{feed-icon.png → feed-icon-28x28.png} +0 -0
- data/doc/images/ruby/LICENSE +15 -0
- data/doc/images/ruby/logo-reflection.png +0 -0
- data/doc/images/ruby/logo-reflection.xcf +0 -0
- data/doc/images/ruby/logo.png +0 -0
- data/doc/images/{LICENSE → tango/LICENSE} +0 -0
- data/doc/images/{caution.png → tango/caution.png} +0 -0
- data/doc/images/{caution.svg → tango/caution.svg} +0 -0
- data/doc/images/{home.png → tango/home.png} +0 -0
- data/doc/images/{home.svg → tango/home.svg} +0 -0
- data/doc/images/{important.png → tango/important.png} +0 -0
- data/doc/images/{important.svg → tango/important.svg} +0 -0
- data/doc/images/{next.png → tango/next.png} +0 -0
- data/doc/images/{next.svg → tango/next.svg} +0 -0
- data/doc/images/{note.png → tango/note.png} +0 -0
- data/doc/images/{note.svg → tango/note.svg} +0 -0
- data/doc/images/{prev.png → tango/prev.png} +0 -0
- data/doc/images/{prev.svg → tango/prev.svg} +0 -0
- data/doc/images/{tip.png → tango/tip.png} +0 -0
- data/doc/images/{tip.svg → tango/tip.svg} +0 -0
- data/doc/images/{up.png → tango/up.png} +0 -0
- data/doc/images/{up.svg → tango/up.svg} +0 -0
- data/doc/images/{warning.png → tango/warning.png} +0 -0
- data/doc/images/{warning.svg → tango/warning.svg} +0 -0
- data/doc/intro.inc +105 -36
- data/doc/lib/doc_format.rb +151 -29
- data/doc/lib/doc_proxy.rb +28 -69
- data/doc/lib/erb_content.rb +10 -22
- data/doc/lib/erb_proxy.rb +13 -24
- data/doc/manual.doc +16 -60
- data/doc/manual.html +257 -340
- data/doc/memo.doc +2 -0
- data/doc/memo.html +11 -11
- data/doc/readme.doc +36 -2
- data/doc/readme.html +214 -51
- data/doc/rss.erb +3 -3
- data/doc/rss.xml +217 -269
- data/ext/Rakefile +7 -22
- data/ext/common.h +10 -21
- data/ext/extconf.rb +5 -0
- data/ext/main.c +2 -18
- data/ext/main.h +1 -16
- data/ext/relay.c +3 -17
- data/ext/relay.h +3 -17
- data/ext/verilog.h +6 -18
- data/ext/vlog.c +3 -21
- data/ext/vlog.h +3 -17
- data/lib/ruby-vpi/erb.rb +7 -20
- data/lib/ruby-vpi/float.rb +6 -20
- data/lib/ruby-vpi/integer.rb +27 -47
- data/lib/ruby-vpi/rake.rb +4 -19
- data/lib/ruby-vpi/rcov.rb +6 -21
- data/lib/ruby-vpi/rdoc.rb +3 -21
- data/lib/ruby-vpi/runner.rb +28 -29
- data/lib/ruby-vpi/runner_proxy.rb +5 -21
- data/lib/ruby-vpi/verilog_parser.rb +5 -20
- data/lib/ruby-vpi/vpi.rb +420 -376
- data/lib/ruby-vpi.rb +26 -32
- data/ref/c/annotated.html +1 -1
- data/ref/c/common_8h.html +1 -1
- data/ref/c/files.html +1 -1
- data/ref/c/functions.html +1 -1
- data/ref/c/functions_vars.html +1 -1
- data/ref/c/globals.html +1 -1
- data/ref/c/globals_0x63.html +1 -1
- data/ref/c/globals_0x65.html +1 -1
- data/ref/c/globals_0x66.html +1 -1
- data/ref/c/globals_0x6d.html +1 -1
- data/ref/c/globals_0x70.html +1 -1
- data/ref/c/globals_0x72.html +1 -1
- data/ref/c/globals_0x73.html +1 -1
- data/ref/c/globals_0x74.html +1 -1
- data/ref/c/globals_0x76.html +1 -1
- data/ref/c/globals_0x78.html +1 -1
- data/ref/c/globals_defs.html +1 -1
- data/ref/c/globals_defs_0x65.html +1 -1
- data/ref/c/globals_defs_0x70.html +1 -1
- data/ref/c/globals_defs_0x76.html +1 -1
- data/ref/c/globals_defs_0x78.html +1 -1
- data/ref/c/globals_enum.html +1 -1
- data/ref/c/globals_eval.html +1 -1
- data/ref/c/globals_func.html +1 -1
- data/ref/c/globals_type.html +1 -1
- data/ref/c/globals_vars.html +1 -1
- data/ref/c/index.html +1 -1
- data/ref/c/main_8c.html +1 -1
- data/ref/c/main_8h.html +1 -1
- data/ref/c/relay_8c.html +1 -1
- data/ref/c/relay_8h.html +1 -1
- data/ref/c/structt__cb__data.html +1 -1
- data/ref/c/structt__vpi__delay.html +1 -1
- data/ref/c/structt__vpi__error__info.html +1 -1
- data/ref/c/structt__vpi__strengthval.html +1 -1
- data/ref/c/structt__vpi__systf__data.html +1 -1
- data/ref/c/structt__vpi__time.html +1 -1
- data/ref/c/structt__vpi__value.html +1 -1
- data/ref/c/structt__vpi__vecval.html +1 -1
- data/ref/c/structt__vpi__vlog__info.html +1 -1
- data/ref/c/verilog_8h.html +1 -1
- data/ref/c/vlog_8c.html +1 -1
- data/ref/c/vlog_8h.html +1 -1
- data/ref/c/vpi__user_8h.html +1 -1
- data/ref/ruby/classes/ERB.html +5 -5
- data/ref/ruby/classes/ERB.src/{M000026.html → M000024.html} +15 -15
- data/ref/ruby/classes/FileUtils.html +10 -10
- data/ref/ruby/classes/FileUtils.src/{M000027.html → M000025.html} +4 -4
- data/ref/ruby/classes/FileUtils.src/{M000028.html → M000026.html} +4 -4
- data/ref/ruby/classes/Float.html +5 -5
- data/ref/ruby/classes/Float.src/{M000022.html → M000020.html} +5 -5
- data/ref/ruby/classes/Integer.html +20 -56
- data/ref/ruby/classes/Integer.src/M000008.html +11 -11
- data/ref/ruby/classes/Integer.src/M000009.html +4 -4
- data/ref/ruby/classes/Integer.src/M000010.html +4 -4
- data/ref/ruby/classes/Integer.src/M000011.html +4 -4
- data/ref/ruby/classes/Integer.src/M000012.html +4 -4
- data/ref/ruby/classes/Integer.src/M000013.html +4 -4
- data/ref/ruby/classes/Integer.src/M000016.html +12 -9
- data/ref/ruby/classes/Integer.src/M000017.html +18 -9
- data/ref/ruby/classes/Integer.src/M000018.html +12 -12
- data/ref/ruby/classes/Integer.src/M000019.html +17 -18
- data/ref/ruby/classes/RDoc.src/M000053.html +25 -25
- data/ref/ruby/classes/RubyVpi/Config.html +3 -3
- data/ref/ruby/classes/RubyVpi.html +11 -5
- data/ref/ruby/classes/RubyVpi.src/{M000029.html → M000027.html} +103 -101
- data/ref/ruby/classes/String.html +21 -15
- data/ref/ruby/classes/String.src/M000021.html +36 -0
- data/ref/ruby/classes/String.src/{M000024.html → M000022.html} +24 -24
- data/ref/ruby/classes/String.src/M000023.html +5 -23
- data/ref/ruby/classes/VerilogParser/Module/Parameter.src/M000007.html +5 -5
- data/ref/ruby/classes/VerilogParser/Module/Port.src/M000003.html +7 -7
- data/ref/ruby/classes/VerilogParser/Module/Port.src/M000004.html +4 -4
- data/ref/ruby/classes/VerilogParser/Module/Port.src/M000005.html +4 -4
- data/ref/ruby/classes/VerilogParser/Module/Port.src/M000006.html +4 -4
- data/ref/ruby/classes/VerilogParser/Module.src/M000002.html +20 -20
- data/ref/ruby/classes/VerilogParser.html +6 -0
- data/ref/ruby/classes/VerilogParser.src/M000001.html +20 -20
- data/ref/ruby/classes/Vpi/Handle.html +89 -88
- data/ref/ruby/classes/Vpi/Handle.src/M000036.html +18 -0
- data/ref/ruby/classes/Vpi/Handle.src/M000037.html +5 -5
- data/ref/ruby/classes/Vpi/Handle.src/M000038.html +5 -5
- data/ref/ruby/classes/Vpi/Handle.src/M000039.html +5 -5
- data/ref/ruby/classes/Vpi/Handle.src/M000040.html +8 -5
- data/ref/ruby/classes/Vpi/Handle.src/M000041.html +8 -8
- data/ref/ruby/classes/Vpi/Handle.src/M000042.html +7 -6
- data/ref/ruby/classes/Vpi/Handle.src/M000043.html +31 -9
- data/ref/ruby/classes/Vpi/Handle.src/M000044.html +74 -31
- data/ref/ruby/classes/Vpi/Handle.src/M000045.html +17 -74
- data/ref/ruby/classes/Vpi/Handle.src/M000046.html +11 -17
- data/ref/ruby/classes/Vpi/Handle.src/M000048.html +31 -0
- data/ref/ruby/classes/Vpi/Handle.src/M000049.html +53 -52
- data/ref/ruby/classes/Vpi/S_vpi_time.src/M000050.html +4 -4
- data/ref/ruby/classes/Vpi/S_vpi_time.src/M000051.html +5 -5
- data/ref/ruby/classes/Vpi/S_vpi_value.html +15 -15
- data/ref/ruby/classes/Vpi/S_vpi_value.src/{M000036.html → M000033.html} +5 -5
- data/ref/ruby/classes/Vpi/S_vpi_value.src/M000034.html +5 -5
- data/ref/ruby/classes/Vpi/S_vpi_value.src/M000035.html +5 -5
- data/ref/ruby/classes/Vpi.html +48 -19
- data/ref/ruby/classes/Vpi.src/M000028.html +28 -0
- data/ref/ruby/classes/Vpi.src/M000029.html +18 -0
- data/ref/ruby/classes/Vpi.src/M000030.html +25 -15
- data/ref/ruby/classes/Vpi.src/M000031.html +9 -5
- data/ref/ruby/classes/Vpi.src/M000032.html +9 -25
- data/ref/ruby/created.rid +1 -1
- data/ref/ruby/files/bin/generate_test_rb.html +2 -1
- data/ref/ruby/files/bin/header_to_ruby_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/erb_rb.html +7 -1
- data/ref/ruby/files/lib/ruby-vpi/float_rb.html +7 -1
- data/ref/ruby/files/lib/ruby-vpi/integer_rb.html +7 -1
- data/ref/ruby/files/lib/ruby-vpi/rake_rb.html +7 -1
- data/ref/ruby/files/lib/ruby-vpi/rcov_rb.html +7 -1
- data/ref/ruby/files/lib/ruby-vpi/rdoc_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/runner_proxy_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/runner_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/verilog_parser_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/vpi_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi_rb.html +7 -1
- data/ref/ruby/fr_method_index.html +34 -34
- data/samp/counter/counter_rspec_runner.rake +4 -0
- data/samp/counter/counter_xunit_runner.rake +4 -0
- data/samp/pipelined_alu/Hw5UnitModel.rb +3 -19
- data/samp/pipelined_alu/README +38 -13
- data/samp/pipelined_alu/TestHw5UnitModel.rb +9 -20
- data/samp/pipelined_alu/hw5_unit.v +1 -16
- data/samp/pipelined_alu/hw5_unit_test_runner.rake +4 -0
- data/samp/pipelined_alu/hw5_unit_test_spec.rb +3 -20
- data/samp/pipelined_alu/int_gen.rb +6 -20
- metadata +47 -43
- data/doc/LICENSE +0 -397
- data/doc/images/feed-icon.LICENSE +0 -2
- data/doc/images/feed-icon.svg +0 -18
- data/ref/ruby/classes/Integer.src/M000020.html +0 -25
- data/ref/ruby/classes/Integer.src/M000021.html +0 -30
- data/ref/ruby/classes/String.src/M000025.html +0 -18
- data/ref/ruby/classes/Vpi/Handle.src/M000047.html +0 -24
- data/ref/ruby/classes/Vpi.src/M000033.html +0 -22
data/lib/ruby-vpi/vpi.rb
CHANGED
|
@@ -1,24 +1,8 @@
|
|
|
1
|
-
# A utility layer which transforms the VPI interface into one that is more
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
This file is part of Ruby-VPI.
|
|
7
|
-
|
|
8
|
-
Ruby-VPI is free software; you can redistribute it and/or
|
|
9
|
-
modify it under the terms of the GNU General Public License
|
|
10
|
-
as published by the Free Software Foundation; either version 2
|
|
11
|
-
of the License, or (at your option) any later version.
|
|
12
|
-
|
|
13
|
-
Ruby-VPI is distributed in the hope that it will be useful,
|
|
14
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
-
GNU General Public License for more details.
|
|
17
|
-
|
|
18
|
-
You should have received a copy of the GNU General Public License
|
|
19
|
-
along with Ruby-VPI; if not, write to the Free Software Foundation,
|
|
20
|
-
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
21
|
-
=end
|
|
1
|
+
# A utility layer which transforms the VPI interface into one that is more
|
|
2
|
+
# suitable for Ruby.
|
|
3
|
+
#--
|
|
4
|
+
# Copyright 2006-2007 Suraj N. Kurapati
|
|
5
|
+
# See the file named LICENSE for details.
|
|
22
6
|
|
|
23
7
|
module Vpi
|
|
24
8
|
# Number of bits in PLI_INT32.
|
|
@@ -31,487 +15,547 @@ module Vpi
|
|
|
31
15
|
INTEGER_MASK = INTEGER_LIMIT - 1
|
|
32
16
|
|
|
33
17
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
#
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
18
|
+
# handles
|
|
19
|
+
|
|
20
|
+
Handle = SWIG::TYPE_p_unsigned_int
|
|
21
|
+
|
|
22
|
+
# An object inside a Verilog simulation (see *vpiHandle* in IEEE Std.
|
|
23
|
+
# 1364-2005).
|
|
24
|
+
#
|
|
25
|
+
# VPI types and properties listed in ext/vpi_user.h can be specified by
|
|
26
|
+
# their names (strings or symbols) or integer constants.
|
|
27
|
+
#
|
|
28
|
+
# = Example names
|
|
29
|
+
# * "intVal"
|
|
30
|
+
# * :intVal
|
|
31
|
+
# * "vpiIntVal"
|
|
32
|
+
# * :vpiIntVal
|
|
33
|
+
# * "VpiIntVal"
|
|
34
|
+
# * :VpiIntVal
|
|
35
|
+
#
|
|
36
|
+
# = Example constants
|
|
37
|
+
# * VpiIntVal
|
|
38
|
+
# * VpiModule
|
|
39
|
+
# * VpiReg
|
|
40
|
+
#
|
|
41
|
+
class Handle
|
|
42
|
+
include Vpi
|
|
43
|
+
|
|
44
|
+
# inherit Enumerable methods, such as #each, #map, #select, etc.
|
|
45
|
+
Enumerable.instance_methods.each do |meth|
|
|
46
|
+
# using a string because define_method does not accept a block until
|
|
47
|
+
# Ruby 1.9
|
|
48
|
+
class_eval %{
|
|
49
|
+
def #{meth} *args, &block
|
|
50
|
+
self[*args].send(:#{meth}, &block)
|
|
51
|
+
end
|
|
52
|
+
}
|
|
53
|
+
end
|
|
63
54
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
55
|
+
# Tests if the logic value of this handle is unknown (x).
|
|
56
|
+
def x?
|
|
57
|
+
self.hexStrVal =~ /x/i
|
|
58
|
+
end
|
|
68
59
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
60
|
+
# Sets the logic value of this handle to unknown (x).
|
|
61
|
+
def x!
|
|
62
|
+
self.hexStrVal = 'x'
|
|
63
|
+
end
|
|
73
64
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
65
|
+
# Tests if the logic value of this handle is high impedance (z).
|
|
66
|
+
def z?
|
|
67
|
+
self.hexStrVal =~ /z/i
|
|
68
|
+
end
|
|
78
69
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
70
|
+
# Sets the logic value of this handle to high impedance (z).
|
|
71
|
+
def z!
|
|
72
|
+
self.hexStrVal = 'z'
|
|
73
|
+
end
|
|
83
74
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
75
|
+
# Tests if the logic value of this handle is currently at a positive edge.
|
|
76
|
+
def posedge?
|
|
77
|
+
old = @lastVal
|
|
78
|
+
new = @lastVal = self.intVal
|
|
88
79
|
|
|
89
|
-
|
|
90
|
-
|
|
80
|
+
old == 0 && new == 1
|
|
81
|
+
end
|
|
91
82
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
83
|
+
# Tests if the logic value of this handle is currently at a negative edge.
|
|
84
|
+
def negedge?
|
|
85
|
+
old = @lastVal
|
|
86
|
+
new = @lastVal = self.intVal
|
|
96
87
|
|
|
97
|
-
|
|
98
|
-
|
|
88
|
+
old == 1 && new == 0
|
|
89
|
+
end
|
|
99
90
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
91
|
+
# Reads the value using the given format (integer constant) and returns a
|
|
92
|
+
# +S_vpi_value+ object.
|
|
93
|
+
def get_value_wrapper aFormat
|
|
94
|
+
val = S_vpi_value.new
|
|
95
|
+
val.format = aFormat
|
|
104
96
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
97
|
+
vpi_get_value self, val
|
|
98
|
+
val
|
|
99
|
+
end
|
|
108
100
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
101
|
+
# Reads the value using the given format (name or integer constant) and
|
|
102
|
+
# returns it. If a format is not given, then the Verilog simulator will
|
|
103
|
+
# attempt to determine the correct format.
|
|
104
|
+
def get_value aFormat = VpiObjTypeVal
|
|
105
|
+
val = get_value_wrapper(resolve_prop_type(aFormat))
|
|
112
106
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
107
|
+
case val.format
|
|
108
|
+
when VpiBinStrVal, VpiOctStrVal, VpiDecStrVal, VpiHexStrVal, VpiStringVal
|
|
109
|
+
val.value.str
|
|
116
110
|
|
|
117
|
-
|
|
118
|
-
|
|
111
|
+
when VpiScalarVal
|
|
112
|
+
val.value.scalar
|
|
119
113
|
|
|
120
|
-
|
|
121
|
-
|
|
114
|
+
when VpiIntVal
|
|
115
|
+
get_value_wrapper(VpiHexStrVal).value.str.to_i(16)
|
|
122
116
|
|
|
123
|
-
|
|
124
|
-
|
|
117
|
+
when VpiRealVal
|
|
118
|
+
val.value.real
|
|
125
119
|
|
|
126
|
-
|
|
127
|
-
|
|
120
|
+
when VpiTimeVal
|
|
121
|
+
val.value.time
|
|
128
122
|
|
|
129
|
-
|
|
130
|
-
|
|
123
|
+
when VpiVectorVal
|
|
124
|
+
val.value.vector
|
|
131
125
|
|
|
132
|
-
|
|
133
|
-
|
|
126
|
+
when VpiStrengthVal
|
|
127
|
+
val.value.strength
|
|
134
128
|
|
|
135
|
-
|
|
136
|
-
|
|
129
|
+
else
|
|
130
|
+
raise "unknown S_vpi_value.format: #{val.format}"
|
|
131
|
+
end
|
|
137
132
|
end
|
|
138
|
-
end
|
|
139
133
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
134
|
+
# Writes the given value using the given format (name or integer
|
|
135
|
+
# constant), time, and delay, and then returns the given value. If a
|
|
136
|
+
# format is not given, then the Verilog simulator will attempt to
|
|
137
|
+
# determine the correct format.
|
|
138
|
+
def put_value aValue, aFormat = nil, aTime = nil, aDelay = VpiNoDelay
|
|
139
|
+
aFormat =
|
|
140
|
+
if aFormat
|
|
141
|
+
resolve_prop_type(aFormat)
|
|
142
|
+
else
|
|
143
|
+
get_value_wrapper(VpiObjTypeVal).format
|
|
144
|
+
end
|
|
148
145
|
|
|
149
|
-
|
|
150
|
-
|
|
146
|
+
newVal = S_vpi_value.new
|
|
147
|
+
newVal.format = aFormat
|
|
151
148
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
149
|
+
case aFormat
|
|
150
|
+
when VpiBinStrVal, VpiOctStrVal, VpiDecStrVal, VpiHexStrVal, VpiStringVal
|
|
151
|
+
newVal.value.str = aValue.to_s
|
|
155
152
|
|
|
156
|
-
|
|
157
|
-
|
|
153
|
+
when VpiScalarVal
|
|
154
|
+
newVal.value.scalar = aValue
|
|
158
155
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
156
|
+
when VpiIntVal
|
|
157
|
+
newVal.format = VpiHexStrVal
|
|
158
|
+
newVal.value.str = aValue.to_i.to_s(16)
|
|
162
159
|
|
|
163
|
-
|
|
164
|
-
|
|
160
|
+
when VpiRealVal
|
|
161
|
+
newVal.value.real = aValue.to_f
|
|
165
162
|
|
|
166
|
-
|
|
167
|
-
|
|
163
|
+
when VpiTimeVal
|
|
164
|
+
newVal.value.time = aValue
|
|
168
165
|
|
|
169
|
-
|
|
170
|
-
|
|
166
|
+
when VpiVectorVal
|
|
167
|
+
newVal.value.vector = aValue
|
|
171
168
|
|
|
172
|
-
|
|
173
|
-
|
|
169
|
+
when VpiStrengthVal
|
|
170
|
+
newVal.value.strength = aValue
|
|
174
171
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
172
|
+
else
|
|
173
|
+
raise "unknown S_vpi_value.format: #{newVal.format}"
|
|
174
|
+
end
|
|
178
175
|
|
|
179
|
-
|
|
176
|
+
vpi_put_value self, newVal, aTime, aDelay
|
|
180
177
|
|
|
181
|
-
|
|
182
|
-
|
|
178
|
+
# ensure that value was written correctly
|
|
179
|
+
readenVal = get_value(aFormat)
|
|
183
180
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
181
|
+
writtenCorrectly =
|
|
182
|
+
case aFormat
|
|
183
|
+
when VpiBinStrVal, VpiOctStrVal, VpiDecStrVal, VpiHexStrVal
|
|
184
|
+
if aValue =~ /[xz]/i # TODO: verify 'z' behavior
|
|
185
|
+
readenVal =~ /[xz]/i
|
|
186
|
+
else
|
|
187
|
+
readenVal == aValue.to_s
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
when VpiStringVal
|
|
190
191
|
readenVal == aValue.to_s
|
|
191
|
-
end
|
|
192
192
|
|
|
193
|
-
|
|
194
|
-
|
|
193
|
+
when VpiIntVal
|
|
194
|
+
# allow for register overflow when limit reached
|
|
195
|
+
readenVal == (aValue.to_i % (2 ** self.vpiSize))
|
|
195
196
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
readenVal == (aValue.to_i % (2 ** self.vpiSize))
|
|
197
|
+
when VpiRealVal
|
|
198
|
+
readenVal == aValue.to_f
|
|
199
199
|
|
|
200
|
-
|
|
201
|
-
|
|
200
|
+
else
|
|
201
|
+
true
|
|
202
|
+
end
|
|
202
203
|
|
|
203
|
-
|
|
204
|
-
|
|
204
|
+
unless writtenCorrectly
|
|
205
|
+
raise "value written (#{aValue.inspect}) does not match value read (#{readenVal.inspect}) from handle #{self}"
|
|
205
206
|
end
|
|
206
207
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
aValue
|
|
212
|
-
end
|
|
208
|
+
aValue
|
|
209
|
+
end
|
|
213
210
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
211
|
+
# Returns an array of child handles of the given types (name or integer
|
|
212
|
+
# constant).
|
|
213
|
+
def [] *aTypes
|
|
214
|
+
handles = []
|
|
217
215
|
|
|
218
|
-
|
|
219
|
-
|
|
216
|
+
aTypes.each do |t|
|
|
217
|
+
t = resolve_prop_type(t)
|
|
220
218
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
219
|
+
if itr = vpi_iterate(t, self)
|
|
220
|
+
while h = vpi_scan(itr)
|
|
221
|
+
handles << h
|
|
222
|
+
end
|
|
224
223
|
end
|
|
225
224
|
end
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
handles
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
# Inspects the given VPI property names, in addition to those common to all handles.
|
|
232
|
-
def inspect *aPropNames
|
|
233
|
-
aPropNames.unshift :fullName, :size, :file, :lineNo
|
|
234
225
|
|
|
235
|
-
|
|
236
|
-
"#{name}=#{self.send(name.to_sym)}"
|
|
226
|
+
handles
|
|
237
227
|
end
|
|
238
228
|
|
|
239
|
-
|
|
240
|
-
|
|
229
|
+
# Inspects the given VPI property names, in addition to those common to
|
|
230
|
+
# all handles.
|
|
231
|
+
def inspect *aPropNames
|
|
232
|
+
aPropNames.unshift :fullName, :size, :file, :lineNo
|
|
241
233
|
|
|
242
|
-
|
|
234
|
+
aPropNames.map! do |name|
|
|
235
|
+
"#{name}=#{self.send(name.to_sym)}"
|
|
236
|
+
end
|
|
243
237
|
|
|
238
|
+
"#<Vpi::Handle #{vpiType_s} #{aPropNames.join(', ')}>"
|
|
239
|
+
end
|
|
244
240
|
|
|
245
|
-
|
|
241
|
+
alias to_s inspect
|
|
246
242
|
|
|
247
|
-
|
|
243
|
+
# Registers a callback that is invoked whenever the value of this object
|
|
244
|
+
# changes.
|
|
245
|
+
def cbValueChange aOptions = {}, &aHandler
|
|
246
|
+
raise ArgumentError unless block_given?
|
|
248
247
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
# 2. VPI properties
|
|
252
|
-
# 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 via #get_value and #put_value.
|
|
253
|
-
def method_missing aMeth, *aArgs, &aBlockArg
|
|
254
|
-
if child = vpi_handle_by_name(aMeth.to_s, self)
|
|
255
|
-
# cache the child for future accesses, in order to cut down number of calls to method_missing
|
|
256
|
-
(class << self; self; end).class_eval do
|
|
257
|
-
define_method aMeth do
|
|
258
|
-
child
|
|
259
|
-
end
|
|
260
|
-
end
|
|
248
|
+
aOptions[:time] ||= S_vpi_time.new(:type => VpiSuppressTime)
|
|
249
|
+
aOptions[:value] ||= S_vpi_value.new(:format => VpiSuppressVal)
|
|
261
250
|
|
|
262
|
-
|
|
251
|
+
alarm = S_cb_data.new(
|
|
252
|
+
:reason => CbValueChange,
|
|
253
|
+
:obj => self,
|
|
254
|
+
:time => aOptions[:time],
|
|
255
|
+
:value => aOptions[:value],
|
|
256
|
+
:index => 0
|
|
257
|
+
)
|
|
263
258
|
|
|
264
|
-
|
|
265
|
-
|
|
259
|
+
vpi_register_cb alarm, &aHandler
|
|
260
|
+
end
|
|
266
261
|
|
|
267
|
-
if prop.operation
|
|
268
|
-
self.send(prop.operation, prop.type, *aArgs, &aBlockArg)
|
|
269
262
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
263
|
+
@@propCache = Hash.new {|h, k| h[k] = Property.resolve(k)}
|
|
264
|
+
|
|
265
|
+
# Provides access to this handle's (1) child handles and (2) VPI
|
|
266
|
+
# properties through method calls. In the case that a child handle has the
|
|
267
|
+
# same name as a VPI property, the child handle will be accessed instead
|
|
268
|
+
# of the VPI property. However, you can still access the VPI property via
|
|
269
|
+
# #get_value and #put_value.
|
|
270
|
+
def method_missing aMeth, *aArgs, &aBlockArg
|
|
271
|
+
if child = vpi_handle_by_name(aMeth.to_s, self)
|
|
272
|
+
# cache the child for future accesses, in order to cut down number of
|
|
273
|
+
# calls to method_missing
|
|
274
|
+
(class << self; self; end).class_eval do
|
|
275
|
+
define_method aMeth do
|
|
276
|
+
child
|
|
283
277
|
end
|
|
278
|
+
end
|
|
284
279
|
|
|
285
|
-
|
|
286
|
-
vpi_get(prop.type, self) unless prop.assignment
|
|
280
|
+
child
|
|
287
281
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
value = vpi_get(prop, self)
|
|
291
|
-
value && (value != 0) # zero is false in C
|
|
292
|
-
end
|
|
282
|
+
else
|
|
283
|
+
prop = @@propCache[aMeth]
|
|
293
284
|
|
|
294
|
-
|
|
295
|
-
|
|
285
|
+
if prop.operation
|
|
286
|
+
self.send(prop.operation, prop.type, *aArgs, &aBlockArg)
|
|
296
287
|
|
|
297
|
-
|
|
298
|
-
|
|
288
|
+
else
|
|
289
|
+
case prop.accessor
|
|
290
|
+
when :d # delay values
|
|
291
|
+
raise NotImplementedError, 'processing of delay values is not yet implemented.'
|
|
292
|
+
# TODO: vpi_put_delays
|
|
293
|
+
# TODO: vpi_get_delays
|
|
294
|
+
|
|
295
|
+
when :l # logic values
|
|
296
|
+
if prop.assignment
|
|
297
|
+
value = aArgs.shift
|
|
298
|
+
put_value(value, prop.type, *aArgs)
|
|
299
|
+
else
|
|
300
|
+
get_value(prop.type)
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
when :i # integer values
|
|
304
|
+
vpi_get(prop.type, self) unless prop.assignment
|
|
305
|
+
|
|
306
|
+
when :b # boolean values
|
|
307
|
+
unless prop.assignment
|
|
308
|
+
value = vpi_get(prop, self)
|
|
309
|
+
value && (value != 0) # zero is false in C
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
when :s # string values
|
|
313
|
+
vpi_get_str(prop.type, self) unless prop.assignment
|
|
314
|
+
|
|
315
|
+
when :h # handle values
|
|
316
|
+
vpi_handle(prop.type, self) unless prop.assignment
|
|
299
317
|
|
|
300
|
-
|
|
301
|
-
|
|
318
|
+
else
|
|
319
|
+
raise NoMethodError, "unable to access VPI property #{prop.name.inspect} through method #{aMeth.inspect} with arguments #{aArgs.inspect} for handle #{self}"
|
|
320
|
+
end
|
|
302
321
|
end
|
|
303
322
|
end
|
|
304
323
|
end
|
|
305
|
-
end
|
|
306
324
|
|
|
307
|
-
|
|
325
|
+
Property = Struct.new :type, :name, :operation, :accessor, :assignment
|
|
308
326
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
327
|
+
# Resolves the given shorthand name into a description of its VPI
|
|
328
|
+
# property.
|
|
329
|
+
def Property.resolve aName # :nodoc:
|
|
330
|
+
# parse the given property name
|
|
331
|
+
tokens = aName.to_s.split(/_/)
|
|
313
332
|
|
|
314
333
|
|
|
315
|
-
|
|
334
|
+
tokens.last.sub!(/[\?!=]$/, '')
|
|
316
335
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
336
|
+
addendum = $&
|
|
337
|
+
isAssign = $& == '='
|
|
338
|
+
isQuery = $& == '?'
|
|
320
339
|
|
|
321
340
|
|
|
322
|
-
|
|
323
|
-
|
|
341
|
+
tokens.last =~ /^[a-z]$/ && tokens.pop
|
|
342
|
+
accessor = $&
|
|
324
343
|
|
|
325
|
-
|
|
344
|
+
name = tokens.pop
|
|
326
345
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
346
|
+
operation =
|
|
347
|
+
unless tokens.empty?
|
|
348
|
+
tokens.join('_') << (addendum || '')
|
|
349
|
+
end
|
|
331
350
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
351
|
+
# determine the VPI integer type for the property
|
|
352
|
+
name = name[0, 1].upcase << name[1..-1]
|
|
353
|
+
name.insert 0, 'Vpi' unless name =~ /^[Vv]pi/
|
|
335
354
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
355
|
+
begin
|
|
356
|
+
type = Vpi.const_get(name)
|
|
357
|
+
rescue NameError
|
|
358
|
+
raise ArgumentError, "#{name.inspect} is not a valid VPI property"
|
|
359
|
+
end
|
|
341
360
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
361
|
+
accessor =
|
|
362
|
+
if accessor
|
|
363
|
+
accessor.to_sym
|
|
345
364
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
365
|
+
else # infer accessor from VPI property name
|
|
366
|
+
if isQuery
|
|
367
|
+
:b
|
|
349
368
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
369
|
+
else
|
|
370
|
+
case name
|
|
371
|
+
when /Time$/
|
|
372
|
+
:d
|
|
354
373
|
|
|
355
|
-
|
|
356
|
-
|
|
374
|
+
when /Val$/
|
|
375
|
+
:l
|
|
357
376
|
|
|
358
|
-
|
|
359
|
-
|
|
377
|
+
when /Type$/, /Direction$/, /Index$/, /Size$/, /Strength\d?$/, /Polarity$/, /Edge$/, /Offset$/, /Mode$/, /LineNo$/
|
|
378
|
+
:i
|
|
360
379
|
|
|
361
|
-
|
|
362
|
-
|
|
380
|
+
when /Is[A-Z]/, /ed$/
|
|
381
|
+
:b
|
|
363
382
|
|
|
364
|
-
|
|
365
|
-
|
|
383
|
+
when /Name$/, /File$/, /Decompile$/
|
|
384
|
+
:s
|
|
366
385
|
|
|
367
|
-
|
|
368
|
-
|
|
386
|
+
when /Parent$/, /Inst$/, /Range$/, /Driver$/, /Net$/, /Load$/, /Conn$/, /Bit$/, /Word$/, /[LR]hs$/, /(In|Out)$/, /Term$/, /Argument$/, /Condition$/, /Use$/, /Operand$/, /Stmt$/, /Expr$/, /Scope$/, /Memory$/, /Delay$/
|
|
387
|
+
:h
|
|
388
|
+
end
|
|
369
389
|
end
|
|
370
390
|
end
|
|
371
|
-
end
|
|
372
391
|
|
|
373
|
-
|
|
374
|
-
|
|
392
|
+
Property.new type, name, operation, accessor, isAssign
|
|
393
|
+
end
|
|
375
394
|
|
|
376
|
-
|
|
395
|
+
private
|
|
377
396
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
397
|
+
# resolve type names into type constants
|
|
398
|
+
def resolve_prop_type aNameOrType
|
|
399
|
+
if aNameOrType.is_a? Integer
|
|
400
|
+
aNameOrType
|
|
401
|
+
else
|
|
402
|
+
@@propCache[aNameOrType.to_sym].type
|
|
403
|
+
end
|
|
384
404
|
end
|
|
385
405
|
end
|
|
386
|
-
end
|
|
387
406
|
|
|
388
407
|
|
|
389
|
-
|
|
408
|
+
# callbacks
|
|
390
409
|
|
|
391
|
-
|
|
392
|
-
|
|
410
|
+
Callback = Struct.new :handler, :token #:nodoc:
|
|
411
|
+
@@callbacks = {}
|
|
393
412
|
|
|
394
|
-
|
|
413
|
+
alias vpi_register_cb_old vpi_register_cb
|
|
395
414
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
415
|
+
# This is a Ruby version of the vpi_register_cb C function. It is identical
|
|
416
|
+
# to the C function, except for the following differences:
|
|
417
|
+
#
|
|
418
|
+
# * This method accepts a block (callback handler) which is executed
|
|
419
|
+
# whenever the callback occurs.
|
|
420
|
+
#
|
|
421
|
+
# * This method overwrites the +cb_rtn+ and +user_data+ fields of the given
|
|
422
|
+
# +S_cb_data+ object.
|
|
423
|
+
#
|
|
424
|
+
def vpi_register_cb aData, &aHandler # :yields: Vpi::S_cb_data
|
|
425
|
+
raise ArgumentError, "block must be given" unless block_given?
|
|
401
426
|
|
|
402
|
-
|
|
427
|
+
key = aHandler.object_id.to_s
|
|
403
428
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
429
|
+
# register the callback with Verilog
|
|
430
|
+
aData.user_data = key
|
|
431
|
+
aData.cb_rtn = Vlog_relay_ruby
|
|
432
|
+
token = vpi_register_cb_old(aData)
|
|
408
433
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
434
|
+
@@callbacks[key] = Callback.new(aHandler, token)
|
|
435
|
+
token
|
|
436
|
+
end
|
|
412
437
|
|
|
413
|
-
|
|
438
|
+
alias vpi_remove_cb_old vpi_remove_cb
|
|
414
439
|
|
|
415
|
-
|
|
416
|
-
|
|
440
|
+
def vpi_remove_cb aData # :nodoc:
|
|
441
|
+
key = aData.user_data
|
|
417
442
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
443
|
+
if c = @@callbacks[key]
|
|
444
|
+
vpi_remove_cb_old c.token
|
|
445
|
+
@@callbacks.delete key
|
|
446
|
+
end
|
|
421
447
|
end
|
|
422
|
-
end
|
|
423
448
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
449
|
+
# Proxy for relay_verilog which supports callbacks.
|
|
450
|
+
# This method should NOT be invoked from callback handlers (see
|
|
451
|
+
# vpi_register_cb) and threads -- otherwise the situation will be like seven
|
|
452
|
+
# remote controls changing the channel on a single television set!
|
|
453
|
+
def relay_verilog_proxy # :nodoc:
|
|
454
|
+
loop do
|
|
455
|
+
relay_verilog
|
|
429
456
|
|
|
430
|
-
|
|
431
|
-
|
|
457
|
+
if reason = relay_ruby_reason # might be nil
|
|
458
|
+
dst = reason.user_data
|
|
432
459
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
460
|
+
if c = @@callbacks[dst]
|
|
461
|
+
c.handler.call reason
|
|
462
|
+
else
|
|
463
|
+
break # main thread is receiver
|
|
464
|
+
end
|
|
437
465
|
end
|
|
438
466
|
end
|
|
439
467
|
end
|
|
440
|
-
end
|
|
441
|
-
|
|
442
468
|
|
|
443
|
-
## simulation control
|
|
444
469
|
|
|
445
|
-
#
|
|
446
|
-
def simulate
|
|
447
|
-
# this is a dummy method!
|
|
448
|
-
end
|
|
470
|
+
# simulation control
|
|
449
471
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
time.integer = aNumSteps
|
|
455
|
-
time.type = VpiSimTime
|
|
456
|
-
|
|
457
|
-
value = S_vpi_value.new
|
|
458
|
-
value.format = VpiSuppressVal
|
|
459
|
-
|
|
460
|
-
alarm = S_cb_data.new
|
|
461
|
-
alarm.reason = CbAfterDelay
|
|
462
|
-
alarm.cb_rtn = Vlog_relay_ruby
|
|
463
|
-
alarm.obj = nil
|
|
464
|
-
alarm.time = time
|
|
465
|
-
alarm.value = value
|
|
466
|
-
alarm.index = 0
|
|
467
|
-
alarm.user_data = nil
|
|
472
|
+
# Simulates the design under test according to RubyVpi.init_bench.
|
|
473
|
+
def simulate
|
|
474
|
+
# this is a dummy method! it is overwritten by RubyVpi.init_bench
|
|
475
|
+
end
|
|
468
476
|
|
|
469
|
-
|
|
477
|
+
# Advances the simulation by the given number of steps.
|
|
478
|
+
def advance_time aNumSteps = 1
|
|
479
|
+
# schedule wake-up callback from verilog
|
|
480
|
+
time = S_vpi_time.new
|
|
481
|
+
time.integer = aNumSteps
|
|
482
|
+
time.type = VpiSimTime
|
|
483
|
+
|
|
484
|
+
value = S_vpi_value.new
|
|
485
|
+
value.format = VpiSuppressVal
|
|
486
|
+
|
|
487
|
+
alarm = S_cb_data.new
|
|
488
|
+
alarm.reason = CbAfterDelay
|
|
489
|
+
alarm.cb_rtn = Vlog_relay_ruby
|
|
490
|
+
alarm.obj = nil
|
|
491
|
+
alarm.time = time
|
|
492
|
+
alarm.value = value
|
|
493
|
+
alarm.index = 0
|
|
494
|
+
alarm.user_data = nil
|
|
495
|
+
|
|
496
|
+
vpi_free_object(vpi_register_cb_old(alarm))
|
|
497
|
+
|
|
498
|
+
# relay to verilog
|
|
499
|
+
relay_verilog_proxy
|
|
500
|
+
end
|
|
470
501
|
|
|
471
|
-
# relay to verilog
|
|
472
|
-
relay_verilog_proxy
|
|
473
|
-
end
|
|
474
502
|
|
|
503
|
+
# utility
|
|
475
504
|
|
|
476
|
-
|
|
505
|
+
# Returns the current simulation time as an integer.
|
|
506
|
+
def simulation_time
|
|
507
|
+
t = S_vpi_time.new
|
|
508
|
+
t.type = VpiSimTime
|
|
477
509
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
t.type = VpiSimTime
|
|
510
|
+
vpi_get_time nil, t
|
|
511
|
+
t.to_i
|
|
512
|
+
end
|
|
482
513
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
514
|
+
class S_vpi_time
|
|
515
|
+
# Returns the high and low portions of this time as a single 64-bit
|
|
516
|
+
# integer.
|
|
517
|
+
def integer
|
|
518
|
+
(self.high << INTEGER_BITS) | self.low
|
|
519
|
+
end
|
|
486
520
|
|
|
521
|
+
# Sets the high and low portions of this time from the given 64-bit
|
|
522
|
+
# integer.
|
|
523
|
+
def integer= aValue
|
|
524
|
+
self.low = aValue & INTEGER_MASK
|
|
525
|
+
self.high = (aValue >> INTEGER_BITS) & INTEGER_MASK
|
|
526
|
+
end
|
|
487
527
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
def integer
|
|
491
|
-
(self.high << INTEGER_BITS) | self.low
|
|
528
|
+
alias to_i integer
|
|
529
|
+
alias to_f real
|
|
492
530
|
end
|
|
493
531
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
end
|
|
532
|
+
class S_vpi_value
|
|
533
|
+
def to_i
|
|
534
|
+
value.integer
|
|
535
|
+
end
|
|
499
536
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
537
|
+
def to_f
|
|
538
|
+
value.real
|
|
539
|
+
end
|
|
503
540
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
541
|
+
def to_s
|
|
542
|
+
value.str
|
|
543
|
+
end
|
|
507
544
|
end
|
|
508
545
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
546
|
+
# make VPI structs more accessible by allowing their members to be
|
|
547
|
+
# initialized through the constructor
|
|
548
|
+
constants.grep(/^S_/).each do |s|
|
|
549
|
+
const_get(s).class_eval do
|
|
550
|
+
alias old_initialize initialize
|
|
512
551
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
552
|
+
def initialize aMembers = {}
|
|
553
|
+
old_initialize
|
|
554
|
+
|
|
555
|
+
aMembers.each_pair do |k, v|
|
|
556
|
+
__send__ "#{k}=", v
|
|
557
|
+
end
|
|
558
|
+
end
|
|
559
|
+
end
|
|
560
|
+
end
|
|
517
561
|
end
|