ruby-vpi 11.1.0 → 11.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +8 -37
- data/bin/generate_test_tpl/bench.v +1 -1
- data/doc/{src/LICENSE → LICENSE} +0 -0
- data/doc/Rakefile +39 -14
- data/doc/common.css +144 -0
- data/doc/common.tpl +49 -0
- data/doc/figures/figures.dia +1589 -0
- data/doc/history.erb +18 -0
- data/doc/history.html +1726 -0
- data/doc/history.rb +14 -0
- data/doc/history.yml +686 -0
- data/doc/images/{COPYING → LICENSE} +0 -0
- data/doc/intro.inc +48 -0
- data/doc/lib/doc_format.rb +62 -0
- data/doc/lib/doc_proxy.rb +160 -0
- data/doc/lib/erb_content.rb +67 -0
- data/doc/lib/erb_proxy.rb +48 -0
- data/doc/manual.erb +768 -0
- data/doc/manual.html +2107 -0
- data/doc/manual.rb +5 -0
- data/{MEMO → doc/memo.erb} +0 -0
- data/{memo.part.html → doc/memo.html} +38 -5
- data/doc/readme.erb +36 -0
- data/doc/readme.html +171 -0
- data/index.html +1 -0
- data/lib/ruby-vpi/float.rb +52 -0
- data/lib/ruby-vpi/rspec.rb +6 -1
- data/lib/ruby-vpi/verilog_parser.rb +4 -5
- data/ref/c/annotated.html +1 -6
- data/ref/c/common_8h.html +1 -1
- data/ref/c/files.html +1 -3
- data/ref/c/functions.html +24 -44
- data/ref/c/functions_vars.html +24 -44
- data/ref/c/globals.html +5 -211
- data/ref/c/globals_0x63.html +32 -49
- data/ref/c/globals_0x65.html +3 -10
- data/ref/c/globals_0x66.html +3 -20
- data/ref/c/globals_0x70.html +19 -26
- data/ref/c/globals_0x72.html +4 -15
- data/ref/c/globals_0x73.html +13 -199
- data/ref/c/globals_0x74.html +2 -9
- data/ref/c/globals_0x76.html +415 -426
- data/ref/c/globals_0x78.html +3 -10
- data/ref/c/globals_defs.html +30 -35
- data/ref/c/globals_defs_0x65.html +2 -7
- data/ref/c/globals_defs_0x70.html +3 -8
- data/ref/c/globals_defs_0x76.html +413 -420
- data/ref/c/globals_defs_0x78.html +2 -7
- data/ref/c/globals_enum.html +1 -1
- data/ref/c/globals_eval.html +1 -1
- data/ref/c/globals_func.html +14 -173
- data/ref/c/globals_type.html +26 -29
- data/ref/c/globals_vars.html +4 -88
- data/ref/c/index.html +1 -1
- data/ref/c/relay_8c.html +1 -1
- data/ref/c/relay_8h.html +1 -1
- data/ref/c/structrelay____RubyOptions____def.html +1 -1
- data/ref/c/structt__cb__data.html +6 -23
- data/ref/c/structt__vpi__delay.html +3 -20
- data/ref/c/structt__vpi__error__info.html +3 -71
- data/ref/c/structt__vpi__strengthval.html +3 -3
- data/ref/c/structt__vpi__systf__data.html +12 -46
- data/ref/c/structt__vpi__time.html +3 -3
- data/ref/c/structt__vpi__value.html +3 -113
- data/ref/c/structt__vpi__vecval.html +3 -3
- data/ref/c/structt__vpi__vlog__info.html +3 -54
- data/ref/c/swig_8c.html +2 -2
- data/ref/c/swig_8h.html +1 -1
- data/ref/c/verilog_8h.html +1 -1
- data/ref/c/vlog_8c.html +1 -1
- data/ref/c/vlog_8h.html +1 -1
- data/ref/c/vpi__user_8h.html +16 -16
- data/ref/ruby/classes/ERB.html +5 -5
- data/ref/ruby/classes/ERB.src/{M000034.html → M000036.html} +0 -0
- data/ref/ruby/classes/FileUtils.html +10 -10
- data/ref/ruby/classes/FileUtils.src/{M000081.html → M000083.html} +0 -0
- data/ref/ruby/classes/FileUtils.src/{M000082.html → M000084.html} +0 -0
- data/ref/ruby/classes/Float.html +140 -0
- data/ref/ruby/classes/Float.src/M000031.html +19 -0
- data/ref/ruby/classes/RDoc.html +5 -5
- data/ref/ruby/classes/RDoc.src/{M000095.html → M000097.html} +0 -0
- data/ref/ruby/classes/RubyVpi.html +10 -10
- data/ref/ruby/classes/RubyVpi.src/{M000083.html → M000085.html} +0 -0
- data/ref/ruby/classes/RubyVpi.src/{M000084.html → M000086.html} +0 -0
- data/ref/ruby/classes/String.html +33 -10
- data/ref/ruby/classes/String.src/M000033.html +28 -5
- data/ref/ruby/classes/String.src/M000034.html +18 -0
- data/ref/ruby/classes/String.src/M000035.html +36 -0
- data/ref/ruby/classes/Template.html +5 -5
- data/ref/ruby/classes/Template.src/{M000031.html → M000032.html} +0 -0
- data/ref/ruby/classes/VerilogParser/Module.src/M000006.html +9 -8
- data/ref/ruby/classes/VerilogParser/Module/Parameter.src/M000011.html +5 -7
- data/ref/ruby/classes/VerilogParser/Module/Port.src/M000007.html +7 -7
- data/ref/ruby/classes/VerilogParser/Module/Port.src/M000008.html +4 -4
- data/ref/ruby/classes/VerilogParser/Module/Port.src/M000009.html +4 -4
- data/ref/ruby/classes/VerilogParser/Module/Port.src/M000010.html +4 -4
- data/ref/ruby/classes/Vpi/Handle.html +46 -46
- data/ref/ruby/classes/Vpi/Handle.src/M000087.html +5 -9
- data/ref/ruby/classes/Vpi/Handle.src/M000088.html +5 -31
- data/ref/ruby/classes/Vpi/Handle.src/M000089.html +9 -74
- data/ref/ruby/classes/Vpi/Handle.src/M000090.html +31 -17
- data/ref/ruby/classes/Vpi/Handle.src/M000091.html +74 -11
- data/ref/ruby/classes/Vpi/Handle.src/M000092.html +30 -0
- data/ref/ruby/classes/Vpi/Handle.src/M000093.html +11 -55
- data/ref/ruby/classes/Vpi/Handle.src/M000095.html +68 -0
- data/ref/ruby/classes/Vpi/Handle/Property.html +5 -5
- data/ref/ruby/classes/Vpi/Handle/Property.src/{M000094.html → M000096.html} +0 -0
- data/ref/ruby/classes/XX/Document.html +45 -45
- data/ref/ruby/classes/XX/Document.src/M000074.html +9 -7
- data/ref/ruby/classes/XX/Document.src/M000075.html +7 -7
- data/ref/ruby/classes/XX/Document.src/M000076.html +7 -9
- data/ref/ruby/classes/XX/Document.src/M000077.html +7 -8
- data/ref/ruby/classes/XX/Document.src/M000078.html +9 -8
- data/ref/ruby/classes/XX/Document.src/M000079.html +8 -21
- data/ref/ruby/classes/XX/Document.src/M000080.html +8 -85
- data/ref/ruby/classes/XX/Document.src/M000081.html +34 -0
- data/ref/ruby/classes/XX/Document.src/M000082.html +98 -0
- data/ref/ruby/classes/XX/HTML4.html +5 -5
- data/ref/ruby/classes/XX/HTML4.src/{M000036.html → M000038.html} +0 -0
- data/ref/ruby/classes/XX/HTML4/Strict.html +5 -5
- data/ref/ruby/classes/XX/HTML4/Strict.src/{M000038.html → M000040.html} +0 -0
- data/ref/ruby/classes/XX/HTML4/Transitional.html +5 -5
- data/ref/ruby/classes/XX/HTML4/Transitional.src/{M000037.html → M000039.html} +0 -0
- data/ref/ruby/classes/XX/Markup.html +5 -5
- data/ref/ruby/classes/XX/Markup.src/{M000043.html → M000045.html} +0 -0
- data/ref/ruby/classes/XX/Markup/ClassMethods.html +40 -40
- data/ref/ruby/classes/XX/Markup/ClassMethods.src/M000046.html +9 -12
- data/ref/ruby/classes/XX/Markup/ClassMethods.src/M000047.html +7 -7
- data/ref/ruby/classes/XX/Markup/ClassMethods.src/M000048.html +12 -14
- data/ref/ruby/classes/XX/Markup/ClassMethods.src/M000049.html +7 -7
- data/ref/ruby/classes/XX/Markup/ClassMethods.src/M000050.html +14 -14
- data/ref/ruby/classes/XX/Markup/ClassMethods.src/M000051.html +7 -9
- data/ref/ruby/classes/XX/Markup/ClassMethods.src/M000052.html +27 -0
- data/ref/ruby/classes/XX/Markup/ClassMethods.src/M000053.html +22 -0
- data/ref/ruby/classes/XX/Markup/InstanceMethods.html +100 -100
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000054.html +43 -18
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000055.html +20 -35
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000056.html +18 -7
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000057.html +35 -18
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000058.html +7 -19
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000059.html +18 -19
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000060.html +19 -15
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000061.html +19 -10
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000062.html +15 -13
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000063.html +10 -7
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000064.html +13 -7
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000065.html +7 -7
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000066.html +7 -7
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000067.html +7 -7
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000068.html +7 -8
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000069.html +7 -7
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000070.html +8 -7
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000071.html +7 -7
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000072.html +20 -0
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000073.html +20 -0
- data/ref/ruby/classes/XX/XHTML.html +5 -5
- data/ref/ruby/classes/XX/XHTML.src/{M000039.html → M000041.html} +0 -0
- data/ref/ruby/classes/XX/XHTML/Strict.html +5 -5
- data/ref/ruby/classes/XX/XHTML/Strict.src/{M000041.html → M000043.html} +0 -0
- data/ref/ruby/classes/XX/XHTML/Transitional.html +5 -5
- data/ref/ruby/classes/XX/XHTML/Transitional.src/{M000040.html → M000042.html} +0 -0
- data/ref/ruby/classes/XX/XML.html +5 -5
- data/ref/ruby/classes/XX/XML.src/{M000035.html → M000037.html} +0 -0
- data/ref/ruby/classes/XX/XMLish.html +5 -5
- data/ref/ruby/classes/XX/XMLish.src/{M000042.html → M000044.html} +0 -0
- data/ref/ruby/created.rid +1 -1
- data/ref/ruby/files/lib/ruby-vpi/float_rb.html +101 -0
- data/ref/ruby/files/lib/ruby-vpi/rspec_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/runner_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/verilog_parser_rb.html +1 -1
- data/ref/ruby/fr_class_index.html +1 -0
- data/ref/ruby/fr_file_index.html +1 -0
- data/ref/ruby/fr_method_index.html +69 -67
- data/samp/counter/counter.v +4 -4
- data/samp/counter/counter_rspec_spec.rb +4 -8
- data/samp/counter/counter_xunit_spec.rb +4 -8
- metadata +112 -196
- data/HEADER +0 -97
- data/HISTORY +0 -687
- data/README +0 -23
- data/doc/background.html +0 -3
- data/doc/background.methodology.html +0 -3
- data/doc/background.organization.html +0 -10
- data/doc/background.running-tests.html +0 -3
- data/doc/background.terminology.html +0 -3
- data/doc/gfdl-0.html +0 -18
- data/doc/gfdl-1.html +0 -70
- data/doc/gfdl-10.html +0 -15
- data/doc/gfdl-2.html +0 -13
- data/doc/gfdl-3.html +0 -31
- data/doc/gfdl-4.html +0 -75
- data/doc/gfdl-5.html +0 -20
- data/doc/gfdl-6.html +0 -12
- data/doc/gfdl-7.html +0 -16
- data/doc/gfdl-8.html +0 -17
- data/doc/gfdl-9.html +0 -9
- data/doc/gfdl-addendum.html +0 -25
- data/doc/gfdl.html +0 -11
- data/doc/glossary.html +0 -3
- data/doc/hacking.html +0 -3
- data/doc/hacking.release-packages.html +0 -7
- data/doc/images/ChangeLog +0 -27
- data/doc/images/blank.png +0 -0
- data/doc/images/callouts/1.png +0 -0
- data/doc/images/callouts/10.png +0 -0
- data/doc/images/callouts/11.png +0 -0
- data/doc/images/callouts/12.png +0 -0
- data/doc/images/callouts/13.png +0 -0
- data/doc/images/callouts/14.png +0 -0
- data/doc/images/callouts/15.png +0 -0
- data/doc/images/callouts/2.png +0 -0
- data/doc/images/callouts/3.png +0 -0
- data/doc/images/callouts/4.png +0 -0
- data/doc/images/callouts/5.png +0 -0
- data/doc/images/callouts/6.png +0 -0
- data/doc/images/callouts/7.png +0 -0
- data/doc/images/callouts/8.png +0 -0
- data/doc/images/callouts/9.png +0 -0
- data/doc/images/callouts/ChangeLog +0 -15
- data/doc/images/copyright +0 -55
- data/doc/images/draft.png +0 -0
- data/doc/images/toc-blank.png +0 -0
- data/doc/images/toc-minus.png +0 -0
- data/doc/images/toc-plus.png +0 -0
- data/doc/index.html +0 -4
- data/doc/introduction.html +0 -3
- data/doc/introduction.license.html +0 -3
- data/doc/introduction.manifest.html +0 -3
- data/doc/introduction.related-works.html +0 -3
- data/doc/introduction.resources.html +0 -3
- data/doc/manual.txt +0 -1852
- data/doc/problem.ivl.html +0 -18
- data/doc/problems.html +0 -3
- data/doc/problems.ruby.html +0 -3
- data/doc/problems.vsim.html +0 -3
- data/doc/setup.html +0 -3
- data/doc/setup.installation.html +0 -9
- data/doc/setup.maintenance.html +0 -3
- data/doc/setup.reqs.html +0 -3
- data/doc/src/figures.dia +0 -0
- data/doc/src/license.xml +0 -446
- data/doc/src/manual.xml +0 -1824
- data/doc/src/manual.xsl +0 -23
- data/doc/src/shared.dtd +0 -62
- data/doc/styles/manual.css +0 -91
- data/doc/usage.examples.html +0 -3
- data/doc/usage.html +0 -3
- data/doc/usage.tools.html +0 -9
- data/doc/usage.tutorial.html +0 -189
- data/header.html +0 -95
- data/header.part.html +0 -95
- data/history.html +0 -1442
- data/history.part.html +0 -1346
- data/memo.html +0 -211
- data/readme.html +0 -138
- data/readme.part.html +0 -42
- data/ref/c/globals_0x62.html +0 -62
- data/ref/c/globals_0x67.html +0 -64
- data/ref/c/globals_0x69.html +0 -62
- data/ref/c/globals_0x6c.html +0 -64
- data/ref/c/globals_0x6d.html +0 -62
- data/ref/c/globals_0x6e.html +0 -63
- data/ref/c/globals_0x75.html +0 -63
- data/ref/c/globals_defs_0x6c.html +0 -57
- data/ref/c/globals_defs_0x6e.html +0 -56
- data/ref/c/globals_defs_0x72.html +0 -57
- data/ref/c/globals_defs_0x73.html +0 -164
- data/ref/c/globals_defs_0x75.html +0 -56
- data/ref/c/globals_func_0x66.html +0 -62
- data/ref/c/globals_func_0x67.html +0 -55
- data/ref/c/globals_func_0x69.html +0 -53
- data/ref/c/globals_func_0x70.html +0 -53
- data/ref/c/globals_func_0x72.html +0 -57
- data/ref/c/globals_func_0x73.html +0 -114
- data/ref/c/globals_func_0x76.html +0 -57
- data/ref/c/structswig__cast__info.html +0 -98
- data/ref/c/structswig__class.html +0 -115
- data/ref/c/structswig__module__info.html +0 -132
- data/ref/c/structswig__type__info.html +0 -132
- data/ref/c/swig__vpi_8h.html +0 -8739
- data/ref/c/swig__wrap_8cin.html +0 -11556
- data/ref/c/unions__vpi__value__value.html +0 -166
- data/ref/ruby/classes/String.src/M000032.html +0 -41
- data/ref/ruby/classes/Vpi/Handle.src/M000085.html +0 -18
- data/ref/ruby/classes/Vpi/Handle.src/M000086.html +0 -18
- data/ref/ruby/classes/XX/Document.src/M000072.html +0 -22
- data/ref/ruby/classes/XX/Document.src/M000073.html +0 -20
- data/ref/ruby/classes/XX/Markup/ClassMethods.src/M000044.html +0 -22
- data/ref/ruby/classes/XX/Markup/ClassMethods.src/M000045.html +0 -20
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000052.html +0 -56
- data/ref/ruby/classes/XX/Markup/InstanceMethods.src/M000053.html +0 -33
- data/style.css +0 -47
File without changes
|
data/doc/intro.inc
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
bq. Ruby-VPI is a "Ruby":http://www.ruby-lang.org interface to "Verilog VPI":http://ieeexplore.ieee.org/xpl/standardstoc.jsp?isnumber=33945. It lets you create complex Verilog test benches easily and wholly in Ruby.
|
2
|
+
|
3
|
+
|
4
|
+
h2(#intro.features). Features
|
5
|
+
|
6
|
+
* Supports the _entire_ IEEE Std 1364-2005 VPI standard.
|
7
|
+
|
8
|
+
* Works with all "major Verilog simulators":manual.html#setup.reqs available today.
|
9
|
+
|
10
|
+
* Enables "agile practices":http://www.agilealliance.org/intro such as
|
11
|
+
** "test-driven":http://www.testdriven.com development
|
12
|
+
** "behavior-driven":http://behaviour-driven.org development
|
13
|
+
** "rapid prototyping":manual.html#usage.tutorial.implement-proto for design exploration
|
14
|
+
|
15
|
+
* Eliminates unneccesary work:
|
16
|
+
** "Specifications":manual.html#usage.tutorial.specification are _readable_, portable, and executable.
|
17
|
+
** The "automated test generator":manual.html#usage.tools.generate-test helps you accomodate design changes with _minimal_ effort.
|
18
|
+
|
19
|
+
* Utilizes the "power and elegance":http://www.ruby-lang.org/en/about/ of Ruby:
|
20
|
+
** Unlimited length integers
|
21
|
+
** Regular expressions
|
22
|
+
** Multi-threading
|
23
|
+
** System calls and I/O
|
24
|
+
** "_ad infinium_":http://rubyforge.org
|
25
|
+
|
26
|
+
* Gives you the _freedom_ to study, modify, and distribute this software, in accordance with the "GNU General Public License":http://www.gnu.org/copyleft/gpl.html.
|
27
|
+
|
28
|
+
|
29
|
+
h2(#intro.appetizers). Appetizers
|
30
|
+
|
31
|
+
Here is a modest sampling to whet your appetite.
|
32
|
+
|
33
|
+
* Assign the value 2^2048^ to a register:
|
34
|
+
|
35
|
+
bq. @some_register.intVal = 2 ** 2048@
|
36
|
+
|
37
|
+
* Check if all nets in a module are at high impedance:
|
38
|
+
|
39
|
+
bq. @some_module.all_net? { |net| net.z? }@
|
40
|
+
|
41
|
+
* See a register's path, width, and location (file & line number):
|
42
|
+
|
43
|
+
bq. @puts some_register@
|
44
|
+
|
45
|
+
* Simulate fifteen clock cycles:
|
46
|
+
|
47
|
+
bq. @15.times { relay_verilog }@
|
48
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2006 Suraj N. Kurapati
|
3
|
+
|
4
|
+
This file is part of Ruby-VPI.
|
5
|
+
|
6
|
+
Ruby-VPI is free software; you can redistribute it and/or
|
7
|
+
modify it under the terms of the GNU General Public License
|
8
|
+
as published by the Free Software Foundation; either version 2
|
9
|
+
of the License, or (at your option) any later version.
|
10
|
+
|
11
|
+
Ruby-VPI is distributed in the hope that it will be useful,
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
GNU General Public License for more details.
|
15
|
+
|
16
|
+
You should have received a copy of the GNU General Public License
|
17
|
+
along with Ruby-VPI; if not, write to the Free Software Foundation,
|
18
|
+
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
19
|
+
=end
|
20
|
+
|
21
|
+
require 'cgi'
|
22
|
+
require 'rubygems'
|
23
|
+
require 'coderay'
|
24
|
+
require 'redcloth'
|
25
|
+
|
26
|
+
class String
|
27
|
+
# Returns the result of running this string through RedCloth.
|
28
|
+
def redcloth
|
29
|
+
RedCloth.new(self).to_html
|
30
|
+
end
|
31
|
+
|
32
|
+
# Adds syntax coloring to <code>...</code> elements in the given text. If the <code> tag has an attribute lang="...", then that is considered the programming language for which appropriate syntax coloring should be applied. Otherwise, the programming language is assumed to be ruby.
|
33
|
+
def coderay
|
34
|
+
gsub %r{<(code)(.*?)>(.*?)</\1>}m do
|
35
|
+
code = CGI.unescapeHTML($3)
|
36
|
+
atts = $2
|
37
|
+
lang =
|
38
|
+
if $2 =~ /lang=('|")(.*?)\1/i
|
39
|
+
$2
|
40
|
+
else
|
41
|
+
:ruby
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
type =
|
46
|
+
if code =~ /\n/
|
47
|
+
:pre
|
48
|
+
else
|
49
|
+
:code
|
50
|
+
end
|
51
|
+
|
52
|
+
html = CodeRay.scan(code, lang).html(:css => :style)
|
53
|
+
|
54
|
+
%{<#{type} class="code"#{atts}>#{html}</#{type}>}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_html
|
59
|
+
redcloth.coderay
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
@@ -0,0 +1,160 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2006 Suraj N. Kurapati
|
3
|
+
|
4
|
+
This file is part of Ruby-VPI.
|
5
|
+
|
6
|
+
Ruby-VPI is free software; you can redistribute it and/or
|
7
|
+
modify it under the terms of the GNU General Public License
|
8
|
+
as published by the Free Software Foundation; either version 2
|
9
|
+
of the License, or (at your option) any later version.
|
10
|
+
|
11
|
+
Ruby-VPI is distributed in the hope that it will be useful,
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
GNU General Public License for more details.
|
15
|
+
|
16
|
+
You should have received a copy of the GNU General Public License
|
17
|
+
along with Ruby-VPI; if not, write to the Free Software Foundation,
|
18
|
+
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
19
|
+
=end
|
20
|
+
|
21
|
+
require 'erb_proxy'
|
22
|
+
|
23
|
+
# Processes ERB templates to produce documentation. Templates may contain "<xref...>" tags where the ... represents the target anchor of the cross-reference.
|
24
|
+
class DocProxy < ErbProxy
|
25
|
+
Block = Struct.new :anchor, :title, :type
|
26
|
+
Heading = Struct.new :anchor, :title, :depth
|
27
|
+
|
28
|
+
attr_reader :blocks, :headings, :references
|
29
|
+
|
30
|
+
def initialize
|
31
|
+
super
|
32
|
+
|
33
|
+
@blocks = Hash.new {|h,k| h[k] = []}
|
34
|
+
@headings = []
|
35
|
+
|
36
|
+
# admonitions
|
37
|
+
[:tip, :note, :important, :caution, :warning].each do |type|
|
38
|
+
add_block_handler :admonition, type do |index, title, text|
|
39
|
+
join_redcloth_elements [
|
40
|
+
%{!<images/#{type}.png(#{type})!},
|
41
|
+
%{p(title). #{type.to_s.capitalize}: #{title}},
|
42
|
+
text,
|
43
|
+
]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# formal blocks; see http://www.sagehill.net/docbookxsl/FormalTitles.html
|
48
|
+
[:figure, :table, :example, :equation, :procedure].each do |type|
|
49
|
+
add_block_handler :formal, type do |index, title, text|
|
50
|
+
join_redcloth_elements [
|
51
|
+
%{p(title). #{type.to_s.capitalize} #{index}. #{title}},
|
52
|
+
text,
|
53
|
+
]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Post-processes the given ERB template result by parsing the document structure and expanding cross-references, and returns the result.
|
59
|
+
def post_process! aResult
|
60
|
+
buffer = aResult
|
61
|
+
|
62
|
+
# parse document structure and insert anchors (so that the table of contents can link directly to these headings) where necessary
|
63
|
+
buffer.gsub! %r{^(\s*h(\d))(\.|\(.*?\)\.)(.*)$} do
|
64
|
+
target = $~.dup
|
65
|
+
|
66
|
+
title = target[4].strip
|
67
|
+
depth = target[2].to_i
|
68
|
+
|
69
|
+
hasAnchor = target[3] =~ /#([^#]+)\)/
|
70
|
+
anchor = $1 || "anchor#{headings.length}"
|
71
|
+
|
72
|
+
|
73
|
+
@headings << Heading.new(anchor, title, depth)
|
74
|
+
@blocks[:section] << Block.new(anchor, title, :section)
|
75
|
+
|
76
|
+
|
77
|
+
if hasAnchor
|
78
|
+
target.to_s
|
79
|
+
else
|
80
|
+
"#{target[1]}(##{anchor})#{target[3]}#{target[4]}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# expand cross-references into links to their targets
|
85
|
+
blocks = @blocks.values.flatten
|
86
|
+
|
87
|
+
buffer.gsub! %r{<xref\s*(.+?)\s*/?>} do
|
88
|
+
anchor = unanchor($1)
|
89
|
+
target = blocks.find {|b| b.anchor == anchor}
|
90
|
+
|
91
|
+
if target
|
92
|
+
%{"the #{target.type} named “#{target.title}”":##{target.anchor}}
|
93
|
+
else
|
94
|
+
warn "unresolved cross-reference to #{anchor}"
|
95
|
+
%{"#{anchor}":##{anchor}}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
buffer
|
100
|
+
end
|
101
|
+
|
102
|
+
# Adds a block handler for the given type of block and outputs the result in a <div> whose CSS class is the given category.
|
103
|
+
# The arguments for the block handler are:
|
104
|
+
# 1. number of the block
|
105
|
+
# 2. title of the block
|
106
|
+
# 3. content of the block
|
107
|
+
def add_block_handler aCategory, aType
|
108
|
+
raise ArgumentError unless block_given?
|
109
|
+
|
110
|
+
add_handler aType do |buf, text, title, anchor|
|
111
|
+
index = @blocks[aType].length + 1
|
112
|
+
|
113
|
+
unless anchor
|
114
|
+
anchor = "#{aType}#{index}"
|
115
|
+
end
|
116
|
+
anchor = unanchor(anchor)
|
117
|
+
|
118
|
+
@blocks[aType] << Block.new(anchor, title, aType)
|
119
|
+
|
120
|
+
|
121
|
+
elts = [
|
122
|
+
%{<div class="#{aCategory}">},
|
123
|
+
%{<div class="#{aType}" id="#{anchor}">},
|
124
|
+
yield(index, title, text),
|
125
|
+
'</div>',
|
126
|
+
'</div>',
|
127
|
+
]
|
128
|
+
|
129
|
+
text = join_redcloth_elements(elts)
|
130
|
+
buf << text
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
# Joins the given elements by putting enough white-space between them so that RedCloth knows they're different elements.
|
137
|
+
def join_redcloth_elements *args
|
138
|
+
args.join "\n\n\n"
|
139
|
+
end
|
140
|
+
|
141
|
+
# Removes the # from a HTML anchor so that only its name is preserved.
|
142
|
+
def unanchor aAnchor
|
143
|
+
aAnchor.sub(/^#+/, '')
|
144
|
+
end
|
145
|
+
|
146
|
+
# update positions of xrefs so that they are later inserted in correct place
|
147
|
+
def update_xrefs aSrcPos, aSrcLen, aDstLen
|
148
|
+
# because it's a replacement, we delete the match and insert the replacement
|
149
|
+
change = 0 - aSrcLen + aDstLen
|
150
|
+
|
151
|
+
@references.select {|ref| ref.position >= aSrcPos}.each do |ref|
|
152
|
+
ref.position += change
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def append_to_buffer aBuff, aText
|
157
|
+
update_xrefs aBuff.length, 0, aText.length
|
158
|
+
aBuff << aText
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2006 Suraj N. Kurapati
|
3
|
+
|
4
|
+
This file is part of Ruby-VPI.
|
5
|
+
|
6
|
+
Ruby-VPI is free software; you can redistribute it and/or
|
7
|
+
modify it under the terms of the GNU General Public License
|
8
|
+
as published by the Free Software Foundation; either version 2
|
9
|
+
of the License, or (at your option) any later version.
|
10
|
+
|
11
|
+
Ruby-VPI is distributed in the hope that it will be useful,
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
GNU General Public License for more details.
|
15
|
+
|
16
|
+
You should have received a copy of the GNU General Public License
|
17
|
+
along with Ruby-VPI; if not, write to the Free Software Foundation,
|
18
|
+
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
19
|
+
=end
|
20
|
+
|
21
|
+
require 'erb'
|
22
|
+
|
23
|
+
# Returns an array containing the current ERB buffer and the content that the given block will append to the buffer when it is invoked.
|
24
|
+
#
|
25
|
+
# == Example
|
26
|
+
# Suppose your ERB template invoked a method with some arguments and some content in a block. You can pass the block to this method to obtain the content contained within the block.
|
27
|
+
#
|
28
|
+
## template = ERB.new <<-EOS
|
29
|
+
## <% wrap_xml "message" do %>
|
30
|
+
## i love ruby!
|
31
|
+
## <% end %>
|
32
|
+
## EOS
|
33
|
+
#
|
34
|
+
# In this case, the ERB template invokes the _wrap_xml_ method to wrap some content within a pair of XML tags.
|
35
|
+
#
|
36
|
+
## def wrap_xml tag, &block
|
37
|
+
## buffer, content = ERB.buffer_and_content(&block)
|
38
|
+
## buffer << "<#{tag}>#{content}</#{tag}>"
|
39
|
+
## end
|
40
|
+
#
|
41
|
+
# When we evaluate the template:
|
42
|
+
## puts template.result(binding)
|
43
|
+
#
|
44
|
+
# we see the following output:
|
45
|
+
## <message>
|
46
|
+
## i love ruby!
|
47
|
+
## </message>
|
48
|
+
#
|
49
|
+
def ERB.buffer_and_content
|
50
|
+
raise ArgumentError unless block_given?
|
51
|
+
|
52
|
+
# buffer + content
|
53
|
+
buffer = yield
|
54
|
+
a = buffer.length
|
55
|
+
|
56
|
+
# buffer + content + content
|
57
|
+
yield
|
58
|
+
b = buffer.length
|
59
|
+
|
60
|
+
# buffer + content
|
61
|
+
content = buffer.slice! a..b
|
62
|
+
|
63
|
+
# buffer
|
64
|
+
buffer.slice!((-content.length)..-1)
|
65
|
+
|
66
|
+
[buffer, content]
|
67
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2006 Suraj N. Kurapati
|
3
|
+
|
4
|
+
This file is part of Ruby-VPI.
|
5
|
+
|
6
|
+
Ruby-VPI is free software; you can redistribute it and/or
|
7
|
+
modify it under the terms of the GNU General Public License
|
8
|
+
as published by the Free Software Foundation; either version 2
|
9
|
+
of the License, or (at your option) any later version.
|
10
|
+
|
11
|
+
Ruby-VPI is distributed in the hope that it will be useful,
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
GNU General Public License for more details.
|
15
|
+
|
16
|
+
You should have received a copy of the GNU General Public License
|
17
|
+
along with Ruby-VPI; if not, write to the Free Software Foundation,
|
18
|
+
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
19
|
+
=end
|
20
|
+
|
21
|
+
require 'erb_content'
|
22
|
+
|
23
|
+
class ErbProxy
|
24
|
+
attr_reader :handlers
|
25
|
+
|
26
|
+
def initialize
|
27
|
+
@handlers = {}
|
28
|
+
end
|
29
|
+
|
30
|
+
# Adds a new handler that can be invoked from a ERB template.
|
31
|
+
# The arguments passed to the handler are:
|
32
|
+
# 1. buffer containing the evaluated results of the ERB template (so far; at this point in time)
|
33
|
+
# 2. content that was passed to the handler from the ERB template
|
34
|
+
# 3. variable number of method arguments passed from the ERB template
|
35
|
+
def add_handler aName, &aHandler # :yields: buffer, content, *args
|
36
|
+
@handlers[aName] = aHandler
|
37
|
+
|
38
|
+
# using a string because define_method does not accept a block until Ruby 1.9
|
39
|
+
instance_eval %{
|
40
|
+
def #{aName} *args, &block
|
41
|
+
raise ArgumentError unless block_given?
|
42
|
+
|
43
|
+
args.unshift(*ERB.buffer_and_content(&block))
|
44
|
+
@handlers[#{aName.inspect}].call(*args)
|
45
|
+
end
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
data/doc/manual.erb
ADDED
@@ -0,0 +1,768 @@
|
|
1
|
+
<div class="cover-page">
|
2
|
+
|
3
|
+
h1. Ruby-VPI user manual
|
4
|
+
|
5
|
+
Suraj N. Kurapati
|
6
|
+
|
7
|
+
<%= Time.now %>
|
8
|
+
|
9
|
+
</div>
|
10
|
+
|
11
|
+
|
12
|
+
h2(#terms). Terms
|
13
|
+
|
14
|
+
Permission is granted to copy, distribute and/or modify this document under the terms of the "GNU Free Documentation License":http://www.gnu.org/copyleft/fdl.html, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts. A copy of the license is included in the the file named "LICENSE":./LICENSE.
|
15
|
+
|
16
|
+
Admonition and navigation graphics are Copyright (c) 2005, 2006 "Tango Desktop Project":http://tango.freedesktop.org. They are licensed under "these terms":./images/LICENSE.
|
17
|
+
|
18
|
+
|
19
|
+
h1(#intro). Introduction
|
20
|
+
|
21
|
+
<%= File.read 'intro.inc' %>
|
22
|
+
|
23
|
+
|
24
|
+
h2(#intro.license). License
|
25
|
+
|
26
|
+
Ruby-VPI is "free software":http://en.wikipedia.org/wiki/Free_software ; you can redistribute it and/or modify it under the terms of the "GNU General Public License":http://www.gnu.org/copyleft/gpl.html as published by the "Free Software Foundation":http://www.fsf.org ; either version 2 of the License, or (at your option) any later version.
|
27
|
+
|
28
|
+
|
29
|
+
h2(#intro.related-works). Related works
|
30
|
+
|
31
|
+
* "JOVE":http://jove.sourceforge.net is a Java interface to VPI.
|
32
|
+
* "Teal":http://teal.sourceforge.net is a C++ interface to VPI.
|
33
|
+
* "ScriptEDA":http://embedded.eecs.berkeley.edu/Alumni/pinhong/scriptEDA/ is a Perl, Python, and Tcl interface to VPI.
|
34
|
+
* "RHDL":http://rhdl.rubyforge.org is a hardware description and verification language based on Ruby.
|
35
|
+
* "MyHDL":http://myhdl.jandecaluwe.com is a hardware description and verification language based on Python, which features conversion to Verilog and co-simulation.
|
36
|
+
|
37
|
+
|
38
|
+
h2(#intro.related-works.pli). Ye olde PLI
|
39
|
+
|
40
|
+
The following projects utilize the archaic *tf* and *acc* PLI interfaces, which have been officially deprecated in IEEE Std 1364-2005.
|
41
|
+
|
42
|
+
* "ScriptSim":http://www.nelsim.com is a Perl, Python, and Tcl/Tk interface to PLI.
|
43
|
+
* "Verilog::Pli":http://www.veripool.com/verilog-pli.html is a Perl interface to PLI.
|
44
|
+
* "JPLI":http://www.time-rover.com/jpli/ is a proprietary Java interface to PLI.
|
45
|
+
|
46
|
+
|
47
|
+
h1(#background). Background
|
48
|
+
|
49
|
+
Ruby-VPI is a "bench":#glossary.bench which lets you "test":#glossary.test Verilog modules using the Ruby language.
|
50
|
+
|
51
|
+
|
52
|
+
h2(#background.methodology). Methodology
|
53
|
+
|
54
|
+
Ruby-VPI presents an open-ended interface to VPI. Thus, you can use any methodology you wish when writing tests.
|
55
|
+
|
56
|
+
|
57
|
+
h2(#background.vocab). Terminology
|
58
|
+
|
59
|
+
<% tip do %>
|
60
|
+
Have a look at the "glossary":#glossary for definitions of terms used in this manual.
|
61
|
+
<% end %>
|
62
|
+
|
63
|
+
As a newcomer into the world of Verilog, I often heard the term *test bench*: "I ran the test bench, but it didn't work!" or "Are you crazy?!! You _still_ haven't written the test bench?", for example. I flipped through my textbook and surfed the Internet for a definition of the term, but it was to no avail. Instead, both resources nonchalantly employed the term _throughout_ their being, as if mocking my ignorance of what seems to be universal knowledge.
|
64
|
+
|
65
|
+
Defeated, I turned to my inner faculties to determine the answer. Let's see, the term _test bench_ has the word _test_—so it has something to do with testing—and it has the word _bench_—so maybe it's referring to a table where the testing should occur. This reasoning grew increasingly familiar as my mind rummaged through towering stores of obsolescence and ultimately revealed dreaded memories of sleepless anguish: debugging electronics in the robotics laboratory.
|
66
|
+
|
67
|
+
Aha! I exclaimed hesitantly, trying to dismiss the past. The term has its roots in the testing of electronic devices, where an engineer would sit at a bench in an electronics laboratory and verify that an electronic component satisfies some criteria. The bench would be furnished with tools of measurement and manipulation—such as oscilloscopes, voltmeters, soldering irons, and so on—which help the engineer to verify the electronic component or locate the sources of defects in the component.
|
68
|
+
|
69
|
+
Alright, now I remember what a laboratory bench is, but how does that compare with the term test bench? Surely they cannot have the same meaning, because it doesn't make sense to _run_ a laboratory bench or to _write_ one. Thus, to avoid propagating such confusion into this manual, I have attempted to clarify the terminology by "simplifying and reintroducing it in a new light":#glossary.
|
70
|
+
|
71
|
+
|
72
|
+
h2(#background.org). Organization
|
73
|
+
|
74
|
+
<% figure "Overall organization of a test", "#fig..organization" do %>
|
75
|
+
!figures/organization.png!
|
76
|
+
<% end %>
|
77
|
+
|
78
|
+
As <xref #fig..organization> shows, a test is composed of a bench, a design, and a specification. To extend the "analogy of an electronics laboratory":#background.vocab, the first acts as the laboratory bench which provides measurement and manipulation tools. The second acts as the electronic component being verified by the engineer. And the third acts as the engineer who measures, manipulates, and verifies the electronic component.
|
79
|
+
|
80
|
+
|
81
|
+
h3(#background.org.vpi). Interface to VPI
|
82
|
+
|
83
|
+
<% figure "Detailed organization of a test", "#fig..organization.detail" do %>
|
84
|
+
!figures/organization_detailed.png!
|
85
|
+
<% end %>
|
86
|
+
|
87
|
+
In <xref #fig..organization.detail>, Ruby-VPI acts as the bench, a Verilog simulator encapsulates the design, and a Ruby interpreter encapsulates the specification. Notice that Ruby-VPI encapsulates all communication between the Ruby interpreter and VPI. This allows the specification, or any Ruby program in general, to access VPI using nothing more than the Ruby language! Thus, Ruby-VPI removes the burden of having to write C programs in order to access VPI.
|
88
|
+
|
89
|
+
Furthermore, Ruby-VPI presents the _entire_ IEEE Std 1364-2005 VPI interface to the Ruby interpreter, but with the following minor changes.
|
90
|
+
|
91
|
+
* The first letter in the name of every function, type, structure, and constant becomes capitalized. For example, the @s_vpi_value@ structure in C becomes the @S_vpi_value@ class in Ruby. Likewise, the @vpiIntVal@ constant in C becomes the @VpiIntVal@ constant in Ruby.
|
92
|
+
|
93
|
+
* The VPI functions @vpi_vprintf@ and @vpi_mcd_vprintf@ are not made accessible to Ruby. However, this isn't a big problem because you can use Ruby's printf method instead.
|
94
|
+
|
95
|
+
bq. The reason for this limitation is that some C compilers have trouble with pointers to the va_list type. For these compilers, the second line in the code shown below causes a "type mismatch" error.
|
96
|
+
|
97
|
+
<code lang="c">
|
98
|
+
void foo(va_list ap) {
|
99
|
+
va_list *p = ≈
|
100
|
+
}
|
101
|
+
</code>
|
102
|
+
|
103
|
+
|
104
|
+
h4(#background.org.vpi.util). VPI utility layer
|
105
|
+
|
106
|
+
From a user's perspective, the VPI utility layer greatly enhances the ability to interact with handles. One simply invokes a handle's methods, which are carefully named in the following manner, to access either (1) its children or (2) its VPI properties.
|
107
|
+
|
108
|
+
The children of a handle are simply the handles that are immediately contained within it in. For example, suppose that you had a Verilog module that contains some registers. The children, of a handle to the module, would be handles to the registers.
|
109
|
+
|
110
|
+
In the event that a child handle has the same name as a VPI property, the child is given priority. However, you can always access VPI properties explicitly via the @Vpi::Handle.get_value@ and @Vpi::Handle.put_value@ methods.
|
111
|
+
|
112
|
+
|
113
|
+
<% figure "Parts of speech for accessing a handle's VPI properties" do %>
|
114
|
+
|_. Operation |_. _ |_. Property |_. _ |_. Accessor |_. Addendum |
|
115
|
+
|\2. optional | required |\3. optional |
|
116
|
+
|
117
|
+
* *Operation* suggests a method that should be invoked in the context of the Property parameter.
|
118
|
+
|
119
|
+
* *Property* suggests a VPI property that should be accessed. The "vpi" prefix, which is common to all VPI properties, can be omitted if you wish. For example, the VPI property "vpiFullName" is considered equivalent to "fullName" and "FullName", but not equivalent "full_name".
|
120
|
+
|
121
|
+
* *Accessor* suggests a VPI function that should be used in order to access the VPI property. When this parameter is not specified, the VPI utility layer will attempt to _guess_ the value of this parameter ("see the source code":../ref/ruby/classes/Vpi/Handle/Property.html of the @Property.resolve@ method for details).
|
122
|
+
|
123
|
+
* *Addendum* suggests that the specified VPI property should be queried as a boolean value when it is a question mark (?). This suggestion is the same as specifying "b" for the Accessor parameter. Also, when this parameter is an equal sign (=), it suggests that the specified VPI property should be written to.
|
124
|
+
<% end %>
|
125
|
+
|
126
|
+
<% table "Possible accessors and their implications" do %>
|
127
|
+
|_. Accessor |_. Kind of value accessed |_. VPI functions used to access the value |
|
128
|
+
| d | delay | @vpi_get_delays@, @vpi_put_delays@ |
|
129
|
+
| l | logic | @vpi_get_value@, @vpi_put_value@ |
|
130
|
+
| i | integer | @vpi_get@ |
|
131
|
+
| b | boolean | @vpi_get@ |
|
132
|
+
| s | string | @vpi_get_str@ |
|
133
|
+
| h | handle | @vpi_handle@ |
|
134
|
+
<% end %>
|
135
|
+
|
136
|
+
<% example "Examples of accessing a handle's VPI properties" do %>
|
137
|
+
|_/2. Ruby expression |_\6. Parts of speech |_/2. Description |
|
138
|
+
||_. Operation |_. _ |_. Property |_. _ |_. Accessor |_. Addendum ||
|
139
|
+
| @handle.vpiIntVal@ | | | vpiIntVal | | | |/4. These expressions access the logic value of the handle's vpiIntVal property. |
|
140
|
+
| @handle.vpiIntVal_l@ | | | vpiIntVal | _ | l | |
|
141
|
+
| @handle.intVal@ | | | intVal | | | |
|
142
|
+
| @handle.intVal_l@ | | | intVal | _ | l | |
|
143
|
+
| @handle.vpiIntVal = 15@ | | | vpiIntVal | | | = |/4. These expressions assign the number 15 to the logic value of the handle's vpiIntVal property. |
|
144
|
+
| @handle.vpiIntVal_l = 15@ | | | vpiIntVal | _ | l | = |
|
145
|
+
| @handle.intVal = 15@ | | | intVal | | | = |
|
146
|
+
| @handle.intVal_l = 15@ | | | intVal | _ | l | = |
|
147
|
+
| @handle.vpiType@ | | | vpiType | | | |/4. These expressions access the integer value of the handle's vpiType property. |
|
148
|
+
| @handle.vpiType_i@ | | | vpiType | _ | i | |
|
149
|
+
| @handle.type@ | | | type | | | |
|
150
|
+
| @handle.type_i@ | | | type | _ | i | |
|
151
|
+
| @handle.vpiProtected@ | | | vpiProtected | | | |/6. These expressions access the boolean value of the handle's vpiProtected property. |
|
152
|
+
| @handle.vpiProtected_b@ | | | vpiProtected | _ | b | |
|
153
|
+
| @handle.vpiProtected?@ | | | vpiProtected | | | ? |
|
154
|
+
| @handle.protected@ | | | protected | | | |
|
155
|
+
| @handle.protected_b@ | | | protected | _ | b | |
|
156
|
+
| @handle.protected?@ | | | protected | | | ? |
|
157
|
+
| @handle.vpiFullName@ | | | vpiFullName | | | |/4. These expressions access the string value of the handle's vpiFullName property. |
|
158
|
+
| @handle.vpiFullName_s@ | | | vpiFullName | _ | s | |
|
159
|
+
| @handle.fullName@ | | | fullName | | | |
|
160
|
+
| @handle.fullName_s@ | | | fullName | _ | s | |
|
161
|
+
| @handle.vpiParent@ | | | vpiParent | | | |/4. These expressions access the handle value of the handle's vpiParent property. |
|
162
|
+
| @handle.vpiParent_h@ | | | vpiParent | _ | h | |
|
163
|
+
| @handle.parent@ | | | parent | | | |
|
164
|
+
| @handle.parent_h@ | | | parent | _ | h | |
|
165
|
+
| <code>handle.each_vpiNet {|net| puts net.fullName}</code> | each | _ | vpiNet | | | |/2. These expressions print the full name of each vpiNet object associated with the handle. |
|
166
|
+
| <code>handle.each_net {|net| puts net.fullName}</code> | each | _ | net | | | |
|
167
|
+
| <code>handle.all_vpiReg? {|reg| reg.size == 1}</code> | all? | _ | vpiReg | | | |/2. These expressions check if all registers associated with the handle are capable of storing only one bit. |
|
168
|
+
| <code>handle.all_reg? {|reg| reg.size == 1}</code> | all? | _ | reg | | | |
|
169
|
+
| <code>handle.select_vpiNet {|net| net.x?}</code> | select | _ | VpiNet | | | |/2. These expressions return a list of nets whose logic value is unknown or "don't care" (x).|
|
170
|
+
| <code>handle.select_net {|net| net.x?}</code> | select | _ | net | | | |
|
171
|
+
<% end %>
|
172
|
+
|
173
|
+
|
174
|
+
h2(#background.running-tests). Running a test
|
175
|
+
|
176
|
+
Unlike an engineer who can verify an electronic component in real-time, the Verilog simulator and the Ruby interpreter (see <xref #fig..organization.detail>) take turns working with objects in a simulation when a test is run. In particular, they take turns manipulating the design and transfer control to each other when appropriate.
|
177
|
+
|
178
|
+
The situation is similar to a pair of friends playing catch. One friend throws a ball to the other, and the other throws it back. Either is able to inspect and modify the ball, but only when it is in hand.
|
179
|
+
|
180
|
+
|
181
|
+
h3(#background.running-tests.init). Initialization
|
182
|
+
|
183
|
+
<% figure "Initialization of a test", "#fig..ruby_init" do %>
|
184
|
+
!figures/ruby_init.png!
|
185
|
+
<% end %>
|
186
|
+
|
187
|
+
A test is first initialized before it is "executed":#background.running-tests.exec. <xref #fig..ruby_init> illustrates the initialization process "described below":#proc..ruby_init.
|
188
|
+
|
189
|
+
# The Verilog simulator initializes the Ruby interpreter by invoking the @$ruby_init;@ system task/function, whose parameters represent the command-line invocation of the Ruby interpreter. For example, one would specify @$ruby_init("ruby", "-w");@ in Verilog to achieve the same effect as running <pre>ruby -w</pre> at a command-prompt.
|
190
|
+
# The Verilog simulator is paused and the Ruby interpreter is initialized with the arguments of the @$ruby_init;@ system task/function.
|
191
|
+
# When the Ruby interpreter invokes the @Vpi::relay_verilog@ method, it is paused and the Verilog simulator is given control.
|
192
|
+
|
193
|
+
|
194
|
+
h3(#background.running-tests.exec). Execution
|
195
|
+
|
196
|
+
After a test is "initialized":#background.running-tests.init, it is executed such that the design is verified against the specification. <xref #fig..ruby_relay> illustrates the execution process "described below":#proc..ruby_relay.
|
197
|
+
|
198
|
+
<% figure "Execution of a test", "#fig..ruby_relay" do %>
|
199
|
+
!figures/ruby_relay.png!
|
200
|
+
<% end %>
|
201
|
+
|
202
|
+
# The Verilog simulator transfers control to the Ruby interpreter by invoking the @$ruby_relay;@ system task/function.
|
203
|
+
# The Verilog simulator is paused and the Ruby interpreter is given control.
|
204
|
+
# When the Ruby interpreter invokes the @Vpi::relay_verilog@ method, it is paused and the Verilog simulator is given control.
|
205
|
+
|
206
|
+
|
207
|
+
h1(#setup). Setup
|
208
|
+
|
209
|
+
|
210
|
+
h2(#setup.manifest). Manifest
|
211
|
+
|
212
|
+
When you extract a release package, the following is what you would expect to find.
|
213
|
+
|
214
|
+
* <tt>doc</tt> contains user documentation in various formats.
|
215
|
+
* <tt>ref</tt> contains reference API documentation in HTML format.
|
216
|
+
* <tt>ext</tt> contains source code, written in the C language, for the "core of Ruby-VPI":#background.org.
|
217
|
+
* <tt>lib</tt> contains Ruby libraries provided by Ruby-VPI.
|
218
|
+
* <tt>bin</tt> contains various tools. See <xref #usage.tools> for more information.
|
219
|
+
* <tt>samp</tt> contains example tests. See <xref #usage.examples> for more information.
|
220
|
+
|
221
|
+
|
222
|
+
h2(#setup.reqs). Requirements
|
223
|
+
|
224
|
+
The following software is necessary in order to use Ruby-VPI.
|
225
|
+
|
226
|
+
* Verilog simulator
|
227
|
+
- Ruby-VPI is known to work with the following simulators. However, you should be able to use it with any Verilog simulator that supports VPI.
|
228
|
+
** "GPL Cver":http://www.pragmatic-c.com/gpl-cver/
|
229
|
+
- version 2.11a or newer is acceptable.
|
230
|
+
** "Icarus Verilog":http://www.icarus.com/eda/Verilog/
|
231
|
+
- version 0.8 or newer is acceptable.
|
232
|
+
** "Synopsys VCS":http://www.synopsys.com/products/simulation/simulation.html
|
233
|
+
- any version that supports the <tt>-load</tt> option is acceptable.
|
234
|
+
** "Mentor Modelsim":http://www.model.com
|
235
|
+
- any version that supports the <tt>-pli</tt> option is acceptable.
|
236
|
+
|
237
|
+
* *make*
|
238
|
+
- any distribution should be acceptable.
|
239
|
+
|
240
|
+
* C compiler
|
241
|
+
- the "GNU Compiler Collection (GCC)":http://www.gnu.org/software/gcc/ is preferred, but any C compiler should be acceptable.
|
242
|
+
|
243
|
+
* "POSIX threads (pthreads)":http://en.wikipedia.org/wiki/Pthreads
|
244
|
+
- header and linkable object files, and operating system support for this library are necessary.
|
245
|
+
|
246
|
+
* "Ruby":http://www.ruby-lang.org
|
247
|
+
- version 1.8 or newer, including header and linkable object files for building extensions, is necessary. You can install Ruby by following "these instructions":http://www.rubygarden.org/faq/section/show/3.
|
248
|
+
|
249
|
+
* "RubyGems":http://rubyforge.org/frs/?group_id=126
|
250
|
+
- any recent version should be acceptable. You can install RubyGems by following "these instructions":http://www.rubygems.org/read/chapter/3.
|
251
|
+
|
252
|
+
|
253
|
+
h2(#setup.recom). Recommendations
|
254
|
+
|
255
|
+
The following software may make your interactions with Ruby-VPI more pleasant.
|
256
|
+
|
257
|
+
|
258
|
+
h3(#setup.recom.merger). Text merging tool
|
259
|
+
|
260
|
+
An _interactive_ text merging tool can greatly simplify the process of transferring wanted changes from one file to another. In particular, such tools are especially beneficial when using the "automated test generator":#usage.tools.generate-test. A handful of the currently available open-source text merging tools are listed below.
|
261
|
+
** "*kdiff3*":http://kdiff3.sourceforge.net/ is a graphical, three-way merging tool for KDE.
|
262
|
+
** "*meld*":http://meld.sourceforge.net/ is a graphical, three-way merging tool for GNOME.
|
263
|
+
** "*tkdiff*":http://tkdiff.sourceforge.net/ is a graphical, two-way merging tool that uses the cross-platform Tk windowing toolkit.
|
264
|
+
** "*xxdiff*":http://furius.ca/xxdiff/ is a graphical, three-way merging tool.
|
265
|
+
** "*imediff2*":http://elonen.iki.fi/code/imediff/ is a textual, fullscreen two-way merging tool. It is very useful when you are working remotely via SSH.
|
266
|
+
|
267
|
+
|
268
|
+
h2(#setup.installation). Installation
|
269
|
+
|
270
|
+
Once you have satisfied the "necessary requirements":#setup.reqs, you can install Ruby-VPI by running the <pre>gem install ruby-vpi</pre> command. RubyGems will install Ruby-VPI into the system gem directory, whose path can be determined by running the <pre>gem env gemdir</pre> command. Within this directory, there is a "gems" subdirectory which contains the Ruby-VPI installation, as illustrated below.
|
271
|
+
|
272
|
+
<pre>
|
273
|
+
$ gem env gemdir
|
274
|
+
/usr/lib/ruby/gems/1.8
|
275
|
+
|
276
|
+
$ ls -d /usr/lib/ruby/gems/1.8/gems/ruby-vpi*
|
277
|
+
/usr/lib/ruby/gems/1.8/gems/ruby-vpi-7.0.0/
|
278
|
+
</pre>
|
279
|
+
|
280
|
+
|
281
|
+
h3(#setup.installation.windows). Installing on Windows
|
282
|
+
|
283
|
+
* Install "Cygwin":http://www.cygwin.com, the Linux-like environment for Windows.
|
284
|
+
|
285
|
+
* Search for object files whose names end with <tt>.so</tt>, <tt>.o</tt>, or <tt>.dll</tt> in your Verilog simulator's installation directory.
|
286
|
+
|
287
|
+
* Determine which object files, among those found in the previous step, contain symbols whose names begin with "_vpi" by running the <pre>for x in *.{o,so,dll}; do nm $x | grep -q '[Tt] _vpi' > /dev/null && echo $x; done</pre> command in Cygwin.
|
288
|
+
** If you are using Mentor Modelsim, the desired object file can be found at a path similar to <tt>C:\Modeltech\win32\libvsim.dll</tt>.
|
289
|
+
** If you are using GPL Cver, the desired object file can be found at a path similar to <tt>C:\gplcver\objs\v_vpi.o</tt>.
|
290
|
+
|
291
|
+
<% note do %>
|
292
|
+
Since Ruby-VPI makes use of the VPI C-language interface, it links to symbols whose names begin with "_vpi". It is possible for these symbols to be undefined when Ruby-VPI is compiled under GNU/Linux and similar operating systems. In contrast, one "cannot compile a shared object file with references to undefined symbols under Windows":http://sourceware.org/ml/cygwin/2001-12/msg01293.html. Thus, we must find a Verilog simulator's shared object file, which contains definitions of all VPI symbols, and give this file to the linker when compiling Ruby-VPI.
|
293
|
+
<% end %>
|
294
|
+
|
295
|
+
* Assign the path of the object file (determined in the previous step) to the @LDFLAGS@ environment variable. For example, if the object file's path is <tt>/foo/bar/vpi.so</tt>, then you would run the <pre>export LDFLAGS=/foo/bar/vpi.so</pre> command in Cygwin.
|
296
|
+
|
297
|
+
* You may now install Ruby-VPI by running the <pre>gem install ruby-vpi</pre> command in Cygwin.
|
298
|
+
|
299
|
+
|
300
|
+
h2(#setup.maintenance). Maintenance
|
301
|
+
|
302
|
+
* You can uninstall Ruby-VPI by running the <pre>gem uninstall ruby-vpi</pre> command.
|
303
|
+
* You can upgrade to the latest release of Ruby-VPI by running the <pre>gem update ruby-vpi</pre> command.
|
304
|
+
|
305
|
+
<% note do %>
|
306
|
+
Learn more about using and manipulating RubyGems in "the RubyGems user manual":http://www.rubygems.org.
|
307
|
+
<% end %>
|
308
|
+
|
309
|
+
|
310
|
+
h1(#usage). Usage
|
311
|
+
|
312
|
+
h2(#usage.tools). Tools
|
313
|
+
|
314
|
+
The <tt>bin</tt> directory contains various utilities which ease the process of writing tests. Each tool provides help and usage information invoked with the <tt>--help</tt> option.
|
315
|
+
|
316
|
+
|
317
|
+
h3(#usage.tools.generate-test). Automated test generation
|
318
|
+
|
319
|
+
The automated test generator (*generate_test.rb*) generates tests from Verilog 2001 module declarations, as demonstrated "in the tutorial":#usage.tutorial.generate-test. A generated test is composed of the following parts:
|
320
|
+
|
321
|
+
* Runner
|
322
|
+
- written in Rake, this file builds and runs the test.
|
323
|
+
* Bench
|
324
|
+
- written in Verilog and Ruby, these files define the testing environment.
|
325
|
+
* Design
|
326
|
+
- written in Ruby, this file provides an interface to the design being verified.
|
327
|
+
* Prototype
|
328
|
+
- written in Ruby, this file defines a prototype of the design being verified.
|
329
|
+
* Specification
|
330
|
+
- written in Ruby, this file describes the expected behavior of the design.
|
331
|
+
|
332
|
+
The reason for dividing a single test into these parts is mainly to decouple the design from the specification. This allows you to focus on writing the specification while the remainder is automatically generated by the tool. For example, when the interface of a Verilog module changes, you would simply re-run this tool and incorporate those changes (using a "text merging tool":#setup.recom) into the test without diverting your focus from the specification.
|
333
|
+
|
334
|
+
<% tip "Using *kdiff3* with the automated test generator." do %>
|
335
|
+
# Create a file named <tt>merge2</tt> with the following content: <code>
|
336
|
+
#!/bin/sh
|
337
|
+
# args: old file, new file
|
338
|
+
kdiff3 --auto --output "$2" "$@"
|
339
|
+
</code>
|
340
|
+
# Make the file executable by running the <pre>chmod +x merge2</pre> command.
|
341
|
+
# Place the file somewhere accessible by your @PATH@ environment variable.
|
342
|
+
# Assign the value "merge2" to the @MERGER@ environment variable using your shell's *export* or *setenv* command.
|
343
|
+
|
344
|
+
From now on, *kdiff3* will be invoked to help you transfer your changes between generated files. When you are finished transferring changes, simply issue the "save the file" command and terminate *kdiff3*. Or, if you do not want to transfer any changes, simply terminate *kdiff3*.
|
345
|
+
<% end %>
|
346
|
+
|
347
|
+
|
348
|
+
h3(#usage.tools.verilog-ruby-conv). Verilog to Ruby conversion
|
349
|
+
|
350
|
+
The *header_to_ruby.rb* tool can be used to convert Verilog header files into Ruby. You can try it by running the <pre>header_to_ruby.rb --help</pre> command.
|
351
|
+
|
352
|
+
|
353
|
+
h2(#usage.tutorial). Tutorial
|
354
|
+
|
355
|
+
# "Declare the design":#usage.tutorial.declare-design, which is a Verilog module, using Verilog 2001 syntax.
|
356
|
+
# "Generate a test":#usage.tutorial.generate-test for the design using the "automated test generator":#usage.tools.generate-test tool.
|
357
|
+
# "Identify your expectations":#usage.tutorial.specification for the design and implement them in the specification.
|
358
|
+
# (Optional) "Implement the prototype":#usage.tutorial.implement-proto of the design in Ruby.
|
359
|
+
# (Optional) "Verify the prototype":#usage.tutorial.test-proto against the specification.
|
360
|
+
# "Implement the design":#usage.tutorial.implement-design in Verilog once the prototype has been verified.
|
361
|
+
# "Verify the design":#usage.tutorial.test-design against the specification.
|
362
|
+
|
363
|
+
|
364
|
+
h3(#usage.tutorial.declare-design). Start with a design
|
365
|
+
|
366
|
+
First, we need a "design":#glossary.design to verify. In this tutorial, <xref #fig..counter.v_decl> will serve as our design. Its interface is composed of the following parts:
|
367
|
+
|
368
|
+
* @Size@ defines the number of bits used to represent the counter's value.
|
369
|
+
* @clock@ causes the @count@ register to increment whenever it reaches a positive edge.
|
370
|
+
* @reset@ causes the @count@ register to become zero when asserted.
|
371
|
+
* @count@ is a register that contains the counter's value.
|
372
|
+
|
373
|
+
<% example "Declaration of a simple up-counter with synchronous reset", "#fig..counter.v_decl" do %>
|
374
|
+
<code lang="verilog">
|
375
|
+
module counter #(parameter Size = 5) (
|
376
|
+
input clock,
|
377
|
+
input reset,
|
378
|
+
output reg [Size - 1 : 0] count
|
379
|
+
);
|
380
|
+
endmodule
|
381
|
+
</code>
|
382
|
+
<% end %>
|
383
|
+
|
384
|
+
<% important "Before we continue..." do %>
|
385
|
+
Save the source code shown in <xref #fig..counter.v_decl> into a file named <tt>counter.v</tt>.
|
386
|
+
<% end %>
|
387
|
+
|
388
|
+
|
389
|
+
h3(#usage.tutorial.generate-test). Generate a test
|
390
|
+
|
391
|
+
Now that we have a "design":#glossary.design to verify, let us generate a "test":#glossary.test for it using the "automated test generator":#usage.tools.generate-test. This tool allows us to implement our specification in either rSpec, xUnit, or our very own format.
|
392
|
+
|
393
|
+
Each format represents a different software development methodology:
|
394
|
+
* rSpec represents "BDD":#glossary.BDD
|
395
|
+
* xUnit represents "TDD":#glossary.TDD
|
396
|
+
* our own format can represent another methodology
|
397
|
+
|
398
|
+
Both rSpec and xUnit are presented in this tutorial.
|
399
|
+
|
400
|
+
Once we have decided how we want to implement our specification, we can proceed to generate a test for our design. <xref #fig..generate-test.rspec> and <xref #fig..generate-test.unit-test> illustrate this process.
|
401
|
+
|
402
|
+
<% example "Generating a test with specification in rSpec format", "#fig..generate-test.rspec" do %>
|
403
|
+
<pre>
|
404
|
+
$ generate_test.rb counter.v --rspec --name rspec
|
405
|
+
|
406
|
+
module counter
|
407
|
+
create counter_rspec_runner.rake
|
408
|
+
create counter_rspec_bench.v
|
409
|
+
create counter_rspec_bench.rb
|
410
|
+
create counter_rspec_design.rb
|
411
|
+
create counter_rspec_proto.rb
|
412
|
+
create counter_rspec_spec.rb
|
413
|
+
</pre>
|
414
|
+
<% end %>
|
415
|
+
|
416
|
+
<% example "Generating a test with specification in xUnit format", "#fig..generate-test.unit-test" do %>
|
417
|
+
<pre>
|
418
|
+
$ generate_test.rb counter.v --xunit --name xunit
|
419
|
+
|
420
|
+
module counter
|
421
|
+
create counter_xunit_runner.rake
|
422
|
+
create counter_xunit_bench.v
|
423
|
+
create counter_xunit_bench.rb
|
424
|
+
create counter_xunit_design.rb
|
425
|
+
create counter_xunit_proto.rb
|
426
|
+
create counter_xunit_spec.rb
|
427
|
+
</pre>
|
428
|
+
<% end %>
|
429
|
+
|
430
|
+
|
431
|
+
h3(#usage.tutorial.specification). Specify your expectations
|
432
|
+
|
433
|
+
So far, the test generation tool has created a basic foundation for our "test":#glossary.test. Now we must build upon this foundation by identifying our "expectation":#glossary.expectation of the "design":#glossary.design. That is, how do we expect the design to _behave_ under certain conditions?
|
434
|
+
|
435
|
+
Here are some reasonable expectations for our simple counter:
|
436
|
+
* A resetted counter's value should be zero.
|
437
|
+
* A resetted counter's value should increment by one count upon each rising clock edge.
|
438
|
+
* A counter with the maximum value should overflow upon increment.
|
439
|
+
|
440
|
+
Now that we have identified a set of expectations for our design, we are ready to implement them in our specification. <xref #fig..counter_rspec_spec.rb> and <xref #fig..counter_xunit_spec.rb> illustrate this process. Note the striking similarities between our expectations and their implementation.
|
441
|
+
|
442
|
+
|
443
|
+
<% example "Specification implemented in rSpec format", "#fig..counter_rspec_spec.rb" do %>
|
444
|
+
<code><%= File.read '../samp/counter/counter_rspec_spec.rb' %></code>
|
445
|
+
<% end %>
|
446
|
+
|
447
|
+
<% example "Specification implemented in xUnit format", "#fig..counter_xunit_spec.rb" do %>
|
448
|
+
<code><%= File.read '../samp/counter/counter_xunit_spec.rb' %></code>
|
449
|
+
<% end %>
|
450
|
+
|
451
|
+
<% important "Before we continue..." do %>
|
452
|
+
# Replace the contents of the file named <tt>counter_rspec_spec.rb</tt> with the source code shown in <xref #fig..counter_rspec_spec.rb>.
|
453
|
+
# Replace the contents of the file named <tt>counter_xunit_spec.rb</tt> with the source code shown in <xref #fig..counter_xunit_spec.rb>.
|
454
|
+
# Replace the contents of the files named <tt>counter_rspec_design.rb</tt> and <tt>counter_xunit_design.rb</tt> with the following code. This code defines the reset! method which resets our Verilog design. <code>
|
455
|
+
def Counter.reset!
|
456
|
+
reset.intVal = 1
|
457
|
+
|
458
|
+
# simulate one clock cycle
|
459
|
+
relay_verilog
|
460
|
+
|
461
|
+
reset.intVal = 0
|
462
|
+
end
|
463
|
+
</code>
|
464
|
+
<% end %>
|
465
|
+
|
466
|
+
|
467
|
+
h3(#usage.tutorial.implement-proto). Implement the prototype
|
468
|
+
|
469
|
+
|
470
|
+
Now that we have a "specification":#glossary.specification against which to verify our "design":#glossary.design, let us build a prototype of our design. By doing so, we exercise our specification, experience potential problems that may arise when we later implement our design in Verilog, and gain confidence in our work. <xref #fig..counter_proto.rb> shows the completed prototype for our design.
|
471
|
+
|
472
|
+
|
473
|
+
<% example "Ruby prototype of our Verilog design", "#fig..counter_proto.rb" do %>
|
474
|
+
<code>
|
475
|
+
def Counter.simulate!
|
476
|
+
if reset.intVal == 1
|
477
|
+
count.intVal = 0
|
478
|
+
else
|
479
|
+
count.intVal += 1
|
480
|
+
end
|
481
|
+
end
|
482
|
+
</code>
|
483
|
+
<% end %>
|
484
|
+
|
485
|
+
<% important "Before we continue..." do %>
|
486
|
+
Replace the contents of the files named <tt>counter_rspec_proto.rb</tt> and <tt>counter_xunit_proto.rb</tt> with the source code shown in <xref #fig..counter_proto.rb>
|
487
|
+
<% end %>
|
488
|
+
|
489
|
+
|
490
|
+
h3(#usage.tutorial.test-proto). Verify the prototype
|
491
|
+
|
492
|
+
Now that we have implemented our prototype, we are ready to verify it against our "specification":#glossary.specification by running the "test":#glossary.test. <xref #fig..test-proto.rspec> and <xref #fig..test-proto.unit-test> illustrate this process.
|
493
|
+
|
494
|
+
<% tip "Reuse your specification." do %>
|
495
|
+
The _same_ specification can be used to verify both prototype and design.
|
496
|
+
<% end %>
|
497
|
+
|
498
|
+
Here, the @PROTOTYPE@ environment variable is assigned a non-empty value while running the test, so that, instead of our design, our prototype is verified against our specification. You can also assign a value to @PROTOTYPE@ before running the test, by using your shell's *export* or *setenv* command. Finally, the Icarus Verilog simulator, denoted by _cver_, is used to run the simulation.
|
499
|
+
|
500
|
+
<% tip "What can the test runner do?" do %>
|
501
|
+
If you invoke the test runner (1) without any arguments or (2) with the <tt>-T</tt> option, it will show you a list of tasks that it can perform for you.
|
502
|
+
<% end %>
|
503
|
+
|
504
|
+
<% example "Running a test with specification in rSpec format", "#fig..test-proto.rspec" do %>
|
505
|
+
<pre>
|
506
|
+
$ rake -f counter_rspec_runner.rake cver PROTOTYPE=1
|
507
|
+
|
508
|
+
Ruby-VPI: prototype has been enabled for test "counter_rspec"
|
509
|
+
|
510
|
+
A resetted counter's value
|
511
|
+
- should be zero
|
512
|
+
- should increment by one count upon each rising clock edge
|
513
|
+
|
514
|
+
A counter with the maximum value
|
515
|
+
- should overflow upon increment
|
516
|
+
|
517
|
+
Finished in 0.018199 seconds
|
518
|
+
|
519
|
+
3 specifications, 0 failures
|
520
|
+
</pre>
|
521
|
+
<% end %>
|
522
|
+
|
523
|
+
<% example "Running a test with specification in xUnit format", "#fig..test-proto.unit-test" do %>
|
524
|
+
<pre>
|
525
|
+
$ rake -f counter_xunit_runner.rake cver PROTOTYPE=1
|
526
|
+
|
527
|
+
Ruby-VPI: prototype has been enabled for test "counter_xunit"
|
528
|
+
|
529
|
+
Loaded suite counter_xunit_bench
|
530
|
+
Started
|
531
|
+
...
|
532
|
+
Finished in 0.040668 seconds.
|
533
|
+
|
534
|
+
3 tests, 35 assertions, 0 failures, 0 errors
|
535
|
+
</pre>
|
536
|
+
<% end %>
|
537
|
+
|
538
|
+
|
539
|
+
h3(#usage.tutorial.implement-design). Implement the design
|
540
|
+
|
541
|
+
Now that we have implemented and verified our prototype, we are ready to implement our "design":#glossary.design. This is often quite simple because we translate _existing_ code from Ruby (our prototype) into Verilog (our design). <xref #fig..counter.v_impl> illustrates the result of this process. Once again, note the striking similarities between the implementation of our prototype and design.
|
542
|
+
|
543
|
+
|
544
|
+
<% example "Implementation of a simple up-counter with synchronous reset", "#fig..counter.v_impl" do %>
|
545
|
+
<code lang="verilog"><%= File.read '../samp/counter/counter.v' %></code>
|
546
|
+
<% end %>
|
547
|
+
|
548
|
+
<% important "Before we continue..." do %>
|
549
|
+
Replace the contents of the file named <tt>counter.v</tt> with the source code shown in <xref #fig..counter.v_impl>
|
550
|
+
<% end %>
|
551
|
+
|
552
|
+
|
553
|
+
h3(#usage.tutorial.test-design). Verify the design
|
554
|
+
|
555
|
+
Now that we have implemented our "design":#glossary.design, we are ready to verify it against our "specification":#glossary.specification by running the "test":#glossary.test. <xref #fig..test-design.rspec> and <xref #fig..test-design.unit-test> illustrate this process.
|
556
|
+
|
557
|
+
Here, the @PROTOTYPE@ environment variable is _not_ specified while running the test, so that our design, instead of our prototype, is verified against our specification. You can also achieve this effect by assigning an empty value to @PROTOTYPE@, or by using your shell's *unset* command. Finally, the GPL Cver Verilog simulator, denoted by _cver_, is used to run the simulation.
|
558
|
+
|
559
|
+
<% tip "Running multiple tests at once." do %>
|
560
|
+
Create a file named <tt>Rakefile</tt> containing the following line.
|
561
|
+
|
562
|
+
bq. @require 'ruby-vpi/runner_proxy'@
|
563
|
+
|
564
|
+
Now you can invoke all test runners in the current directory simply by executing <pre>rake cver</pre> (where _cver_ denotes the GPL Cver simulator).
|
565
|
+
<% end %>
|
566
|
+
|
567
|
+
<% example "Running a test with specification in rSpec format", "#fig..test-design.rspec" do %>
|
568
|
+
<pre>
|
569
|
+
$ rake -f counter_rspec_runner.rake cver
|
570
|
+
|
571
|
+
A resetted counter's value
|
572
|
+
- should be zero
|
573
|
+
- should increment by one count upon each rising clock edge
|
574
|
+
|
575
|
+
A counter with the maximum value
|
576
|
+
- should overflow upon increment
|
577
|
+
|
578
|
+
Finished in 0.005628 seconds
|
579
|
+
|
580
|
+
3 specifications, 0 failures
|
581
|
+
</pre>
|
582
|
+
<% end %>
|
583
|
+
|
584
|
+
<% example "Running a test with specification in xUnit format", "#fig..test-design.unit-test" do %>
|
585
|
+
<pre>
|
586
|
+
$ rake -f counter_xunit_runner.rake cver
|
587
|
+
|
588
|
+
Loaded suite counter_xunit_bench
|
589
|
+
Started
|
590
|
+
...
|
591
|
+
Finished in 0.006766 seconds.
|
592
|
+
|
593
|
+
3 tests, 35 assertions, 0 failures, 0 errors
|
594
|
+
</pre>
|
595
|
+
<% end %>
|
596
|
+
|
597
|
+
|
598
|
+
h2(#usage.examples). Examples
|
599
|
+
|
600
|
+
The <tt>samp</tt> directory contains several example tests which illustrate how Ruby-VPI can be used. Each example has an associated <tt>Rakefile</tt> which simplifies the process of running it. Therefore, simply navigate into an example directory and run the <pre>rake</pre> command to get started.
|
601
|
+
|
602
|
+
Also, some example specifications make use of BDD through the rSpec library. See <xref #background.methodology> for a discussion of rSpec.
|
603
|
+
|
604
|
+
|
605
|
+
h1(#hacking). Hacking
|
606
|
+
|
607
|
+
h2(#hacking.release-packages). Building release packages
|
608
|
+
|
609
|
+
In addition to the "normal requirements":./doc/usage.requirements.html, you need the following software to build release packages:
|
610
|
+
|
611
|
+
* "SWIG":http://www.swig.org/
|
612
|
+
* "RedCloth":http://rubyforge.org/projects/redcloth/
|
613
|
+
* "CodeRay":http://rubyforge.org/projects/coderay/
|
614
|
+
|
615
|
+
Once you have satisfied these requirements, you can run <pre>rake release</pre> to build the release packages. Also, see the output of <pre>rake -T</pre> for more build options.
|
616
|
+
|
617
|
+
|
618
|
+
h1(#problems). Known problems
|
619
|
+
|
620
|
+
This chapter presents known problems and possible solutions. In addition, previously solved problems have been retained for historical reference.
|
621
|
+
|
622
|
+
|
623
|
+
h2(#problems.ruby). Ruby
|
624
|
+
|
625
|
+
|
626
|
+
h3(#problems.ruby.SystemStackError). SystemStackError
|
627
|
+
|
628
|
+
<%= @fixed_in_2_0_0 %>
|
629
|
+
|
630
|
+
If a "stack level too deep (SystemStackError)" error occurs during the simulation, then increase the system-resource limit for stack-size by running the <pre>ulimit -s unlimited</pre> command before starting the simulation.
|
631
|
+
|
632
|
+
|
633
|
+
h3(#problems.ruby.xUnit). test/unit
|
634
|
+
|
635
|
+
<%= @fixed_in_2_0_0 %>
|
636
|
+
|
637
|
+
If your specification employs Ruby's unit testing framework, then you will encounter an error saying "[BUG] cross-thread violation on rb_gc()".
|
638
|
+
|
639
|
+
|
640
|
+
h2(#problem.ivl). Icarus Verilog
|
641
|
+
|
642
|
+
|
643
|
+
h3(#problems.ivl.vpi_handle_by_name). Vpi::vpi_handle_by_name
|
644
|
+
|
645
|
+
|
646
|
+
h4(#problems.ivl.vpi_handle_by_name.absolute-paths). Give full paths to Verilog objects
|
647
|
+
|
648
|
+
In version 0.8 and snapshot 20061009 of Icarus Verilog, the @vpi_handle_by_name@ function requires an _absolute_ path (including the name of the bench which instantiates the design) to a Verilog object. In addition, @vpi_handle_by_name@ is unable to retrieve the handle for a module parameter.
|
649
|
+
|
650
|
+
For example, consider <xref #ex..TestFoo> Here, one needs to specify @TestFoo.my_foo.clk@ instead of @my_foo.clk@ in order to access the clk input of the my_foo module instance.
|
651
|
+
|
652
|
+
<% example "Part of a bench which instantiates a Verilog design", "#ex..TestFoo" do %>
|
653
|
+
<code lang="verilog">
|
654
|
+
module TestFoo;
|
655
|
+
reg clk_reg;
|
656
|
+
Foo my_foo(.clk(clk_reg));
|
657
|
+
endmodule
|
658
|
+
</code>
|
659
|
+
<% end %>
|
660
|
+
|
661
|
+
h4(#problems.ivl.vpi_handle_by_name.connect-registers). Registers must be connected
|
662
|
+
|
663
|
+
In version 0.8 of Icarus Verilog, if you want to access a register in a design, then it must be connected to something (either assigned to a wire or passed as a parameter to a module instantiation). Otherwise, you will get a @nil@ value as the result of @vpi_handle_by_name@ method.
|
664
|
+
|
665
|
+
For example, suppose you wanted to access the @clk_reg@ register, from the bench shown in <xref #ex..TestFoo_bad> If you execute the statement @clk_reg = vpi_handle_by_name("TestFoo.clk_reg", nil)@ in a specification, then you will discover that the @vpi_handle_by_name@ method returns @nil@ instead of a handle to the @clk_reg@ register.
|
666
|
+
|
667
|
+
The solution is to change the design such that it appears like the one shown in <xref #ex..TestFoo_fix> where the register is connected to a wire, or <xref #ex..TestFoo> where the register is connected to a module instantiation.
|
668
|
+
|
669
|
+
<% example "Bad design with unconnected registers", "#ex..TestFoo_bad" do %>
|
670
|
+
<code lang="verilog">
|
671
|
+
module TestFoo;
|
672
|
+
reg clk_reg;
|
673
|
+
endmodule
|
674
|
+
</code>
|
675
|
+
|
676
|
+
Here the @clk_reg@ register is not connected to anything.
|
677
|
+
<% end %>
|
678
|
+
|
679
|
+
<% example "Fixed design with wired registers", "#ex..TestFoo_fix" do %>
|
680
|
+
<code lang="verilog">
|
681
|
+
module TestFoo;
|
682
|
+
reg clk_reg;
|
683
|
+
wire clk_wire;
|
684
|
+
assign clk_wire = clk_reg;
|
685
|
+
endmodule
|
686
|
+
</code>
|
687
|
+
|
688
|
+
Here the @clk_reg@ register is connected to the @clk_wire@ wire.
|
689
|
+
<% end %>
|
690
|
+
|
691
|
+
|
692
|
+
h3(#problems.ivl.vpi_reset). Vpi::reset
|
693
|
+
|
694
|
+
<div class="caution">The @vpi_control@ method was removed in release 3.0.0 (2006-04-23). Please use @Vpi::vpi_control(VpiReset)@ instead.</div>
|
695
|
+
|
696
|
+
In version 0.8 of Icarus Verilog, the @vpi_control(vpiReset)@ VPI function causes an assertion to fail inside the simulator. As a result, the simulation terminates and a core dump is produced.
|
697
|
+
|
698
|
+
|
699
|
+
h2(#problems.vsim). Mentor Modelsim
|
700
|
+
|
701
|
+
|
702
|
+
h3(#problems.vsim.ruby_run). ruby_run();
|
703
|
+
|
704
|
+
<%= @fixed_in_2_0_0 %>
|
705
|
+
|
706
|
+
Version 6.1b of Mentor Modelsim doesn't play nicely with either an embedded Ruby interpreter or POSIX threads in a PLI application. When Ruby-VPI invokes the ruby_run function (which starts the Ruby interpreter), the simulator terminates immediately with an exit status of 0.
|
707
|
+
|
708
|
+
|
709
|
+
h1(#glossary). Glossary
|
710
|
+
|
711
|
+
|
712
|
+
h2(#glossary.bench). Bench
|
713
|
+
|
714
|
+
An environment in which a "design":#glossary.design is verified against a "specification":#glossary.specification. Often, it is used to emulate conditions in which the design will be eventually deployed.
|
715
|
+
|
716
|
+
|
717
|
+
h2(#glossary.BDD). BDD
|
718
|
+
|
719
|
+
Behavior driven development.
|
720
|
+
|
721
|
+
A software development methodology which emphasizes thinking in terms of behavior when designing, implementing, and verifying software. See the "official wiki":http://behaviour-driven.org/ for more information.
|
722
|
+
|
723
|
+
|
724
|
+
h2(#glossary.design). Design
|
725
|
+
|
726
|
+
An idea or entity that is verified against a "specification":#glossary.specification in order to ensure correctness or soundness of its being. In other words, it is the thing being checked: does it work or not?
|
727
|
+
|
728
|
+
|
729
|
+
h2(#glossary.expectation). Expectation
|
730
|
+
|
731
|
+
The desired response to some stimulus.
|
732
|
+
|
733
|
+
|
734
|
+
h2(#glossary.handle). Handle
|
735
|
+
|
736
|
+
An object in a Verilog simulation. For example, a handle can represent a wire, register, module, if-statement, expression, and so on.
|
737
|
+
|
738
|
+
|
739
|
+
h2(#glossary.rake). Rake
|
740
|
+
|
741
|
+
bq. Rake is a build tool, written in Ruby, using Ruby as a build language. Rake is similar to make in scope and purpose. -- "Rake documentation":http://docs.rubyrake.org
|
742
|
+
|
743
|
+
See the "Rake website":http://rake.rubyforge.org for more information.
|
744
|
+
|
745
|
+
|
746
|
+
h2(#glossary.rspec). rSpec
|
747
|
+
|
748
|
+
Ruby framework for BDD. See the "rSpec website":http://rspec.rubyforge.org and "tutorial":http://rspec.rubyforge.org/tutorials/index.html for more information.
|
749
|
+
|
750
|
+
|
751
|
+
h2(#glossary.specification). Specification
|
752
|
+
|
753
|
+
A set of "expectation":#glossary.expectations which define the desired behavior of a "design":#glossary.design when it is subjected to certain conditions.
|
754
|
+
|
755
|
+
|
756
|
+
h2(#glossary.TDD). TDD
|
757
|
+
|
758
|
+
Test Driven Development.
|
759
|
+
|
760
|
+
|
761
|
+
h2(#glossary.test). Test
|
762
|
+
|
763
|
+
Something that checks if a "design":#glossary.design satisfies a "specification":#glossary.specification.
|
764
|
+
|
765
|
+
|
766
|
+
h2(#glossary.test_bench). Test bench
|
767
|
+
|
768
|
+
An allusion to "a bench in an electronics laboratory":#background.vocab, or so it seems.
|