ruby-vpi 18.0.2 → 19.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 (232) hide show
  1. data/Rakefile +15 -19
  2. data/bin/generate/proto.rb +15 -10
  3. data/bin/ruby-vpi +2 -0
  4. data/doc/README +3 -5
  5. data/doc/Rakefile +3 -3
  6. data/doc/common.css +24 -136
  7. data/doc/common.tpl +48 -37
  8. data/doc/figures/figures.dia +19 -19
  9. data/doc/figures/ruby_relay.png +0 -0
  10. data/doc/history.html +252 -67
  11. data/doc/history.inc +98 -1
  12. data/doc/history.yaml +105 -0
  13. data/doc/intro.inc +43 -32
  14. data/doc/lib/doc_format.rb +19 -13
  15. data/doc/lib/doc_proxy.rb +7 -7
  16. data/doc/manual.doc +156 -117
  17. data/doc/manual.html +601 -560
  18. data/doc/memo.html +29 -25
  19. data/doc/print.css +63 -4
  20. data/doc/readme.doc +4 -6
  21. data/doc/readme.html +129 -111
  22. data/doc/rss.xml +168 -7
  23. data/doc/screen.css +146 -0
  24. data/doc/spacing.css +57 -0
  25. data/{samp → examples}/counter/RSpec/Rakefile +0 -0
  26. data/{samp → examples}/counter/RSpec/counter_design.rb +0 -0
  27. data/examples/counter/RSpec/counter_proto.rb +9 -0
  28. data/{samp → examples}/counter/RSpec/counter_runner.rake +0 -0
  29. data/{samp → examples}/counter/RSpec/counter_spec.rb +0 -0
  30. data/{samp → examples}/counter/Rakefile +0 -0
  31. data/{samp → examples}/counter/counter.v +0 -0
  32. data/{samp → examples}/counter/xUnit/Rakefile +0 -0
  33. data/{samp → examples}/counter/xUnit/counter_bench.rb +0 -0
  34. data/{samp → examples}/counter/xUnit/counter_bench.v +0 -0
  35. data/{samp → examples}/counter/xUnit/counter_design.rb +0 -0
  36. data/examples/counter/xUnit/counter_proto.rb +9 -0
  37. data/{samp → examples}/counter/xUnit/counter_runner.rake +0 -0
  38. data/{samp → examples}/counter/xUnit/counter_spec.rb +0 -0
  39. data/{samp → examples}/pipelined_alu/Hw5UnitModel.rb +0 -0
  40. data/{samp → examples}/pipelined_alu/README +0 -0
  41. data/{samp → examples}/pipelined_alu/Rakefile +0 -0
  42. data/{samp → examples}/pipelined_alu/TestHw5UnitModel.rb +0 -0
  43. data/{samp → examples}/pipelined_alu/hw5_unit.v +0 -0
  44. data/{samp → examples}/pipelined_alu/hw5_unit_design.rb +0 -7
  45. data/examples/pipelined_alu/hw5_unit_proto.rb +2 -0
  46. data/{samp → examples}/pipelined_alu/hw5_unit_runner.rake +0 -0
  47. data/{samp → examples}/pipelined_alu/hw5_unit_spec.rb +0 -0
  48. data/{samp → examples}/pipelined_alu/int_gen.rb +0 -0
  49. data/{samp → examples}/register_file/LICENSE +0 -0
  50. data/{samp → examples}/register_file/README +0 -0
  51. data/{samp → examples}/register_file/Rakefile +0 -0
  52. data/{samp → examples}/register_file/register_file.v +0 -0
  53. data/{samp → examples}/register_file/register_file_design.rb +0 -0
  54. data/examples/register_file/register_file_proto.rb +11 -0
  55. data/{samp → examples}/register_file/register_file_runner.rake +0 -0
  56. data/{samp → examples}/register_file/register_file_spec.rb +0 -0
  57. data/ext/main.c +5 -5
  58. data/ext/swig_vpi.i +6 -2
  59. data/lib/ruby-vpi/core/callback.rb +142 -0
  60. data/lib/ruby-vpi/core/edge.rb +128 -0
  61. data/lib/ruby-vpi/core/handle.rb +421 -0
  62. data/lib/ruby-vpi/core/scheduler.rb +244 -0
  63. data/lib/ruby-vpi/core/struct.rb +123 -0
  64. data/lib/ruby-vpi/core.rb +41 -0
  65. data/lib/ruby-vpi/rcov.rb +25 -12
  66. data/lib/ruby-vpi/runner.rb +30 -26
  67. data/lib/ruby-vpi/runner_boot_loader.rb +67 -37
  68. data/lib/ruby-vpi.rb +2 -2
  69. data/ref/c/annotated.html +1 -1
  70. data/ref/c/common_8h.html +1 -1
  71. data/ref/c/files.html +1 -1
  72. data/ref/c/functions.html +1 -1
  73. data/ref/c/functions_vars.html +1 -1
  74. data/ref/c/globals.html +1 -1
  75. data/ref/c/globals_0x63.html +1 -1
  76. data/ref/c/globals_0x65.html +1 -1
  77. data/ref/c/globals_0x66.html +1 -1
  78. data/ref/c/globals_0x6d.html +1 -1
  79. data/ref/c/globals_0x70.html +1 -1
  80. data/ref/c/globals_0x72.html +1 -1
  81. data/ref/c/globals_0x73.html +1 -1
  82. data/ref/c/globals_0x74.html +1 -1
  83. data/ref/c/globals_0x76.html +1 -1
  84. data/ref/c/globals_0x78.html +1 -1
  85. data/ref/c/globals_defs.html +1 -1
  86. data/ref/c/globals_defs_0x65.html +1 -1
  87. data/ref/c/globals_defs_0x70.html +1 -1
  88. data/ref/c/globals_defs_0x76.html +1 -1
  89. data/ref/c/globals_defs_0x78.html +1 -1
  90. data/ref/c/globals_enum.html +1 -1
  91. data/ref/c/globals_eval.html +1 -1
  92. data/ref/c/globals_func.html +1 -1
  93. data/ref/c/globals_type.html +1 -1
  94. data/ref/c/globals_vars.html +1 -1
  95. data/ref/c/index.html +1 -1
  96. data/ref/c/main_8c.html +1 -1
  97. data/ref/c/main_8h.html +1 -1
  98. data/ref/c/relay_8c.html +1 -1
  99. data/ref/c/relay_8h.html +1 -1
  100. data/ref/c/structt__cb__data.html +1 -1
  101. data/ref/c/structt__vpi__delay.html +1 -1
  102. data/ref/c/structt__vpi__error__info.html +1 -1
  103. data/ref/c/structt__vpi__strengthval.html +1 -1
  104. data/ref/c/structt__vpi__systf__data.html +1 -1
  105. data/ref/c/structt__vpi__time.html +1 -1
  106. data/ref/c/structt__vpi__value.html +1 -1
  107. data/ref/c/structt__vpi__vecval.html +1 -1
  108. data/ref/c/structt__vpi__vlog__info.html +1 -1
  109. data/ref/c/verilog_8h.html +1 -1
  110. data/ref/c/vlog_8c.html +1 -1
  111. data/ref/c/vlog_8h.html +1 -1
  112. data/ref/c/vpi__user_8h.html +1 -1
  113. data/ref/ruby/classes/ERB.html +7 -5
  114. data/ref/ruby/classes/ERB.src/{M000026.html → M000024.html} +0 -0
  115. data/ref/ruby/classes/FileUtils.html +11 -11
  116. data/ref/ruby/classes/FileUtils.src/{M000027.html → M000025.html} +0 -0
  117. data/ref/ruby/classes/FileUtils.src/{M000028.html → M000026.html} +0 -0
  118. data/ref/ruby/classes/Float.html +8 -6
  119. data/ref/ruby/classes/Float.src/{M000021.html → M000019.html} +0 -0
  120. data/ref/ruby/classes/Integer.html +67 -65
  121. data/ref/ruby/classes/Integer.src/M000007.html +25 -0
  122. data/ref/ruby/classes/Integer.src/{M000014.html → M000008.html} +5 -5
  123. data/ref/ruby/classes/Integer.src/M000009.html +5 -12
  124. data/ref/ruby/classes/Integer.src/M000010.html +5 -5
  125. data/ref/ruby/classes/Integer.src/M000011.html +5 -5
  126. data/ref/ruby/classes/Integer.src/M000012.html +5 -5
  127. data/ref/ruby/classes/Integer.src/M000015.html +25 -0
  128. data/ref/ruby/classes/Integer.src/M000016.html +31 -0
  129. data/ref/ruby/classes/Integer.src/M000017.html +12 -12
  130. data/ref/ruby/classes/Integer.src/M000018.html +17 -18
  131. data/ref/ruby/classes/Object.html +126 -0
  132. data/ref/ruby/classes/RDoc.html +5 -5
  133. data/ref/ruby/classes/RDoc.src/{M000061.html → M000081.html} +0 -0
  134. data/ref/ruby/classes/RubyVPI.html +50 -9
  135. data/ref/ruby/classes/String.html +22 -20
  136. data/ref/ruby/classes/String.src/M000020.html +36 -0
  137. data/ref/ruby/classes/String.src/M000021.html +41 -0
  138. data/ref/ruby/classes/String.src/M000022.html +5 -23
  139. data/ref/ruby/classes/String.src/M000023.html +5 -28
  140. data/ref/ruby/classes/{Vpi → VPI}/Handle.html +442 -140
  141. data/ref/ruby/classes/{Vpi/Handle.src/M000042.html → VPI/Handle.src/M000037.html} +4 -4
  142. data/ref/ruby/classes/VPI/Handle.src/M000038.html +21 -0
  143. data/ref/ruby/classes/VPI/Handle.src/M000039.html +18 -0
  144. data/ref/ruby/classes/{Vpi/Handle.src/M000036.html → VPI/Handle.src/M000040.html} +5 -5
  145. data/ref/ruby/classes/VPI/Handle.src/M000045.html +18 -0
  146. data/ref/ruby/classes/{Vpi/Handle.src/M000038.html → VPI/Handle.src/M000046.html} +5 -5
  147. data/ref/ruby/classes/VPI/Handle.src/M000057.html +18 -0
  148. data/ref/ruby/classes/{Vpi/Handle.src/M000040.html → VPI/Handle.src/M000058.html} +5 -5
  149. data/ref/ruby/classes/VPI/Handle.src/M000061.html +18 -0
  150. data/ref/ruby/classes/VPI/Handle.src/M000062.html +18 -0
  151. data/ref/ruby/classes/{Vpi/Handle.src/M000054.html → VPI/Handle.src/M000065.html} +11 -11
  152. data/ref/ruby/classes/VPI/Handle.src/M000067.html +21 -0
  153. data/ref/ruby/classes/VPI/Handle.src/M000068.html +28 -0
  154. data/ref/ruby/classes/VPI/Handle.src/M000069.html +50 -0
  155. data/ref/ruby/classes/{Vpi/Handle.src/M000048.html → VPI/Handle.src/M000070.html} +6 -6
  156. data/ref/ruby/classes/{Vpi/Handle.src/M000049.html → VPI/Handle.src/M000071.html} +6 -6
  157. data/ref/ruby/classes/{Vpi/Handle.src/M000050.html → VPI/Handle.src/M000072.html} +5 -5
  158. data/ref/ruby/classes/{Vpi/Handle.src/M000051.html → VPI/Handle.src/M000073.html} +17 -17
  159. data/ref/ruby/classes/VPI/Handle.src/M000075.html +18 -0
  160. data/ref/ruby/classes/VPI/Handle.src/M000076.html +40 -0
  161. data/ref/ruby/classes/{Vpi/Handle.src/M000056.html → VPI/Handle.src/M000077.html} +18 -18
  162. data/ref/ruby/classes/{Vpi → VPI}/S_vpi_time.html +22 -20
  163. data/ref/ruby/classes/VPI/S_vpi_time.src/M000078.html +18 -0
  164. data/ref/ruby/classes/VPI/S_vpi_time.src/M000079.html +19 -0
  165. data/ref/ruby/classes/{Vpi → VPI}/S_vpi_value.html +37 -23
  166. data/ref/ruby/classes/VPI/S_vpi_value.src/M000034.html +35 -0
  167. data/ref/ruby/classes/VPI/S_vpi_value.src/M000035.html +42 -0
  168. data/ref/ruby/classes/VPI/S_vpi_value.src/M000036.html +42 -0
  169. data/ref/ruby/classes/{Vpi.html → VPI.html} +129 -34
  170. data/ref/ruby/classes/VPI.src/M000027.html +19 -0
  171. data/ref/ruby/classes/VPI.src/M000028.html +18 -0
  172. data/ref/ruby/classes/VPI.src/M000029.html +19 -0
  173. data/ref/ruby/classes/VPI.src/M000031.html +25 -0
  174. data/ref/ruby/classes/VPI.src/M000032.html +26 -0
  175. data/ref/ruby/classes/VerilogParser/Module/Port.html +17 -15
  176. data/ref/ruby/classes/VerilogParser/Module/Port.src/M000004.html +23 -0
  177. data/ref/ruby/classes/VerilogParser/Module/Port.src/{M000007.html → M000005.html} +0 -0
  178. data/ref/ruby/classes/VerilogParser/Module/Port.src/M000006.html +5 -10
  179. data/ref/ruby/classes/VerilogParser/Module.html +7 -5
  180. data/ref/ruby/classes/VerilogParser/Module.src/{M000005.html → M000003.html} +0 -0
  181. data/ref/ruby/classes/VerilogParser.html +7 -5
  182. data/ref/ruby/classes/VerilogParser.src/{M000004.html → M000002.html} +0 -0
  183. data/ref/ruby/created.rid +1 -1
  184. data/ref/ruby/files/bin/generate_rb.html +2 -2
  185. data/ref/ruby/files/lib/ruby-vpi/{vpi_rb.html → core/callback_rb.html} +7 -8
  186. data/ref/ruby/files/lib/ruby-vpi/core/edge_rb.html +114 -0
  187. data/ref/ruby/files/lib/ruby-vpi/core/handle_rb.html +107 -0
  188. data/ref/ruby/files/lib/ruby-vpi/core/scheduler_rb.html +114 -0
  189. data/ref/ruby/files/lib/ruby-vpi/core/struct_rb.html +108 -0
  190. data/ref/ruby/files/lib/ruby-vpi/core_rb.html +121 -0
  191. data/ref/ruby/files/lib/ruby-vpi/rcov_rb.html +1 -1
  192. data/ref/ruby/files/lib/ruby-vpi/runner_boot_loader_rb.html +5 -41
  193. data/ref/ruby/files/lib/ruby-vpi/runner_boot_loader_rb.src/M000001.html +3 -3
  194. data/ref/ruby/files/lib/ruby-vpi/runner_rb.html +1 -1
  195. data/ref/ruby/files/lib/ruby-vpi_rb.html +1 -1
  196. data/ref/ruby/fr_class_index.html +5 -4
  197. data/ref/ruby/fr_file_index.html +6 -1
  198. data/ref/ruby/fr_method_index.html +80 -60
  199. metadata +126 -103
  200. data/ext/swig_vpi.h +0 -924
  201. data/ext/swig_wrap.cin +0 -7083
  202. data/lib/ruby-vpi/vpi.rb +0 -651
  203. data/ref/ruby/classes/Integer.src/M000013.html +0 -18
  204. data/ref/ruby/classes/Integer.src/M000019.html +0 -25
  205. data/ref/ruby/classes/Integer.src/M000020.html +0 -30
  206. data/ref/ruby/classes/String.src/M000024.html +0 -18
  207. data/ref/ruby/classes/String.src/M000025.html +0 -18
  208. data/ref/ruby/classes/VerilogParser/Module/Port.src/M000008.html +0 -18
  209. data/ref/ruby/classes/Vpi/Handle.src/M000035.html +0 -18
  210. data/ref/ruby/classes/Vpi/Handle.src/M000037.html +0 -18
  211. data/ref/ruby/classes/Vpi/Handle.src/M000039.html +0 -18
  212. data/ref/ruby/classes/Vpi/Handle.src/M000041.html +0 -18
  213. data/ref/ruby/classes/Vpi/Handle.src/M000043.html +0 -21
  214. data/ref/ruby/classes/Vpi/Handle.src/M000044.html +0 -21
  215. data/ref/ruby/classes/Vpi/Handle.src/M000045.html +0 -22
  216. data/ref/ruby/classes/Vpi/Handle.src/M000046.html +0 -50
  217. data/ref/ruby/classes/Vpi/Handle.src/M000047.html +0 -91
  218. data/ref/ruby/classes/Vpi/Handle.src/M000053.html +0 -18
  219. data/ref/ruby/classes/Vpi/Handle.src/M000057.html +0 -40
  220. data/ref/ruby/classes/Vpi/S_vpi_time.src/M000058.html +0 -18
  221. data/ref/ruby/classes/Vpi/S_vpi_time.src/M000059.html +0 -19
  222. data/ref/ruby/classes/Vpi/S_vpi_value.src/M000032.html +0 -18
  223. data/ref/ruby/classes/Vpi/S_vpi_value.src/M000033.html +0 -18
  224. data/ref/ruby/classes/Vpi/S_vpi_value.src/M000034.html +0 -18
  225. data/ref/ruby/classes/Vpi.src/M000029.html +0 -28
  226. data/ref/ruby/classes/Vpi.src/M000030.html +0 -39
  227. data/ref/ruby/classes/Vpi.src/M000031.html +0 -20
  228. data/ref/ruby/files/lib/ruby-vpi/runner_boot_loader_rb.src/M000002.html +0 -18
  229. data/samp/counter/RSpec/counter_proto.rb +0 -10
  230. data/samp/counter/xUnit/counter_proto.rb +0 -10
  231. data/samp/pipelined_alu/hw5_unit_proto.rb +0 -4
  232. data/samp/register_file/register_file_proto.rb +0 -11
