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.
Files changed (208) hide show
  1. data/LICENSE +23 -340
  2. data/Rakefile +169 -192
  3. data/bin/generate_test.rb +26 -25
  4. data/bin/generate_test_tpl/runner.rake +4 -10
  5. data/bin/header_to_ruby.rb +3 -20
  6. data/doc/README +11 -0
  7. data/doc/Rakefile +8 -21
  8. data/doc/common.css +44 -10
  9. data/doc/common.tpl +5 -10
  10. data/doc/history.doc +8 -7
  11. data/doc/history.html +228 -560
  12. data/doc/history.rb +7 -11
  13. data/doc/{history.yml → history.yaml} +325 -128
  14. data/doc/images/{feed-icon.png → feed-icon-28x28.png} +0 -0
  15. data/doc/images/ruby/LICENSE +15 -0
  16. data/doc/images/ruby/logo-reflection.png +0 -0
  17. data/doc/images/ruby/logo-reflection.xcf +0 -0
  18. data/doc/images/ruby/logo.png +0 -0
  19. data/doc/images/{LICENSE → tango/LICENSE} +0 -0
  20. data/doc/images/{caution.png → tango/caution.png} +0 -0
  21. data/doc/images/{caution.svg → tango/caution.svg} +0 -0
  22. data/doc/images/{home.png → tango/home.png} +0 -0
  23. data/doc/images/{home.svg → tango/home.svg} +0 -0
  24. data/doc/images/{important.png → tango/important.png} +0 -0
  25. data/doc/images/{important.svg → tango/important.svg} +0 -0
  26. data/doc/images/{next.png → tango/next.png} +0 -0
  27. data/doc/images/{next.svg → tango/next.svg} +0 -0
  28. data/doc/images/{note.png → tango/note.png} +0 -0
  29. data/doc/images/{note.svg → tango/note.svg} +0 -0
  30. data/doc/images/{prev.png → tango/prev.png} +0 -0
  31. data/doc/images/{prev.svg → tango/prev.svg} +0 -0
  32. data/doc/images/{tip.png → tango/tip.png} +0 -0
  33. data/doc/images/{tip.svg → tango/tip.svg} +0 -0
  34. data/doc/images/{up.png → tango/up.png} +0 -0
  35. data/doc/images/{up.svg → tango/up.svg} +0 -0
  36. data/doc/images/{warning.png → tango/warning.png} +0 -0
  37. data/doc/images/{warning.svg → tango/warning.svg} +0 -0
  38. data/doc/intro.inc +105 -36
  39. data/doc/lib/doc_format.rb +151 -29
  40. data/doc/lib/doc_proxy.rb +28 -69
  41. data/doc/lib/erb_content.rb +10 -22
  42. data/doc/lib/erb_proxy.rb +13 -24
  43. data/doc/manual.doc +16 -60
  44. data/doc/manual.html +257 -340
  45. data/doc/memo.doc +2 -0
  46. data/doc/memo.html +11 -11
  47. data/doc/readme.doc +36 -2
  48. data/doc/readme.html +214 -51
  49. data/doc/rss.erb +3 -3
  50. data/doc/rss.xml +217 -269
  51. data/ext/Rakefile +7 -22
  52. data/ext/common.h +10 -21
  53. data/ext/extconf.rb +5 -0
  54. data/ext/main.c +2 -18
  55. data/ext/main.h +1 -16
  56. data/ext/relay.c +3 -17
  57. data/ext/relay.h +3 -17
  58. data/ext/verilog.h +6 -18
  59. data/ext/vlog.c +3 -21
  60. data/ext/vlog.h +3 -17
  61. data/lib/ruby-vpi/erb.rb +7 -20
  62. data/lib/ruby-vpi/float.rb +6 -20
  63. data/lib/ruby-vpi/integer.rb +27 -47
  64. data/lib/ruby-vpi/rake.rb +4 -19
  65. data/lib/ruby-vpi/rcov.rb +6 -21
  66. data/lib/ruby-vpi/rdoc.rb +3 -21
  67. data/lib/ruby-vpi/runner.rb +28 -29
  68. data/lib/ruby-vpi/runner_proxy.rb +5 -21
  69. data/lib/ruby-vpi/verilog_parser.rb +5 -20
  70. data/lib/ruby-vpi/vpi.rb +420 -376
  71. data/lib/ruby-vpi.rb +26 -32
  72. data/ref/c/annotated.html +1 -1
  73. data/ref/c/common_8h.html +1 -1
  74. data/ref/c/files.html +1 -1
  75. data/ref/c/functions.html +1 -1
  76. data/ref/c/functions_vars.html +1 -1
  77. data/ref/c/globals.html +1 -1
  78. data/ref/c/globals_0x63.html +1 -1
  79. data/ref/c/globals_0x65.html +1 -1
  80. data/ref/c/globals_0x66.html +1 -1
  81. data/ref/c/globals_0x6d.html +1 -1
  82. data/ref/c/globals_0x70.html +1 -1
  83. data/ref/c/globals_0x72.html +1 -1
  84. data/ref/c/globals_0x73.html +1 -1
  85. data/ref/c/globals_0x74.html +1 -1
  86. data/ref/c/globals_0x76.html +1 -1
  87. data/ref/c/globals_0x78.html +1 -1
  88. data/ref/c/globals_defs.html +1 -1
  89. data/ref/c/globals_defs_0x65.html +1 -1
  90. data/ref/c/globals_defs_0x70.html +1 -1
  91. data/ref/c/globals_defs_0x76.html +1 -1
  92. data/ref/c/globals_defs_0x78.html +1 -1
  93. data/ref/c/globals_enum.html +1 -1
  94. data/ref/c/globals_eval.html +1 -1
  95. data/ref/c/globals_func.html +1 -1
  96. data/ref/c/globals_type.html +1 -1
  97. data/ref/c/globals_vars.html +1 -1
  98. data/ref/c/index.html +1 -1
  99. data/ref/c/main_8c.html +1 -1
  100. data/ref/c/main_8h.html +1 -1
  101. data/ref/c/relay_8c.html +1 -1
  102. data/ref/c/relay_8h.html +1 -1
  103. data/ref/c/structt__cb__data.html +1 -1
  104. data/ref/c/structt__vpi__delay.html +1 -1
  105. data/ref/c/structt__vpi__error__info.html +1 -1
  106. data/ref/c/structt__vpi__strengthval.html +1 -1
  107. data/ref/c/structt__vpi__systf__data.html +1 -1
  108. data/ref/c/structt__vpi__time.html +1 -1
  109. data/ref/c/structt__vpi__value.html +1 -1
  110. data/ref/c/structt__vpi__vecval.html +1 -1
  111. data/ref/c/structt__vpi__vlog__info.html +1 -1
  112. data/ref/c/verilog_8h.html +1 -1
  113. data/ref/c/vlog_8c.html +1 -1
  114. data/ref/c/vlog_8h.html +1 -1
  115. data/ref/c/vpi__user_8h.html +1 -1
  116. data/ref/ruby/classes/ERB.html +5 -5
  117. data/ref/ruby/classes/ERB.src/{M000026.html → M000024.html} +15 -15
  118. data/ref/ruby/classes/FileUtils.html +10 -10
  119. data/ref/ruby/classes/FileUtils.src/{M000027.html → M000025.html} +4 -4
  120. data/ref/ruby/classes/FileUtils.src/{M000028.html → M000026.html} +4 -4
  121. data/ref/ruby/classes/Float.html +5 -5
  122. data/ref/ruby/classes/Float.src/{M000022.html → M000020.html} +5 -5
  123. data/ref/ruby/classes/Integer.html +20 -56
  124. data/ref/ruby/classes/Integer.src/M000008.html +11 -11
  125. data/ref/ruby/classes/Integer.src/M000009.html +4 -4
  126. data/ref/ruby/classes/Integer.src/M000010.html +4 -4
  127. data/ref/ruby/classes/Integer.src/M000011.html +4 -4
  128. data/ref/ruby/classes/Integer.src/M000012.html +4 -4
  129. data/ref/ruby/classes/Integer.src/M000013.html +4 -4
  130. data/ref/ruby/classes/Integer.src/M000016.html +12 -9
  131. data/ref/ruby/classes/Integer.src/M000017.html +18 -9
  132. data/ref/ruby/classes/Integer.src/M000018.html +12 -12
  133. data/ref/ruby/classes/Integer.src/M000019.html +17 -18
  134. data/ref/ruby/classes/RDoc.src/M000053.html +25 -25
  135. data/ref/ruby/classes/RubyVpi/Config.html +3 -3
  136. data/ref/ruby/classes/RubyVpi.html +11 -5
  137. data/ref/ruby/classes/RubyVpi.src/{M000029.html → M000027.html} +103 -101
  138. data/ref/ruby/classes/String.html +21 -15
  139. data/ref/ruby/classes/String.src/M000021.html +36 -0
  140. data/ref/ruby/classes/String.src/{M000024.html → M000022.html} +24 -24
  141. data/ref/ruby/classes/String.src/M000023.html +5 -23
  142. data/ref/ruby/classes/VerilogParser/Module/Parameter.src/M000007.html +5 -5
  143. data/ref/ruby/classes/VerilogParser/Module/Port.src/M000003.html +7 -7
  144. data/ref/ruby/classes/VerilogParser/Module/Port.src/M000004.html +4 -4
  145. data/ref/ruby/classes/VerilogParser/Module/Port.src/M000005.html +4 -4
  146. data/ref/ruby/classes/VerilogParser/Module/Port.src/M000006.html +4 -4
  147. data/ref/ruby/classes/VerilogParser/Module.src/M000002.html +20 -20
  148. data/ref/ruby/classes/VerilogParser.html +6 -0
  149. data/ref/ruby/classes/VerilogParser.src/M000001.html +20 -20
  150. data/ref/ruby/classes/Vpi/Handle.html +89 -88
  151. data/ref/ruby/classes/Vpi/Handle.src/M000036.html +18 -0
  152. data/ref/ruby/classes/Vpi/Handle.src/M000037.html +5 -5
  153. data/ref/ruby/classes/Vpi/Handle.src/M000038.html +5 -5
  154. data/ref/ruby/classes/Vpi/Handle.src/M000039.html +5 -5
  155. data/ref/ruby/classes/Vpi/Handle.src/M000040.html +8 -5
  156. data/ref/ruby/classes/Vpi/Handle.src/M000041.html +8 -8
  157. data/ref/ruby/classes/Vpi/Handle.src/M000042.html +7 -6
  158. data/ref/ruby/classes/Vpi/Handle.src/M000043.html +31 -9
  159. data/ref/ruby/classes/Vpi/Handle.src/M000044.html +74 -31
  160. data/ref/ruby/classes/Vpi/Handle.src/M000045.html +17 -74
  161. data/ref/ruby/classes/Vpi/Handle.src/M000046.html +11 -17
  162. data/ref/ruby/classes/Vpi/Handle.src/M000048.html +31 -0
  163. data/ref/ruby/classes/Vpi/Handle.src/M000049.html +53 -52
  164. data/ref/ruby/classes/Vpi/S_vpi_time.src/M000050.html +4 -4
  165. data/ref/ruby/classes/Vpi/S_vpi_time.src/M000051.html +5 -5
  166. data/ref/ruby/classes/Vpi/S_vpi_value.html +15 -15
  167. data/ref/ruby/classes/Vpi/S_vpi_value.src/{M000036.html → M000033.html} +5 -5
  168. data/ref/ruby/classes/Vpi/S_vpi_value.src/M000034.html +5 -5
  169. data/ref/ruby/classes/Vpi/S_vpi_value.src/M000035.html +5 -5
  170. data/ref/ruby/classes/Vpi.html +48 -19
  171. data/ref/ruby/classes/Vpi.src/M000028.html +28 -0
  172. data/ref/ruby/classes/Vpi.src/M000029.html +18 -0
  173. data/ref/ruby/classes/Vpi.src/M000030.html +25 -15
  174. data/ref/ruby/classes/Vpi.src/M000031.html +9 -5
  175. data/ref/ruby/classes/Vpi.src/M000032.html +9 -25
  176. data/ref/ruby/created.rid +1 -1
  177. data/ref/ruby/files/bin/generate_test_rb.html +2 -1
  178. data/ref/ruby/files/bin/header_to_ruby_rb.html +1 -1
  179. data/ref/ruby/files/lib/ruby-vpi/erb_rb.html +7 -1
  180. data/ref/ruby/files/lib/ruby-vpi/float_rb.html +7 -1
  181. data/ref/ruby/files/lib/ruby-vpi/integer_rb.html +7 -1
  182. data/ref/ruby/files/lib/ruby-vpi/rake_rb.html +7 -1
  183. data/ref/ruby/files/lib/ruby-vpi/rcov_rb.html +7 -1
  184. data/ref/ruby/files/lib/ruby-vpi/rdoc_rb.html +1 -1
  185. data/ref/ruby/files/lib/ruby-vpi/runner_proxy_rb.html +1 -1
  186. data/ref/ruby/files/lib/ruby-vpi/runner_rb.html +1 -1
  187. data/ref/ruby/files/lib/ruby-vpi/verilog_parser_rb.html +1 -1
  188. data/ref/ruby/files/lib/ruby-vpi/vpi_rb.html +1 -1
  189. data/ref/ruby/files/lib/ruby-vpi_rb.html +7 -1
  190. data/ref/ruby/fr_method_index.html +34 -34
  191. data/samp/counter/counter_rspec_runner.rake +4 -0
  192. data/samp/counter/counter_xunit_runner.rake +4 -0
  193. data/samp/pipelined_alu/Hw5UnitModel.rb +3 -19
  194. data/samp/pipelined_alu/README +38 -13
  195. data/samp/pipelined_alu/TestHw5UnitModel.rb +9 -20
  196. data/samp/pipelined_alu/hw5_unit.v +1 -16
  197. data/samp/pipelined_alu/hw5_unit_test_runner.rake +4 -0
  198. data/samp/pipelined_alu/hw5_unit_test_spec.rb +3 -20
  199. data/samp/pipelined_alu/int_gen.rb +6 -20
  200. metadata +47 -43
  201. data/doc/LICENSE +0 -397
  202. data/doc/images/feed-icon.LICENSE +0 -2
  203. data/doc/images/feed-icon.svg +0 -18
  204. data/ref/ruby/classes/Integer.src/M000020.html +0 -25
  205. data/ref/ruby/classes/Integer.src/M000021.html +0 -30
  206. data/ref/ruby/classes/String.src/M000025.html +0 -18
  207. data/ref/ruby/classes/Vpi/Handle.src/M000047.html +0 -24
  208. 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 suitable for Ruby.
