Verilog

計算機アーキテクチャ演習第2回
Verilogの復習
慶應義塾大学 理工学部 情報工学科
天野
変数と定数

変数

wire宣言:信号に名前を付ける



reg宣言:データを記憶できるレジスタが生成



[最大:最小] 最小は通常0にすることが多い
定数

<ビット幅> ′<基数><数値>




reg dff;
reg [3:0] acc;
両方ともバスの宣言が可能


wire sign;
wire [3:0] data1;
基数は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 y = com ? ina + inb : ina – inb;
前回井口先生が紹介し
function文を使う た方法、落とし穴あり

always文を使う 一時期FPGAベンダが推奨し

assign文を使う
た方法、落とし穴あり
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でも選択構文でも良い)
終わったら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する


Process WindowのModelSim Simulaterの+
ファイルをSaveする
印をクリックすると、ModelSimのアイコンが出て
左下のProcess
WindowのBehavioal
くるので、これをクリック
波形を確認しよう
変更したくなったら



一度、ModelSimをQuitして、Xilinx iseに
戻り
編集して、再びクリックしてスタート
本当はModelSim内で変更、リスタート等す
べて可能
次回の演習




4bit ALUを設計
comを3ビットとし、前学期やったアキュ
ムレータマシンに相当する機能を付け加
えよ
ModelSimでシミュレーションして動作を
確認
ファイルをメールで提出