@@ -0,0 +1,244 @@
1
+ # Concurrent processes.
2
+ #--
3
+ # Copyright 2007 Suraj N. Kurapati
4
+ # See the file named LICENSE for details.
5
+
6
+ Thread.abort_on_exception = true
7
+
8
+ require 'singleton'
9
+
10
+ module RubyVPI
11
+ class SchedulerClass #:nodoc:
12
+ include Singleton
13
+
14
+
15
+ Task = Struct.new(:thread, :state)
16
+
17
+ class Task #:nodoc:
18
+ def run
19
+ self.state = :run
20
+ self.thread.wakeup
21
+ end
22
+
23
+ def stop
24
+ self.state = :wait
25
+ Thread.stop
26
+ end
27
+
28
+ def stop?
29
+ self.thread.stop? and self.state == :wait
30
+ end
31
+ end
32
+
33
+
34
+ def initialize
35
+ @thread2task = { Thread.main => Task.new(Thread.main, :run) }
36
+ @thread2task_sw = @thread2task.dup # software threads
37
+ @thread2task_hw = {} # hardware threads (Ruby prototype of DUT)
38
+ @thread2task_lock = Mutex.new
39
+
40
+
41
+ # base case: hardware runs first before any software does at startup
42
+ @time = 0
43
+
44
+ unless RubyVPI::USE_PROTOTYPE
45
+ Callback.relay_verilog(VPI::CbReadOnlySynch, 0)
46
+ end
47
+
48
+ @scheduler = Thread.new do
49
+ # pause because boot loader is not fully init yet
50
+ Thread.stop
51
+
52
+ loop do
53
+ # run software in current time step
54
+ run_tasks @thread2task_sw, true
55
+ Edge.refresh_cache
56
+
57
+ # go to time slot where writing is permitted before flushing writes
58
+ unless RubyVPI::USE_PROTOTYPE
59
+ Callback.relay_verilog(VPI::CbAfterDelay, 1)
60
+ end
61
+
62
+ flush_writes
63
+
64
+ # run hardware in next time step
65
+ @time += 1
66
+
67
+ if RubyVPI::USE_PROTOTYPE
68
+ run_tasks @thread2task_hw, false
69
+ flush_writes
70
+ else
71
+ Callback.relay_verilog(VPI::CbReadOnlySynch, 0)
72
+ end
73
+ end
74
+ end
75
+
76
+
77
+ @handle2write = Hash.new {|h,k| h[k] = []}
78
+ @handle2write_lock = Mutex.new
79
+ end
80
+
81
+ def current_time
82
+ @time
83
+ end
84
+
85
+ def start
86
+ @scheduler.wakeup
87
+ end
88
+
89
+ # Registers the calling thread with the scheduler.
90
+ def attach
91
+ key = Thread.current
92
+
93
+ hash =
94
+ if caller.grep(/_proto\.rb/).empty?
95
+ @thread2task_sw
96
+ else
97
+ @thread2task_hw
98
+ end
99
+
100
+ @thread2task_lock.synchronize do
101
+ task = Task.new(key, :run)
102
+ hash[key] = task
103
+ @thread2task[key] = task
104
+ end
105
+ end
106
+
107
+ # Unregisters the calling thread from the scheduler.
108
+ def detach
109
+ key = Thread.current
110
+
111
+ @thread2task_lock.synchronize do
112
+ @thread2task.delete key
113
+ @thread2task_hw.delete key
114
+ @thread2task_sw.delete key
115
+ end
116
+ end
117
+
118
+ # Waits for the scheduler to arrive in the next time step.
119
+ def await
120
+ key = Thread.current
121
+
122
+ task = @thread2task_lock.synchronize do
123
+ @thread2task[key]
124
+ end
125
+
126
+ task.stop
127
+ end
128
+
129
+ def ensure_caller_is_registered
130
+ unless @thread2task_lock.synchronize {@thread2task.key? Thread.current}
131
+ raise SecurityError, 'This method may only be invoked from within a process (see the VPI::process() method).'
132
+ end
133
+ end
134
+
135
+ Write = Struct.new :thread, :trace, :args
136
+
137
+ # Captures the given write operation so it
138
+ # can be flushed later, at the correct time.
139
+ def capture_write aHandle, *aArgs
140
+ @handle2write_lock.synchronize do
141
+ @handle2write[aHandle] << Write.new(Thread.current, caller, aArgs)
142
+ end
143
+ end
144
+
145
+ private
146
+
147
+ # Flushes all captured writes.
148
+ def flush_writes
149
+ @handle2write_lock.synchronize do
150
+ @handle2write.each_pair do |handle, writes|
151
+ if writes.map {|w| w.thread}.uniq.length > 1
152
+ culprits = writes.map {|w| "\n\n#{w.thread}" << w.trace.map {|x| "\n\t#{x}"}.join}.join
153
+ STDERR.puts "Race condition detected at time step #{current_time}: the logic value of handle #{handle} is being modified by more than one concurrent process: #{culprits}"
154
+ exit 1
155
+ end
156
+
157
+ writes.each do |w|
158
+ VPI::__scheduler__vpi_put_value(handle, *w.args)
159
+ end
160
+
161
+ writes.clear
162
+ end
163
+ end
164
+ end
165
+
166
+ def run_tasks aHash, aExitWhenEmpty
167
+ @thread2task_lock.synchronize do
168
+ tasks = aHash.values
169
+ tasks.each {|t| t.run}
170
+
171
+ if aExitWhenEmpty and tasks.empty?
172
+ Thread.exit
173
+ end
174
+ end
175
+
176
+ loop do
177
+ ready = @thread2task_lock.synchronize do
178
+ aHash.values.all? {|t| t.stop?}
179
+ end
180
+
181
+ if ready
182
+ break
183
+ else
184
+ Thread.pass
185
+ end
186
+ end
187
+ end
188
+ end
189
+
190
+ Scheduler = SchedulerClass.instance
191
+ end
192
+
193
+ module VPI
194
+ alias_method :__scheduler__vpi_put_value, :vpi_put_value
195
+ module_function :__scheduler__vpi_put_value
196
+
197
+ def vpi_put_value *args #:nodoc:
198
+ RubyVPI::Scheduler.capture_write(*args)
199
+ end
200
+
201
+
202
+ # Returns the current simulation time.
203
+ def current_time
204
+ RubyVPI::Scheduler.current_time
205
+ end
206
+
207
+ # Wait until the simulation advances by the given number of time steps.
208
+ def advance_time aNumTimeSteps = 1
209
+ RubyVPI::Scheduler.ensure_caller_is_registered
210
+ aNumTimeSteps.times { RubyVPI::Scheduler.await }
211
+ end
212
+
213
+ alias wait advance_time
214
+
215
+
216
+ # Creates a new concurrent process, which will execute the
217
+ # given block with the given arguments, and returns it.
218
+ def process *aBlockArgs
219
+ RubyVPI::Scheduler.ensure_caller_is_registered
220
+ raise ArgumentError, "block must be given" unless block_given?
221
+
222
+ Thread.new do
223
+ RubyVPI::Scheduler.attach
224
+ yield(*aBlockArgs)
225
+ RubyVPI::Scheduler.detach
226
+ end
227
+ end
228
+
229
+ # Wraps the given block inside an infinite loop and executes it
230
+ # inside a new concurrent process (see the VPI::process method).
231
+ def always *aBlockArgs, &aBlock
232
+ process do
233
+ loop do
234
+ startTime = VPI.current_time
235
+ aBlock.call(*aBlockArgs)
236
+ finishTime = VPI.current_time
237
+
238
+ VPI.advance_time unless finishTime > startTime
239
+ end
240
+ end
241
+ end
242
+
243
+ alias forever always
244
+ end
@@ -0,0 +1,123 @@
1
+ # VPI structures (S_vpi_* and S_cb_*) stuff
2
+ #--
3
+ # Copyright 2006 Suraj N. Kurapati
4
+ # See the file named LICENSE for details.
5
+
6
+ module VPI
7
+ class S_vpi_time
8
+ # Returns the high and low portions of
9
+ # this time as a single 64-bit integer.
10
+ def integer
11
+ (self.high << INTEGER_BITS) | self.low
12
+ end
13
+
14
+ # Sets the high and low portions of this
15
+ # time from the given 64-bit integer.
16
+ def integer= aValue
17
+ self.low = aValue & INTEGER_MASK
18
+ self.high = (aValue >> INTEGER_BITS) & INTEGER_MASK
19
+ end
20
+
21
+ alias to_i integer
22
+ alias to_f real
23
+ end
24
+
25
+ class S_vpi_value
26
+ # Attempts to detect the format of the given value.
27
+ # Returns +nil+ if detection is not possible.
28
+ def S_vpi_value.detect_format aValue
29
+ if aValue.respond_to? :to_int
30
+ VpiIntVal
31
+
32
+ elsif aValue.respond_to? :to_float
33
+ VpiRealVal
34
+
35
+ elsif aValue.respond_to? :to_str
36
+ VpiStringVal
37
+
38
+ elsif aValue.is_a? S_vpi_time
39
+ VpiTimeVal
40
+
41
+ elsif aValue.is_a? S_vpi_vecval
42
+ VpiVectorVal
43
+
44
+ elsif aValue.is_a? S_vpi_strengthval
45
+ VpiStrengthVal
46
+ end
47
+ end
48
+
49
+ # Writes the given value, which has the given format.
50
+ def write aValue, aFormat
51
+ case aFormat
52
+ when VpiBinStrVal, VpiOctStrVal, VpiDecStrVal, VpiHexStrVal, VpiStringVal
53
+ value.str = aValue.to_s
54
+
55
+ when VpiScalarVal
56
+ value.scalar = aValue.to_i
57
+
58
+ when VpiIntVal
59
+ value.integer = aValue.to_i
60
+
61
+ when VpiRealVal
62
+ value.real = aValue.to_f
63
+
64
+ when VpiTimeVal
65
+ value.time = aValue
66
+
67
+ when VpiVectorVal
68
+ value.vector = aValue
69
+
70
+ when VpiStrengthVal
71
+ value.strength = aValue
72
+
73
+ else
74
+ raise "unknown format: #{aFormat.inspect}"
75
+ end
76
+ end
77
+
78
+ # Returns the value in the given format.
79
+ def read aFormat = self.format
80
+ case aFormat
81
+ when VpiBinStrVal, VpiOctStrVal, VpiDecStrVal, VpiHexStrVal, VpiStringVal
82
+ value.str.to_s
83
+
84
+ when VpiScalarVal
85
+ value.scalar.to_i
86
+
87
+ when VpiIntVal
88
+ value.integer.to_i
89
+
90
+ when VpiRealVal
91
+ value.real.to_f
92
+
93
+ when VpiTimeVal
94
+ value.time
95
+
96
+ when VpiVectorVal
97
+ value.vector
98
+
99
+ when VpiStrengthVal
100
+ value.strength
101
+
102
+ else
103
+ raise "unknown format: #{aFormat.inspect}"
104
+ end
105
+ end
106
+ end
107
+
108
+ # make VPI structs more accessible by allowing their
109
+ # members to be initialized through the constructor
110
+ constants.grep(/^S_/).each do |s|
111
+ const_get(s).class_eval do
112
+ alias __struct__initialize initialize
113
+
114
+ def initialize aMembers = {} #:nodoc:
115
+ __struct__initialize
116
+
117
+ aMembers.each_pair do |k, v|
118
+ __send__("#{k}=", v)
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,41 @@
1
+ # A utility layer which transforms the VPI interface
2
+ # into one that is more suitable for Ruby.
3
+ #--
4
+ # Copyright 2006 Suraj N. Kurapati
5
+ # See the file named LICENSE for details.
6
+
7
+ module VPI
8
+ # restore compatibility with the C language version of VPI: in Ruby,
9
+ # constants are capitalized, whereas in C, they do not have to be.
10
+ constants.grep(/^(S_|Cb|Vpi)/).each do |name|
11
+ meth = name[0,1].downcase << name[1..-1]
12
+ value = const_get(name)
13
+
14
+ define_method meth do value end
15
+ module_function meth
16
+ end
17
+
18
+ # Number of bits in PLI_INT32.
19
+ INTEGER_BITS = 32
20
+
21
+ # Lowest upper bound of PLI_INT32.
22
+ INTEGER_LIMIT = 2 ** INTEGER_BITS
23
+
24
+ # Bit-mask capable of capturing PLI_INT32.
25
+ INTEGER_MASK = INTEGER_LIMIT - 1
26
+ end
27
+
28
+ module RubyVPI
29
+ SIMULATOR = ENV['RUBYVPI_SIMULATOR'].to_sym
30
+ USE_DEBUGGER = ENV['DEBUGGER'].to_i == 1
31
+ USE_COVERAGE = ENV['COVERAGE'].to_i == 1
32
+ USE_PROTOTYPE = ENV['PROTOTYPE'].to_i == 1
33
+ USE_PROFILER = ENV['PROFILER'].to_i == 1
34
+ end
35
+
36
+ require 'thread'
37
+ require 'ruby-vpi/core/struct'
38
+ require 'ruby-vpi/core/handle'
39
+ require 'ruby-vpi/core/edge'
40
+ require 'ruby-vpi/core/callback'
41
+ require 'ruby-vpi/core/scheduler'
data/lib/ruby-vpi/rcov.rb CHANGED
@@ -23,23 +23,36 @@ require 'rcov'
23
23
  require 'rcov/report'
