| 97 | | |
| 98 | | |
| | 97 | == インスタンス化について == |
| | 98 | VerilogHDLでモジュールを利用するには、その定義をするだけでなく、その実体を作り出す必要があります。 |
| | 99 | これをインスタンス化といいます。 |
| | 100 | |
| | 101 | 参考書では、18ページ「3.1.2 全加算器のHDL記述」に説明があります。 |
| | 102 | 図3.4がその例となっていて、ここではfull_adder回路の定義の中で、half_adder回路を2つインスタンス化しています。 |
| | 103 | "i0"と"i1"はインスタンスの名前で、他のインスタンスと重ならない任意の名前をつけることができます。 |
| | 104 | |
| | 105 | 図3.4では、明示的に信号の接続を記述していますが、以下のように省略して記述できます。 |
| | 106 | この場合には、並んでいる順番に信号が接続されます。 |
| | 107 | {{{ |
| | 108 | module full_adder(a, b, ci, s, co); |
| | 109 | input a, b, ci; |
| | 110 | output s, co; |
| | 111 | wire w0, w1, w2; |
| | 112 | |
| | 113 | assign co = w1 | w2; |
| | 114 | half_adder i0 (w1, w0, a, b); // half_adder i0 (.co(w1), .s(w0), .a(a), .b(b)); |
| | 115 | half_adder i1 (w2, s, w0, ci); // half_adder i1 (.co(w2), .s(s), .a(w0), .b(ci)); |
| | 116 | endmodule |
| | 117 | }}} |
| | 118 | |
| | 119 | == テストベンチの作成 == |
| | 120 | 作成したALUが正しく動作するかどうかシミュレーションによって確認します。 |
| | 121 | すべての入力値の組み合わせについてチェックするのは 不可能ですから(非常に時間がかかる)、 |
| | 122 | 下の表に示されている入力の組み合わせについてシミュレーションを行い、出力が期待値と一致することを確認します。 |
| | 123 | |
| | 124 | まず、テストパターンをシミュレーションするためのテストベンチのテンプレートを示します。 |
| | 125 | {{{ |
| | 126 | `timescale 1ns/1ps |
| | 127 | |
| | 128 | `include "ALU.v" // Include statement of ALU module |
| | 129 | |
| | 130 | module ALUtestbench; // testbench module ALUtestbench do not have inputs and output |
| | 131 | |
| | 132 | reg [31:0] inA; |
| | 133 | reg [31:0] inB; |
| | 134 | reg [3:0] inALUop; |
| | 135 | wire [31:0] outALUresult; |
| | 136 | wire outZero; |
| | 137 | |
| | 138 | ALU alu(inA,inB,inALUop,outALUresult,outZero); // Instance definition |
| | 139 | |
| | 140 | initial |
| | 141 | begin |
| | 142 | |
| | 143 | $dumpfile("ALUtestbench.vcd"); //Function call for the save of execution results as VCD format to |
| | 144 | $dumpvars(0, alu); //Function call to specify the top module |
| | 145 | |
| | 146 | #0 inALUop = 4'b0000; inA= 32'h00000000; inB = 32'h00000000; //Setting of inputs |
| | 147 | |
| | 148 | #100 //Time passes. ALU operates for inputs. |
| | 149 | |
| | 150 | $display( $time, " ALUoperation=%h, A=%h, B=%h, ALUresult=%h, Zero=%h",inALUop,inA,inB,outALUresult,outZero); |
| | 151 | // Display of inputs and outputs |
| | 152 | |
| | 153 | inALUop = 4'b0000; inA= 32'h0F0F0F0F; inB = 32'hF0F0F0F0; |
| | 154 | |
| | 155 | #100 |
| | 156 | |
| | 157 | $display( $time, " ALUoperation=%h, A=%h, B=%h, ALUresult=%h, Zero=%h",inALUop,inA,inB,outALUresult,outZero); |
| | 158 | |
| | 159 | .... |
| | 160 | // In this space, describe other testbench descriptions |
| | 161 | .... |
| | 162 | |
| | 163 | inALUop = 4'b0000; inA= 32'h00000000; inB = 32'h00000000; // dummy input |
| | 164 | $finish; |
| | 165 | end |
| | 166 | endmodule |
| | 167 | }}} |
| | 168 | |
| | 169 | このテストベンチ記述を完成させます。ファイル名は「ALUtestbench.v」とします。 |
| | 170 | |
| | 171 | このテストベンチを実行すると、$DISPLAY文により結果がテキスト形式で表示され、 |
| | 172 | 同時に$dumpfileと$dumpvars文によりVCD形式でファイル「ALUtestbench.vcd」に保存されます。 |
| | 173 | |
| | 174 | {{{ |
| | 175 | ALU alu(inA,inB,inALUop,outALUresult,outZero); // Instance definition |
| | 176 | }}} |
| | 177 | の行で、ALUモジュールをインスタンス化しています。接続は省略記法でおこなっていることに注意してください。 |
| | 178 | |
| | 179 | == テストベンチの実行 == |
| | 180 | シミュレータは「ncverilog」コマンドを使います。 |
| | 181 | |
| | 182 | {{{ |
| | 183 | ncverilog ALUtestbench.v |
| | 184 | }}} |
| | 185 | |
| | 186 | というコマンドで、テストベンチを実行することができます。 |
| | 187 | 最初に文法チェックが行われるので,そこでエラーが発生したら、ファイルを修正してください。 |
| | 188 | エラーがなくなったら、テストベンチが実行されます。 |
| | 189 | $display文による実行結果を確認してください。 |
| | 190 | 実行途中の全ての信号の状態は「ALUtestbench.vcd」に保存されます。 |
| | 191 | |
| | 192 | 波形ビューアsimvisionを用いて実行結果を確認します。 |
| | 193 | simvision起動後、File -> Open Database で、シミュレーションで作成したVCDファイル「ALUtestbench.vcd」を選択します。 |
| | 194 | ファイルの種類をVCD Fileにして、ファイルを選択すること。 |
| | 195 | これ以降は、今までCadenceの統合環境icdsでの作業と同じです。 |
| | 196 | 確認したい信号名を選んで、右上の波形マークをクリックして、波形を確認します。 |
| | 197 | |
| | 198 | = 今週の課題 = |
| | 199 | 下の入力パターンを全て「ALUtestbench.v」に追加して、ALUの動作を確認してください。 |
| | 200 | 演習時間内に動作確認をおこなうので、挙手してTAまたは教員に動作を示すこと。 |