.
<% example "Running a test with specification in rSpec format", "#fig..test-proto.rspec" do %>
$ rake -f counter_rspec_runner.rake cver PROTOTYPE=1
Ruby-VPI: prototype has been enabled for test "counter_rspec"
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.018199 seconds
3 specifications, 0 failures
<% end %>
<% example "Running a test with specification in xUnit format", "#fig..test-proto.unit-test" do %>
$ rake -f counter_xunit_runner.rake cver PROTOTYPE=1
Ruby-VPI: prototype has been enabled for test "counter_xunit"
Loaded suite counter_xunit_bench
Started
...
Finished in 0.040668 seconds.
3 tests, 35 assertions, 0 failures, 0 errors
<% end %>
In these examples, 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 "GPL Cver simulator":#setup.reqs, denoted by _cver_, is used to run the simulation.
<% tip "What can the test runner do?" do %>
If you invoke the test runner (1) without any arguments or (2) with the --tasks option, it will show you a list of tasks that it can perform for you.
<% end %>
h3(#usage.tutorial.implement-design). Implement the design
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). The result of this process is illustrated by .
<% example "Implementation of a simple up-counter with synchronous reset", "#fig..counter.v_impl" do %>
<%= File.read '../samp/counter/counter.v' %>
<% end %>
<% important "Before we continue..." do %>
Replace the contents of the file named counter.v with the source code shown in
<% end %>
h3(#usage.tutorial.test-design). Verify the design
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. and 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.
<% 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 %>
h2(#usage.examples). Examples
The samp directory contains several example tests which illustrate how Ruby-VPI can be used. Each example 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.