24
24
 
25
25
 
26
+ module RubyVPI::Coverage #:nodoc:
27
+ end
28
+
26
29
  module RubyVPI
27
- COVERAGE_ANALYSIS = Rcov::CodeCoverageAnalyzer.new
28
- COVERAGE_ANALYSIS.install_hook
30
+ module Coverage
31
+ @@analyzer = Rcov::CodeCoverageAnalyzer.new
32
+
33
+ def Coverage.start
34
+ @@analyzer.install_hook
35
+ end
36
+
37
+ def Coverage.stop
38
+ @@analyzer.remove_hook
39
+ end
29
40
 
30
- COVERAGE_ANALYSIS_HANDLERS = []
31
41
 
32
- at_exit do
33
- COVERAGE_ANALYSIS.remove_hook
42
+ @@handlers = []
34
43
 
35
- COVERAGE_ANALYSIS_HANDLERS.each do |a|
36
- a.call COVERAGE_ANALYSIS
44
+ # Invokes the given block after code coverage analysis has completed.
45
+ def Coverage.attach &aBlock # :yield: Rcov::CodeCoverageAnalyzer
46
+ raise ArgumentError unless block_given?
47
+ @@handlers << aBlock if aBlock
37
48
  end
38
- end
39
49
 
40
- # Invokes the given block, which yields COVERAGE_ANALYSIS,
41
- # after code coverage analysis has completed.
42
- def RubyVPI.with_coverage_analysis &aBlock # :nodoc:
43
- COVERAGE_ANALYSIS_HANDLERS << aBlock if aBlock
50
+ at_exit do
51
+ Coverage.stop
52
+
53
+ @@handlers.each do |h|
54
+ h.call @@analyzer
55
+ end
56
+ end
44
57
  end
