ruby-vpi 16.0.1 → 17.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (247) hide show
  1. data/LICENSE +19 -19
  2. data/README +1 -1
  3. data/Rakefile +35 -32
  4. data/bin/convert.rb +28 -0
  5. data/bin/generate/design.rb +16 -0
  6. data/bin/generate/proto.rb +13 -0
  7. data/bin/generate/runner.rake +33 -0
  8. data/bin/generate/spec.rb +45 -0
  9. data/bin/generate.rb +177 -0
  10. data/bin/ruby-vpi +56 -0
  11. data/doc/Rakefile +20 -4
  12. data/doc/common.css +92 -33
  13. data/doc/common.inc +13 -0
  14. data/doc/common.tpl +42 -28
  15. data/doc/history.doc +11 -11
  16. data/doc/history.html +769 -248
  17. data/doc/history.inc +909 -0
  18. data/doc/history.rb +9 -0
  19. data/doc/history.yaml +69 -0
  20. data/doc/intro.inc +170 -178
  21. data/doc/lib/doc_format.rb +57 -144
  22. data/doc/lib/doc_proxy.rb +504 -88
  23. data/doc/lib/erb_content.rb +8 -8
  24. data/doc/lib/erb_proxy.rb +17 -17
  25. data/doc/manual.doc +626 -777
  26. data/doc/manual.html +1541 -1031
  27. data/doc/memo.doc +38 -36
  28. data/doc/memo.html +64 -28
  29. data/doc/readme.doc +4 -31
  30. data/doc/readme.html +221 -163
  31. data/doc/rss.erb +1 -1
  32. data/doc/rss.xml +73 -1761
  33. data/ext/Rakefile +6 -5
  34. data/ext/main.c +17 -15
  35. data/ext/relay.c +4 -7
  36. data/ext/relay.h +2 -2
  37. data/ext/swig_vpi.h +2 -2
  38. data/ext/swig_vpi.i +1 -2
  39. data/ext/swig_wrap.cin +12 -16
  40. data/ext/vlog.c +5 -5
  41. data/ext/vlog.h +2 -2
  42. data/lib/ruby-vpi/erb.rb +3 -3
  43. data/lib/ruby-vpi/float.rb +2 -2
  44. data/lib/ruby-vpi/rcov.rb +5 -7
  45. data/lib/ruby-vpi/runner.rb +43 -41
  46. data/lib/ruby-vpi/runner_boot_loader.rb +117 -0
  47. data/lib/ruby-vpi/runner_proxy.rb +6 -8
  48. data/lib/ruby-vpi/util.rb +10 -0
  49. data/lib/ruby-vpi/verilog_parser.rb +28 -56
  50. data/lib/ruby-vpi/vpi.rb +168 -123
  51. data/lib/ruby-vpi.rb +22 -143
  52. data/ref/c/annotated.html +1 -1
  53. data/ref/c/common_8h.html +1 -1
  54. data/ref/c/files.html +1 -1
  55. data/ref/c/functions.html +1 -1
  56. data/ref/c/functions_vars.html +1 -1
  57. data/ref/c/globals.html +1 -1
  58. data/ref/c/globals_0x63.html +1 -1
  59. data/ref/c/globals_0x65.html +1 -1
  60. data/ref/c/globals_0x66.html +1 -1
  61. data/ref/c/globals_0x6d.html +1 -1
  62. data/ref/c/globals_0x70.html +1 -1
  63. data/ref/c/globals_0x72.html +1 -1
  64. data/ref/c/globals_0x73.html +1 -1
  65. data/ref/c/globals_0x74.html +1 -1
  66. data/ref/c/globals_0x76.html +1 -1
  67. data/ref/c/globals_0x78.html +1 -1
  68. data/ref/c/globals_defs.html +1 -1
  69. data/ref/c/globals_defs_0x65.html +1 -1
  70. data/ref/c/globals_defs_0x70.html +1 -1
  71. data/ref/c/globals_defs_0x76.html +1 -1
  72. data/ref/c/globals_defs_0x78.html +1 -1
  73. data/ref/c/globals_enum.html +1 -1
  74. data/ref/c/globals_eval.html +1 -1
  75. data/ref/c/globals_func.html +1 -1
  76. data/ref/c/globals_type.html +1 -1
  77. data/ref/c/globals_vars.html +1 -1
  78. data/ref/c/index.html +1 -1
  79. data/ref/c/main_8c.html +1 -1
  80. data/ref/c/main_8h.html +1 -1
  81. data/ref/c/relay_8c.html +1 -1
  82. data/ref/c/relay_8h.html +1 -1
  83. data/ref/c/structt__cb__data.html +1 -1
  84. data/ref/c/structt__vpi__delay.html +1 -1
  85. data/ref/c/structt__vpi__error__info.html +1 -1
  86. data/ref/c/structt__vpi__strengthval.html +1 -1
  87. data/ref/c/structt__vpi__systf__data.html +1 -1
  88. data/ref/c/structt__vpi__time.html +1 -1
  89. data/ref/c/structt__vpi__value.html +1 -1
  90. data/ref/c/structt__vpi__vecval.html +1 -1
  91. data/ref/c/structt__vpi__vlog__info.html +1 -1
  92. data/ref/c/verilog_8h.html +1 -1
  93. data/ref/c/vlog_8c.html +1 -1
  94. data/ref/c/vlog_8h.html +1 -1
  95. data/ref/c/vpi__user_8h.html +1 -1
  96. data/ref/ruby/classes/ERB.html +5 -5
  97. data/ref/ruby/classes/ERB.src/{M000024.html → M000026.html} +0 -0
  98. data/ref/ruby/classes/FileUtils.html +11 -11
  99. data/ref/ruby/classes/FileUtils.src/{M000025.html → M000027.html} +0 -0
  100. data/ref/ruby/classes/FileUtils.src/{M000026.html → M000028.html} +0 -0
  101. data/ref/ruby/classes/Float.html +6 -6
  102. data/ref/ruby/classes/Float.src/{M000020.html → M000021.html} +0 -0
  103. data/ref/ruby/classes/Integer.html +65 -65
  104. data/ref/ruby/classes/Integer.src/M000009.html +12 -5
  105. data/ref/ruby/classes/Integer.src/M000010.html +5 -5
  106. data/ref/ruby/classes/Integer.src/M000011.html +5 -5
  107. data/ref/ruby/classes/Integer.src/M000012.html +5 -5
  108. data/ref/ruby/classes/Integer.src/M000013.html +5 -5
  109. data/ref/ruby/classes/Integer.src/M000014.html +18 -0
  110. data/ref/ruby/classes/Integer.src/M000017.html +12 -18
  111. data/ref/ruby/classes/Integer.src/M000018.html +18 -12
  112. data/ref/ruby/classes/Integer.src/M000019.html +12 -17
  113. data/ref/ruby/classes/Integer.src/M000020.html +30 -0
  114. data/ref/ruby/classes/RDoc.html +5 -5
  115. data/ref/ruby/classes/RDoc.src/{M000053.html → M000058.html} +0 -0
  116. data/ref/ruby/classes/{RubyVpi/Config.html → RubyVPI.html} +20 -6
  117. data/ref/ruby/classes/String.html +34 -15
  118. data/ref/ruby/classes/String.src/M000022.html +5 -28
  119. data/ref/ruby/classes/String.src/M000023.html +5 -5
  120. data/ref/ruby/classes/String.src/{M000021.html → M000024.html} +0 -0
  121. data/ref/ruby/classes/String.src/M000025.html +41 -0
  122. data/ref/ruby/classes/VerilogParser/Module/Port.html +16 -36
  123. data/ref/ruby/classes/VerilogParser/Module/Port.src/M000006.html +10 -5
  124. data/ref/ruby/classes/VerilogParser/Module/Port.src/{M000004.html → M000007.html} +4 -4
  125. data/ref/ruby/classes/VerilogParser/Module/Port.src/{M000005.html → M000008.html} +4 -4
  126. data/ref/ruby/classes/VerilogParser/Module.html +28 -9
  127. data/ref/ruby/classes/VerilogParser/Module.src/M000005.html +29 -0
  128. data/ref/ruby/classes/VerilogParser.html +5 -39
  129. data/ref/ruby/classes/VerilogParser.src/M000004.html +26 -0
  130. data/ref/ruby/classes/Vpi/Handle.html +179 -77
  131. data/ref/ruby/classes/Vpi/Handle.src/M000035.html +18 -0
  132. data/ref/ruby/classes/Vpi/Handle.src/M000036.html +5 -5
  133. data/ref/ruby/classes/Vpi/Handle.src/M000037.html +5 -5
  134. data/ref/ruby/classes/Vpi/Handle.src/M000038.html +5 -5
  135. data/ref/ruby/classes/Vpi/Handle.src/M000039.html +5 -5
  136. data/ref/ruby/classes/Vpi/Handle.src/M000040.html +5 -8
  137. data/ref/ruby/classes/Vpi/Handle.src/M000041.html +5 -8
  138. data/ref/ruby/classes/Vpi/Handle.src/M000042.html +5 -9
  139. data/ref/ruby/classes/Vpi/Handle.src/M000043.html +8 -31
  140. data/ref/ruby/classes/Vpi/Handle.src/M000044.html +8 -74
  141. data/ref/ruby/classes/Vpi/Handle.src/M000045.html +9 -17
  142. data/ref/ruby/classes/Vpi/Handle.src/M000046.html +31 -11
  143. data/ref/ruby/classes/Vpi/Handle.src/M000047.html +86 -0
  144. data/ref/ruby/classes/Vpi/Handle.src/M000048.html +17 -18
  145. data/ref/ruby/classes/Vpi/Handle.src/M000050.html +18 -0
  146. data/ref/ruby/classes/Vpi/Handle.src/M000051.html +24 -0
  147. data/ref/ruby/classes/Vpi/Handle.src/M000053.html +31 -0
  148. data/ref/ruby/classes/Vpi/Handle.src/M000054.html +89 -0
  149. data/ref/ruby/classes/Vpi/S_vpi_time.html +16 -16
  150. data/ref/ruby/classes/Vpi/S_vpi_time.src/{M000050.html → M000055.html} +4 -4
  151. data/ref/ruby/classes/Vpi/S_vpi_time.src/{M000051.html → M000056.html} +5 -5
  152. data/ref/ruby/classes/Vpi/S_vpi_value.html +15 -15
  153. data/ref/ruby/classes/Vpi/S_vpi_value.src/{M000035.html → M000032.html} +5 -5
  154. data/ref/ruby/classes/Vpi/S_vpi_value.src/M000033.html +5 -5
  155. data/ref/ruby/classes/Vpi/S_vpi_value.src/M000034.html +5 -5
  156. data/ref/ruby/classes/Vpi.html +6 -42
  157. data/ref/ruby/classes/Vpi.src/M000029.html +15 -5
  158. data/ref/ruby/classes/Vpi.src/M000030.html +24 -24
  159. data/ref/ruby/classes/Vpi.src/M000031.html +6 -8
  160. data/ref/ruby/created.rid +1 -1
  161. data/ref/ruby/files/bin/{header_to_ruby_rb.html → convert_rb.html} +5 -5
  162. data/ref/ruby/files/bin/{generate_test_rb.html → generate_rb.html} +8 -21
  163. data/ref/ruby/files/lib/ruby-vpi/erb_rb.html +1 -1
  164. data/ref/ruby/files/lib/ruby-vpi/float_rb.html +1 -1
  165. data/ref/ruby/files/lib/ruby-vpi/integer_rb.html +1 -1
  166. data/ref/ruby/files/lib/ruby-vpi/rake_rb.html +1 -1
  167. data/ref/ruby/files/lib/ruby-vpi/rcov_rb.html +1 -1
  168. data/ref/ruby/files/lib/ruby-vpi/rdoc_rb.html +1 -1
  169. data/ref/ruby/files/lib/ruby-vpi/runner_boot_loader_rb.html +197 -0
  170. data/ref/ruby/files/lib/ruby-vpi/runner_boot_loader_rb.src/M000001.html +17 -0
  171. data/ref/ruby/files/lib/ruby-vpi/runner_boot_loader_rb.src/M000002.html +18 -0
  172. data/ref/ruby/files/lib/ruby-vpi/runner_proxy_rb.html +1 -1
  173. data/ref/ruby/files/lib/ruby-vpi/runner_rb.html +6 -19
  174. data/ref/ruby/files/lib/ruby-vpi/util_rb.html +101 -0
  175. data/ref/ruby/files/lib/ruby-vpi/verilog_parser_rb.html +8 -1
  176. data/ref/ruby/files/lib/ruby-vpi/vpi_rb.html +1 -1
  177. data/ref/ruby/files/lib/ruby-vpi_rb.html +2 -14
  178. data/ref/ruby/fr_class_index.html +1 -3
  179. data/ref/ruby/fr_file_index.html +4 -2
  180. data/ref/ruby/fr_method_index.html +56 -51
  181. data/ref/ruby/index.html +1 -1
  182. data/samp/counter/RSpec/Rakefile +1 -0
  183. data/samp/counter/RSpec/counter_design.rb +15 -0
  184. data/samp/counter/RSpec/counter_proto.rb +10 -0
  185. data/samp/counter/RSpec/counter_runner.rake +44 -0
  186. data/samp/counter/RSpec/counter_spec.rb +39 -0
  187. data/samp/counter/Rakefile +1 -1
  188. data/samp/counter/counter.v +7 -7
  189. data/samp/counter/xUnit/Rakefile +1 -0
  190. data/samp/counter/xUnit/counter_bench.rb +95 -0
  191. data/samp/counter/{counter_xunit_bench.v → xUnit/counter_bench.v} +0 -0
  192. data/samp/counter/xUnit/counter_design.rb +15 -0
  193. data/samp/counter/xUnit/counter_proto.rb +10 -0
  194. data/samp/counter/xUnit/counter_runner.rake +44 -0
  195. data/samp/counter/{counter_xunit_spec.rb → xUnit/counter_spec.rb} +9 -9
  196. data/samp/pipelined_alu/Rakefile +1 -1
  197. data/samp/pipelined_alu/TestHw5UnitModel.rb +4 -5
  198. data/samp/pipelined_alu/hw5_unit.v +55 -85
  199. data/samp/pipelined_alu/hw5_unit_design.rb +51 -0
  200. data/samp/pipelined_alu/hw5_unit_proto.rb +4 -0
  201. data/samp/pipelined_alu/hw5_unit_runner.rake +43 -0
  202. data/samp/pipelined_alu/hw5_unit_spec.rb +64 -0
  203. data/samp/register_file/LICENSE +20 -0
  204. data/samp/register_file/README +4 -0
  205. data/samp/register_file/Rakefile +1 -0
  206. data/samp/register_file/register_file.v +18 -0
  207. data/samp/register_file/register_file_design.rb +11 -0
  208. data/samp/register_file/register_file_proto.rb +11 -0
  209. data/samp/register_file/register_file_runner.rake +43 -0
  210. data/samp/register_file/register_file_spec.rb +58 -0
  211. metadata +78 -66
  212. data/bin/generate_test.rb +0 -200
  213. data/bin/generate_test_tpl/bench.rb +0 -89
  214. data/bin/generate_test_tpl/bench.v +0 -26
  215. data/bin/generate_test_tpl/design.rb +0 -11
  216. data/bin/generate_test_tpl/proto.rb +0 -16
  217. data/bin/generate_test_tpl/runner.rake +0 -42
  218. data/bin/generate_test_tpl/spec.rb +0 -37
  219. data/bin/header_to_ruby.rb +0 -27
  220. data/ref/ruby/classes/Integer.src/M000008.html +0 -25
  221. data/ref/ruby/classes/Integer.src/M000016.html +0 -25
  222. data/ref/ruby/classes/RubyVpi.html +0 -199
  223. data/ref/ruby/classes/RubyVpi.src/M000027.html +0 -121
  224. data/ref/ruby/classes/VerilogParser/Module/Parameter.html +0 -160
  225. data/ref/ruby/classes/VerilogParser/Module/Parameter.src/M000007.html +0 -19
  226. data/ref/ruby/classes/VerilogParser/Module/Port.src/M000003.html +0 -21
  227. data/ref/ruby/classes/VerilogParser/Module.src/M000002.html +0 -34
  228. data/ref/ruby/classes/VerilogParser.src/M000001.html +0 -34
  229. data/ref/ruby/classes/Vpi/Handle.src/M000049.html +0 -69
  230. data/ref/ruby/classes/Vpi.src/M000028.html +0 -28
  231. data/ref/ruby/classes/Vpi.src/M000032.html +0 -22
  232. data/samp/counter/counter_rspec_bench.rb +0 -86
  233. data/samp/counter/counter_rspec_bench.v +0 -9
  234. data/samp/counter/counter_rspec_design.rb +0 -8
  235. data/samp/counter/counter_rspec_proto.rb +0 -13
  236. data/samp/counter/counter_rspec_runner.rake +0 -52
  237. data/samp/counter/counter_rspec_spec.rb +0 -39
  238. data/samp/counter/counter_xunit_bench.rb +0 -86
  239. data/samp/counter/counter_xunit_design.rb +0 -8
  240. data/samp/counter/counter_xunit_proto.rb +0 -13
  241. data/samp/counter/counter_xunit_runner.rake +0 -52
  242. data/samp/pipelined_alu/hw5_unit_test_bench.rb +0 -86
  243. data/samp/pipelined_alu/hw5_unit_test_bench.v +0 -14
  244. data/samp/pipelined_alu/hw5_unit_test_design.rb +0 -61
  245. data/samp/pipelined_alu/hw5_unit_test_proto.rb +0 -7
  246. data/samp/pipelined_alu/hw5_unit_test_runner.rake +0 -52
  247. data/samp/pipelined_alu/hw5_unit_test_spec.rb +0 -68
