ruby-vpi 16.0.1 → 17.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +19 -19
- data/README +1 -1
- data/Rakefile +35 -32
- data/bin/convert.rb +28 -0
- data/bin/generate/design.rb +16 -0
- data/bin/generate/proto.rb +13 -0
- data/bin/generate/runner.rake +33 -0
- data/bin/generate/spec.rb +45 -0
- data/bin/generate.rb +177 -0
- data/bin/ruby-vpi +56 -0
- data/doc/Rakefile +20 -4
- data/doc/common.css +92 -33
- data/doc/common.inc +13 -0
- data/doc/common.tpl +42 -28
- data/doc/history.doc +11 -11
- data/doc/history.html +769 -248
- data/doc/history.inc +909 -0
- data/doc/history.rb +9 -0
- data/doc/history.yaml +69 -0
- data/doc/intro.inc +170 -178
- data/doc/lib/doc_format.rb +57 -144
- data/doc/lib/doc_proxy.rb +504 -88
- data/doc/lib/erb_content.rb +8 -8
- data/doc/lib/erb_proxy.rb +17 -17
- data/doc/manual.doc +626 -777
- data/doc/manual.html +1541 -1031
- data/doc/memo.doc +38 -36
- data/doc/memo.html +64 -28
- data/doc/readme.doc +4 -31
- data/doc/readme.html +221 -163
- data/doc/rss.erb +1 -1
- data/doc/rss.xml +73 -1761
- data/ext/Rakefile +6 -5
- data/ext/main.c +17 -15
- data/ext/relay.c +4 -7
- data/ext/relay.h +2 -2
- data/ext/swig_vpi.h +2 -2
- data/ext/swig_vpi.i +1 -2
- data/ext/swig_wrap.cin +12 -16
- data/ext/vlog.c +5 -5
- data/ext/vlog.h +2 -2
- data/lib/ruby-vpi/erb.rb +3 -3
- data/lib/ruby-vpi/float.rb +2 -2
- data/lib/ruby-vpi/rcov.rb +5 -7
- data/lib/ruby-vpi/runner.rb +43 -41
- data/lib/ruby-vpi/runner_boot_loader.rb +117 -0
- data/lib/ruby-vpi/runner_proxy.rb +6 -8
- data/lib/ruby-vpi/util.rb +10 -0
- data/lib/ruby-vpi/verilog_parser.rb +28 -56
- data/lib/ruby-vpi/vpi.rb +168 -123
- data/lib/ruby-vpi.rb +22 -143
- data/ref/c/annotated.html +1 -1
- data/ref/c/common_8h.html +1 -1
- data/ref/c/files.html +1 -1
- data/ref/c/functions.html +1 -1
- data/ref/c/functions_vars.html +1 -1
- data/ref/c/globals.html +1 -1
- data/ref/c/globals_0x63.html +1 -1
- data/ref/c/globals_0x65.html +1 -1
- data/ref/c/globals_0x66.html +1 -1
- data/ref/c/globals_0x6d.html +1 -1
- data/ref/c/globals_0x70.html +1 -1
- data/ref/c/globals_0x72.html +1 -1
- data/ref/c/globals_0x73.html +1 -1
- data/ref/c/globals_0x74.html +1 -1
- data/ref/c/globals_0x76.html +1 -1
- data/ref/c/globals_0x78.html +1 -1
- data/ref/c/globals_defs.html +1 -1
- data/ref/c/globals_defs_0x65.html +1 -1
- data/ref/c/globals_defs_0x70.html +1 -1
- data/ref/c/globals_defs_0x76.html +1 -1
- data/ref/c/globals_defs_0x78.html +1 -1
- data/ref/c/globals_enum.html +1 -1
- data/ref/c/globals_eval.html +1 -1
- data/ref/c/globals_func.html +1 -1
- data/ref/c/globals_type.html +1 -1
- data/ref/c/globals_vars.html +1 -1
- data/ref/c/index.html +1 -1
- data/ref/c/main_8c.html +1 -1
- data/ref/c/main_8h.html +1 -1
- data/ref/c/relay_8c.html +1 -1
- data/ref/c/relay_8h.html +1 -1
- data/ref/c/structt__cb__data.html +1 -1
- data/ref/c/structt__vpi__delay.html +1 -1
- data/ref/c/structt__vpi__error__info.html +1 -1
- data/ref/c/structt__vpi__strengthval.html +1 -1
- data/ref/c/structt__vpi__systf__data.html +1 -1
- data/ref/c/structt__vpi__time.html +1 -1
- data/ref/c/structt__vpi__value.html +1 -1
- data/ref/c/structt__vpi__vecval.html +1 -1
- data/ref/c/structt__vpi__vlog__info.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 +1 -1
- data/ref/ruby/classes/ERB.html +5 -5
- data/ref/ruby/classes/ERB.src/{M000024.html → M000026.html} +0 -0
- data/ref/ruby/classes/FileUtils.html +11 -11
- data/ref/ruby/classes/FileUtils.src/{M000025.html → M000027.html} +0 -0
- data/ref/ruby/classes/FileUtils.src/{M000026.html → M000028.html} +0 -0
- data/ref/ruby/classes/Float.html +6 -6
- data/ref/ruby/classes/Float.src/{M000020.html → M000021.html} +0 -0
- data/ref/ruby/classes/Integer.html +65 -65
- data/ref/ruby/classes/Integer.src/M000009.html +12 -5
- data/ref/ruby/classes/Integer.src/M000010.html +5 -5
- data/ref/ruby/classes/Integer.src/M000011.html +5 -5
- data/ref/ruby/classes/Integer.src/M000012.html +5 -5
- data/ref/ruby/classes/Integer.src/M000013.html +5 -5
- data/ref/ruby/classes/Integer.src/M000014.html +18 -0
- data/ref/ruby/classes/Integer.src/M000017.html +12 -18
- data/ref/ruby/classes/Integer.src/M000018.html +18 -12
- data/ref/ruby/classes/Integer.src/M000019.html +12 -17
- data/ref/ruby/classes/Integer.src/M000020.html +30 -0
- data/ref/ruby/classes/RDoc.html +5 -5
- data/ref/ruby/classes/RDoc.src/{M000053.html → M000058.html} +0 -0
- data/ref/ruby/classes/{RubyVpi/Config.html → RubyVPI.html} +20 -6
- data/ref/ruby/classes/String.html +34 -15
- data/ref/ruby/classes/String.src/M000022.html +5 -28
- data/ref/ruby/classes/String.src/M000023.html +5 -5
- data/ref/ruby/classes/String.src/{M000021.html → M000024.html} +0 -0
- data/ref/ruby/classes/String.src/M000025.html +41 -0
- data/ref/ruby/classes/VerilogParser/Module/Port.html +16 -36
- data/ref/ruby/classes/VerilogParser/Module/Port.src/M000006.html +10 -5
- data/ref/ruby/classes/VerilogParser/Module/Port.src/{M000004.html → M000007.html} +4 -4
- data/ref/ruby/classes/VerilogParser/Module/Port.src/{M000005.html → M000008.html} +4 -4
- data/ref/ruby/classes/VerilogParser/Module.html +28 -9
- data/ref/ruby/classes/VerilogParser/Module.src/M000005.html +29 -0
- data/ref/ruby/classes/VerilogParser.html +5 -39
- data/ref/ruby/classes/VerilogParser.src/M000004.html +26 -0
- data/ref/ruby/classes/Vpi/Handle.html +179 -77
- data/ref/ruby/classes/Vpi/Handle.src/M000035.html +18 -0
- data/ref/ruby/classes/Vpi/Handle.src/M000036.html +5 -5
- data/ref/ruby/classes/Vpi/Handle.src/M000037.html +5 -5
- data/ref/ruby/classes/Vpi/Handle.src/M000038.html +5 -5
- data/ref/ruby/classes/Vpi/Handle.src/M000039.html +5 -5
- data/ref/ruby/classes/Vpi/Handle.src/M000040.html +5 -8
- data/ref/ruby/classes/Vpi/Handle.src/M000041.html +5 -8
- data/ref/ruby/classes/Vpi/Handle.src/M000042.html +5 -9
- data/ref/ruby/classes/Vpi/Handle.src/M000043.html +8 -31
- data/ref/ruby/classes/Vpi/Handle.src/M000044.html +8 -74
- data/ref/ruby/classes/Vpi/Handle.src/M000045.html +9 -17
- data/ref/ruby/classes/Vpi/Handle.src/M000046.html +31 -11
- data/ref/ruby/classes/Vpi/Handle.src/M000047.html +86 -0
- data/ref/ruby/classes/Vpi/Handle.src/M000048.html +17 -18
- data/ref/ruby/classes/Vpi/Handle.src/M000050.html +18 -0
- data/ref/ruby/classes/Vpi/Handle.src/M000051.html +24 -0
- data/ref/ruby/classes/Vpi/Handle.src/M000053.html +31 -0
- data/ref/ruby/classes/Vpi/Handle.src/M000054.html +89 -0
- data/ref/ruby/classes/Vpi/S_vpi_time.html +16 -16
- data/ref/ruby/classes/Vpi/S_vpi_time.src/{M000050.html → M000055.html} +4 -4
- data/ref/ruby/classes/Vpi/S_vpi_time.src/{M000051.html → M000056.html} +5 -5
- data/ref/ruby/classes/Vpi/S_vpi_value.html +15 -15
- data/ref/ruby/classes/Vpi/S_vpi_value.src/{M000035.html → M000032.html} +5 -5
- data/ref/ruby/classes/Vpi/S_vpi_value.src/M000033.html +5 -5
- data/ref/ruby/classes/Vpi/S_vpi_value.src/M000034.html +5 -5
- data/ref/ruby/classes/Vpi.html +6 -42
- data/ref/ruby/classes/Vpi.src/M000029.html +15 -5
- data/ref/ruby/classes/Vpi.src/M000030.html +24 -24
- data/ref/ruby/classes/Vpi.src/M000031.html +6 -8
- data/ref/ruby/created.rid +1 -1
- data/ref/ruby/files/bin/{header_to_ruby_rb.html → convert_rb.html} +5 -5
- data/ref/ruby/files/bin/{generate_test_rb.html → generate_rb.html} +8 -21
- data/ref/ruby/files/lib/ruby-vpi/erb_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/float_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/integer_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/rake_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/rcov_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/rdoc_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/runner_boot_loader_rb.html +197 -0
- data/ref/ruby/files/lib/ruby-vpi/runner_boot_loader_rb.src/M000001.html +17 -0
- data/ref/ruby/files/lib/ruby-vpi/runner_boot_loader_rb.src/M000002.html +18 -0
- data/ref/ruby/files/lib/ruby-vpi/runner_proxy_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/runner_rb.html +6 -19
- data/ref/ruby/files/lib/ruby-vpi/util_rb.html +101 -0
- data/ref/ruby/files/lib/ruby-vpi/verilog_parser_rb.html +8 -1
- data/ref/ruby/files/lib/ruby-vpi/vpi_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi_rb.html +2 -14
- data/ref/ruby/fr_class_index.html +1 -3
- data/ref/ruby/fr_file_index.html +4 -2
- data/ref/ruby/fr_method_index.html +56 -51
- data/ref/ruby/index.html +1 -1
- data/samp/counter/RSpec/Rakefile +1 -0
- data/samp/counter/RSpec/counter_design.rb +15 -0
- data/samp/counter/RSpec/counter_proto.rb +10 -0
- data/samp/counter/RSpec/counter_runner.rake +44 -0
- data/samp/counter/RSpec/counter_spec.rb +39 -0
- data/samp/counter/Rakefile +1 -1
- data/samp/counter/counter.v +7 -7
- data/samp/counter/xUnit/Rakefile +1 -0
- data/samp/counter/xUnit/counter_bench.rb +95 -0
- data/samp/counter/{counter_xunit_bench.v → xUnit/counter_bench.v} +0 -0
- data/samp/counter/xUnit/counter_design.rb +15 -0
- data/samp/counter/xUnit/counter_proto.rb +10 -0
- data/samp/counter/xUnit/counter_runner.rake +44 -0
- data/samp/counter/{counter_xunit_spec.rb → xUnit/counter_spec.rb} +9 -9
- data/samp/pipelined_alu/Rakefile +1 -1
- data/samp/pipelined_alu/TestHw5UnitModel.rb +4 -5
- data/samp/pipelined_alu/hw5_unit.v +55 -85
- data/samp/pipelined_alu/hw5_unit_design.rb +51 -0
- data/samp/pipelined_alu/hw5_unit_proto.rb +4 -0
- data/samp/pipelined_alu/hw5_unit_runner.rake +43 -0
- data/samp/pipelined_alu/hw5_unit_spec.rb +64 -0
- data/samp/register_file/LICENSE +20 -0
- data/samp/register_file/README +4 -0
- data/samp/register_file/Rakefile +1 -0
- data/samp/register_file/register_file.v +18 -0
- data/samp/register_file/register_file_design.rb +11 -0
- data/samp/register_file/register_file_proto.rb +11 -0
- data/samp/register_file/register_file_runner.rake +43 -0
- data/samp/register_file/register_file_spec.rb +58 -0
- metadata +78 -66
- data/bin/generate_test.rb +0 -200
- data/bin/generate_test_tpl/bench.rb +0 -89
- data/bin/generate_test_tpl/bench.v +0 -26
- data/bin/generate_test_tpl/design.rb +0 -11
- data/bin/generate_test_tpl/proto.rb +0 -16
- data/bin/generate_test_tpl/runner.rake +0 -42
- data/bin/generate_test_tpl/spec.rb +0 -37
- data/bin/header_to_ruby.rb +0 -27
- data/ref/ruby/classes/Integer.src/M000008.html +0 -25
- data/ref/ruby/classes/Integer.src/M000016.html +0 -25
- data/ref/ruby/classes/RubyVpi.html +0 -199
- data/ref/ruby/classes/RubyVpi.src/M000027.html +0 -121
- data/ref/ruby/classes/VerilogParser/Module/Parameter.html +0 -160
- data/ref/ruby/classes/VerilogParser/Module/Parameter.src/M000007.html +0 -19
- data/ref/ruby/classes/VerilogParser/Module/Port.src/M000003.html +0 -21
- data/ref/ruby/classes/VerilogParser/Module.src/M000002.html +0 -34
- data/ref/ruby/classes/VerilogParser.src/M000001.html +0 -34
- data/ref/ruby/classes/Vpi/Handle.src/M000049.html +0 -69
- data/ref/ruby/classes/Vpi.src/M000028.html +0 -28
- data/ref/ruby/classes/Vpi.src/M000032.html +0 -22
- data/samp/counter/counter_rspec_bench.rb +0 -86
- data/samp/counter/counter_rspec_bench.v +0 -9
- data/samp/counter/counter_rspec_design.rb +0 -8
- data/samp/counter/counter_rspec_proto.rb +0 -13
- data/samp/counter/counter_rspec_runner.rake +0 -52
- data/samp/counter/counter_rspec_spec.rb +0 -39
- data/samp/counter/counter_xunit_bench.rb +0 -86
- data/samp/counter/counter_xunit_design.rb +0 -8
- data/samp/counter/counter_xunit_proto.rb +0 -13
- data/samp/counter/counter_xunit_runner.rake +0 -52
- data/samp/pipelined_alu/hw5_unit_test_bench.rb +0 -86
- data/samp/pipelined_alu/hw5_unit_test_bench.v +0 -14
- data/samp/pipelined_alu/hw5_unit_test_design.rb +0 -61
- data/samp/pipelined_alu/hw5_unit_test_proto.rb +0 -7
- data/samp/pipelined_alu/hw5_unit_test_runner.rake +0 -52
- data/samp/pipelined_alu/hw5_unit_test_spec.rb +0 -68
@@ -0,0 +1,44 @@
|
|
1
|
+
# Array of paths and shell globs (see the Dir.glob method's documentation for
|
2
|
+
# details) to source files and directories that contain source files. These
|
3
|
+
# source files will be loaded by the simulator before the simulation begins.
|
4
|
+
SIMULATOR_SOURCES = FileList[
|
5
|
+
'counter.v',
|
6
|
+
'..'
|
7
|
+
]
|
8
|
+
|
9
|
+
# Command-line arguments for the simulator. These arguments can be
|
10
|
+
# specified as a string or an array of strings, as demonstrated below:
|
11
|
+
#
|
12
|
+
# :cver => "this is a single string argument",
|
13
|
+
# :cver => ["these", "are", "separate", "arguments"],
|
14
|
+
# :cver => %w[these are also separate arguments],
|
15
|
+
#
|
16
|
+
SIMULATOR_ARGUMENTS = {
|
17
|
+
# GPL Cver
|
18
|
+
:cver => "",
|
19
|
+
|
20
|
+
# Icarus Verilog
|
21
|
+
:ivl => "",
|
22
|
+
|
23
|
+
# Synopsys VCS
|
24
|
+
:vcs => "",
|
25
|
+
|
26
|
+
# Mentor Modelsim
|
27
|
+
:vsim => "",
|
28
|
+
|
29
|
+
# Cadence NC-Sim
|
30
|
+
:ncsim => "",
|
31
|
+
|
32
|
+
}
|
33
|
+
|
34
|
+
# This task is invoked before the simulator runs. It
|
35
|
+
# can be used to make preprations, such as converting
|
36
|
+
# Verilog header files into Ruby, for the simulation.
|
37
|
+
task :setup do
|
38
|
+
# To learn how to write Rake tasks, please see:
|
39
|
+
# http://docs.rubyrake.org/read/chapter/4#page16
|
40
|
+
end
|
41
|
+
|
42
|
+
# This command loads the Ruby-VPI runner template,
|
43
|
+
# which runs the simulator using the above parameters.
|
44
|
+
require 'ruby-vpi/runner'
|
@@ -1,7 +1,7 @@
|
|
1
|
-
|
1
|
+
require 'test/unit'
|
2
2
|
|
3
3
|
# lowest upper bound of counter's value
|
4
|
-
LIMIT = 2 ** Counter
|
4
|
+
LIMIT = 2 ** Counter::Size
|
5
5
|
|
6
6
|
# maximum allowed value for a counter
|
7
7
|
MAX = LIMIT - 1
|
@@ -12,13 +12,13 @@ class ResettedCounterValue < Test::Unit::TestCase
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def test_zero
|
15
|
-
assert_equal 0, Counter.count.intVal
|
15
|
+
assert_equal( 0, Counter.count.intVal )
|
16
16
|
end
|
17
17
|
|
18
18
|
def test_increment
|
19
19
|
LIMIT.times do |i|
|
20
|
-
assert_equal i, Counter.count.intVal
|
21
|
-
|
20
|
+
assert_equal( i, Counter.count.intVal )
|
21
|
+
Counter.cycle! # increment the counter
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -28,12 +28,12 @@ class MaximumCounterValue < Test::Unit::TestCase
|
|
28
28
|
Counter.reset!
|
29
29
|
|
30
30
|
# increment the counter to maximum value
|
31
|
-
MAX.times {
|
32
|
-
assert_equal MAX, Counter.count.intVal
|
31
|
+
MAX.times { Counter.cycle! }
|
32
|
+
assert_equal( MAX, Counter.count.intVal )
|
33
33
|
end
|
34
34
|
|
35
35
|
def test_overflow
|
36
|
-
|
37
|
-
assert_equal 0, Counter.count.intVal
|
36
|
+
Counter.cycle! # increment the counter
|
37
|
+
assert_equal( 0, Counter.count.intVal )
|
38
38
|
end
|
39
39
|
end
|
data/samp/pipelined_alu/Rakefile
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require 'ruby-vpi/runner_proxy'
|
1
|
+
require 'ruby-vpi/runner_proxy'
|
@@ -2,17 +2,16 @@
|
|
2
2
|
# Copyright 2006 Suraj N. Kurapati
|
3
3
|
# See the file named LICENSE for details.
|
4
4
|
|
5
|
-
require '
|
5
|
+
require 'int_gen'
|
6
6
|
require 'Hw5UnitModel'
|
7
7
|
require 'test/unit'
|
8
|
-
require 'pp'
|
9
8
|
|
10
9
|
class TestHw5UnitModel < Test::Unit::TestCase
|
11
10
|
NUM_VECTORS = 4000
|
12
11
|
|
13
12
|
def setup
|
14
13
|
@model = Hw5UnitModel.new
|
15
|
-
@ingen =
|
14
|
+
@ingen = IntegerGenerator.new 32
|
16
15
|
end
|
17
16
|
|
18
17
|
def test_reset
|
@@ -28,8 +27,8 @@ class TestHw5UnitModel < Test::Unit::TestCase
|
|
28
27
|
inputQueue << Hw5UnitModel::Operation.new(
|
29
28
|
Hw5UnitModel::OPERATIONS[rand(Hw5UnitModel::OPERATIONS.size)],
|
30
29
|
i,
|
31
|
-
@ingen.
|
32
|
-
@ingen.
|
30
|
+
@ingen.random.abs,
|
31
|
+
@ingen.random.abs
|
33
32
|
)
|
34
33
|
end
|
35
34
|
|
@@ -3,161 +3,131 @@
|
|
3
3
|
See the file named LICENSE for details.
|
4
4
|
*/
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
input
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
, output reg [`WIDTH-1:0] res
|
25
|
-
, output reg [`DATABITS-1:0] out_databits
|
26
|
-
, output reg [1:0] out_op
|
6
|
+
module hw5_unit
|
7
|
+
#(parameter WIDTH = 32,
|
8
|
+
parameter DATABITS = 7,
|
9
|
+
parameter OP_NOP = 0,
|
10
|
+
parameter OP_ADD = 1,
|
11
|
+
parameter OP_SUB = 2,
|
12
|
+
parameter OP_MULT = 3)
|
13
|
+
( input clk,
|
14
|
+
input reset,
|
15
|
+
|
16
|
+
input [DATABITS-1:0] in_databits,
|
17
|
+
input [WIDTH-1:0] a,
|
18
|
+
input [WIDTH-1:0] b,
|
19
|
+
input [1:0] in_op,
|
20
|
+
|
21
|
+
output reg [WIDTH-1:0] res,
|
22
|
+
output reg [DATABITS-1:0] out_databits,
|
23
|
+
output reg [1:0] out_op
|
27
24
|
);
|
28
25
|
|
29
26
|
|
30
27
|
/* PHASE 0: perform the ALU operations */
|
31
28
|
|
32
29
|
// operation ID
|
33
|
-
reg [
|
34
|
-
reg [1:0]
|
30
|
+
reg [DATABITS-1:0] in_databits_phase0;
|
31
|
+
reg [1:0] in_op_phase0;
|
35
32
|
|
36
33
|
always @(*) begin
|
37
|
-
in_databits_phase0
|
38
|
-
in_op_phase0
|
34
|
+
in_databits_phase0 = in_databits;
|
35
|
+
in_op_phase0 = in_op;
|
39
36
|
end
|
40
37
|
|
41
38
|
// addition
|
42
|
-
reg [
|
39
|
+
reg [WIDTH-1:0] add_result_phase0;
|
43
40
|
|
44
41
|
always @(*) begin
|
45
42
|
add_result_phase0 = a + b;
|
46
43
|
end
|
47
44
|
|
48
45
|
// subtraction
|
49
|
-
reg [
|
46
|
+
reg [WIDTH-1:0] sub_result_phase0;
|
50
47
|
|
51
48
|
always @(*) begin
|
52
49
|
sub_result_phase0 = a - b;
|
53
50
|
end
|
54
51
|
|
55
52
|
// multiplication
|
56
|
-
reg [
|
53
|
+
reg [WIDTH-1:0] mul_result_phase0;
|
57
54
|
|
58
55
|
always @(*) begin
|
59
56
|
mul_result_phase0 = a * b;
|
60
57
|
end
|
61
58
|
|
62
59
|
|
63
|
-
// always @(posedge clk) begin
|
64
|
-
// $display("in_databits_phase0 => %d", in_databits_phase0);
|
65
|
-
// $display("in_op_phase0 => %d", in_op_phase0);
|
66
|
-
// $display("add_result_phase0 => %d", add_result_phase0);
|
67
|
-
// $display("sub_result_phase0 => %d", sub_result_phase0);
|
68
|
-
// $display("mul_result_phase0 => %d", mul_result_phase0);
|
69
|
-
// end
|
70
|
-
|
71
|
-
|
72
60
|
/* PHASE 1: delay the ALU results */
|
73
61
|
|
74
|
-
reg
|
75
|
-
reg
|
62
|
+
reg [DATABITS-1:0] in_databits_phase1;
|
63
|
+
reg [1:0] in_op_phase1;
|
76
64
|
|
77
|
-
reg
|
78
|
-
reg
|
79
|
-
reg
|
65
|
+
reg [WIDTH-1:0] add_result_phase1;
|
66
|
+
reg [WIDTH-1:0] sub_result_phase1;
|
67
|
+
reg [WIDTH-1:0] mul_result_phase1;
|
80
68
|
|
81
69
|
always @(posedge clk) begin
|
82
70
|
in_databits_phase1 <= in_databits_phase0;
|
83
|
-
in_op_phase1
|
71
|
+
in_op_phase1 <= in_op_phase0;
|
84
72
|
|
85
|
-
add_result_phase1
|
86
|
-
sub_result_phase1
|
87
|
-
mul_result_phase1
|
73
|
+
add_result_phase1 <= add_result_phase0;
|
74
|
+
sub_result_phase1 <= sub_result_phase0;
|
75
|
+
mul_result_phase1 <= mul_result_phase0;
|
88
76
|
end
|
89
77
|
|
90
|
-
// always @(posedge clk) begin
|
91
|
-
// $display("in_databits_phase1 => %d", in_databits_phase1);
|
92
|
-
// $display("in_op_phase1 => %d", in_op_phase1);
|
93
|
-
// $display("add_result_phase1 => %d", add_result_phase1);
|
94
|
-
// $display("sub_result_phase1 => %d", sub_result_phase1);
|
95
|
-
// $display("mul_result_phase1 => %d", mul_result_phase1);
|
96
|
-
// end
|
97
|
-
|
98
78
|
|
99
79
|
/* PHASE 2: delay the ALU results */
|
100
80
|
|
101
|
-
reg [
|
102
|
-
reg [1:0]
|
81
|
+
reg [DATABITS-1:0] in_databits_phase2;
|
82
|
+
reg [1:0] in_op_phase2;
|
103
83
|
|
104
|
-
reg [
|
105
|
-
reg [
|
106
|
-
reg [
|
84
|
+
reg [WIDTH-1:0] add_result_phase2;
|
85
|
+
reg [WIDTH-1:0] sub_result_phase2;
|
86
|
+
reg [WIDTH-1:0] mul_result_phase2;
|
107
87
|
|
108
88
|
always @(posedge clk) begin
|
109
89
|
in_databits_phase2 <= in_databits_phase1;
|
110
|
-
in_op_phase2
|
90
|
+
in_op_phase2 <= in_op_phase1;
|
111
91
|
|
112
|
-
add_result_phase2
|
113
|
-
sub_result_phase2
|
114
|
-
mul_result_phase2
|
92
|
+
add_result_phase2 <= add_result_phase1;
|
93
|
+
sub_result_phase2 <= sub_result_phase1;
|
94
|
+
mul_result_phase2 <= mul_result_phase1;
|
115
95
|
end
|
116
96
|
|
117
|
-
// always @(posedge clk) begin
|
118
|
-
// $display("in_databits_phase2 => %d", in_databits_phase2);
|
119
|
-
// $display("in_op_phase2 => %d", in_op_phase2);
|
120
|
-
// $display("add_result_phase2 => %d", add_result_phase2);
|
121
|
-
// $display("sub_result_phase2 => %d", sub_result_phase2);
|
122
|
-
// $display("mul_result_phase2 => %d", mul_result_phase2);
|
123
|
-
// end
|
124
|
-
|
125
97
|
|
126
98
|
/* PHASE 3: produce the outputs */
|
127
99
|
|
128
|
-
reg [
|
129
|
-
reg [1:0]
|
130
|
-
reg [
|
100
|
+
reg [DATABITS-1:0] out_databits_next;
|
101
|
+
reg [1:0] out_op_next;
|
102
|
+
reg [WIDTH-1:0] res_next;
|
131
103
|
|
132
104
|
always @(*) begin
|
133
|
-
if (reset)
|
134
|
-
out_op_next =
|
135
|
-
|
105
|
+
if (reset)
|
106
|
+
out_op_next = OP_NOP;
|
107
|
+
else
|
136
108
|
out_op_next = in_op_phase2;
|
137
|
-
end
|
138
109
|
|
139
110
|
out_databits_next = in_databits_phase2;
|
140
111
|
|
141
112
|
case (in_op_phase2)
|
142
|
-
|
113
|
+
OP_NOP:
|
143
114
|
res_next = 0;
|
144
115
|
|
145
|
-
|
116
|
+
OP_ADD:
|
146
117
|
res_next = add_result_phase2;
|
147
118
|
|
148
|
-
|
119
|
+
OP_SUB:
|
149
120
|
res_next = sub_result_phase2;
|
150
121
|
|
151
|
-
|
122
|
+
OP_MULT:
|
152
123
|
res_next = mul_result_phase2;
|
153
124
|
endcase
|
154
125
|
end
|
155
126
|
|
156
127
|
always @(posedge clk) begin
|
157
|
-
res
|
158
|
-
out_op
|
128
|
+
res <= res_next;
|
129
|
+
out_op <= out_op_next;
|
159
130
|
out_databits <= out_databits_next;
|
160
131
|
end
|
161
132
|
|
162
133
|
endmodule
|
163
|
-
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Simulates the design under test for one clock cycle.
|
2
|
+
def cycle!
|
3
|
+
clk.high!
|
4
|
+
advance_time
|
5
|
+
clk.low!
|
6
|
+
advance_time
|
7
|
+
end
|
8
|
+
|
9
|
+
# Brings the design under test into a blank state.
|
10
|
+
def reset!
|
11
|
+
clk.x!
|
12
|
+
reset.x!
|
13
|
+
in_databits.x!
|
14
|
+
a.x!
|
15
|
+
b.x!
|
16
|
+
in_op.x!
|
17
|
+
|
18
|
+
reset.high!
|
19
|
+
5.times { cycle! }
|
20
|
+
reset.low!
|
21
|
+
end
|
22
|
+
|
23
|
+
OPERATIONS = (OP_NOP .. OP_MULT).to_a
|
24
|
+
|
25
|
+
# Represents an ALU operation.
|
26
|
+
class Operation
|
27
|
+
attr_accessor :type, :tag, :arg1, :arg2, :result
|
28
|
+
|
29
|
+
def initialize(type, tag, arg1 = 0, arg2 = 0)
|
30
|
+
raise ArgumentError unless OPERATIONS.include? type
|
31
|
+
|
32
|
+
@type = type
|
33
|
+
@tag = tag
|
34
|
+
@arg1 = arg1
|
35
|
+
@arg2 = arg2
|
36
|
+
end
|
37
|
+
|
38
|
+
# Computes the result of this operation.
|
39
|
+
def compute
|
40
|
+
case @type
|
41
|
+
when OP_ADD
|
42
|
+
@arg1 + @arg2
|
43
|
+
|
44
|
+
when OP_SUB
|
45
|
+
@arg1 - @arg2
|
46
|
+
|
47
|
+
when OP_MULT
|
48
|
+
@arg1 * @arg2
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# Array of paths and shell globs (see the Dir.glob method's documentation for
|
2
|
+
# details) to source files and directories that contain source files. These
|
3
|
+
# source files will be loaded by the simulator before the simulation begins.
|
4
|
+
SIMULATOR_SOURCES = FileList[
|
5
|
+
'hw5_unit.v',
|
6
|
+
]
|
7
|
+
|
8
|
+
# Command-line arguments for the simulator. These arguments can be
|
9
|
+
# specified as a string or an array of strings, as demonstrated below:
|
10
|
+
#
|
11
|
+
# :cver => "this is a single string argument",
|
12
|
+
# :cver => ["these", "are", "separate", "arguments"],
|
13
|
+
# :cver => %w[these are also separate arguments],
|
14
|
+
#
|
15
|
+
SIMULATOR_ARGUMENTS = {
|
16
|
+
# GPL Cver
|
17
|
+
:cver => "",
|
18
|
+
|
19
|
+
# Icarus Verilog
|
20
|
+
:ivl => "",
|
21
|
+
|
22
|
+
# Synopsys VCS
|
23
|
+
:vcs => "",
|
24
|
+
|
25
|
+
# Mentor Modelsim
|
26
|
+
:vsim => "",
|
27
|
+
|
28
|
+
# Cadence NC-Sim
|
29
|
+
:ncsim => "",
|
30
|
+
|
31
|
+
}
|
32
|
+
|
33
|
+
# This task is invoked before the simulator runs. It
|
34
|
+
# can be used to make preprations, such as converting
|
35
|
+
# Verilog header files into Ruby, for the simulation.
|
36
|
+
task :setup do
|
37
|
+
# To learn how to write Rake tasks, please see:
|
38
|
+
# http://docs.rubyrake.org/read/chapter/4#page16
|
39
|
+
end
|
40
|
+
|
41
|
+
# This command loads the Ruby-VPI runner template,
|
42
|
+
# which runs the simulator using the above parameters.
|
43
|
+
require 'ruby-vpi/runner'
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'int_gen'
|
3
|
+
|
4
|
+
class Hw5_unit_spec < Test::Unit::TestCase
|
5
|
+
# Number of input sequences to test.
|
6
|
+
NUM_TESTS = 4000
|
7
|
+
|
8
|
+
# Bitmask capable of capturing ALU result.
|
9
|
+
ALU_RESULT_MASK = (2 ** Hw5_unit::WIDTH) - 1
|
10
|
+
|
11
|
+
# Upper limit of values allowed for an operation's tag.
|
12
|
+
OPERATION_TAG_LIMIT = 2 ** Hw5_unit::DATABITS
|
13
|
+
|
14
|
+
def setup
|
15
|
+
Hw5_unit.reset!
|
16
|
+
@intGen = IntegerGenerator.new(Hw5_unit::WIDTH)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_pipeline
|
20
|
+
issuedOps = []
|
21
|
+
numIssued = numVerified = 0
|
22
|
+
|
23
|
+
until numVerified == NUM_TESTS
|
24
|
+
# issue a new operation
|
25
|
+
if numIssued < NUM_TESTS
|
26
|
+
op = Hw5_unit::Operation.new(
|
27
|
+
Hw5_unit::OPERATIONS[rand(Hw5_unit::OPERATIONS.size)],
|
28
|
+
numIssued % OPERATION_TAG_LIMIT,
|
29
|
+
@intGen.random,
|
30
|
+
@intGen.random
|
31
|
+
)
|
32
|
+
|
33
|
+
Hw5_unit.a.intVal = op.arg1
|
34
|
+
Hw5_unit.b.intVal = op.arg2
|
35
|
+
Hw5_unit.in_op.intVal = op.type
|
36
|
+
Hw5_unit.in_databits.intVal = op.tag
|
37
|
+
|
38
|
+
issuedOps << op
|
39
|
+
numIssued += 1
|
40
|
+
end
|
41
|
+
|
42
|
+
Hw5_unit.cycle!
|
43
|
+
|
44
|
+
# verify result of finished operation
|
45
|
+
unless Hw5_unit.out_databits.x?
|
46
|
+
finishedOp = Hw5_unit::Operation.new(
|
47
|
+
Hw5_unit.out_op.intVal,
|
48
|
+
Hw5_unit.out_databits.intVal
|
49
|
+
)
|
50
|
+
finishedOp.result = Hw5_unit.res.intVal & ALU_RESULT_MASK
|
51
|
+
|
52
|
+
expectedOp = issuedOps.shift
|
53
|
+
assert_equal expectedOp.type, finishedOp.type, "incorrect operation"
|
54
|
+
assert_equal expectedOp.tag, finishedOp.tag, "incorrect tag"
|
55
|
+
|
56
|
+
unless finishedOp.type == Hw5_unit::OP_NOP
|
57
|
+
assert_equal expectedOp.compute & ALU_RESULT_MASK, finishedOp.result, "incorrect result"
|
58
|
+
end
|
59
|
+
|
60
|
+
numVerified += 1
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2007 Jacinto Shy II
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'ruby-vpi/runner_proxy'
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module register_file (
|
2
|
+
input wire [1:0] rdReg,
|
3
|
+
input wire [1:0] wtReg,
|
4
|
+
input wire rw,
|
5
|
+
input wire enable,
|
6
|
+
input wire [3:0] inBus,
|
7
|
+
output reg [3:0] outBus
|
8
|
+
);
|
9
|
+
reg [3:0] register [0:3];
|
10
|
+
|
11
|
+
always @(*) begin
|
12
|
+
if (rw == 0) begin
|
13
|
+
outBus = register[rdReg];
|
14
|
+
end else if (enable) begin
|
15
|
+
register[wtReg] = inBus;
|
16
|
+
end
|
17
|
+
end
|
18
|
+
endmodule
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# Ruby prototype of the design under test's Verilog implementation.
|
2
|
+
def feign!
|
3
|
+
if rw.low?
|
4
|
+
reg = register.memoryWord_a[rdReg.intVal]
|
5
|
+
outBus.intVal = reg.intVal
|
6
|
+
|
7
|
+
elsif enable.high?
|
8
|
+
reg = register.memoryWord_a[wtReg.intVal]
|
9
|
+
reg.intVal = inBus.intVal
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# Array of paths and shell globs (see the Dir.glob method's documentation for
|
2
|
+
# details) to source files and directories that contain source files. These
|
3
|
+
# source files will be loaded by the simulator before the simulation begins.
|
4
|
+
SIMULATOR_SOURCES = FileList[
|
5
|
+
'register_file.v',
|
6
|
+
]
|
7
|
+
|
8
|
+
# Command-line arguments for the simulator. These arguments can be
|
9
|
+
# specified as a string or an array of strings, as demonstrated below:
|
10
|
+
#
|
11
|
+
# :cver => "this is a single string argument",
|
12
|
+
# :cver => ["these", "are", "separate", "arguments"],
|
13
|
+
# :cver => %w[these are also separate arguments],
|
14
|
+
#
|
15
|
+
SIMULATOR_ARGUMENTS = {
|
16
|
+
# GPL Cver
|
17
|
+
:cver => "",
|
18
|
+
|
19
|
+
# Icarus Verilog
|
20
|
+
:ivl => "",
|
21
|
+
|
22
|
+
# Synopsys VCS
|
23
|
+
:vcs => "",
|
24
|
+
|
25
|
+
# Mentor Modelsim
|
26
|
+
:vsim => "",
|
27
|
+
|
28
|
+
# Cadence NC-Sim
|
29
|
+
:ncsim => "",
|
30
|
+
|
31
|
+
}
|
32
|
+
|
33
|
+
# This task is invoked before the simulator runs. It
|
34
|
+
# can be used to make preprations, such as converting
|
35
|
+
# Verilog header files into Ruby, for the simulation.
|
36
|
+
task :setup do
|
37
|
+
# To learn how to write Rake tasks, please see:
|
38
|
+
# http://docs.rubyrake.org/read/chapter/4#page16
|
39
|
+
end
|
40
|
+
|
41
|
+
# This command loads the Ruby-VPI runner template,
|
42
|
+
# which runs the simulator using the above parameters.
|
43
|
+
require 'ruby-vpi/runner'
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec'
|
2
|
+
|
3
|
+
module RegisterInterface
|
4
|
+
MAX_INDEX = Register_file.register.size - 1
|
5
|
+
|
6
|
+
def set_registers(vals)
|
7
|
+
Register_file.rw.intVal = 1
|
8
|
+
|
9
|
+
0.upto(MAX_INDEX) do |i|
|
10
|
+
Register_file.wtReg.intVal = i
|
11
|
+
Register_file.inBus.intVal = vals[i]
|
12
|
+
Register_file.cycle!
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def expect_registers(vals)
|
17
|
+
Register_file.rw.intVal = 0
|
18
|
+
|
19
|
+
MAX_INDEX.downto(0) do |i|
|
20
|
+
Register_file.rdReg.intVal = i
|
21
|
+
Register_file.cycle!
|
22
|
+
Register_file.outBus.intVal.should == vals[i]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "An enabled register file" do
|
28
|
+
include RegisterInterface
|
29
|
+
|
30
|
+
before do
|
31
|
+
Register_file.reset!
|
32
|
+
Register_file.enable.intVal = 1
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should be able to write and then read registers" do
|
36
|
+
testVals = [1, 7, 3, 12]
|
37
|
+
|
38
|
+
set_registers(testVals)
|
39
|
+
expect_registers(testVals)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "A disabled register file" do
|
44
|
+
include RegisterInterface
|
45
|
+
|
46
|
+
before do
|
47
|
+
Register_file.reset!
|
48
|
+
Register_file.enable.intVal = 0
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should not write new values" do
|
52
|
+
zeros = [0, 0, 0, 0]
|
53
|
+
testVals = [1, 7, 3, 12]
|
54
|
+
|
55
|
+
set_registers(testVals)
|
56
|
+
expect_registers(zeros)
|
57
|
+
end
|
58
|
+
end
|