45
58
  end
@@ -26,7 +26,7 @@ require 'ruby-vpi/util'
26
26
  end
27
27
 
28
28
  # auto-detect and set default parameters
29
- runnerPath = caller.grep(/runner.rake/).first.rstrip_from(':')
29
+ runnerPath = caller.grep(/runner\.rake/).first.rstrip_from(':')
30
30
  @target = File.basename(runnerPath).rstrip_from('_')
31
31
 
32
32
  task :setup
@@ -84,6 +84,15 @@ def expand_incdir_options aSimId # :nodoc:
84
84
  @incdirs.map {|i| prefix + i}
85
85
  end
86
86
 
87
+ # Creates a new task for running the given simulator.
88
+ def sim_task aSimId #:nodoc:
89
+ desc "Simulate with #{RubyVPI::SIMULATORS[aSimId].name}."
90
+ task aSimId => :setup do
91
+ ENV['RUBYVPI_SIMULATOR'] = aSimId.to_s
92
+ yield aSimId
93
+ end
94
+ end
95
+
87
96
 
88
97
  desc "Show a list of available tasks."
89
98
  task :default do
@@ -92,24 +101,22 @@ task :default do
92
101
  end
93
102
 
94
103
 
95
- desc "Simulate with #{RubyVPI::SIMULATORS[:cver].name}."
96
- task :cver => :setup do
104
+ sim_task :cver do |id|
97
105
  sh 'cver',
