Changes between Initial Version and Version 1 of Ex04課題2016


Ignore:
Timestamp:
May 12, 2016 2:06:23 PM (10 years ago)
Author:
nakasato
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Ex04課題2016

    v1 v1  
     1トップ:http://galaxy.u-aizu.ac.jp/note/wiki/CAEX2016 
     2 
     3= 準備 =  
     4今週から、MIPSプロセッサを設計します。 
     5そのために、VerilogHDLを用いた記述方法、シミュレータ、波形ビューアなどの各種CADツールの使いかたを習得します。 
     6 
     7== シミュレーションのためのログイン == 
     8{{{ 
     9ssh -X hdw1dc 
     10}}} 
     11 
     12simvisionのウインドウが開かない場合には、 
     13 
     14{{{ 
     15/bin/ssh -X hdw1dc 
     16}}} 
     17でログインすること。 
     18 
     19hostnameは各自の目の前の計算機にすること。 
     20 
     21 
     22= ALUモジュールの設計と検証 = 
     23算術論理演算ユニット(arithmetic logic unit, ALU)は、加算や減算などの算術演算や、 
     24ANDやORなどの論理演算を行うプロセッサの中枢部分です。 
     25今週はMIPSプロセッサで使われる32ビットのALUを作成し、 
     26さらにシミュレーションによって動作検証をします。 
     27 
     28今回設計するALUの入出力信号は次の図の通りです。 
     29AとBは入力でどちらも32ビット幅です。 
     30ALU制御入力(ALUoperation)は4ビット幅の入力で、演算の種類を指定します。 
     31演算結果(ALUresult)も32ビットで出力されます。 
     32ゼロ判定出力(Zero)は演算結果が32ビットとも0であるときに1となる信号です。  
     33  
     34[[Image(http://galaxy.u-aizu.ac.jp/note/raw-attachment/wiki/Ex04%E8%AA%B2%E9%A1%8C2015/alu.gif)]] 
     35 
     36このALUでは下に示す6種類の演算をサポートします。第4版上巻p.290参照。 
     37 
     38|| ALU制御入力 || 機能 || 
     39|| 0b0000      || AND  ||  
     40|| 0b0001      || OR   ||  
     41|| 0b0010      || 加算  ||  
     42|| 0b0110      || 減算  ||  
     43|| 0b0111      || Set on less than ||  
     44|| 0b1100      || NOR  ||  
     45 
     46ANDは2つの入力の各ビットの論理積、ORは論理和を実行することを意味します。 
     47Set on less than は比較命令で利用される演算で、2つの入力の大小関係によって 0 または 1 を次の表のように出力します。 
     48 
     49|| || ALUの出力 || 
     50|| A < B || 0x00000001 || 
     51|| A ≧ B || 0x00000000 || 
     52 
     53今回作成するプロセッサでは、加算、減算実行時にはオーバフローは想定しません。 
     54オーバフローが発生した場合でも、下位のbitは正しい値が出力されるように設計します。 
     55 
     56== ALUモジュールの作成 == 
     57ALUは3つの入力A,B,ALUoperation、2つの出力ALUresultとZeroをもちます。 
     58 
     59以下は、ALUモジュールのVerilog HDL記述です。 
     60{{{ 
     61module  ALU(A,B,ALUoperation,ALUresult,Zero);     
     62       
     63input [31:0]     A;  
     64input [31:0]     B;  
     65input [3:0]      ALUoperation;  
     66output [31:0]    ALUresult;  
     67output           Zero;  
     68       
     69reg    [31:0]    ALUresult;  
     70wire   [32:0]    tmp;  
     71       
     72      // Output Zero is defined by assign statement       
     73      assign Zero = (ALUresult == 0)? 1'b1 : 1'b0;  
     74       
     75      // tmp is the result of A - B, in 33bit  
     76      assign tmp = {A[31], A} - {B[31], B};  
     77       
     78      // Output ALUresult is defined by always statement  
     79      always @(A or B or ALUoperation or tmp)  
     80        begin case( ALUoperation )  
     81          4'b0000 : ALUresult <= A & B;  
     82          4'b0001 : ALUresult <= A | B;  
     83          4'b0010 : ALUresult <= A + B;  
     84          4'b0110 : ALUresult <= A - B;  
     85          4'b0111 : ALUresult <= {31'b0, tmp[32]};  
     86          4'b1100 : ALUresult <= (~A) & (~B);  
     87          default : ALUresult <= 32'b0;  
     88       endcase  
     89      end  
     90       
     91endmodule      
     92}}} 
     93 
     94上記の記述をファイル名「ALU.v」として保存します。 
     95以下の演習では、ファイル名は「(モジュール名).v」としてください。 
     96また、1つのファイルには1つのモジュールを定義します。 
     97 
     98VerilogHDLの記述方法は、参考図書を参考にしてください。 
     99この記述では、抽象度の高いBehaviorレベルでの設計が行われています。 
     100 
     101このALU記述では、assign文とalways文を用いています。 
     102両方をalways文で設計することもできます. 
     103加減算、大小比較は、VerilogHDLの算術演算を用いて実現しています。 
     104 
     105加減算における入力AとBは2の補数で表された符号付き32bitデータです。 
     106下位31ビットが数をあらわし、最上位ビットが符号を表します。 
     107 
     108== インスタンス化について == 
     109VerilogHDLでモジュールを利用するには、その定義をするだけでなく、その実体を作り出す必要があります。 
     110これをインスタンス化といいます。 
     111 
     112参考書では、18ページ「3.1.2 全加算器のHDL記述」に説明があります。 
     113図3.4がその例となっていて、ここではfull_adder回路の定義の中で、half_adder回路を2つインスタンス化しています。 
     114"i0"と"i1"はインスタンスの名前で、他のインスタンスと重ならない任意の名前をつけることができます。 
     115 
     116図3.4では、明示的に信号の接続を記述していますが、以下のように省略して記述できます。 
     117この場合には、並んでいる順番に信号が接続されます。 
     118{{{ 
     119module full_adder(a, b, ci, s, co); 
     120   input a, b, ci; 
     121   output s, co; 
     122   wire   w0, w1, w2; 
     123 
     124   assign co = w1 | w2; 
     125   half_adder i0 (w1, w0, a, b);  // half_adder i0 (.co(w1), .s(w0), .a(a), .b(b)); 
     126   half_adder i1 (w2, s, w0, ci); // half_adder i1 (.co(w2), .s(s), .a(w0), .b(ci)); 
     127endmodule 
     128}}} 
     129 
     130== テストベンチの作成 == 
     131作成したALUが正しく動作するかどうかシミュレーションによって確認します。 
     132すべての入力値の組み合わせについてチェックするのは 不可能ですから(非常に時間がかかる)、 
     133下の表に示されている入力の組み合わせについてシミュレーションを行い、出力が期待値と一致することを確認します。  
     134 
     135まず、テストパターンをシミュレーションするためのテストベンチのテンプレートを示します。 
     136{{{ 
     137`timescale 1ns/1ps       
     138       
     139`include "ALU.v"   // Include statement of ALU module    
     140       
     141module  ALUtestbench;   // testbench module ALUtestbench do not have inputs and output  
     142       
     143reg [31:0]     inA;  
     144reg [31:0]     inB;  
     145reg [3:0]      inALUop;  
     146wire [31:0]    outALUresult;  
     147wire           outZero;  
     148       
     149ALU     alu(inA,inB,inALUop,outALUresult,outZero); // Instance definition  
     150       
     151initial       
     152 begin       
     153       
     154  $dumpfile("ALUtestbench.vcd"); //Function call for the save of execution results as VCD format to       
     155  $dumpvars(0, alu); //Function call to specify the top module       
     156       
     157  #0 inALUop = 4'b0000; inA= 32'h00000000; inB = 32'h00000000;      //Setting of inputs  
     158       
     159  #100      //Time passes. ALU operates for inputs.  
     160       
     161  $display( $time, " ALUoperation=%h, A=%h, B=%h, ALUresult=%h, Zero=%h",inALUop,inA,inB,outALUresult,outZero);      
     162      // Display of inputs and outputs  
     163       
     164  inALUop = 4'b0000; inA= 32'h0F0F0F0F; inB = 32'hF0F0F0F0;        
     165       
     166  #100        
     167       
     168  $display( $time, " ALUoperation=%h, A=%h, B=%h, ALUresult=%h, Zero=%h",inALUop,inA,inB,outALUresult,outZero);      
     169       
     170     ....  
     171     // In this space, describe other testbench descriptions  
     172     ....  
     173       
     174  inALUop = 4'b0000; inA= 32'h00000000; inB = 32'h00000000; // dummy input  
     175  $finish;        
     176 end       
     177endmodule      
     178}}} 
     179 
     180このテストベンチ記述を完成させます。ファイル名は「ALUtestbench.v」とします。 
     181 
     182このテストベンチを実行すると、$DISPLAY文により結果がテキスト形式で表示され、 
     183同時に$dumpfileと$dumpvars文によりVCD形式でファイル「ALUtestbench.vcd」に保存されます。 
     184 
     185{{{ 
     186ALU     alu(inA,inB,inALUop,outALUresult,outZero); // Instance definition  
     187}}} 
     188の行で、ALUモジュールをインスタンス化しています。接続は省略記法でおこなっていることに注意してください。 
     189 
     190== テストベンチの実行 == 
     191シミュレータは「nverilog」コマンドを使います。 
     192 
     193{{{ 
     194ncverilog ALUtestbench.v 
     195}}} 
     196 
     197というコマンドで、テストベンチを実行することができます。 
     198最初に文法チェックが行われるので,そこでエラーが発生したら、ファイルを修正してください。 
     199エラーがなくなったら、テストベンチが実行されます。 
     200$display文による実行結果を確認してください。 
     201実行途中の全ての信号の状態は「ALUtestbench.vcd」に保存されます。 
     202 
     203波形ビューアsimvisionを用いて実行結果を確認します。 
     204simvision起動後、File -> Open Database で、シミュレーションで作成したVCDファイル「ALUtestbench.vcd」を選択します。 
     205ファイルの種類をVCD Fileにして、ファイルを選択すること。 
     206これ以降は、今までCadenceの統合環境icdsでの作業と同じです。 
     207確認したい信号名を選んで、右上の波形マークをクリックして、波形を確認します。 
     208 
     209= 今週の課題 = 
     210下の入力パターンを全て「ALUtestbench.v」に追加して、ALUの動作を確認してください。 
     211演習時間内に動作確認をおこなうので、挙手してTAまたは教員に動作を示すこと。 
     212 
     213[[Image(http://galaxy.u-aizu.ac.jp/note/raw-attachment/wiki/Ex04%E8%AA%B2%E9%A1%8C2015/test.png)]]