| Version 7 (modified by nakasato, 9 years ago) (diff) |
|---|
トップ:http://galaxy.u-aizu.ac.jp/note/wiki/CAEX2017
準備
今週から、MIPSアーキテクチャのプロセッサを設計します。 そのために、Verilog HDLを用いた記述方法、シミュレータ、波形ビューアなどの各種CADツールの使いかたを習得します。
注意点
CADのツールは、Linuxのサーバーで動作します。プロセッサを設計するためには、Verilog HDLによりプロセッサを記述したり、 テストベンチを作成する必要があり、emacsを使って編集する際にはSolarisのサーバーを使う必要があります。 今回以降の演習では、"solsv"(Solaris)のターミナルと"cadsv"(Linux)のターミナルの両方を立ち上げて、ファイル編集とCADの利用を使い分けてください。
ALUモジュールの設計とテスト(動作検証)
算術論理演算ユニット(arithmetic logic unit, ALU)は、加算や減算などの算術演算や、 ANDやORなどの論理演算を行う、プロセッサの中枢部分です。 今週はMIPSプロセッサで使われる32ビットのALUを作成し、 さらにシミュレーションによって動作検証をします。
今回設計するALUの入出力信号は次の図の通りです。 AとBは入力でどちらも32ビット幅です。 ALU制御入力(ALUoperation)は4ビット幅の入力で、演算の種類を指定します。 演算結果(ALUresult)も32ビットで出力されます。 ゼロ判定出力(Zero)は演算結果が32ビットとも0であるときに1となる信号です。
このALUでは下に示す6種類の演算をサポートします。第5版上巻p.251参照。
| ALU制御入力 | 機能 |
| 0b0000 | AND |
| 0b0001 | OR |
| 0b0010 | 加算 |
| 0b0110 | 減算 |
| 0b0111 | Set on less than |
| 0b1100 | NOR |
ANDは2つの入力の各ビットの論理積、ORは論理和を実行することを意味します。 Set on less than は比較命令で利用される演算で、2つの入力の大小関係によって 0 または 1 を次の表のように出力します。
| ALUの出力 | |
| A < B | 0x00000001 |
| A ≧ B | 0x00000000 |
今回作成するプロセッサでは、加算、減算実行時にはオーバフローは想定しません。 オーバフローが発生した場合でも、下位のbitは正しい値が出力されるように設計します。
ALUモジュールの作成
ALUは3つの入力A,B,ALUoperation、2つの出力ALUresultとZeroをもちます。
以下は、ALUモジュールのVerilog HDL記述です。
module ALU(A,B,ALUoperation,ALUresult,Zero);
input [31:0] A;
input [31:0] B;
input [3:0] ALUoperation;
output [31:0] ALUresult;
output Zero;
reg [31:0] ALUresult;
wire [32:0] tmp;
// Output Zero is defined by assign statement
assign Zero = (ALUresult == 0)? 1'b1 : 1'b0;
// tmp is the result of A - B, in 33bit
assign tmp = {A[31], A} - {B[31], B};
// Output ALUresult is defined by always statement
always @(A or B or ALUoperation or tmp)
begin case( ALUoperation )
4'b0000 : ALUresult <= A & B;
4'b0001 : ALUresult <= A | B;
4'b0010 : ALUresult <= A + B;
4'b0110 : ALUresult <= A - B;
4'b0111 : ALUresult <= {31'b0, tmp[32]};
4'b1100 : ALUresult <= (~A) & (~B);
default : ALUresult <= 32'b0;
endcase
end
endmodule
VerilogHDLの記述方法は、参考図書を参考にしてください。 この記述では、抽象度の高いBehaviorレベルでの設計が行われています。
加減算における入力AとBは2の補数で表された符号付き32bitデータです。 下位31ビットが数をあらわし、最上位ビットが符号を表します。
このALU記述では、assign文とalways文を用いています。 両方をalways文で設計することもできます. 加減算、大小比較は、VerilogHDLの算術演算を用いて実現しています。
上記のVerilog HDL記述をファイル名「ALU.v」として保存してください。
以降の演習では、ファイル名は「(モジュール名).v」としてください。また、1つのファイルには1つのモジュールを定義します。
インスタンス化について
VerilogHDLでモジュールを利用するには、その定義をするだけでなく、その実体を作り出す必要があります。 これをインスタンス化といいます。
参考書では、18ページ「3.1.2 全加算器のHDL記述」に説明があります。 図3.4がその例となっていて、ここではfull_adder回路の定義の中で、half_adder回路を2つインスタンス化しています。 "i0"と"i1"はインスタンスの名前で、他のインスタンスと重ならない任意の名前をつけることができます。
図3.4では、明示的に信号の接続を記述していますが、以下のように省略して記述できます。 この場合には、並んでいる順番に信号が接続されます。
module full_adder(a, b, ci, s, co); input a, b, ci; output s, co; wire w0, w1, w2; assign co = w1 | w2; half_adder i0 (w1, w0, a, b); // half_adder i0 (.co(w1), .s(w0), .a(a), .b(b)); half_adder i1 (w2, s, w0, ci); // half_adder i1 (.co(w2), .s(s), .a(w0), .b(ci)); endmodule
テストベンチの作成
作成したALUが正しく動作するかどうかシミュレーションによって確認します。 すべての入力値の組み合わせについてチェックするのは不可能ですから(非常に時間がかかるため)、 下の表に示されている入力の組み合わせについてシミュレーションを行い、出力が期待値と一致することを確認します。
まず、テストパターンをシミュレーションするためのテストベンチのテンプレートを示します。
`timescale 1ns/1ps
`include "ALU.v" // Include statement of ALU module
module ALUtestbench; // testbench module ALUtestbench do not have inputs and output
reg [31:0] inA;
reg [31:0] inB;
reg [3:0] inALUop;
wire [31:0] outALUresult;
wire outZero;
ALU alu(inA,inB,inALUop,outALUresult,outZero); // Instance definition
initial
begin
$dumpfile("ALUtestbench.vcd"); //Function call for the save of execution results as VCD format to
$dumpvars(0, alu); //Function call to specify the top module
#0 inALUop = 4'b0000; inA= 32'h00000000; inB = 32'h00000000; //Setting of inputs
#100 //Time passes. ALU operates for inputs.
$display( $time, " ALUoperation=%h, A=%h, B=%h, ALUresult=%h, Zero=%h",inALUop,inA,inB,outALUresult,outZero);
// Display of inputs and outputs
inALUop = 4'b0000; inA= 32'h0F0F0F0F; inB = 32'hF0F0F0F0;
#100
$display( $time, " ALUoperation=%h, A=%h, B=%h, ALUresult=%h, Zero=%h",inALUop,inA,inB,outALUresult,outZero);
....
// In this space, describe other testbench descriptions
....
inALUop = 4'b0000; inA= 32'h00000000; inB = 32'h00000000; // dummy input
$finish;
end
endmodule
このテストベンチ記述を完成させます。ファイル名は「ALUtestbench.v」とします。
このテストベンチを実行すると、$display文により結果がテキスト形式で表示され、 同時に$dumpfileと$dumpvars文によりVCD形式でファイル「ALUtestbench.vcd」に保存されます。
ALU alu(inA,inB,inALUop,outALUresult,outZero); // Instance definition
の行で、ALUモジュールをインスタンス化しています。接続は省略記法でおこなっていることに注意してください。
テストベンチの実行
シミュレータは「ncverilog」コマンドを使います。
ncverilog ALUtestbench.v
というコマンドで、テストベンチを実行することができます。 最初に文法チェックが行われるので,そこでエラーが発生したら、ファイルを修正してください。 エラーがなくなったら、テストベンチが実行されます。 $display文による実行結果を確認してください。 実行途中の全ての信号の状態は「ALUtestbench.vcd」に保存されます。
ALUモジュールの全ての信号の内容を確認するには、波形ビューアが利用できます。 "cadsv"で"simvision"コマンドを実行し起動してください。 simvision起動後、「File -> Open Database」で、シミュレーションで作成したVCDファイル「ALUtestbench.vcd」を選択します。 この時、ファイルの種類をVCD Fileにして、ファイルを選択すること。
これ以降は、今までCadenceの統合環境icdsでの作業と同じです。 確認したい信号名を選んで、右上の波形マークをクリックして、波形を確認します。
今週の課題
下の入力パターンを全て「ALUtestbench.v」に追加して、ALUの動作を確認してください。 演習時間内に動作確認をおこなうので、挙手してTAまたは教員に動作を示すこと。
Attachments (2)
- alu.gif (1.7 KB) - added by nakasato 9 years ago.
- test.png (49.9 KB) - added by nakasato 9 years ago.
Download all attachments as: .zip


