illustrate this process.
<% example "Running a test with specification in rSpec format", "#fig..test-design.rspec" do %>
$ rake -f counter_rspec_runner.rake cver
A resetted counter's value
- should be zero
- should increment by one count upon each rising clock edge
A counter with the maximum value
- should overflow upon increment
Finished in 0.005628 seconds
3 specifications, 0 failures
<% end %>
<% example "Running a test with specification in xUnit format", "#fig..test-design.unit-test" do %>
$ rake -f counter_xunit_runner.rake cver
Loaded suite counter_xunit_bench
Started
...
Finished in 0.006766 seconds.
3 tests, 35 assertions, 0 failures, 0 errors
<% end %>
In these examples, 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 simulator":#setup.reqs, denoted by _cver_, is used to run the simulation.
h2(#usage.test-runner). Test runner
A test runner is a file, generated by the "automated test generator":#usage.tools.generate-test, whose name ends with .rake. It helps you run generated tests -- you can think of it as a _makefile_ if you are familiar with C programming in a UNIX environment.
<% example "Seeing what a test runner can do" do %>
When you invoke a test runner without any arguments, it will show you a list of available tasks:
$ rake -f some_test_runner.rake
<%= `rake -f ../samp/counter/counter_rspec_runner.rake` %>
<% end %>
<% tip "Running multiple tests at once." do %>
Create a file named Rakefile containing the following line.
bq. @require 'ruby-vpi/runner_proxy'@
Now you can invoke all test runners in the current directory simply by executing rake cver
(where _cver_ denotes the "GPL Cver simulator":#setup.reqs).
<% end %>
h3(#usage.test-runner.env-vars). Environment variables
Test runners support the following _environment_ variables, which allow you to easily change the behavior of the test runner.
* @COVERAGE@ enables code coverage analysis and generation of code coverage reports.
* @DEBUG@ enables the "interactive debugger":#usage.debugger in its "post-mortem debugging mode":http://www.datanoise.com/articles/2006/12/20/post-mortem-debugging.
* @PROTOTYPE@ enables the Ruby prototype for the design under test.
To activate these variables, simply assign a non-empty value to them. For example, @DEBUG=1@ and @DEBUG=yes@ and @DEBUG=foo_bar_baz@ all activate the @DEBUG@ variable.
To deactivate these variables, simply assign an _empty_ value to them, *unset* them in your shell, or do not specify them as command-line arguments to rake. For example, both @DEBUG=@ dectivates the @DEBUG@ variable.
In addition, you can specify variable assignments as arguments to the *rake* command. For example, rake DEBUG=1
is equivalent to
$ DEBUG=1
$ export DEBUG
$ rake
in Bourne shell or
% setenv DEBUG 1
% rake
in C shell.
<% example "Running a test with environment variables" do %>
Here we enable the prototype and code coverage analysis:
rake -f some_test_runner.rake PROTOTYPE=1 COVERAGE=1
Here we _disable_ the prototype and enable the code coverage analysis. Note that both of these invocations are equivalent:
rake -f some_test_runner.rake PROTOTYPE= COVERAGE=1
rake -f some_test_runner.rake COVERAGE=1
<% end %>
h2(#usage.debugger). Interactive debugger
The "ruby-debug project":http://www.datanoise.com/articles/category/ruby-debug serves as the interactive debugger for Ruby-VPI.
# Enable the debugger by activating the @DEBUG@ environment variable (see for details).
# Put the @debugger@ command in your code -- anywhere you wish to activate an interactive debugging session. These commands are automatically ignored when the debugger is disabled; so you can safely leave them in your code, if you wish.
h3(#usage.debugger.init). Advanced initialization
By default, Ruby-VPI enables the debugger by invoking the @Debugger.start@ method. If you wish to perform more advanced initialization, such as having the debugger accept remote network connections for interfacing with a remote debugging session or perhaps with an IDE (see "the ruby-debug documentation":http://www.datanoise.com/articles/category/ruby-debug for details), then:
# Deactivate the @DEBUG@ environment variable.
# Put your own code, which initializes the debugger, above the @RubyVpi.init_bench@ line in your generated spec.rb file.
h2(#usage.examples). Sample tests
The samp directory contains several sample tests which illustrate how Ruby-VPI can be used. Each sample has an associated Rakefile which simplifies the process of running it. Therefore, simply navigate into an example directory and run the rake
command to get started.
h1(#hacking). Hacking
h2(#hacking.release-packages). Building release packages
In addition to the "normal requirements":#setup.reqs, you need the following software to build release packages:
* "SWIG":http://www.swig.org/
* "RedCloth":http://rubyforge.org/projects/redcloth/
* "CodeRay":http://rubyforge.org/projects/coderay/
Once you have satisfied these requirements, you can run rake release
to build the release packages. Also, see the output of rake -T
for more build options.
h1(#problems). Known problems
This chapter presents known problems and possible solutions. In addition, previously solved problems have been retained for historical reference.
h2(#problems.ruby). Ruby
h3(#problems.ruby.SystemStackError). SystemStackError
<% note "Fixed in 2.0.0." do %>
This problem was fixed in release 2.0.0 (2006-04-17).
<% end %>
If a "stack level too deep (SystemStackError)" error occurs during the simulation, then increase the system-resource limit for stack-size by running the ulimit -s unlimited
command before starting the simulation.
h3(#problems.ruby.xUnit). test/unit
<% note "Fixed in 2.0.0." do %>
This problem was fixed in release 2.0.0 (2006-04-17).
<% end %>
If your specification employs Ruby's unit testing framework, then you will encounter an error saying "[BUG] cross-thread violation on rb_gc()".
h2(#problem.ivl). Icarus Verilog
h3(#problems.ivl.vpi_handle_by_name). Vpi::vpi_handle_by_name
h4(#problems.ivl.vpi_handle_by_name.absolute-paths). Give full paths to Verilog objects
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@ always returns @nil@ when its second parameter is specified.
For example, consider . Here, one must write @vpi_handle_by_name("TestFoo.my_foo.clk", nil)@ instead of @vpi_handle_by_name("my_foo.clk", TestFoo)@ in order to access the @clk@ input of the @my_foo@ module instance.
<% example "Part of a bench which instantiates a Verilog design", "#ex..TestFoo" do %>
module TestFoo;
reg clk_reg;
Foo my_foo(.clk(clk_reg));
endmodule
<% end %>
h4(#problems.ivl.vpi_handle_by_name.connect-registers). Registers must be connected
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.
For example, suppose you wanted to access the @clk_reg@ register, from the bench shown in 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.
The solution is to change the design such that it appears like the one shown in where the register is connected to a wire, or where the register is connected to a module instantiation.
<% example "Bad design with unconnected registers", "#ex..TestFoo_bad" do %>
module TestFoo;
reg clk_reg;
endmodule
Here the @clk_reg@ register is not connected to anything.
<% end %>
<% example "Fixed design with wired registers", "#ex..TestFoo_fix" do %>
module TestFoo;
reg clk_reg;
wire clk_wire;
assign clk_wire = clk_reg;
endmodule
Here the @clk_reg@ register is connected to the @clk_wire@ wire.
<% end %>
h3(#problems.ivl.vpi_reset). Vpi::reset
The @vpi_control@ method was removed in release 3.0.0 (2006-04-23). Please use @Vpi::vpi_control(VpiReset)@ instead.
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.
h2(#problems.vsim). Mentor Modelsim
h3(#problems.vsim.ruby_run). ruby_run();
<% note "Fixed in 2.0.0." do %>
This problem was fixed in release 2.0.0 (2006-04-17).
<% end %>
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.
h1(#glossary). Glossary
h2(#glossary.bench). Bench
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.
h2(#glossary.BDD). Behavior driven development (BDD)
An "agile software development methodology":http://agilemanifesto.org/ which emphasizes thinking in terms of behavior when designing, implementing, and verifying software.
See the "official wiki":http://behaviour-driven.org/ for more information.
h2(#glossary.design). Design
A Verilog module 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?
h2(#glossary.expectation). Expectation
The desired response to some stimulus.
h2(#glossary.handle). Handle
A reference to an object inside the Verilog simulation that was obtained through the @vpi_handle_by_name@ function.
h2(#glossary.rake). Rake
bq. Rake is a build tool, written in Ruby, using Ruby as a build language. Rake is similar to *make* in scope and purpose.
bq>. --"Rake documentation":http://docs.rubyrake.org
h2(#glossary.rspec). rSpec
The "BDD":#glossary.BDD framework for Ruby.
See the "rSpec website":http://rspec.rubyforge.org and "tutorial":http://rspec.rubyforge.org/tutorials/index.html for more information.
h2(#glossary.specification). Specification
A set of "expectations":#glossary.expectations which define the desired behavior of a "design":#glossary.design when it is subjected to certain stimulus.
h2(#glossary.TDD). Test driven development (TDD)
An "agile software development methodology":http://agilemanifesto.org/ which emphasizes (1) testing functionality before implementing it and (2) refactoring.
See "this introductory article":http://www.agiledata.org/essays/tdd.html for more information.
h2(#glossary.test). Test
Something that checks if a "design":#glossary.design satisfies a "specification":#glossary.specification.
h2(#glossary.test_bench). Test bench
An allusion to "a bench in an electronics laboratory":#background.vocab, or so it seems.