2
-
3
- =begin
4
- Copyright 2006 Suraj N. Kurapati
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
- ## handles
35
-
36
- Handle = SWIG::TYPE_p_unsigned_int
37
-
38
- # An object inside a Verilog simulation (see *vpiHandle* in IEEE Std. 1364-2005).
39
- # * VPI types and properties listed in ext/vpi_user.h can be specified by their names (strings or symbols) or integer constants.
40
- # * example names:
41
- # * "intVal"
42
- # * :intVal
43
- # * "vpiIntVal"
44
- # * :vpiIntVal
45
- # * "VpiIntVal"
46
- # * :VpiIntVal
47
- # * example constants:
48
- # * VpiIntVal
49
- # * VpiModule
50
- # * VpiReg
51
- class Handle
52
- include Vpi
53
-
54
- # inherit Enumerable methods, such as #each, #map, #select, etc.
55
- Enumerable.instance_methods.each do |meth|
56
- # using a string because define_method does not accept a block until Ruby 1.9
57
- class_eval %{
58
- def #{meth} *args, &block
59
- self[*args].send(:#{meth}, &block)
60
- end
61
- }
62
- end
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
- # Tests if the logic value of this handle is unknown (x).
65
- def x?
66
- self.hexStrVal =~ /x/i
67
- end
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
- # Sets the logic value of this handle to unknown (x).
70
- def x!
71
- self.hexStrVal = 'x'
72
- end
60
+ # Sets the logic value of this handle to unknown (x).
61
+ def x!
62
+ self.hexStrVal = 'x'
63
+ end
73
64
 
74
- # Tests if the logic value of this handle is high impedance (z).
75
- def z?
76
- self.hexStrVal =~ /z/i
77
- end
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
- # Sets the logic value of this handle to high impedance (z).
80
- def z!
81
- self.hexStrVal = 'z'
82
- end
70
+ # Sets the logic value of this handle to high impedance (z).
71
+ def z!
72
+ self.hexStrVal = 'z'
73
+ end
83
74
 
84
- # Tests if the logic value of this handle is currently at a positive edge.
85
- def posedge?
86
- old = @lastVal
87
- new = @lastVal = self.intVal
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
- old == 0 && new == 1
90
- end
80
+ old == 0 && new == 1
81
+ end
91
82
 
92
- # Tests if the logic value of this handle is currently at a negative edge.
93
- def negedge?
94
- old = @lastVal
95
- new = @lastVal = self.intVal
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
- old == 1 && new == 0
98
- end
88
+ old == 1 && new == 0
89
+ end
99
90
 
100
- # Reads the value using the given format (integer constant) and returns a +S_vpi_value+ object.
101
- def get_value_wrapper aFormat
102
- val = S_vpi_value.new
103
- val.format = aFormat
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
- vpi_get_value self, val
106
- val
107
- end
97
+ vpi_get_value self, val
98
+ val
99
+ end
108
100
 
109
- # Reads the value using the given format (name or integer constant) and returns it. If a format is not given, then the Verilog simulator will attempt to determine the correct format.
110
- def get_value aFormat = VpiObjTypeVal
111
- val = get_value_wrapper(resolve_prop_type(aFormat))
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
- case val.format
114
- when VpiBinStrVal, VpiOctStrVal, VpiDecStrVal, VpiHexStrVal, VpiStringVal
115
- val.value.str
107
+ case val.format
108
+ when VpiBinStrVal, VpiOctStrVal, VpiDecStrVal, VpiHexStrVal, VpiStringVal
109
+ val.value.str
116
110
 
117
- when VpiScalarVal
118
- val.value.scalar
111
+ when VpiScalarVal
112
+ val.value.scalar
119
113
 
120
- when VpiIntVal
121
- get_value_wrapper(VpiHexStrVal).value.str.to_i(16)
114
+ when VpiIntVal
115
+ get_value_wrapper(VpiHexStrVal).value.str.to_i(16)
122
116
 
123
- when VpiRealVal
124
- val.value.real
117
+ when VpiRealVal
118
+ val.value.real
125
119
 
126
- when VpiTimeVal
127
- val.value.time
120
+ when VpiTimeVal
121
+ val.value.time
128
122
 
129
- when VpiVectorVal
130
- val.value.vector
123
+ when VpiVectorVal
124
+ val.value.vector
131
125
 
132
- when VpiStrengthVal
133
- val.value.strength
126
+ when VpiStrengthVal
127
+ val.value.strength
134
128
 
135
- else
136
- raise "unknown S_vpi_value.format: #{val.format}"
129
+ else
130
+ raise "unknown S_vpi_value.format: #{val.format}"
131
+ end
137
132
  end
138
- end
139
133
 
140
- # Writes the given value using the given format (name or integer constant), time, and delay, and then returns the given value. If a format is not given, then the Verilog simulator will attempt to determine the correct format.
141
- def put_value aValue, aFormat = nil, aTime = nil, aDelay = VpiNoDelay
142
- aFormat =
143
- if aFormat
144
- resolve_prop_type(aFormat)
145
- else
146
- get_value_wrapper(VpiObjTypeVal).format
147
- end
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
- newVal = S_vpi_value.new
150
- newVal.format = aFormat
146
+ newVal = S_vpi_value.new
147
+ newVal.format = aFormat
151
148
 
152
- case aFormat
153
- when VpiBinStrVal, VpiOctStrVal, VpiDecStrVal, VpiHexStrVal, VpiStringVal
154
- newVal.value.str = aValue.to_s
149
+ case aFormat
150
+ when VpiBinStrVal, VpiOctStrVal, VpiDecStrVal, VpiHexStrVal, VpiStringVal
151
+ newVal.value.str = aValue.to_s
155
152
 
156
- when VpiScalarVal
157
- newVal.value.scalar = aValue
153
+ when VpiScalarVal
154
+ newVal.value.scalar = aValue
158
155
 
159
- when VpiIntVal
160
- newVal.format = VpiHexStrVal
161
- newVal.value.str = aValue.to_i.to_s(16)
156
+ when VpiIntVal
157
+ newVal.format = VpiHexStrVal
158
+ newVal.value.str = aValue.to_i.to_s(16)
162
159
 
163
- when VpiRealVal
164
- newVal.value.real = aValue.to_f
160
+ when VpiRealVal
161
+ newVal.value.real = aValue.to_f
165
162
 
166
- when VpiTimeVal
167
- newVal.value.time = aValue
163
+ when VpiTimeVal
164
+ newVal.value.time = aValue
168
165
 
169
- when VpiVectorVal
170
- newVal.value.vector = aValue
166
+ when VpiVectorVal
167
+ newVal.value.vector = aValue
171
168
 
172
- when VpiStrengthVal
173
- newVal.value.strength = aValue
169
+ when VpiStrengthVal
170
+ newVal.value.strength = aValue
174
171
 
175
- else
176
- raise "unknown S_vpi_value.format: #{newVal.format}"
177
- end
172
+ else
173
+ raise "unknown S_vpi_value.format: #{newVal.format}"
174
+ end
178
175
 
179
- vpi_put_value self, newVal, aTime, aDelay
176
+ vpi_put_value self, newVal, aTime, aDelay
180
177
 
181
- # ensure that value was written correctly
182
- readenVal = get_value(aFormat)
178
+ # ensure that value was written correctly
179
+ readenVal = get_value(aFormat)
183
180
 
184
- writtenCorrectly =
185
- case aFormat
186
- when VpiBinStrVal, VpiOctStrVal, VpiDecStrVal, VpiHexStrVal
187
- if aValue =~ /[xz]/i # TODO: verify 'z' behavior
188
- readenVal =~ /[xz]/i
189
- else
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
- when VpiStringVal
194
- readenVal == aValue.to_s
193
+ when VpiIntVal
194
+ # allow for register overflow when limit reached
195
+ readenVal == (aValue.to_i % (2 ** self.vpiSize))
195
196
 
196
- when VpiIntVal
197
- # allow for register overflow when limit reached
198
- readenVal == (aValue.to_i % (2 ** self.vpiSize))
197
+ when VpiRealVal
198
+ readenVal == aValue.to_f
199
199
 
200
- when VpiRealVal
201
- readenVal == aValue.to_f
200
+ else
201
+ true
202
+ end
202
203
 
203
- else
204
- true
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
- unless writtenCorrectly
208
- raise "value written (#{aValue.inspect}) does not match value read (#{readenVal.inspect}) from handle #{self}"
209
- end
210
-
211
- aValue
212
- end
208
+ aValue
209
+ end
213
210
 
214
- # Returns an array of child handles of the given types (name or integer constant).
215
- def [] *aTypes
216
- handles = []
211
+ # Returns an array of child handles of the given types (name or integer
212
+ # constant).
213
+ def [] *aTypes
214
+ handles = []
217
215
 
218
- aTypes.each do |t|
219
- t = resolve_prop_type(t)
216
+ aTypes.each do |t|
217
+ t = resolve_prop_type(t)
220
218
 
221
- if itr = vpi_iterate(t, self)
222
- while h = vpi_scan(itr)
223
- handles << h
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
- aPropNames.map! do |name|
236
- "#{name}=#{self.send(name.to_sym)}"
226
+ handles
237
227
  end
238
228
 
239
- "#<Vpi::Handle #{vpiType_s} #{aPropNames.join(', ')}>"
240
- end
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
- alias to_s inspect
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
- ## properties
241
+ alias to_s inspect
246
242
 
247
- @@propCache = Hash.new {|h, k| h[k] = Property.resolve(k)}
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
- # Provides access to this handle's
250
- # 1. child handles
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
- child
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
- else
265
- prop = @@propCache[aMeth]
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
- else
271
- case prop.accessor
272
- when :d # delay values
273
- raise NotImplementedError, 'processing of delay values is not yet implemented.'
274
- # TODO: vpi_put_delays
275
- # TODO: vpi_get_delays
276
-
277
- when :l # logic values
278
- if prop.assignment
279
- value = aArgs.shift
280
- put_value(value, prop.type, *aArgs)
281
- else
282
- get_value(prop.type)
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
- when :i # integer values
286
- vpi_get(prop.type, self) unless prop.assignment
280
+ child
287
281
 
288
- when :b # boolean values
289
- unless prop.assignment
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
- when :s # string values
295
- vpi_get_str(prop.type, self) unless prop.assignment
285
+ if prop.operation
286
+ self.send(prop.operation, prop.type, *aArgs, &aBlockArg)
296
287
 
297
- when :h # handle values
298
- vpi_handle(prop.type, self) unless prop.assignment
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
- else
301
- raise NoMethodError, "unable to access VPI property #{prop.name.inspect} through method #{aMeth.inspect} with arguments #{aArgs.inspect} for handle #{self}"
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
- Property = Struct.new :type, :name, :operation, :accessor, :assignment
325
+ Property = Struct.new :type, :name, :operation, :accessor, :assignment
308
326
 
309
- # Resolves the given shorthand name into a description of its VPI property.
310
- def Property.resolve aName # :nodoc:
311
- # parse the given property name
312
- tokens = aName.to_s.split(/_/)
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
- tokens.last.sub!(/[\?!=]$/, '')
334
+ tokens.last.sub!(/[\?!=]$/, '')
316
335
 
317
- addendum = $&
318
- isAssign = $& == '='
319
- isQuery = $& == '?'
336
+ addendum = $&
337
+ isAssign = $& == '='
338
+ isQuery = $& == '?'
320
339
 
321
340
 
322
- tokens.last =~ /^[a-z]$/ && tokens.pop
323
- accessor = $&
341
+ tokens.last =~ /^[a-z]$/ && tokens.pop
342
+ accessor = $&
324
343
 
325
- name = tokens.pop
344
+ name = tokens.pop
326
345
 
327
- operation =
328
- unless tokens.empty?
329
- tokens.join('_') << (addendum || '')
330
- end
346
+ operation =
347
+ unless tokens.empty?
348
+ tokens.join('_') << (addendum || '')
349
+ end
331
350
 
332
- # determine the VPI integer type for the property
333
- name = name[0, 1].upcase << name[1..-1]
334
- name.insert 0, 'Vpi' unless name =~ /^[Vv]pi/
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
- begin
337
- type = Vpi.const_get(name)
338
- rescue NameError
339
- raise ArgumentError, "#{name.inspect} is not a valid VPI property"
340
- end
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
- accessor =
343
- if accessor
344
- accessor.to_sym
361
+ accessor =
362
+ if accessor
363
+ accessor.to_sym
345
364
 
346
- else # infer accessor from VPI property name
347
- if isQuery
348
- :b
365
+ else # infer accessor from VPI property name
366
+ if isQuery
367
+ :b
349
368
 
350
- else
351
- case name
352
- when /Time$/
353
- :d
369
+ else
370
+ case name
371
+ when /Time$/
372
+ :d
354
373
 
355
- when /Val$/
356
- :l
374
+ when /Val$/
375
+ :l
357
376
 
358
- when /Type$/, /Direction$/, /Index$/, /Size$/, /Strength\d?$/, /Polarity$/, /Edge$/, /Offset$/, /Mode$/, /LineNo$/
359
- :i
377
+ when /Type$/, /Direction$/, /Index$/, /Size$/, /Strength\d?$/, /Polarity$/, /Edge$/, /Offset$/, /Mode$/, /LineNo$/
378
+ :i
360
379
 
361
- when /Is[A-Z]/, /ed$/
362
- :b
380
+ when /Is[A-Z]/, /ed$/
381
+ :b
363
382
 
364
- when /Name$/, /File$/, /Decompile$/
365
- :s
383
+ when /Name$/, /File$/, /Decompile$/
384
+ :s
366
385
 
367
- when /Parent$/, /Inst$/, /Range$/, /Driver$/, /Net$/, /Load$/, /Conn$/, /Bit$/, /Word$/, /[LR]hs$/, /(In|Out)$/, /Term$/, /Argument$/, /Condition$/, /Use$/, /Operand$/, /Stmt$/, /Expr$/, /Scope$/, /Memory$/, /Delay$/
368
- :h
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
- Property.new type, name, operation, accessor, isAssign
374
- end
392
+ Property.new type, name, operation, accessor, isAssign
393
+ end
375
394
 
376
- private
395
+ private
377
396
 
378
- # resolve type names into type constants
379
- def resolve_prop_type aNameOrType
380
- if aNameOrType.is_a? Integer
381
- aNameOrType
382
- else
383
- @@propCache[aNameOrType.to_sym].type
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
- ## callbacks
408
+ # callbacks
390
409
 
391
- Callback = Struct.new :handler, :token #:nodoc:
392
- @@callbacks = {}
410
+ Callback = Struct.new :handler, :token #:nodoc:
411
+ @@callbacks = {}
393
412
 
394
- alias vpi_register_cb_old vpi_register_cb
413
+ alias vpi_register_cb_old vpi_register_cb
395
414
 
396
- # This is a Ruby version of the vpi_register_cb C function. It is identical to the C function, except for the following differences:
397
- # * This method accepts a block (callback handler) which is executed whenever the callback occurs.
398
- # * This method overwrites the +cb_rtn+ and +user_data+ fields of the given +S_cb_data+ object.
399
- def vpi_register_cb aData, &aHandler # :yields: Vpi::S_cb_data
400
- raise ArgumentError, "block must be given" unless block_given?
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
- key = aHandler.object_id.to_s
427
+ key = aHandler.object_id.to_s
403
428
 
404
- # register the callback with Verilog
405
- aData.user_data = key
406
- aData.cb_rtn = Vlog_relay_ruby
407
- token = vpi_register_cb_old(aData)
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
- @@callbacks[key] = Callback.new(aHandler, token)
410
- token
411
- end
434
+ @@callbacks[key] = Callback.new(aHandler, token)
435
+ token
436
+ end
412
437
 
413
- alias vpi_remove_cb_old vpi_remove_cb
438
+ alias vpi_remove_cb_old vpi_remove_cb
414
439
 
415
- def vpi_remove_cb aData # :nodoc:
416
- key = aData.user_data
440
+ def vpi_remove_cb aData # :nodoc:
441
+ key = aData.user_data
417
442
 
418
- if c = @@callbacks[key]
419
- vpi_remove_cb_old c.token
420
- @@callbacks.delete key
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
- # Proxy for relay_verilog which supports callbacks.
425
- # This method should NOT be invoked from callback handlers (see vpi_register_cb) and threads -- otherwise the situation will be like seven remote controls changing the channel on a single television set!
426
- def relay_verilog_proxy # :nodoc:
427
- loop do
428
- relay_verilog
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
- if reason = relay_ruby_reason # might be nil
431
- dst = reason.user_data
457
+ if reason = relay_ruby_reason # might be nil
458
+ dst = reason.user_data
432
459
 
433
- if c = @@callbacks[dst]
434
- c.handler.call reason
435
- else
436
- break # main thread is receiver
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
- # Simulates the design under test according to RubyVpi.init_bench.
446
- def simulate
447
- # this is a dummy method!
448
- end
470
+ # simulation control
449
471
 
450
- # Advances the simulation by the given number of steps.
451
- def advance_time aNumSteps = 1
452
- # schedule wake-up callback from verilog
453
- time = S_vpi_time.new
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
- vpi_free_object(vpi_register_cb_old(alarm))
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
- ## utility
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
- # Returns the current simulation time as an integer.
479
- def simulation_time
480
- t = S_vpi_time.new
481
- t.type = VpiSimTime
510
+ vpi_get_time nil, t
511
+ t.to_i
512
+ end
482
513
 
483
- vpi_get_time nil, t
484
- t.to_i
485
- end
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
- class S_vpi_time
489
- # Returns the high and low portions of this time as a single 64-bit integer.
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
- # Sets the high and low portions of this time from the given 64-bit integer.
495
- def integer= aValue
496
- self.low = aValue & INTEGER_MASK
497
- self.high = (aValue >> INTEGER_BITS) & INTEGER_MASK
498
- end
532
+ class S_vpi_value
533
+ def to_i
534
+ value.integer
535
+ end
499
536
 
500
- alias to_i integer
501
- alias to_f real
502
- end
537
+ def to_f
538
+ value.real
539
+ end
503
540
 
504
- class S_vpi_value
505
- def to_i
506
- value.integer
541
+ def to_s
542
+ value.str
543
+ end
507
544
  end
508
545
 
509
- def to_f
510
- value.real
511
- end
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
- def to_s
514
- value.str
515
- end
516
- end
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