98
- "+loadvpi=#{object_file_path(:cver)}:#{LOADER_FUNC}",
99
- SIMULATOR_ARGUMENTS[:cver],
100
- expand_incdir_options(:cver),
106
+ "+loadvpi=#{object_file_path(id)}:#{LOADER_FUNC}",
107
+ SIMULATOR_ARGUMENTS[id],
108
+ expand_incdir_options(id),
101
109
  @sources
102
110
  end
103
111
 
104
112
  CLOBBER.include 'verilog.log'
105
113
 
106
114
 
107
- desc "Simulate with #{RubyVPI::SIMULATORS[:ivl].name}."
108
- task :ivl => :setup do
109
- cp object_file_path(:ivl), 'ruby-vpi.vpi'
115
+ sim_task :ivl do |id|
116
+ cp object_file_path(id), 'ruby-vpi.vpi'
110
117
  sh %w[iverilog -mruby-vpi],
111
- SIMULATOR_ARGUMENTS[:ivl],
112
- expand_incdir_options(:ivl),
118
+ SIMULATOR_ARGUMENTS[id],
119
+ expand_incdir_options(id),
113
120
  @sources
114
121
  sh 'vvp -M. a.out'
115
122
  end
@@ -117,28 +124,26 @@ end
117
124
  CLEAN.include 'ruby-vpi.vpi', 'a.out'
