ruby-vpi 16.0.1 → 17.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|