Upload
mina
View
55
Download
4
Embed Size (px)
DESCRIPTION
第二部 回路記述編. 第 3 章 文法概略と基本記述スタイル. 3.1 文法を少々 3.1.1 ~ 3.1.3. module モジュール名 ( ポート・リスト ) ;. ポート宣言. ネット宣言 レジスタ宣言 パラメータ宣言. 回路記述 assign 文 組み合わせ回路の記述 function always 文 順序回路の記述 下位モジュール呼び出し. endmodule. 図 3.1 モジュール構造. 3.1 文法を少々 3.1.1 モジュール構造. - PowerPoint PPT Presentation
Citation preview
第 3 章
文法概略と基本記述スタイル
第二部 回路記述編
3.1 文法を少々 3.1.1 ~3.1.3
3.1 文法を少々 3.1.1 モジュール構造
module モジュール名 ( ポート・リスト ) ;
ポート宣言
ネット宣言
レジスタ宣言
パラメータ宣言
回路記述
assign 文 組み合わせ回路の記述
function
always 文 順序回路の記述
下位モジュール呼び出し
endmodule
図 3.1 モジュール構造
回路を記述する構造がモジュールです
「モジュール」は予約語の
module と endmodule で囲まれ回路表現から
シミュレーション用の入力まで、すべてがこ
の中で記述される。
module に続き、モジュール名、ポート・リスト、
を記述する。
「ポート・リスト」とは、出力、入力の端子名を
例拳したものです。
モジュール名やポート・リスト名などの識別子には英数字と_(アンダ スコ・ア)が使え、大文字小文字を区別します。
(a) ポート宣言例
input ck,res; // 入力
input [7:0] bus1, bus2; // 入力、バス信号
output busy; // 出力
input [15:0] dbus; // 双方出力
(b) ネット宣言例
wire enb1; // バス信号
wire [7:0] bus;
(c) レジスタ宣言例
reg ff1, ff2;
reg [3:0] cnt4; // 4 ビット レジスタ・
reg [7:0] mem [0:255]; // 256 バイト・メモリ
(d) パラメータ宣言例
parameter STEP=1000; // 1 クロック周期
parameter HALT =2’b00, INIT=2’b01,ACTION=2’b10: // ステート
parameter MEMSIZE=1024;
reg [7:0] mem [0:MEMSIZE-1]; // パラメータ使用例
図 3.2 各種宣言例
宣言部分構成
ポート・リストに対応したポート・リスト宣言
モジュール内部で用いる信号を定義する
ネット宣言とレジスタ宣言
定数を定義するパラメータ宣言
回路記述部分構成
組み合わせ回路
assign 文
function
順序回路
always 文
別のモジュールを接続する
下位モジュール呼び出し
3.1.2 論理値と数値表現
論理値
Verilog HDL で扱える論理値は
‘ 0’, ‘1’, ‘x’( 不定値 ), ‘z’( ハイ・インピーダンス )
の 4 値です。 8 値の信号強度
supply, strong, pull, large, weak, medium, small, highz
を付加できます。信号強度を指定しなければ、 strong
となります。シミュレーションのときだけ用いる。
定数の表現
<ビット幅> <基数><数値>
<ビット幅>は、定数のビット幅を表現する 10 進数、省略すると 32 ビットとして扱われる。
<基数>は、何進数の数値かを表す、次の 4 種類がある。
b, B : 2 進数 , o, O : 8 進数 d, D : 10 進数 , x, X : 16進数
これも省略可能で、省略時は 10 進数として扱われる。
<数値>は、定数の値を示す、基数に応じた数値を扱える。
8 進数なら 0~7 と x,z 、 16 進なら 0~9 、 a~f ( A~F )と x,z 、 10 進は x,z 扱えない。
表 3.1 定数の例
数値対数 ビット幅 基数 2 進数表現10 32 10 進 00…01010
1′ b1 1 2 進 18′ haa 8 16 進 101010104′ bz 4 2 進 zzzz
8′ o377 8 8 進 111111118′ b000_11xx 8 2 進 000011xx
′ hff 32 16 進 00…011111111 4′ d5 4 10 進 101
3.1.3 データ型
信号(変数)の型宣言
( 1 ) レジスタ型( reg 宣言したもの):ラッチやフリップフロップ( FF, 値を保存する)
( 2 ) ネット型( wire 宣言したもの):配線部分(値を保持しない)
いずれの型も、参照する場合の制限はない。式の右辺で用いたり、 function の
引き数に用いることができる。しかし、代入する場合に次のように制約がある。
レジスタ型信号への代入は、 always 文、 task,function の中だけ
ネット型信号への代入は、 assign 文の中だけ
これらに反した代入は、文法エラーとなる。
型宣言の省略
図 3.3 ( a )の信号は、省略するのが一般的です、ポート宣言した信号は、デフォルトでネット型です、入力 / 出力にかかわらず、ネット型であれば型宣言を省略できる。
図 3.3 ( b )の例では temp を未宣言で用いることができる。しかし、多ビットのネット信号の場合はネット宣言忘れると 1ビット信号として扱われてしまう、文法エラーにはなりませんが、シミュレータが「ポートのビット数が一致しない」という警告メッセージを出力する。
図 3.3
ネット宣言を省略できる例
( a ) ポート信号
module DFF ( CK, D, Q ) ;
input CK, D ;
output Q ;
reg Q ;
always @ (posedge CK)
Q<= D ;
endmodule
wire CK, D ; 省略可
( b ) フリミティブ・ゲートやモジュール
呼び出しのときの 1 ビット信号
module RSFF ( SB, RB, Q ) ;
input SB, RB ;
output Q ;
nand na1 ( Q, SB, temp ) ;
nand na2 ( temp, Q, RB ) ;
endmodule
Wire temp ; 省略可
ネット型とレジスタ型の使い分け
文法的には値を保持するレジスタ型、値を保持しないネット型と明確な区別
があるが、回路記述の中では混乱することもある、例をあげて、使い分けを
説明する。
ポート信号にも型がある、ポートの種
類によって図 3.4 ( a )のような使い分け
がある、これ以外の組み合わせ、例え
ば入力ポートをレジスタ型で宣言する
と文法エラーになる。
dout
din
dio
module sample ( . . . ) ;
input din ;
wrie din ; // 入力はネット型
output dout ;
reg dout ; // 出力はネット型がレジスタ型
inout dio ;
wire dio ; // 双方向はネット型図 3.4 ネット型とレジスタ型
( a ) ポート番号
ブロック間の接続信号は、図 3.4 ( b )のようにネット型で宣言し接続する、レジスタがたで
宣言してしまうと、出力側のブロックを接続した部分で文法エラーになる、入力側のブロ
ックの接続は、文法上可能です、テストベンチにおいて、検証対象に信号を接続して入
力を変化させるときなどにこの方法を使う。
module Top ( . . . ) ;
. . .
Reg [15:0] dbus ; // wire [15:0] dbus なら OK
BLK_A A( .dout(dbus), . . . ) ; // 出力に reg は接続できない
BLK_B B( .din(dbus), . . . ) ; // 入力側への reg 接続可
. . .
endmodule
CK
D Q
FF1 dout din
dbus
wire dbus ;
× reg dbus ;
Top
BLK_A BLK_B
( b ) ブロック間接続信号
弓仲研修士一年
畦元 隼
3.1.4 多ビット信号
宣言時におけるビット幅指定
input [3:0] a,b; 4 ビットの入力 aと bwire [7:0] dbus; 8ビットのネット信号reg [15:8] adder_hi; 8ビットのレジスト信号reg [7:0] adder_lo; 8ビットのレジスト信号
ビット幅をもった信号を用いるためには、信号の宣言時に [MSB:LSB] の形式でビット幅と範囲を指定するまた 多ビット信号は、「符号なし整数」として扱われる例
但し、ビット指定は一つの宣言に一回しか許されない
×→ wire [3:0] cnt4, [7:0] cnt8;
×→ reg busy, [2:0] status;
例○→ wire [3:0] cnt4 ;wire [7:0] cnt8;
○→ reg busy;
reg [2:0] status;
多ビット信号のビット選択多ビット信号を 1 ビット単位でアクセスするときは以下の
ようにする
1 ビットだけ代入することもできる
assign MSB = dbus[7]; MSB に dbus の 7 ビット目の値を入れる
assign LSB = dbus[0]; MSB に dbus の 0 ビット目の値を入れる
任意のビット指定
assign dbus[4] = half_carry;
dbus の 4 ビット目に half_carry の値を入れる
例
例
多ビット信号の部分選択多ビット信号をある範囲でアクセスする
ときは、
部分的に代入も出来る
wire [3:0] Hi_digit; Hi_digit は 4 ビット幅
assign Hi_digit = adder_hi [15:12]; Hi_digit に adder_hiの
12 ビット目から 15ビット目
までの値を代入wire [3:0] Lo_digit; Lo_digit は 4 ビット幅assign dbus[3:0] = Lo_digit; dbus の 0 ビット目から 3
ビット目に Lo_digit の値を代入
ここで、範囲外にアクセスしたときには不定(x) となり範囲外に代入すると文法エラーとなる
例
例
レジスタ配列(メモリ)レジスタ型の信号は、配列を作ることが出来る
reg [7:0] men [0:255];
men は 8 ビット ×256ワード、つまり 256 バイトのメモリになる、
これをレジスタ配置と呼ぶ
例
レジスタ配置については、ビット選択や部分選択が行えない必ずワード単位のアクセスとなる
例 men [100]; レジスタ配置 men の 100 番地の内容
ビット選択や部分選択を行うためには、一時的なネット信号を用いる wire [7:0] temp;
Assign temp = men[100]; temp として men[100] を定義する
temp [7] ・・・ men[100] の最上位ビットtemp [3:0] ・・・ men[100] の下位 4 ビット
例
レジスタ配置は「ベクタ信号(ビット幅を持った信号)の一次元配列」と考えることが出来るVerilog HDLでは、プログラム言語のように 2次元 /3 次元など
の多次元配列を作ることが出来ない
また、スカラ信号( 1 ビットの信号)の一次元配列も可能
Reg men_1 [0:15];
1 ビット ×16ワードつまり全体で 16 ビットのレジスタとなる例
但し、レジスタ配列なので、そのままでは部分選択は出来ない
3.1.5 演算子と演算優先順位
演算子 C言語との共通点と相違点
共通点Verilog HDLで扱える演算は、基本的に C言語のものと同一である
Verilog HDLの演算子は表のようになっている
演算子 演算 演算子 演算算術演算 論理演算
+ 加算、プラス符号 ! 論理否定- 減算、マイナス符号 && AND論理* 乗算 || OR論理/ 除算 等号演算% 剰余 == 等しい
ビット演算 != 等しくない~ NOT === (x,z )等しい も比較& AND !== (x,z )等しくない も比較| OR 関係演算^ EX-OR < 小~̂ EX-NOR <= 小または等しい
リダクション演算 > 大& AND >= 大または等しい~& NAND シフト演算| OR >> 左にシフト~| NOR << 右にシフト^ EX-OR その他~̂ EX-NOR ?: 条件演算
{} 連接
=== : x( 不定値 ) 、 z( ハイインピーダンス ) は == などではすべて偽と されてしまうためx、zも比較するのに用いられる!== : ===同様の理由で用いられる
相違点Verilog HDL 固有の連接演算やリダクション演算があ
る。また、 C言語で用いられる ++(インクリメント ) 演算
や、 --(デクリメント ) 演算はない。代入は演算扱いではないので
などと出来ない。
if (regA = 4`h5) ~ 代入は演算扱いされないのでこのような間違いもエラーとして吐か
れる
補足
×→ a = b = c =1`b0;
演算の優先順位各演算子の優先順位は表のようになっている
最上位の演算子は単項演算子で各項の頭に付ける演算子なっている
「論理否定」 「リダクション演算子」「符号の演算」 が最優先
! ~ & ~& | ~| ^ ~^ + -* / %+ -<< >>
< <= > >=& ^ ~^|&&?:
高
低
- in , ! adder など
3.1.6 等号演算と関係
2項の値の一致・不一致を判定する等号演算では、演算子 ==、 != を使用する。2項の大小を比較する関係関数は、演算子 <、 >を使用する。( =と組み合わせることができる。)
※基本的な演算内容はC言語と同じ。
例: assign match = ( regA == regB ) ;
regA と regB が一致していれば’ 1’ (真)、
不一致なら’ 0’ (偽)の値を返す。
①演算2項の等号演算/関係演算
比較する2項のどちらかに‘ x’ (不定値)、’ z’(ハイ・インピーダンス値)が含まれると、比較対象外なので「偽」として扱われる。直接比較したい場合は === (一致)、 !== (不一致)を用いる。(ただし、論理合成対象外)
※不定値:値が代入されていないもの。 ハイ・インピーダンス値:出力信号線を電気的に切
り離した状態。(高抵抗により遮断される。)
例: if ( regA == 4’hx ) ; if ( regA === 4’hx ) ;
3.1.6 等号演算と関係②2項に不定値かハイ・インピーダンス値が含まれる場合
3.1.7 連接演算
連接演算では何項でも連接できる。一般の演算と同様に、代入文の右辺ばかりでなく、モジュール呼び出しのポートやファンクションの引き数にも使用できる。※ポートリスト:入力・出力の端子名を列挙したもの。
wire [15:0] addr_bus ;
assign addr_bus = { addr_hi, addr_lo } ;
addr_hi と addr_lo は 8ビットのレジスタ信号とする。
addr_bus は addr_hi と addr_lo を連接して 16ビットの信号になる。
連接演算の左側が重いビットとして扱われる。
①連接演算を代入文の右辺で使用
3.1.7 連接演算
Verilog HDL では、ビット幅が異なる変数の演算や代入が許される。この場合、左辺が 5ビットなので、右辺の a+b は MSB 側に 0を付けた 5ビットとして演算される。また、代入の左辺のビット幅が右辺よりも小さい場合、 MSB が欠落して代入される。代入の左辺で用いることができるのが連接演算の最大のメリット。
wire [3:0] a, b, sum;
wire carry;
assign { carry, sum } = a + b ;
a,b,sum は各 4ビットなので、場合によって結果が 5ビットになる。
carry と sum を連接した 5ビットに加算回路を代入することで、 carry には桁上げ信号が、 sum には加算結果が代入される。
②連接演算を代入文の左辺で使用
3.1.7 連接演算
{ 4{ 2’b10 } } ・・・ 8’b10101010
wire [15:0] word ;
wire [31:0] double ;
assign double = { { 16{word[15]} }, word } ;
2 ビットの“ 10” を4回繰り返し、 8ビットの“ 10101010” を表現。
16ビット信号 word を 32 ビット信号 double に代入する際に、word の符号ビットである word[15] を 16 回繰り返し、double の上位 16 ビットに代入。
③繰り返しを記述する連接演算
3.1.8 リダクション演算リダクション関数:項の先頭に演算子を付ける単項演算。※演算子は &、 ~、 ^、 |を組み合わせたもので、ビット幅を持った信号内の全ビットに作用し、演算結果は1ビットの値になる。
assign all_one = cnt[7] & cnt[6] & cnt[5] & cnt[4] & cnt[3] & cnt[2] & cnt[1] & cnt[0] ;
assign parity = cnt[7] ^ cnt[6] ^ cnt[5] ^ cnt[4] ^ cnt[3] ^ cnt[2] ^ cnt[1] ^ cnt[0] ;
reg [7:0] cnt ;
assign all_one = & cnt ;
assign parity = ^ cnt ;
↓リダクション関数を使った場合
8ビットのレジスタ cnt の全てのビットが‘ 1’ の時に値が‘ 1’になる。
cnt の各ビットの EX-ORをとったもの。
3.1.9 回路記述に必要な構文
function の呼び出しは「式」の中で行う。したがって、代入文の右辺や下位モジュールの接続、他の関数の引き数などに用いる。※引き数:①仮引き数・・・ function の定義などで使われる仮の入力信号 ②実引き数・・・ function などの呼び出し時に実際に与えられる信号
function [7:0] sum;
input [7:0] a, b;
sum = a + b;
endfunction
☆8 ビット加算回路の function の定義
wire [7:0] result, in0, in1;
assign result = sum( in0, in1 ) ;
☆function の呼び出し
ビット幅
ファンクション名宣言
ステートメント
式
if 文2方向の分岐を記述する構文。ステートメントに属するため、「 always 文」
「 initial 文」「 function 」「 task」の中だけで記述できる。
?
if 文
① ②
function [7:0] select;
input s;
input [7:0] in0, in1;
begin
if ( s==1’b0 )
select = in0;
else
select = in1;
end
endfunction
assign dout = select( sel, d0, d1 );
module sel2to1 ( d0, d1, dsel1, dout );
input [7:0] d0, d1;
input sel;
output [7:0] dout;
if ( sel==1’b0 )
dout = d0;
else
dout = d1;
endmodule
↑モジュール直下では使えないため NG
式
ステートメント2
ステートメント1
直前の ifに対応(なくてもよい)
case 文多方向の分岐を記述する構文。case に続いてカッコ内に記述した式の値が
ケースアイテムに記述した式の値と一致した先を実行。
?
case文
② ③①
function [7:0] select;
input s;
input [7:0] in0, in1;
begin
case ( s )
1’b0: select = in0;
1’b1: select = in1;
default: select = 8’hxx;
endcase
end
endfunction
assign dout = select( sel, d0, d1 );
式
ステートメント3
ステートメント1 ケースアイテ
ムステートメント2