230 likes | 529 Views
計算機アーキテクチャ演習第 2 回 Verilog の復習. 慶應義塾大学 理工学部 情報工学科 天野. 変数と定数. 変数 wire 宣言:信号に名前を付ける wire sign; wire [3:0] data1; reg 宣言:データを記憶できるレジスタが生成 reg dff; reg [3:0] acc; 両方ともバスの宣言が可能 [ 最大:最小 ] 最小は通常0にすることが多い 定数 <ビット幅> ′ <基数><数値> 基数は 2 進 b,16 進 h 、何もつかなければ 10 進数 (32 ビット ) 16’b11001010 16’hca
E N D
計算機アーキテクチャ演習第2回Verilogの復習 慶應義塾大学 理工学部 情報工学科 天野
変数と定数 • 変数 • wire宣言:信号に名前を付ける • wire sign; • wire [3:0] data1; • reg宣言:データを記憶できるレジスタが生成 • reg dff; • reg [3:0] acc; • 両方ともバスの宣言が可能 • [最大:最小] 最小は通常0にすることが多い • 定数 • <ビット幅> ′<基数><数値> • 基数は2進b,16進h、何もつかなければ10進数(32ビット) • 16’b11001010 • 16’hca • パラメータ • parameter文(前回井口先生がやった)で定数は定義するのが良い
assign文と論理演算 • assign文 • 継続的な代入:配線が繋がっていていつでも出力される • 左辺はwireのみ • assign y = a + b; • assign y = a & b|~a&~b; • 普通の論理演算素子が使える • 算術演算 + ー * / % • ビット演算 ~(NOT) & | ^(Ex-OR) • 論理演算 ! && || • リダクション演算 & ~& | ~| ^ (変数の頭に付ける&aなど) • 等号、関係 == != < <= > >= • シフト << >> • 条件演算 ? : • 二つのassign文は同時並行的に実行される • 同じ出力に対して2つの文でassignするのはエラー
ビット切り出しと連結 • ビット切り出し • wire [15:0] a; • wire [7:0] x,y; • assign x = a[15:8] & a[7:0]; • 連結 • assign a = {x,y}; • assign {c, y} = ina+inb; • {4{2’b10}} →10101010 • assign a = {16{x[15]}, x};
選択的な記述 • Verilogは二つの文を書くと並列に動く • では、ある条件でAの文、別の条件でBの文を動かす選択的記述は? • 三つの方法がある • assign文を使う • assign y = com ? ina + inb : ina – inb; • function文を使う • always文を使う 天野は好きだが一般には推奨されない 前回井口先生が紹介した方法、落とし穴あり 一時期FPGAベンダが推奨した方法、落とし穴あり
assign文を使う方法 assign y = (com==ADD) ? a + b: (com== SUB) ? a - b: (com== AND) ? a & b: a | b; • なんとなくCASE文っぽく見えるんじゃない? • 余計な宣言が不要で面倒が一番少ない • 欠点: • 条件が単純なcase文的な場合はうまく書けるが、条件構造が複雑だと読みにくい • 不要な優先順位が付いて合成系を制約する可能性がある
ALUの記述例 module ALU(A, B, COM, ALUOUT); parameter DWIDTH = 4; parameter NOP=3'b000, LD=3'b001, AND=3'b010, OR =3'b011, SL=3'b100, SR=3'b101, ADD=3'b110, SUB=3'b111; input [DWIDTH-1:0] A, B; input [2:0] COM; output [DWIDTH-1:0] ALUOUT; assign ALUOUT = COM == NOP ? A : COM == LD ? B : COM == AND ? A & B: COM == …. : …. ; // ここの間は自分で埋めること endmodule
function文 -if文の利用- assign y = alu(a,b,com); function [3:0] alu (ina,inb,com); input [3:0] ina,inb; input [2:0] com; begin if (com==ADD) alu = a + b ; else if (com==SUB) alu = a –b ; else if (com==AND) alu = a & b ; else alu = a | b; end endfunction
function文 –case文の利用- assign y = alu(a,b,com); function [3:0] alu (ina,inb,com); input [3:0] ina,inb; input [2:0] com; begin case(com) ADD: alu = a + b ; SUB: alu = a –b ; AND: alu = a & b ; default: alu = a | b; endcase end endfunction
function文の問題点 • 出力が複数の場合はどうするの? • 意味的に関係があるものは出力の連結を利用 • 意味的に関係の薄い出力を一つのfunction文に指定してはいけない→分けること! • 代入時のビット幅、割付に注意→あまりたくさんの出力をfunction文で指定することはお勧めできない • そもそもfunctionって複数個所で呼ぶことに意味があるのでは??? ま、いいじゃん
function文の複数出力指定 assign {c,y} = alu(a,b,com); function [4:0] alu (ina,inb,com); input [3:0] ina,inb; input [2:0] com; begin case(com) ADD: alu = a + b ; SUB: alu = a –b ; AND: alu = {1’b0,a & b} ; default: alu = {1’b0,a | b}; endcase end endfunction
なぜ選択的な構文が書けないか? • 出力が複数になると、値が定義されなくなるから begin if (com==`ADD){c,y}= a + b ; else if (com==`AND) y = a & b ; else y = a | b; end • と書かれると、cはADD以外では何を出して良いかわからなくなってしまう。 • この時cを不定にして合成系に任せるという手もあるが、Verilogはこれを許さず、何とか値を入れようとする • Verilogは基本的に出力一つに対してその論理を入力の組み合わせとして考え、データパスと制御を分離する方法であり、これはこれで優れていると言える
ALUの記述 module ALU(A, B, COM, ALUOUT); parameter DWIDTH = 4; parameter NOP=3'b000, LD=3'b001, AND=3'b010, OR =3'b011, SL=3'b100, SR=3'b101, ADD=3'b110, SUB=3'b111; input [DWIDTH-1:0] A, B; input [2:0] COM; output [DWIDTH-1:0] ALUOUT; assign ALUOUT = alu(A, B, COM); function [DWIDTH-1:0] alu; input [DWIDTH-1:0] A, B; input [2:0] COM; begin case (COM) NOP: alu = A; LD: alu = B; // ここの間は自分で埋めること default: alu = 4'bxxxx; endcase end endfunction endmodule
来週の演習 ALUのシミュレーション • ModelSimを利用する • Mentor社の本格的なシミュレータ • Verilog用テストベンチを使う • テストベンチとは、シミュレーションの制御のみを行うVerilog記述 • 前期も本当は使っていたのだが、Xilinx社の波形エディタを介していたので、多分一見分からなかったと思う
プロジェクトの作成 • iseを立ち上げる • File -> New Project • Project Wizardが上がる • Project名を適当(ALUとか)に付ける • Select the Device and Design Flow for the Projectのウインドウが出る • SimulaterをModelsim-SE Verilogに後はデフォルトで大丈夫(多分)
New Source Verilog moduleを選択 ALU.v Nextで入出力の設定画面に行くがパラメータを使いたいのでここはパスする 以降、ひたすらNextで進んでFinish
ここに、設計の記述を打ち込む(Functionでも選択構文でも良い)ここに、設計の記述を打ち込む(Functionでも選択構文でも良い) 終わったらFile -> Save
Behavioral Simulationを選択 どこかのファイルを選んで右クリックし、New Sourceを選択 ファイルの種類はVerilog Test Fixtureを選択 ファイル名はALUTEST.vなど あとはどんどんNextを押し、Finish
テストベンチのテンプレート module ALUTEST_v; // Inputs reg [3:0] A; reg [3:0] B; reg [2:0] COM; // Outputs wire [3:0] ALUOUT; // Instantiate the Unit Under Test (UUT) ALU uut ( .A(A), .B(B), .COM(COM), .ALUOUT(ALUOUT) ); initial begin // Initialize Inputs A = 0; B = 0; COM = 0; // Wait 100 ns for global reset to finish #100; // Add stimulus here end endmodule COM=1; #100; COM=6; #100;などやってみる たとえばB=2とかして 100ns時間経過 ここに入力変化を 書き込む
Modelsimの起動 ファイルをSaveする ProcessWindowのModelSim Simulaterの+印をクリックすると、ModelSimのアイコンが出てくるので、これをクリック • ファイルをSaveする • 左下のProcess WindowのBehavioal
変更したくなったら • 一度、ModelSimをQuitして、Xilinxiseに戻り • 編集して、再びクリックしてスタート • 本当はModelSim内で変更、リスタート等すべて可能
次回の演習 • 4bit ALUを設計 • comを3ビットとし、前学期やったアキュムレータマシンに相当する機能を付け加えよ • ModelSimでシミュレーションして動作を確認 • ファイルをメールで提出