ruby-vpi 7.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +398 -0
- data/LICENSE +340 -0
- data/MEMO +38 -0
- data/README +9 -0
- data/Rakefile +271 -0
- data/bin/generate_test.rb +258 -0
- data/bin/generate_test_tpl/bench.rb +31 -0
- data/bin/generate_test_tpl/bench.v +54 -0
- data/bin/generate_test_tpl/design.rb +26 -0
- data/bin/generate_test_tpl/proto.rb +8 -0
- data/bin/generate_test_tpl/runner.rake +28 -0
- data/bin/generate_test_tpl/spec.rb +46 -0
- data/bin/header_to_ruby.rb +70 -0
- data/doc/Rakefile +55 -0
- data/doc/src/LICENSE +397 -0
- data/doc/src/figures/organization.png +0 -0
- data/doc/src/figures/organization_detailed.png +0 -0
- data/doc/src/figures/ruby_init.png +0 -0
- data/doc/src/figures/ruby_relay.png +0 -0
- data/doc/src/figures.dia +0 -0
- data/doc/src/images/COPYING +67 -0
- data/doc/src/images/ChangeLog +27 -0
- data/doc/src/images/blank.png +0 -0
- data/doc/src/images/callouts/1.png +0 -0
- data/doc/src/images/callouts/10.png +0 -0
- data/doc/src/images/callouts/11.png +0 -0
- data/doc/src/images/callouts/12.png +0 -0
- data/doc/src/images/callouts/13.png +0 -0
- data/doc/src/images/callouts/14.png +0 -0
- data/doc/src/images/callouts/15.png +0 -0
- data/doc/src/images/callouts/2.png +0 -0
- data/doc/src/images/callouts/3.png +0 -0
- data/doc/src/images/callouts/4.png +0 -0
- data/doc/src/images/callouts/5.png +0 -0
- data/doc/src/images/callouts/6.png +0 -0
- data/doc/src/images/callouts/7.png +0 -0
- data/doc/src/images/callouts/8.png +0 -0
- data/doc/src/images/callouts/9.png +0 -0
- data/doc/src/images/callouts/ChangeLog +15 -0
- data/doc/src/images/caution.png +0 -0
- data/doc/src/images/caution.svg +290 -0
- data/doc/src/images/copyright +55 -0
- data/doc/src/images/draft.png +0 -0
- data/doc/src/images/home.png +0 -0
- data/doc/src/images/home.svg +386 -0
- data/doc/src/images/important.png +0 -0
- data/doc/src/images/important.svg +163 -0
- data/doc/src/images/next.png +0 -0
- data/doc/src/images/next.svg +191 -0
- data/doc/src/images/note.png +0 -0
- data/doc/src/images/note.svg +483 -0
- data/doc/src/images/prev.png +0 -0
- data/doc/src/images/prev.svg +852 -0
- data/doc/src/images/tip.png +0 -0
- data/doc/src/images/tip.svg +1145 -0
- data/doc/src/images/toc-blank.png +0 -0
- data/doc/src/images/toc-minus.png +0 -0
- data/doc/src/images/toc-plus.png +0 -0
- data/doc/src/images/up.png +0 -0
- data/doc/src/images/up.svg +195 -0
- data/doc/src/images/warning.png +0 -0
- data/doc/src/images/warning.svg +334 -0
- data/doc/src/license.xml +446 -0
- data/doc/src/manual.xml +1582 -0
- data/doc/src/manual.xsl +23 -0
- data/doc/src/shared.dtd +63 -0
- data/doc/src/styles/manual.css +87 -0
- data/doc/txt/manual.txt +1657 -0
- data/doc/xhtml/background.html +3 -0
- data/doc/xhtml/background.methodology.html +3 -0
- data/doc/xhtml/background.organization.html +10 -0
- data/doc/xhtml/background.running-tests.html +3 -0
- data/doc/xhtml/background.terminology.html +3 -0
- data/doc/xhtml/figures/organization.png +0 -0
- data/doc/xhtml/figures/organization_detailed.png +0 -0
- data/doc/xhtml/figures/ruby_init.png +0 -0
- data/doc/xhtml/figures/ruby_relay.png +0 -0
- data/doc/xhtml/gfdl-0.html +18 -0
- data/doc/xhtml/gfdl-1.html +70 -0
- data/doc/xhtml/gfdl-10.html +15 -0
- data/doc/xhtml/gfdl-2.html +13 -0
- data/doc/xhtml/gfdl-3.html +31 -0
- data/doc/xhtml/gfdl-4.html +75 -0
- data/doc/xhtml/gfdl-5.html +20 -0
- data/doc/xhtml/gfdl-6.html +12 -0
- data/doc/xhtml/gfdl-7.html +16 -0
- data/doc/xhtml/gfdl-8.html +17 -0
- data/doc/xhtml/gfdl-9.html +9 -0
- data/doc/xhtml/gfdl-addendum.html +25 -0
- data/doc/xhtml/gfdl.html +11 -0
- data/doc/xhtml/glossary.html +3 -0
- data/doc/xhtml/images/COPYING +67 -0
- data/doc/xhtml/images/ChangeLog +27 -0
- data/doc/xhtml/images/blank.png +0 -0
- data/doc/xhtml/images/callouts/1.png +0 -0
- data/doc/xhtml/images/callouts/10.png +0 -0
- data/doc/xhtml/images/callouts/11.png +0 -0
- data/doc/xhtml/images/callouts/12.png +0 -0
- data/doc/xhtml/images/callouts/13.png +0 -0
- data/doc/xhtml/images/callouts/14.png +0 -0
- data/doc/xhtml/images/callouts/15.png +0 -0
- data/doc/xhtml/images/callouts/2.png +0 -0
- data/doc/xhtml/images/callouts/3.png +0 -0
- data/doc/xhtml/images/callouts/4.png +0 -0
- data/doc/xhtml/images/callouts/5.png +0 -0
- data/doc/xhtml/images/callouts/6.png +0 -0
- data/doc/xhtml/images/callouts/7.png +0 -0
- data/doc/xhtml/images/callouts/8.png +0 -0
- data/doc/xhtml/images/callouts/9.png +0 -0
- data/doc/xhtml/images/callouts/ChangeLog +15 -0
- data/doc/xhtml/images/caution.png +0 -0
- data/doc/xhtml/images/caution.svg +290 -0
- data/doc/xhtml/images/copyright +55 -0
- data/doc/xhtml/images/draft.png +0 -0
- data/doc/xhtml/images/home.png +0 -0
- data/doc/xhtml/images/home.svg +386 -0
- data/doc/xhtml/images/important.png +0 -0
- data/doc/xhtml/images/important.svg +163 -0
- data/doc/xhtml/images/next.png +0 -0
- data/doc/xhtml/images/next.svg +191 -0
- data/doc/xhtml/images/note.png +0 -0
- data/doc/xhtml/images/note.svg +483 -0
- data/doc/xhtml/images/prev.png +0 -0
- data/doc/xhtml/images/prev.svg +852 -0
- data/doc/xhtml/images/tip.png +0 -0
- data/doc/xhtml/images/tip.svg +1145 -0
- data/doc/xhtml/images/toc-blank.png +0 -0
- data/doc/xhtml/images/toc-minus.png +0 -0
- data/doc/xhtml/images/toc-plus.png +0 -0
- data/doc/xhtml/images/up.png +0 -0
- data/doc/xhtml/images/up.svg +195 -0
- data/doc/xhtml/images/warning.png +0 -0
- data/doc/xhtml/images/warning.svg +334 -0
- data/doc/xhtml/index.html +4 -0
- data/doc/xhtml/introduction.html +3 -0
- data/doc/xhtml/introduction.license.html +3 -0
- data/doc/xhtml/introduction.manifest.html +3 -0
- data/doc/xhtml/introduction.related-works.html +3 -0
- data/doc/xhtml/introduction.resources.html +3 -0
- data/doc/xhtml/problem.ivl.html +18 -0
- data/doc/xhtml/problems.html +3 -0
- data/doc/xhtml/problems.ruby.html +3 -0
- data/doc/xhtml/problems.vsim.html +3 -0
- data/doc/xhtml/styles/manual.css +87 -0
- data/doc/xhtml/usage.examples.html +3 -0
- data/doc/xhtml/usage.html +3 -0
- data/doc/xhtml/usage.installation.html +3 -0
- data/doc/xhtml/usage.requirements.html +3 -0
- data/doc/xhtml/usage.tools.html +3 -0
- data/doc/xhtml/usage.tutorial.html +199 -0
- data/ext/Doxyfile +272 -0
- data/ext/README +124 -0
- data/ext/Rakefile +65 -0
- data/ext/common.h +56 -0
- data/ext/extconf.rb +4 -0
- data/ext/relay.cin +146 -0
- data/ext/relay.hin +48 -0
- data/ext/ruby-vpi.c +36 -0
- data/ext/swig.cin +38 -0
- data/ext/swig.hin +39 -0
- data/ext/swig_vpi.h +924 -0
- data/ext/swig_vpi.i +8 -0
- data/ext/swig_wrap.cin +4613 -0
- data/ext/verilog.h +59 -0
- data/ext/vlog.cin +92 -0
- data/ext/vlog.hin +57 -0
- data/ext/vpi_user.h +924 -0
- data/gem_extconf.rb +8 -0
- data/history.html +809 -0
- data/lib/ruby-vpi/erb.rb +41 -0
- data/lib/ruby-vpi/rake.rb +35 -0
- data/lib/ruby-vpi/rdoc.rb +51 -0
- data/lib/ruby-vpi/rspec.rb +32 -0
- data/lib/ruby-vpi/runner.rb +22 -0
- data/lib/ruby-vpi/vpi_util.rb +310 -0
- data/lib/ruby-vpi.rb +58 -0
- data/memo.html +86 -0
- data/readme.html +19 -0
- data/ref/c/annotated.html +36 -0
- data/ref/c/common_8h.html +178 -0
- data/ref/c/doxygen.css +310 -0
- data/ref/c/doxygen.png +0 -0
- data/ref/c/files.html +35 -0
- data/ref/c/functions.html +135 -0
- data/ref/c/functions_vars.html +135 -0
- data/ref/c/globals.html +55 -0
- data/ref/c/globals_0x63.html +86 -0
- data/ref/c/globals_0x65.html +55 -0
- data/ref/c/globals_0x66.html +55 -0
- data/ref/c/globals_0x70.html +71 -0
- data/ref/c/globals_0x72.html +62 -0
- data/ref/c/globals_0x73.html +65 -0
- data/ref/c/globals_0x74.html +55 -0
- data/ref/c/globals_0x76.html +472 -0
- data/ref/c/globals_0x78.html +55 -0
- data/ref/c/globals_defs.html +81 -0
- data/ref/c/globals_defs_0x65.html +50 -0
- data/ref/c/globals_defs_0x70.html +51 -0
- data/ref/c/globals_defs_0x76.html +463 -0
- data/ref/c/globals_defs_0x78.html +50 -0
- data/ref/c/globals_enum.html +39 -0
- data/ref/c/globals_eval.html +40 -0
- data/ref/c/globals_func.html +49 -0
- data/ref/c/globals_type.html +63 -0
- data/ref/c/globals_vars.html +42 -0
- data/ref/c/hierarchy.html +36 -0
- data/ref/c/index.html +20 -0
- data/ref/c/relay_8cin.html +268 -0
- data/ref/c/relay_8hin.html +161 -0
- data/ref/c/ruby-vpi_8c.html +34 -0
- data/ref/c/structrelay____RubyOptions____def.html +84 -0
- data/ref/c/structt__cb__data.html +208 -0
- data/ref/c/structt__vpi__delay.html +183 -0
- data/ref/c/structt__vpi__error__info.html +208 -0
- data/ref/c/structt__vpi__strengthval.html +108 -0
- data/ref/c/structt__vpi__systf__data.html +208 -0
- data/ref/c/structt__vpi__time.html +133 -0
- data/ref/c/structt__vpi__value.html +285 -0
- data/ref/c/structt__vpi__vecval.html +83 -0
- data/ref/c/structt__vpi__vlog__info.html +133 -0
- data/ref/c/swig_8cin.html +91 -0
- data/ref/c/swig_8hin.html +99 -0
- data/ref/c/tab_b.gif +0 -0
- data/ref/c/tab_l.gif +0 -0
- data/ref/c/tab_r.gif +0 -0
- data/ref/c/tabs.css +102 -0
- data/ref/c/verilog_8h.html +149 -0
- data/ref/c/vlog_8cin.html +199 -0
- data/ref/c/vlog_8hin.html +152 -0
- data/ref/c/vpi__user_8h.html +12747 -0
- data/ref/ruby/classes/Counter.html +258 -0
- data/ref/ruby/classes/Counter.src/M000037.html +20 -0
- data/ref/ruby/classes/Counter.src/M000038.html +22 -0
- data/ref/ruby/classes/Counter.src/M000039.html +20 -0
- data/ref/ruby/classes/Counter.src/M000040.html +22 -0
- data/ref/ruby/classes/CounterProto.html +164 -0
- data/ref/ruby/classes/CounterProto.src/M000004.html +22 -0
- data/ref/ruby/classes/CounterProto.src/M000005.html +22 -0
- data/ref/ruby/classes/ERB.html +158 -0
- data/ref/ruby/classes/ERB.src/M000034.html +29 -0
- data/ref/ruby/classes/FileUtils.html +165 -0
- data/ref/ruby/classes/FileUtils.src/M000047.html +18 -0
- data/ref/ruby/classes/FileUtils.src/M000048.html +18 -0
- data/ref/ruby/classes/Hw5UnitModel/Operation.html +216 -0
- data/ref/ruby/classes/Hw5UnitModel/Operation.src/M000011.html +25 -0
- data/ref/ruby/classes/Hw5UnitModel/Operation.src/M000012.html +33 -0
- data/ref/ruby/classes/Hw5UnitModel/Operation.src/M000013.html +18 -0
- data/ref/ruby/classes/Hw5UnitModel.html +256 -0
- data/ref/ruby/classes/Hw5UnitModel.src/M000006.html +24 -0
- data/ref/ruby/classes/Hw5UnitModel.src/M000008.html +20 -0
- data/ref/ruby/classes/Hw5UnitModel.src/M000009.html +38 -0
- data/ref/ruby/classes/Hw5UnitModel.src/M000010.html +22 -0
- data/ref/ruby/classes/Hw5_unit.html +196 -0
- data/ref/ruby/classes/Hw5_unit.src/M000003.html +27 -0
- data/ref/ruby/classes/Hw5_unit_spec.html +237 -0
- data/ref/ruby/classes/Hw5_unit_spec.src/M000023.html +21 -0
- data/ref/ruby/classes/Hw5_unit_spec.src/M000024.html +21 -0
- data/ref/ruby/classes/Hw5_unit_spec.src/M000025.html +67 -0
- data/ref/ruby/classes/InputGenerator.html +260 -0
- data/ref/ruby/classes/InputGenerator.src/M000027.html +18 -0
- data/ref/ruby/classes/InputGenerator.src/M000028.html +18 -0
- data/ref/ruby/classes/InputGenerator.src/M000029.html +19 -0
- data/ref/ruby/classes/InputGenerator.src/M000030.html +38 -0
- data/ref/ruby/classes/InputGenerator.src/M000031.html +19 -0
- data/ref/ruby/classes/InputGenerator.src/M000032.html +19 -0
- data/ref/ruby/classes/MaximumCounterValue.html +159 -0
- data/ref/ruby/classes/MaximumCounterValue.src/M000035.html +23 -0
- data/ref/ruby/classes/MaximumCounterValue.src/M000036.html +21 -0
- data/ref/ruby/classes/ModuleInfo.html +199 -0
- data/ref/ruby/classes/ModuleInfo.src/M000018.html +44 -0
- data/ref/ruby/classes/ModuleInfo.src/M000019.html +26 -0
- data/ref/ruby/classes/OutputInfo.html +304 -0
- data/ref/ruby/classes/OutputInfo.src/M000017.html +51 -0
- data/ref/ruby/classes/RDoc.html +135 -0
- data/ref/ruby/classes/RDoc.src/M000051.html +40 -0
- data/ref/ruby/classes/ResettedCounterValue.html +174 -0
- data/ref/ruby/classes/ResettedCounterValue.src/M000014.html +19 -0
- data/ref/ruby/classes/ResettedCounterValue.src/M000015.html +18 -0
- data/ref/ruby/classes/ResettedCounterValue.src/M000016.html +23 -0
- data/ref/ruby/classes/RubyVPI.html +186 -0
- data/ref/ruby/classes/RubyVPI.src/M000049.html +18 -0
- data/ref/ruby/classes/RubyVPI.src/M000050.html +39 -0
- data/ref/ruby/classes/SWIG/TYPE_p_unsigned_int.html +370 -0
- data/ref/ruby/classes/SWIG/TYPE_p_unsigned_int.src/M000041.html +22 -0
- data/ref/ruby/classes/SWIG/TYPE_p_unsigned_int.src/M000042.html +44 -0
- data/ref/ruby/classes/SWIG/TYPE_p_unsigned_int.src/M000043.html +82 -0
- data/ref/ruby/classes/SWIG/TYPE_p_unsigned_int.src/M000044.html +127 -0
- data/ref/ruby/classes/SWIG/TYPE_p_unsigned_int.src/M000045.html +26 -0
- data/ref/ruby/classes/SWIG/TYPE_p_unsigned_int.src/M000046.html +18 -0
- data/ref/ruby/classes/SWIG.html +111 -0
- data/ref/ruby/classes/String.html +140 -0
- data/ref/ruby/classes/String.src/M000033.html +37 -0
- data/ref/ruby/classes/Template.html +158 -0
- data/ref/ruby/classes/Template.src/M000026.html +18 -0
- data/ref/ruby/classes/TestHw5UnitModel.html +180 -0
- data/ref/ruby/classes/TestHw5UnitModel.src/M000020.html +19 -0
- data/ref/ruby/classes/TestHw5UnitModel.src/M000021.html +19 -0
- data/ref/ruby/classes/TestHw5UnitModel.src/M000022.html +64 -0
- data/ref/ruby/created.rid +1 -0
- data/ref/ruby/files/bin/generate_test_rb.html +236 -0
- data/ref/ruby/files/bin/generate_test_rb.src/M000001.html +29 -0
- data/ref/ruby/files/bin/generate_test_tpl/bench_rb.html +115 -0
- data/ref/ruby/files/bin/generate_test_tpl/design_rb.html +107 -0
- data/ref/ruby/files/bin/generate_test_tpl/proto_rb.html +107 -0
- data/ref/ruby/files/bin/generate_test_tpl/spec_rb.html +140 -0
- data/ref/ruby/files/bin/generate_test_tpl/spec_rb.src/M000002.html +22 -0
- data/ref/ruby/files/bin/header_to_ruby_rb.html +116 -0
- data/ref/ruby/files/ext/extconf_rb.html +108 -0
- data/ref/ruby/files/gem_extconf_rb.html +114 -0
- data/ref/ruby/files/lib/ruby-vpi/erb_rb.html +108 -0
- data/ref/ruby/files/lib/ruby-vpi/rake_rb.html +108 -0
- data/ref/ruby/files/lib/ruby-vpi/rdoc_rb.html +108 -0
- data/ref/ruby/files/lib/ruby-vpi/rspec_rb.html +115 -0
- data/ref/ruby/files/lib/ruby-vpi/runner_rb.html +108 -0
- data/ref/ruby/files/lib/ruby-vpi/vpi_util_rb.html +108 -0
- data/ref/ruby/files/lib/ruby-vpi_rb.html +108 -0
- data/ref/ruby/files/samp/counter/counter_rspecTest_bench_rb.html +115 -0
- data/ref/ruby/files/samp/counter/counter_rspecTest_design_rb.html +107 -0
- data/ref/ruby/files/samp/counter/counter_rspecTest_proto_rb.html +107 -0
- data/ref/ruby/files/samp/counter/counter_rspecTest_spec_rb.html +142 -0
- data/ref/ruby/files/samp/counter/counter_unitTest_bench_rb.html +115 -0
- data/ref/ruby/files/samp/counter/counter_unitTest_design_rb.html +107 -0
- data/ref/ruby/files/samp/counter/counter_unitTest_proto_rb.html +107 -0
- data/ref/ruby/files/samp/counter/counter_unitTest_spec_rb.html +135 -0
- data/ref/ruby/files/samp/pipelined_alu/Hw5UnitModel_rb.html +101 -0
- data/ref/ruby/files/samp/pipelined_alu/InputGenerator_rb.html +101 -0
- data/ref/ruby/files/samp/pipelined_alu/TestHw5UnitModel_rb.html +111 -0
- data/ref/ruby/files/samp/pipelined_alu/hw5_unit_bench_rb.html +108 -0
- data/ref/ruby/files/samp/pipelined_alu/hw5_unit_design_rb.html +107 -0
- data/ref/ruby/files/samp/pipelined_alu/hw5_unit_spec_rb.html +112 -0
- data/ref/ruby/fr_class_index.html +46 -0
- data/ref/ruby/fr_file_index.html +55 -0
- data/ref/ruby/fr_method_index.html +77 -0
- data/ref/ruby/index.html +24 -0
- data/ref/ruby/rdoc-style.css +208 -0
- data/samp/counter/Rakefile +1 -0
- data/samp/counter/counter.v +20 -0
- data/samp/counter/counter_rspecTest_bench.rb +9 -0
- data/samp/counter/counter_rspecTest_bench.v +28 -0
- data/samp/counter/counter_rspecTest_design.rb +22 -0
- data/samp/counter/counter_rspecTest_proto.rb +10 -0
- data/samp/counter/counter_rspecTest_runner.rake +28 -0
- data/samp/counter/counter_rspecTest_spec.rb +47 -0
- data/samp/counter/counter_unitTest_bench.rb +9 -0
- data/samp/counter/counter_unitTest_bench.v +28 -0
- data/samp/counter/counter_unitTest_design.rb +22 -0
- data/samp/counter/counter_unitTest_proto.rb +10 -0
- data/samp/counter/counter_unitTest_runner.rake +28 -0
- data/samp/counter/counter_unitTest_spec.rb +49 -0
- data/samp/pipelined_alu/Hw5UnitModel.rb +134 -0
- data/samp/pipelined_alu/InputGenerator.rb +94 -0
- data/samp/pipelined_alu/README +127 -0
- data/samp/pipelined_alu/Rakefile +1 -0
- data/samp/pipelined_alu/TestHw5UnitModel.rb +88 -0
- data/samp/pipelined_alu/hw5_unit.v +186 -0
- data/samp/pipelined_alu/hw5_unit_bench.rb +8 -0
- data/samp/pipelined_alu/hw5_unit_bench.v +45 -0
- data/samp/pipelined_alu/hw5_unit_design.rb +18 -0
- data/samp/pipelined_alu/hw5_unit_runner.rake +10 -0
- data/samp/pipelined_alu/hw5_unit_spec.rb +123 -0
- data/tpl/launcher.rake +30 -0
- data/tpl/runner.rake +96 -0
- data/tpl/synopsys_vcs.tab +2 -0
- metadata +484 -0
@@ -0,0 +1,134 @@
|
|
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
|
+
# Behavioral model of the hw5_unit Verilog module.
|
22
|
+
class Hw5UnitModel
|
23
|
+
|
24
|
+
# Represents an ALU operation.
|
25
|
+
class Operation
|
26
|
+
attr_accessor :type, :tag, :arg1, :arg2, :stage, :result
|
27
|
+
|
28
|
+
def initialize(type, tag, arg1 = 0, arg2 = 0)
|
29
|
+
raise ArgumentError unless OPERATIONS.include? type
|
30
|
+
|
31
|
+
@type = type
|
32
|
+
@tag = tag
|
33
|
+
@arg1 = arg1
|
34
|
+
@arg2 = arg2
|
35
|
+
|
36
|
+
@stage = 0
|
37
|
+
end
|
38
|
+
|
39
|
+
# Computes the result of this operation.
|
40
|
+
def compute
|
41
|
+
case @type
|
42
|
+
when :add
|
43
|
+
@arg1 + @arg2
|
44
|
+
|
45
|
+
when :sub
|
46
|
+
@arg1 - @arg2
|
47
|
+
|
48
|
+
when :mul
|
49
|
+
@arg1 * @arg2
|
50
|
+
|
51
|
+
when :nop
|
52
|
+
nil
|
53
|
+
|
54
|
+
else
|
55
|
+
raise
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def compute!
|
60
|
+
@result = compute
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
# Supported types of ALU operations.
|
66
|
+
OPERATIONS = [ :add, :sub, :mul, :nop ]
|
67
|
+
|
68
|
+
# Number of cycles each operation uses.
|
69
|
+
OPERATION_LATENCIES = {
|
70
|
+
:add => 3, #1,
|
71
|
+
:sub => 3, #2,
|
72
|
+
:mul => 3, #3,
|
73
|
+
:nop => 3, #1,
|
74
|
+
}
|
75
|
+
|
76
|
+
# The famous no-operation.
|
77
|
+
NOP = Hw5UnitModel::Operation.new(:nop, nil)
|
78
|
+
|
79
|
+
|
80
|
+
def reset
|
81
|
+
@aluQueues = {}
|
82
|
+
@outputQueue = []
|
83
|
+
|
84
|
+
# create a separate pipeline for each operation
|
85
|
+
OPERATIONS.each do |op|
|
86
|
+
@aluQueues[op] = []
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
alias_method :initialize, :reset
|
91
|
+
|
92
|
+
|
93
|
+
# Starts the given operation during the present cycle.
|
94
|
+
def startOperation(op)
|
95
|
+
@aluQueues[op.type] << op
|
96
|
+
|
97
|
+
p "started operation:", op if $DEBUG
|
98
|
+
end
|
99
|
+
|
100
|
+
# Performs the behavior for the present cycle.
|
101
|
+
def cycle
|
102
|
+
# perform ALU operations
|
103
|
+
@aluQueues.each_pair do |alu, pipeline|
|
104
|
+
finished = []
|
105
|
+
|
106
|
+
pipeline.each do |op|
|
107
|
+
# when the operation has finished all pipeline stages, compute the result and output it
|
108
|
+
if op.stage >= OPERATION_LATENCIES[op.type]
|
109
|
+
op.compute!
|
110
|
+
finished << op
|
111
|
+
@outputQueue << op
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
# perform the next stage of the operation
|
116
|
+
op.stage += 1
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
# remove finished operations from pipeline
|
121
|
+
@aluQueues[alu] = pipeline - finished
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Returns the output for the present cycle.
|
126
|
+
def output
|
127
|
+
unless @outputQueue.empty?
|
128
|
+
@outputQueue.shift
|
129
|
+
else
|
130
|
+
NOP
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
@@ -0,0 +1,94 @@
|
|
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
|
+
# Generates random input sequences of configurable length.
|
22
|
+
class InputGenerator
|
23
|
+
|
24
|
+
# the first 1000 prime numbers, gotten from <http://en.wikipedia.org/wiki/List_of_prime_numbers#The_first_1000_prime_numbers>
|
25
|
+
PrimeNums = [
|
26
|
+
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919
|
27
|
+
]
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
# @param bits Number of bits that can be used to represent a generated input sequence
|
32
|
+
def initialize(bits)
|
33
|
+
self.bits = bits
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
# gets the number of bits that can be used to represent a generated input sequence
|
39
|
+
def bits
|
40
|
+
@inputBits
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
# sets the number of bits that can be used to represent a generated input sequence
|
46
|
+
def bits=(num)
|
47
|
+
@inputBits = num
|
48
|
+
@inputLimit = 2 ** @inputBits
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
# generates a random input sequence
|
54
|
+
def gen
|
55
|
+
# randomly select a specific kind of integer to generate
|
56
|
+
# @note param to rand() is number of situations in this 'case' block
|
57
|
+
case rand(6)
|
58
|
+
when 0 # positive numbers
|
59
|
+
rand(@inputLimit)
|
60
|
+
|
61
|
+
when 1 # negative numbers
|
62
|
+
-rand(@inputLimit)
|
63
|
+
|
64
|
+
when 2 # zero
|
65
|
+
0
|
66
|
+
|
67
|
+
when 3 # one
|
68
|
+
1
|
69
|
+
|
70
|
+
when 4 # prime numbers
|
71
|
+
genPrime
|
72
|
+
|
73
|
+
when 5 # power-of-two numbers
|
74
|
+
genPowerOfTwo
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
# generates a random prime number
|
81
|
+
def genPrime
|
82
|
+
prime = PrimeNums[rand(PrimeNums.size)]
|
83
|
+
prime < @inputLimit ? prime : 2
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
# generates a random power-of-two number
|
89
|
+
def genPowerOfTwo
|
90
|
+
power = rand(@inputBits) + 1
|
91
|
+
(2 ** power) - 1
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
PIPELINED ALU
|
2
|
+
|
3
|
+
This example is my solution to a homework assignment for an Advanced Logic Design class I had taken during the Winter of 2006 at University of California, Santa Cruz. Relevant portions of the problem have been revised and reproduced here with permission from the instructor: professor Jose Renau.
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
PROBLEM
|
8
|
+
|
9
|
+
Implement the functionality for hw5 unit, a pipelined ALU:
|
10
|
+
|
11
|
+
`define WIDTH 32
|
12
|
+
`define DATABITS 7
|
13
|
+
`define OP_NOP 0
|
14
|
+
`define OP_ADD 1
|
15
|
+
`define OP_SUB 2
|
16
|
+
`define OP_MULT 3
|
17
|
+
|
18
|
+
module hw5_unit(
|
19
|
+
input clk
|
20
|
+
,input reset
|
21
|
+
|
22
|
+
// inputs
|
23
|
+
,input [`DATABITS-1:0] in_databits
|
24
|
+
,input [`WIDTH-1:0] a
|
25
|
+
,input [`WIDTH-1:0] b
|
26
|
+
,input [1:0] in_op
|
27
|
+
|
28
|
+
// outputs
|
29
|
+
,output reg [`WIDTH-1:0] res
|
30
|
+
,output reg [`DATABITS-1:0] out_databits
|
31
|
+
,output reg [1:0] out_op
|
32
|
+
);
|
33
|
+
|
34
|
+
|
35
|
+
MAJOR POINTS
|
36
|
+
|
37
|
+
1. in_op selects the operation to perform (OP_NOP means no operation).
|
38
|
+
|
39
|
+
2. A new operation may be started every cycle.
|
40
|
+
|
41
|
+
3. OP_ADD must have 1 cycle latency.
|
42
|
+
|
43
|
+
4. OP_SUB must have 2 cycles latency.
|
44
|
+
|
45
|
+
5. OP_MULT must have 3 cycles latency.
|
46
|
+
|
47
|
+
6. There is only one result (res). Since three operations can finish every cycle, you need to buffer the other two. Note that since at most one operation starts per cycle, a 3-entry buffer should be enough.
|
48
|
+
|
49
|
+
7. Each operation has an associated tag (in_databits) which you must pass back with the result (out_databits). For example, if a OP_MULT operation is started with parameters a=2, b=4, in_databits=3; then after the multiplication finishes three cycles later, the outputs should be res=8, out_databits=3, out_op=OP_MULT.
|
50
|
+
|
51
|
+
8. The testbench used to verify this module must:
|
52
|
+
|
53
|
+
a. Test random combinations of positive, zero, one, prime numbers, power-of-two values from powers 1 to 32, and random numbers.
|
54
|
+
|
55
|
+
b. Execute random combinations of add, subtract, and multiply operations.
|
56
|
+
|
57
|
+
c. Perform tests for 4000 ALU operations.
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
DESIGN
|
62
|
+
|
63
|
+
From the start, my approach was to use a single queue to solve the resource conflict (only one ALU can give an output per cycle). After drawing some sketches and understanding the problem, I wrote the following algorithm to solve the resource conflict:
|
64
|
+
|
65
|
+
def queue_results(a, b, c)
|
66
|
+
output a
|
67
|
+
enqueue b, c
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
We cannot perform all the operations in the queue_results method using only one cycle. However, if the queue_results method is not implemented as shown, then the design will not work---it will be chaotic and produce incoherent results.
|
72
|
+
|
73
|
+
The trick is to satisfy the post-conditions of the queue_results method (one result is outputted and the other two have been queued) using multiple clock cycles:
|
74
|
+
|
75
|
+
1. enqueue b
|
76
|
+
(remember a and c)
|
77
|
+
|
78
|
+
2. enqueue c
|
79
|
+
(remember a)
|
80
|
+
|
81
|
+
3. output a
|
82
|
+
|
83
|
+
or
|
84
|
+
|
85
|
+
1. enqueue b
|
86
|
+
(remember a and c)
|
87
|
+
|
88
|
+
2. enqueue c; output a
|
89
|
+
(nothing to remember)
|
90
|
+
|
91
|
+
Note that we cannot output the 'a' result during the first cycle because that would violate the post-conditions.
|
92
|
+
|
93
|
+
|
94
|
+
After gaining this understanding, I realized that a separate queue was wholly unnecessary. Instead, I could simply use pipeline registers to remember values until they were needed (i.e. the 'a' result is output only in the last cycle).
|
95
|
+
|
96
|
+
This approach uses exactly the same number of pipeline registers (three in this case) as the size of the queue suggested by the Professor. Also, this approach uses less storage than the three-queues (one for each ALU output; therefore 9 registers) approach suggested by the Professor.
|
97
|
+
|
98
|
+
|
99
|
+
Finally, I wrote a behavioral model (see MODEL section) of the RTL using Ruby and verified both my initial approach (magical single-cycle queueing of multiple items) and its later improvement (the pipeline-register approach).
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
MODEL
|
104
|
+
|
105
|
+
$ cd tests
|
106
|
+
$ ruby -w TestHw5UnitModel.rb # use the "-d" option for details
|
107
|
+
|
108
|
+
|
109
|
+
The model is written in Ruby and comes with a unit test which is similar to the Ruby-VPI test bench I wrote for the RTL implementation.
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
TEST BENCH
|
114
|
+
|
115
|
+
$ ulimit -s unlimited
|
116
|
+
$ make VERILOG=$VCS_HOME VCS_FLAGS="-cc gcc32 -ld gcc32" vcs
|
117
|
+
|
118
|
+
... lots of output here ...
|
119
|
+
|
120
|
+
hw5_unit_tb.rb passed successfully!
|
121
|
+
CPU time: .120 seconds to compile + .268 seconds to link +
|
122
|
+
30.042 seconds in simulation
|
123
|
+
|
124
|
+
|
125
|
+
|
126
|
+
The test bench structure was ported from my unit test for the behavioral model of hw5_unit.
|
127
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
load '../../tpl/launcher.rake'
|
@@ -0,0 +1,88 @@
|
|
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 'InputGenerator'
|
22
|
+
require 'Hw5UnitModel'
|
23
|
+
require 'test/unit'
|
24
|
+
require 'pp'
|
25
|
+
|
26
|
+
class TestHw5UnitModel < Test::Unit::TestCase
|
27
|
+
NUM_VECTORS = 4000
|
28
|
+
|
29
|
+
def setup
|
30
|
+
@model = Hw5UnitModel.new
|
31
|
+
@ingen = InputGenerator.new 32
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_reset
|
35
|
+
@model.reset
|
36
|
+
assert_same Hw5UnitModel::NOP, @model.output
|
37
|
+
end
|
38
|
+
|
39
|
+
def testModel
|
40
|
+
# generate input for module
|
41
|
+
inputQueue = []
|
42
|
+
|
43
|
+
NUM_VECTORS.times do |i|
|
44
|
+
inputQueue << Hw5UnitModel::Operation.new(Hw5UnitModel::OPERATIONS[rand(Hw5UnitModel::OPERATIONS.size)], i, @ingen.gen.abs, @ingen.gen.abs)
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
# test the module
|
49
|
+
outputQueue = []
|
50
|
+
cycle = 0
|
51
|
+
|
52
|
+
until inputQueue.length == outputQueue.length
|
53
|
+
if $DEBUG
|
54
|
+
print "\n" * 3
|
55
|
+
p ">> cycle #{cycle}"
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# start a new operation
|
60
|
+
if cycle < inputQueue.length
|
61
|
+
@model.startOperation inputQueue[cycle]
|
62
|
+
cycle += 1
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
# simulate a clock cycle
|
67
|
+
@model.cycle
|
68
|
+
|
69
|
+
|
70
|
+
# verify the output
|
71
|
+
output = @model.output
|
72
|
+
p "output:", output if $DEBUG
|
73
|
+
|
74
|
+
unless output == Hw5UnitModel::NOP
|
75
|
+
assert_not_nil inputQueue.find {|op| op.tag == output.tag }, "unknown tag on result: #{output.tag}"
|
76
|
+
assert_equal output.compute, output.result, "incorrect result"
|
77
|
+
|
78
|
+
outputQueue << output
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
if $DEBUG
|
83
|
+
puts
|
84
|
+
pp @model
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
/*
|
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
|
+
*/
|
20
|
+
|
21
|
+
`define WIDTH 32
|
22
|
+
`define DATABITS 7
|
23
|
+
`define OP_NOP 0
|
24
|
+
`define OP_ADD 1
|
25
|
+
`define OP_SUB 2
|
26
|
+
`define OP_MULT 3
|
27
|
+
|
28
|
+
module hw5_unit(
|
29
|
+
input clk
|
30
|
+
, input reset
|
31
|
+
|
32
|
+
// inputs
|
33
|
+
, input [`DATABITS-1:0] in_databits
|
34
|
+
, input [`WIDTH-1:0] a
|
35
|
+
, input [`WIDTH-1:0] b
|
36
|
+
, input [1:0] in_op
|
37
|
+
|
38
|
+
// outputs
|
39
|
+
, output reg [`WIDTH-1:0] res
|
40
|
+
, output reg [`DATABITS-1:0] out_databits
|
41
|
+
, output reg [1:0] out_op
|
42
|
+
);
|
43
|
+
|
44
|
+
|
45
|
+
//-------------------------------------
|
46
|
+
// PHASE 0: perform the ALU operations
|
47
|
+
|
48
|
+
// operation ID
|
49
|
+
reg [`DATABITS-1:0] in_databits_phase0;
|
50
|
+
reg [1:0] in_op_phase0;
|
51
|
+
|
52
|
+
always @(*) begin
|
53
|
+
in_databits_phase0 = in_databits;
|
54
|
+
in_op_phase0 = in_op;
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
// addition
|
59
|
+
reg [`WIDTH-1:0] add_result_phase0;
|
60
|
+
|
61
|
+
always @(*) begin
|
62
|
+
add_result_phase0 = a + b;
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
// subtraction
|
67
|
+
reg [`WIDTH-1:0] sub_result_phase0;
|
68
|
+
|
69
|
+
always @(*) begin
|
70
|
+
sub_result_phase0 = a - b;
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
// multiplication
|
75
|
+
reg [`WIDTH-1:0] mul_result_phase0;
|
76
|
+
|
77
|
+
always @(*) begin
|
78
|
+
mul_result_phase0 = a * b;
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
// always @(posedge clk) begin
|
83
|
+
// $display("in_databits_phase0 => %d", in_databits_phase0);
|
84
|
+
// $display("in_op_phase0 => %d", in_op_phase0);
|
85
|
+
// $display("add_result_phase0 => %d", add_result_phase0);
|
86
|
+
// $display("sub_result_phase0 => %d", sub_result_phase0);
|
87
|
+
// $display("mul_result_phase0 => %d", mul_result_phase0);
|
88
|
+
// end
|
89
|
+
|
90
|
+
|
91
|
+
//-------------------------------------
|
92
|
+
// PHASE 1: delay the ALU results
|
93
|
+
|
94
|
+
reg [`DATABITS-1:0] in_databits_phase1;
|
95
|
+
reg [1:0] in_op_phase1;
|
96
|
+
|
97
|
+
reg [`WIDTH-1:0] add_result_phase1;
|
98
|
+
reg [`WIDTH-1:0] sub_result_phase1;
|
99
|
+
reg [`WIDTH-1:0] mul_result_phase1;
|
100
|
+
|
101
|
+
always @(posedge clk) begin
|
102
|
+
in_databits_phase1 <= in_databits_phase0;
|
103
|
+
in_op_phase1 <= in_op_phase0;
|
104
|
+
|
105
|
+
add_result_phase1 <= add_result_phase0;
|
106
|
+
sub_result_phase1 <= sub_result_phase0;
|
107
|
+
mul_result_phase1 <= mul_result_phase0;
|
108
|
+
end
|
109
|
+
|
110
|
+
// always @(posedge clk) begin
|
111
|
+
// $display("in_databits_phase1 => %d", in_databits_phase1);
|
112
|
+
// $display("in_op_phase1 => %d", in_op_phase1);
|
113
|
+
// $display("add_result_phase1 => %d", add_result_phase1);
|
114
|
+
// $display("sub_result_phase1 => %d", sub_result_phase1);
|
115
|
+
// $display("mul_result_phase1 => %d", mul_result_phase1);
|
116
|
+
// end
|
117
|
+
|
118
|
+
|
119
|
+
//-------------------------------------
|
120
|
+
// PHASE 2: delay the ALU results
|
121
|
+
|
122
|
+
reg [`DATABITS-1:0] in_databits_phase2;
|
123
|
+
reg [1:0] in_op_phase2;
|
124
|
+
|
125
|
+
reg [`WIDTH-1:0] add_result_phase2;
|
126
|
+
reg [`WIDTH-1:0] sub_result_phase2;
|
127
|
+
reg [`WIDTH-1:0] mul_result_phase2;
|
128
|
+
|
129
|
+
always @(posedge clk) begin
|
130
|
+
in_databits_phase2 <= in_databits_phase1;
|
131
|
+
in_op_phase2 <= in_op_phase1;
|
132
|
+
|
133
|
+
add_result_phase2 <= add_result_phase1;
|
134
|
+
sub_result_phase2 <= sub_result_phase1;
|
135
|
+
mul_result_phase2 <= mul_result_phase1;
|
136
|
+
end
|
137
|
+
|
138
|
+
// always @(posedge clk) begin
|
139
|
+
// $display("in_databits_phase2 => %d", in_databits_phase2);
|
140
|
+
// $display("in_op_phase2 => %d", in_op_phase2);
|
141
|
+
// $display("add_result_phase2 => %d", add_result_phase2);
|
142
|
+
// $display("sub_result_phase2 => %d", sub_result_phase2);
|
143
|
+
// $display("mul_result_phase2 => %d", mul_result_phase2);
|
144
|
+
// end
|
145
|
+
|
146
|
+
|
147
|
+
//-------------------------------------
|
148
|
+
// PHASE 3: produce the outputs
|
149
|
+
|
150
|
+
reg [`DATABITS-1:0] out_databits_next;
|
151
|
+
reg [1:0] out_op_next;
|
152
|
+
reg [`WIDTH-1:0] res_next;
|
153
|
+
|
154
|
+
always @(*) begin
|
155
|
+
if (reset) begin
|
156
|
+
out_op_next = `OP_NOP;
|
157
|
+
end else begin
|
158
|
+
out_op_next = in_op_phase2;
|
159
|
+
end
|
160
|
+
|
161
|
+
out_databits_next = in_databits_phase2;
|
162
|
+
|
163
|
+
// determine res_next
|
164
|
+
case (in_op_phase2)
|
165
|
+
`OP_NOP:
|
166
|
+
res_next = 0;
|
167
|
+
|
168
|
+
`OP_ADD:
|
169
|
+
res_next = add_result_phase2;
|
170
|
+
|
171
|
+
`OP_SUB:
|
172
|
+
res_next = sub_result_phase2;
|
173
|
+
|
174
|
+
`OP_MULT:
|
175
|
+
res_next = mul_result_phase2;
|
176
|
+
endcase
|
177
|
+
end
|
178
|
+
|
179
|
+
always @(posedge clk) begin
|
180
|
+
res <= res_next;
|
181
|
+
out_op <= out_op_next;
|
182
|
+
out_databits <= out_databits_next;
|
183
|
+
end
|
184
|
+
|
185
|
+
endmodule
|
186
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
`define WIDTH 32
|
2
|
+
`define DATABITS 7
|
3
|
+
`define OP_NOP 0
|
4
|
+
`define OP_ADD 1
|
5
|
+
`define OP_SUB 2
|
6
|
+
`define OP_MULT 3
|
7
|
+
|
8
|
+
module hw5_unit_bench;
|
9
|
+
|
10
|
+
// configuration for the design under test
|
11
|
+
|
12
|
+
|
13
|
+
// accessors for the design under test
|
14
|
+
reg clk ;
|
15
|
+
reg reset ;
|
16
|
+
reg [`DATABITS-1:0] in_databits ;
|
17
|
+
reg [`WIDTH-1:0] a ;
|
18
|
+
reg [`WIDTH-1:0] b ;
|
19
|
+
reg [1:0] in_op ;
|
20
|
+
wire [`WIDTH-1:0] res ;
|
21
|
+
wire [`DATABITS-1:0] out_databits ;
|
22
|
+
wire [1:0] out_op;
|
23
|
+
|
24
|
+
|
25
|
+
// instantiate the design under test
|
26
|
+
hw5_unit hw5_unit_bench_design (.clk(clk), .reset(reset), .in_databits(in_databits), .a(a), .b(b), .in_op(in_op), .res(res), .out_databits(out_databits), .out_op(out_op));
|
27
|
+
|
28
|
+
|
29
|
+
// interface to Ruby-VPI
|
30
|
+
initial begin
|
31
|
+
clk = 0;
|
32
|
+
$ruby_init("ruby", "-w", "-I", "../../lib", "hw5_unit_bench.rb");
|
33
|
+
end
|
34
|
+
|
35
|
+
// generate a 50% duty-cycle clock for the design under test
|
36
|
+
always begin
|
37
|
+
#5 clk = ~clk;
|
38
|
+
end
|
39
|
+
|
40
|
+
// transfer control to Ruby-VPI every clock cycle
|
41
|
+
always @(posedge clk) begin
|
42
|
+
#1 $ruby_relay();
|
43
|
+
end
|
44
|
+
|
45
|
+
endmodule
|