118
125
 
119
126
 
120
- desc "Simulate with #{RubyVPI::SIMULATORS[:vcs].name}."
121
- task :vcs => :setup do
127
+ sim_task :vcs do |id|
122
128
  sh %w[vcs -R +v2k +vpi +cli],
123
129
  '-P', File.join(File.dirname(__FILE__), 'pli.tab'),
124
- '-load', "#{object_file_path(:vcs)}:#{LOADER_FUNC}",
130
+ '-load', "#{object_file_path(id)}:#{LOADER_FUNC}",
125
131
  ('-full64' if @archIs64),
126
- SIMULATOR_ARGUMENTS[:vcs],
127
- expand_incdir_options(:vcs),
132
+ SIMULATOR_ARGUMENTS[id],
133
+ expand_incdir_options(id),
128
134
  @sources
129
135
  end
130
136
 
131
137
  CLEAN.include 'csrc', 'simv*'
132
138
 
133
139
 
134
- desc "Simulate with #{RubyVPI::SIMULATORS[:vsim].name}."
135
- task :vsim => :setup do
140
+ sim_task :vsim do |id|
136
141
  sh 'vlib work'
137
- sh 'vlog', expand_incdir_options(:vsim), @sources
142
+ sh 'vlog', expand_incdir_options(id), @sources
138
143
  sh %w[vsim -c],
139
144
  '-do', 'run -all; exit',
140
- '-pli', object_file_path(:vsim),
141
- SIMULATOR_ARGUMENTS[:vsim],
145
+ '-pli', object_file_path(id),
146
+ SIMULATOR_ARGUMENTS[id],
142
147
  @target
143
148
  end
144
149
 
@@ -146,13 +151,12 @@ CLEAN.include 'work', 'vsim.wlf'
146
151
  CLOBBER.include 'transcript'
147
152
 
148
153
 
149
- desc "Simulate with #{RubyVPI::SIMULATORS[:ncsim].name}."
150
- task :ncsim => :setup do
154
+ sim_task :ncsim do |id|
151
155
  sh %w[ncverilog +access+rwc +plinowarn],
152
- "+loadvpi=#{object_file_path(:ncsim)}:#{LOADER_FUNC}",
156
+ "+loadvpi=#{object_file_path(id)}:#{LOADER_FUNC}",
153
157
  ('+nc64bit' if @archIs64),
154
- SIMULATOR_ARGUMENTS[:ncsim],
155
- expand_incdir_options(:ncsim),
158
+ SIMULATOR_ARGUMENTS[id],
159
+ expand_incdir_options(id),
156
160
  @sources
157
161
  end
158
162