@@ -3,8 +3,10 @@
3
3
  # Copyright 2006-2007 Suraj N. Kurapati
4
4
  # See the file named LICENSE for details.
5
5
 
6
+ require 'ruby-vpi/util'
7
+
6
8
  class VerilogParser
7
- attr_reader :modules, :constants, :includes
9
+ attr_reader :modules
8
10
 
9
11
  # Parses the given Verilog source code.
10
12
  def initialize aInput
@@ -14,82 +16,57 @@ class VerilogParser
14
16
  input.gsub! %r{//.*$}, ''
15
17
  input.gsub! %r{/\*.*?\*/}m, ''
16
18
 
17
- @modules = input.scan(%r{module.*?;}m).map! do |decl|
18
- Module.new decl
19
- end
20
-
21
- @constants = input.scan(%r{(`define\s+(\w+)\s+(.+))}).map! do |matches|
22
- Constant.new(*matches)
23
- end
24
-
25
- @includes = input.scan(%r{(`include\s*(\S+))}).map! do |matches|
26
- Include.new(*matches)
19
+ @modules = input.scan(%r{(module.*?;)(.*?)endmodule}m).map do |matches|
20
+ Module.new(*matches)
27
21
  end
28
22
  end
29
23
 
30
- Constant = Struct.new(:decl, :name, :value)
31
- Include = Struct.new(:decl, :target)
32
-
33
24
  class Module
34
- attr_reader :decl, :name, :parameters, :ports
25
+ attr_reader :decl, :body, :name,
26
+ :ports, :input_ports, :output_ports,
27
+ :clock_port, :reset_port
35
28
 
36
- def initialize aDecl
29
+ def initialize aDecl, aBody
37
30
  @decl = aDecl.strip
31
+ @body = aBody
38
32
 
39
- @decl =~ %r{module\s+(\w+)\s*(?:\#\((.*?)\))?\s*\((.*?)\)\s*;}m
40
- @name, paramDecls, portDecls = $1, $2, $3
33
+ @decl =~ %r{module\s+(\w+)\s*(?:\#\(.*?\))?\s*(?:\((.*?)\))?\s*;}m
34
+ @name, portDecls = $1, $2.to_s
41
35
 
42
- @parameters =
43
- if paramDecls =~ %r{\bparameter\b(.*)$}
44
- $1.split(',').map! do |decl|
45
- Parameter.new decl
46
- end
47
- else
48
- []
49
- end
36
+ @ports = portDecls.split(',').map {|decl| Port.new decl, self}
37
+ @input_ports = @ports.select {|p| p.input?}
38
+ @output_ports = @ports.select {|p| p.output?}
50
39
 
51
- @ports = portDecls.split(',').map! do |decl|
52
- Port.new decl
53
- end
54
- end
55
-
56
- class Parameter
57
- attr_reader :decl, :name, :value
58
-
59
- def initialize aDecl
60
- @decl = aDecl.strip
61
- @name, @value = @decl.split('=').map! {|s| s.strip}
62
- end
40
+ @clock_port = @ports.find {|p| p.name =~ /clock|clo?c?k/i}
41
+ @reset_port = @ports.find {|p| p.name =~ /reset|re?se?t/i}
63
42
  end
64
43
 
65
44
  class Port
66
- attr_reader :decl, :name, :size
45
+ attr_reader :decl, :name
67
46
 
68
- def initialize aDecl
69
- @decl = aDecl.strip
47
+ def initialize aDecl, aModule
48
+ @decl = aDecl
49
+ @name = aDecl.scan(/\S+/).last
70
50
 
71
- @decl =~ /(\[.*?\])?\s*(\w+)$/
72
- @size, @name = $1, $2
51
+ parser = /\b(input|output|inout)\b[^;]*\b#{@name}\b/m
52
+ aDecl =~ parser || aModule.body =~ parser
53
+ @type = $1
73
54
  end
74
55
 
75
56
  def input?
76
- @decl =~ /\binput\b/
57
+ @type != 'output'
77
58
  end
78
59
 
79
60
  def output?
80
- @decl =~ /\boutput\b/
81
- end
82
-
83
- def reg?
84
- @decl =~ /\breg\b/
61
+ @type != 'input'
85
62
  end
86
63
  end
87
64
  end
88
65
  end
89
66
 
90
67
  class String
91
- # Converts this string containing Verilog code into syntactically correct Ruby
92
- # code.
68
+ # Converts this string containing Verilog
69
+ # code into syntactically correct Ruby code.
93
70
  def verilog_to_ruby
94
71
  content = self.dup
95
72
 
@@ -116,9 +93,4 @@ class String
116
93
 
117
94
  content
118
95
  end
119
-
120
- # Converts this string into a valid Ruby constant name.
121
- def to_ruby_const_name
122
- self[0, 1].upcase << self[1..-1]
123
- end
124
96
  end
data/lib/ruby-vpi/vpi.rb CHANGED
@@ -1,28 +1,26 @@
1
- # A utility layer which transforms the VPI interface into one that is more
2
- # suitable for Ruby.
1
+ # A utility layer which transforms the VPI interface
2
+ # into one that is more suitable for Ruby.
3
3
  #--
4
4
  # Copyright 2006-2007 Suraj N. Kurapati
5
5
  # See the file named LICENSE for details.
6
6
 
7
7
  module Vpi
8
8
  # Number of bits in PLI_INT32.
9
- INTEGER_BITS = 32
9
+ INTEGER_BITS = 32
10
10
 
11
11
  # Lowest upper bound of PLI_INT32.
12
12
  INTEGER_LIMIT = 2 ** INTEGER_BITS
13
13
 
14
14
  # Bit-mask capable of capturing PLI_INT32.
15
- INTEGER_MASK = INTEGER_LIMIT - 1
16
-
15
+ INTEGER_MASK = INTEGER_LIMIT - 1
17
16
 
18
17
  # handles
19
18
 
20
19
  Handle = SWIG::TYPE_p_unsigned_int
21
20
 
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
21
+ # A handle is an object inside a Verilog simulation (see
22
+ # *vpiHandle* in IEEE Std. 1364-2005). VPI types and
23
+ # properties listed in ext/vpi_user.h can be specified by
26
24
  # their names (strings or symbols) or integer constants.
27
25
  #
28
26
  # = Example names
@@ -41,17 +39,6 @@ module Vpi
41
39
  class Handle
42
40
  include Vpi
43
41
 
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
54
-
55
42
  # Tests if the logic value of this handle is unknown (x).
56
43
  def x?
57
44
  self.hexStrVal =~ /x/i
@@ -72,6 +59,26 @@ module Vpi
72
59
  self.hexStrVal = 'z'
73
60
  end
74
61
 
62
+ # Tests if the logic value of this handle is at "logic high" level.
63
+ def high?
64
+ self.intVal != 0
65
+ end
66
+
67
+ # Sets the logic value of this handle to "logic high" level.
68
+ def high!
69
+ self.intVal = 1
70
+ end
71
+
72
+ # Tests if the logic value of this handle is at "logic low" level.
73
+ def low?
74
+ self.hexStrVal =~ /^0+$/
75
+ end
76
+
77
+ # Sets the logic value of this handle to "logic low" level.
78
+ def low!
79
+ self.intVal = 0
80
+ end
81
+
75
82
  # Tests if the logic value of this handle is currently at a positive edge.
76
83
  def posedge?
77
84
  old = @lastVal
@@ -88,18 +95,20 @@ module Vpi
88
95
  old == 1 && new == 0
89
96
  end
90
97
 
91
- # Reads the value using the given format (integer constant) and returns a
92
- # +S_vpi_value+ object.
98
+ # Reads the value using the given
99
+ # format (integer constant) and
100
+ # returns a +S_vpi_value+ object.
93
101
  def get_value_wrapper aFormat
94
- val = S_vpi_value.new
102
+ val = S_vpi_value.new
95
103
  val.format = aFormat
96
104
 
97
105
  vpi_get_value self, val
98
106
  val
99
107
  end
100
108
 
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
109
+ # Reads the value using the given format (name or
110
+ # integer constant) and returns it. If a format
111
+ # is not given, then the Verilog simulator will
103
112
  # attempt to determine the correct format.
104
113
  def get_value aFormat = VpiObjTypeVal
105
114
  val = get_value_wrapper(resolve_prop_type(aFormat))
@@ -112,7 +121,7 @@ module Vpi
112
121
  val.value.scalar
113
122
 
114
123
  when VpiIntVal
115
- get_value_wrapper(VpiHexStrVal).value.str.to_i(16)
124
+ get_value_wrapper(VpiBinStrVal).value.str.gsub(/[^01]/, '0').to_i(2)
116
125
 
117
126
  when VpiRealVal
118
127
  val.value.real
@@ -131,10 +140,10 @@ module Vpi
131
140
  end
132
141
  end
133
142
 
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.
143
+ # Writes the given value using the given format (name or
144
+ # integer constant), time, and delay, and then returns the
145
+ # given value. If a format is not given, then the Verilog
146
+ # simulator will attempt to determine the correct format.
138
147
  def put_value aValue, aFormat = nil, aTime = nil, aDelay = VpiNoDelay
139
148
  aFormat =
140
149
  if aFormat
@@ -143,28 +152,27 @@ module Vpi
143
152
  get_value_wrapper(VpiObjTypeVal).format
144
153
  end
145
154
 
146
- newVal = S_vpi_value.new
147
- newVal.format = aFormat
155
+ newVal = S_vpi_value.new(:format => aFormat)
148
156
 
149
157
  case aFormat
150
158
  when VpiBinStrVal, VpiOctStrVal, VpiDecStrVal, VpiHexStrVal, VpiStringVal
151
- newVal.value.str = aValue.to_s
159
+ newVal.value.str = aValue.to_s
152
160
 
153
161
  when VpiScalarVal
154
- newVal.value.scalar = aValue
162
+ newVal.value.scalar = aValue
155
163
 
156
164
  when VpiIntVal
157
- newVal.format = VpiHexStrVal
158
- newVal.value.str = aValue.to_i.to_s(16)
165
+ newVal.format = VpiHexStrVal
166
+ newVal.value.str = aValue.to_i.to_s(16)
159
167
 
160
168
  when VpiRealVal
161
- newVal.value.real = aValue.to_f
169
+ newVal.value.real = aValue.to_f
162
170
 
163
171
  when VpiTimeVal
164
- newVal.value.time = aValue
172
+ newVal.value.time = aValue
165
173
 
166
174
  when VpiVectorVal
167
- newVal.value.vector = aValue
175
+ newVal.value.vector = aValue
168
176
 
169
177
  when VpiStrengthVal
170
178
  newVal.value.strength = aValue
@@ -173,7 +181,7 @@ module Vpi
173
181
  raise "unknown S_vpi_value.format: #{newVal.format}"
174
182
  end
175
183
 
176
- vpi_put_value self, newVal, aTime, aDelay
184
+ vpi_put_value(self, newVal, aTime, aDelay)
177
185
 
178
186
  # ensure that value was written correctly
179
187
  readenVal = get_value(aFormat)
@@ -192,7 +200,7 @@ module Vpi
192
200
 
193
201
  when VpiIntVal
194
202
  # allow for register overflow when limit reached
195
- readenVal == (aValue.to_i % (2 ** self.vpiSize))
203
+ readenVal == (aValue.to_i % (2 ** vpi_get(VpiSize, self)))
196
204
 
197
205
  when VpiRealVal
198
206
  readenVal == aValue.to_f
@@ -202,19 +210,19 @@ module Vpi
202
210
  end
203
211
 
204
212
  unless writtenCorrectly
205
- raise "value written (#{aValue.inspect}) does not match value read (#{readenVal.inspect}) from handle #{self}"
213
+ raise "value written (#{aValue.inspect}) does not match value read (#{readenVal.inspect}) on handle #{self}"
206
214
  end
207
215
 
208
216
  aValue
209
217
  end
210
218
 
211
- # Returns an array of child handles of the given types (name or integer
212
- # constant).
219
+ # Returns an array of child handles of the
220
+ # given types (name or integer constant).
213
221
  def [] *aTypes
214
222
  handles = []
215
223
 
216
- aTypes.each do |t|
217
- t = resolve_prop_type(t)
224
+ aTypes.each do |arg|
225
+ t = resolve_prop_type(arg)
218
226
 
219
227
  if itr = vpi_iterate(t, self)
220
228
  while h = vpi_scan(itr)
@@ -226,8 +234,31 @@ module Vpi
226
234
  handles
227
235
  end
228
236
 
229
- # Inspects the given VPI property names, in addition to those common to
230
- # all handles.
237
+
238
+ # inherit Enumerable methods, such as #each, #map, #select, etc.
239
+ Enumerable.instance_methods.push('each').each do |meth|
240
+ # using a string because define_method
241
+ # does not accept a block until Ruby 1.9
242
+ class_eval %{
243
+ def #{meth}(*args, &block)
244
+ if ary = self[*args]
245
+ ary.#{meth}(&block)
246
+ end
247
+ end
248
+ }, __FILE__, __LINE__
249
+ end
250
+
251
+ # bypass Enumerable's #to_a method, which relies on #each
252
+ alias to_a []
253
+
254
+ # Sort by absolute VPI path.
255
+ def <=> other
256
+ self.fullName <=> other.fullName
257
+ end
258
+
259
+
260
+ # Inspects the given VPI property names, in
261
+ # addition to those common to all handles.
231
262
  def inspect *aPropNames
232
263
  aPropNames.unshift :fullName, :size, :file, :lineNo
233
264
 
@@ -240,8 +271,8 @@ module Vpi
240
271
 
241
272
  alias to_s inspect
242
273
 
243
- # Registers a callback that is invoked whenever the value of this object
244
- # changes.
274
+ # Registers a callback that is invoked
275
+ # whenever the value of this object changes.
245
276
  def cbValueChange aOptions = {}, &aHandler
246
277
  raise ArgumentError unless block_given?
247
278
 
@@ -262,20 +293,21 @@ module Vpi
262
293
 
263
294
  @@propCache = Hash.new {|h, k| h[k] = Property.resolve(k)}
264
295
 
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.
296
+ # Provides access to this handle's (1) child handles
297
+ # and (2) VPI properties through method calls. In the
298
+ # case that a child handle has the same name as a VPI
299
+ # property, the child handle will be accessed instead
300
+ # of the VPI property. However, you can still access
301
+ # the VPI property via #get_value and #put_value.
270
302
  def method_missing aMeth, *aArgs, &aBlockArg
271
303
  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
277
- end
304
+ # cache the child for future accesses, in order
305
+ # to cut down number of calls to method_missing
306
+ (class << self; self; end).class_eval do
307
+ define_method aMeth do
308
+ child
278
309
  end
310
+ end
279
311
 
280
312
  child
281
313
 
@@ -283,8 +315,7 @@ module Vpi
283
315
  prop = @@propCache[aMeth]
284
316
 
285
317
  if prop.operation
286
- self.send(prop.operation, prop.type, *aArgs, &aBlockArg)
287
-
318
+ self.__send__(prop.operation, prop.type, *aArgs, &aBlockArg)
288
319
  else
289
320
  case prop.accessor
290
321
  when :d # delay values
@@ -301,19 +332,40 @@ module Vpi
301
332
  end
302
333
 
303
334
  when :i # integer values
304
- vpi_get(prop.type, self) unless prop.assignment
335
+ unless prop.assignment
336
+ vpi_get(prop.type, self)
337
+ else
338
+ raise NotImplementedError
339
+ end
305
340
 
306
341
  when :b # boolean values
307
342
  unless prop.assignment
308
343
  value = vpi_get(prop, self)
309
344
  value && (value != 0) # zero is false in C
345
+ else
346
+ raise NotImplementedError
310
347
  end
311
348
 
312
349
  when :s # string values
313
- vpi_get_str(prop.type, self) unless prop.assignment
350
+ unless prop.assignment
351
+ vpi_get_str(prop.type, self)
352
+ else
353
+ raise NotImplementedError
354
+ end
314
355
 
315
356
  when :h # handle values
316
- vpi_handle(prop.type, self) unless prop.assignment
357
+ unless prop.assignment
358
+ vpi_handle(prop.type, self)
359
+ else
360
+ raise NotImplementedError
361
+ end
362
+
363
+ when :a # array of child handles
364
+ unless prop.assignment
365
+ self[prop.type]
366
+ else
367
+ raise NotImplementedError
368
+ end
317
369
 
318
370
  else
319
371
  raise NoMethodError, "unable to access VPI property #{prop.name.inspect} through method #{aMeth.inspect} with arguments #{aArgs.inspect} for handle #{self}"
@@ -322,10 +374,12 @@ module Vpi
322
374
  end
323
375
  end
324
376
 
325
- Property = Struct.new :type, :name, :operation, :accessor, :assignment
377
+ private
378
+
379
+ Property = Struct.new(:type, :name, :operation, :accessor, :assignment)
326
380
 
327
- # Resolves the given shorthand name into a description of its VPI
328
- # property.
381
+ # Resolves the given shorthand name into
382
+ # a description of its VPI property.
329
383
  def Property.resolve aName # :nodoc:
330
384
  # parse the given property name
331
385
  tokens = aName.to_s.split(/_/)
@@ -335,7 +389,7 @@ module Vpi
335
389
 
336
390
  addendum = $&
337
391
  isAssign = $& == '='
338
- isQuery = $& == '?'
392
+ isQuery = $& == '?'
339
393
 
340
394
 
341
395
  tokens.last =~ /^[a-z]$/ && tokens.pop
@@ -389,11 +443,9 @@ module Vpi
389
443
  end
390
444
  end
391
445
 
392
- Property.new type, name, operation, accessor, isAssign
446
+ Property.new(type, name, operation, accessor, isAssign)
393
447
  end
394
448
 
395
- private
396
-
397
449
  # resolve type names into type constants
398
450
  def resolve_prop_type aNameOrType
399
451
  if aNameOrType.is_a? Integer
@@ -412,14 +464,14 @@ module Vpi
412
464
 
413
465
  alias vpi_register_cb_old vpi_register_cb
414
466
 
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:
467
+ # This is a Ruby version of the vpi_register_cb C function. It is
468
+ # identical to the C function, except for the following differences:
417
469
  #
418
- # * This method accepts a block (callback handler) which is executed
419
- # whenever the callback occurs.
470
+ # * This method accepts a block (callback handler)
471
+ # which is executed whenever the callback occurs.
420
472
  #
421
- # * This method overwrites the +cb_rtn+ and +user_data+ fields of the given
422
- # +S_cb_data+ object.
473
+ # * This method overwrites the +cb_rtn+ and +user_data+
474
+ # fields of the given +S_cb_data+ object.
423
475
  #
424
476
  def vpi_register_cb aData, &aHandler # :yields: Vpi::S_cb_data
425
477
  raise ArgumentError, "block must be given" unless block_given?
@@ -428,10 +480,10 @@ module Vpi
428
480
 
429
481
  # register the callback with Verilog
430
482
  aData.user_data = key
431
- aData.cb_rtn = Vlog_relay_ruby
432
- token = vpi_register_cb_old(aData)
483
+ aData.cb_rtn = Vlog_relay_ruby
484
+ token = vpi_register_cb_old(aData)
433
485
 
434
- @@callbacks[key] = Callback.new(aHandler, token)
486
+ @@callbacks[key] = Callback.new(aHandler, token)
435
487
  token
436
488
  end
437
489
 
@@ -446,10 +498,10 @@ module Vpi
446
498
  end
447
499
  end
448
500
 
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!
501
+ # Proxy for relay_verilog which supports callbacks. This method
502
+ # should NOT be invoked from callback handlers (see vpi_register_cb)
503
+ # and threads -- otherwise the situation will be like seven remote
504
+ # controls changing the channel on a single television set!
453
505
  def relay_verilog_proxy # :nodoc:
454
506
  loop do
455
507
  relay_verilog
@@ -469,28 +521,23 @@ module Vpi
469
521
 
470
522
  # simulation control
471
523
 
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
476
-
477
524
  # Advances the simulation by the given number of steps.
478
525
  def advance_time aNumSteps = 1
479
526
  # 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
527
+ time = S_vpi_time.new
528
+ time.integer = aNumSteps
529
+ time.type = VpiSimTime
530
+
531
+ value = S_vpi_value.new
532
+ value.format = VpiSuppressVal
533
+
534
+ alarm = S_cb_data.new
535
+ alarm.reason = CbAfterDelay
536
+ alarm.cb_rtn = Vlog_relay_ruby
537
+ alarm.obj = nil
538
+ alarm.time = time
539
+ alarm.value = value
540
+ alarm.index = 0
494
541
  alarm.user_data = nil
495
542
 
496
543
  vpi_free_object(vpi_register_cb_old(alarm))
@@ -504,24 +551,22 @@ module Vpi
504
551
 
505
552
  # Returns the current simulation time as an integer.
506
553
  def simulation_time
507
- t = S_vpi_time.new
508
- t.type = VpiSimTime
509
-
554
+ t = S_vpi_time.new :type => VpiSimTime
510
555
  vpi_get_time nil, t
511
556
  t.to_i
512
557
  end
513
558
 
514
559
  class S_vpi_time
515
- # Returns the high and low portions of this time as a single 64-bit
516
- # integer.
560
+ # Returns the high and low portions of
561
+ # this time as a single 64-bit integer.
517
562
  def integer
518
563
  (self.high << INTEGER_BITS) | self.low
519
564
  end
520
565
 
521
- # Sets the high and low portions of this time from the given 64-bit
522
- # integer.
566
+ # Sets the high and low portions of this
567
+ # time from the given 64-bit integer.
523
568
  def integer= aValue
524
- self.low = aValue & INTEGER_MASK
569
+ self.low = aValue & INTEGER_MASK
525
570
  self.high = (aValue >> INTEGER_BITS) & INTEGER_MASK
526
571
  end
527
572
 
@@ -543,19 +588,19 @@ module Vpi
543
588
  end
544
589
  end
545
590
 
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
591
+ # make VPI structs more accessible by allowing their
592
+ # members to be initialized through the constructor
593
+ constants.grep(/^S_/).each do |s|
594
+ const_get(s).class_eval do
595
+ alias old_initialize initialize
551
596
 
552
- def initialize aMembers = {}
553
- old_initialize
597
+ def initialize aMembers = {} #:nodoc:
598
+ old_initialize
554
599
 
555
- aMembers.each_pair do |k, v|
556
- __send__ "#{k}=", v
557
- end
600
+ aMembers.each_pair do |k, v|
601
+ __send__ "#{k}=", v
558
602
  end
559
603
  end
560
604
  end
605
+ end
561
606
  end