29
第3第 第第第第第第第第第第第第第 第第第 第第第第第 3.1 第第第第第 3.1. 1 3.1.3

第 3 章 文法概略と基本記述スタイル

  • 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

Page 1: 第 3 章 文法概略と基本記述スタイル

第 3 章

文法概略と基本記述スタイル

第二部  回路記述編

3.1  文法を少々 3.1.1 ~3.1.3

Page 2: 第 3 章 文法概略と基本記述スタイル

3.1 文法を少々      3.1.1 モジュール構造

module  モジュール名  ( ポート・リスト )  ;

ポート宣言

ネット宣言

レジスタ宣言

パラメータ宣言

回路記述

    assign 文  組み合わせ回路の記述

    function

always 文 順序回路の記述

   下位モジュール呼び出し

endmodule

図 3.1  モジュール構造

回路を記述する構造がモジュールです

「モジュール」は予約語の

module と endmodule で囲まれ回路表現から

シミュレーション用の入力まで、すべてがこ

の中で記述される。

module に続き、モジュール名、ポート・リスト、

を記述する。

「ポート・リスト」とは、出力、入力の端子名を

例拳したものです。

Page 3: 第 3 章 文法概略と基本記述スタイル

モジュール名やポート・リスト名などの識別子には英数字と_(アンダ スコ・ア)が使え、大文字小文字を区別します。

(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 文

 別のモジュールを接続する

 下位モジュール呼び出し

Page 4: 第 3 章 文法概略と基本記述スタイル

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

Page 5: 第 3 章 文法概略と基本記述スタイル

3.1.3  データ型

 信号(変数)の型宣言

( 1 ) レジスタ型( reg 宣言したもの):ラッチやフリップフロップ( FF, 値を保存する)

( 2 ) ネット型( wire 宣言したもの):配線部分(値を保持しない)

いずれの型も、参照する場合の制限はない。式の右辺で用いたり、 function の

引き数に用いることができる。しかし、代入する場合に次のように制約がある。

 レジスタ型信号への代入は、 always 文、 task,function の中だけ

 ネット型信号への代入は、 assign 文の中だけ

これらに反した代入は、文法エラーとなる。

Page 6: 第 3 章 文法概略と基本記述スタイル

 型宣言の省略

図 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 ;   省略可 

Page 7: 第 3 章 文法概略と基本記述スタイル

 ネット型とレジスタ型の使い分け

文法的には値を保持するレジスタ型、値を保持しないネット型と明確な区別

があるが、回路記述の中では混乱することもある、例をあげて、使い分けを

説明する。

ポート信号にも型がある、ポートの種

類によって図 3.4 ( a )のような使い分け

がある、これ以外の組み合わせ、例え

ば入力ポートをレジスタ型で宣言する

と文法エラーになる。

dout

din

dio

module sample ( . . . ) ;

input din ;

wrie din ; // 入力はネット型

output dout ;

reg dout ; // 出力はネット型がレジスタ型

inout dio ;

wire dio ; // 双方向はネット型図 3.4  ネット型とレジスタ型

( a ) ポート番号

Page 8: 第 3 章 文法概略と基本記述スタイル

ブロック間の接続信号は、図 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 ) ブロック間接続信号

Page 9: 第 3 章 文法概略と基本記述スタイル

弓仲研修士一年

畦元 隼

Page 10: 第 3 章 文法概略と基本記述スタイル

3.1.4 多ビット信号

Page 11: 第 3 章 文法概略と基本記述スタイル

宣言時におけるビット幅指定

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;

Page 12: 第 3 章 文法概略と基本記述スタイル

多ビット信号のビット選択多ビット信号を 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 の値を入れる

Page 13: 第 3 章 文法概略と基本記述スタイル

多ビット信号の部分選択多ビット信号をある範囲でアクセスする

ときは、

部分的に代入も出来る

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) となり範囲外に代入すると文法エラーとなる

Page 14: 第 3 章 文法概略と基本記述スタイル

レジスタ配列(メモリ)レジスタ型の信号は、配列を作ることが出来る

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 ビット

Page 15: 第 3 章 文法概略と基本記述スタイル

レジスタ配置は「ベクタ信号(ビット幅を持った信号)の一次元配列」と考えることが出来るVerilog HDLでは、プログラム言語のように 2次元 /3 次元など

の多次元配列を作ることが出来ない

また、スカラ信号( 1 ビットの信号)の一次元配列も可能

Reg men_1 [0:15];

1 ビット ×16ワードつまり全体で 16 ビットのレジスタとなる例

但し、レジスタ配列なので、そのままでは部分選択は出来ない

Page 16: 第 3 章 文法概略と基本記述スタイル

3.1.5 演算子と演算優先順位

Page 17: 第 3 章 文法概略と基本記述スタイル

演算子 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も比較するのに用いられる!==  : ===同様の理由で用いられる

Page 18: 第 3 章 文法概略と基本記述スタイル

相違点Verilog HDL 固有の連接演算やリダクション演算があ

る。また、 C言語で用いられる ++(インクリメント ) 演算

や、    --(デクリメント ) 演算はない。代入は演算扱いではないので

などと出来ない。

if (regA = 4`h5) ~ 代入は演算扱いされないのでこのような間違いもエラーとして吐か

れる

補足

×→ a = b = c =1`b0;

Page 19: 第 3 章 文法概略と基本記述スタイル

演算の優先順位各演算子の優先順位は表のようになっている

最上位の演算子は単項演算子で各項の頭に付ける演算子なっている

「論理否定」    「リダクション演算子」「符号の演算」   が最優先

! ~ & ~& | ~| ^ ~^ + -* / %+ -<< >>

< <= > >=& ^ ~^|&&?:

- in , ! adder など

Page 20: 第 3 章 文法概略と基本記述スタイル
Page 21: 第 3 章 文法概略と基本記述スタイル

3.1.6  等号演算と関係

2項の値の一致・不一致を判定する等号演算では、演算子 ==、 != を使用する。2項の大小を比較する関係関数は、演算子 <、 >を使用する。( =と組み合わせることができる。)

※基本的な演算内容はC言語と同じ。

例: assign match = ( regA == regB ) ;

    regA と regB が一致していれば’ 1’ (真)、

   不一致なら’ 0’ (偽)の値を返す。

①演算2項の等号演算/関係演算

Page 22: 第 3 章 文法概略と基本記述スタイル

比較する2項のどちらかに‘ x’ (不定値)、’ z’(ハイ・インピーダンス値)が含まれると、比較対象外なので「偽」として扱われる。直接比較したい場合は === (一致)、 !== (不一致)を用いる。(ただし、論理合成対象外)

※不定値:値が代入されていないもの。 ハイ・インピーダンス値:出力信号線を電気的に切

り離した状態。(高抵抗により遮断される。)

例: if ( regA == 4’hx ) ; if ( regA === 4’hx ) ;

3.1.6  等号演算と関係②2項に不定値かハイ・インピーダンス値が含まれる場合

Page 23: 第 3 章 文法概略と基本記述スタイル

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ビットの信号になる。

連接演算の左側が重いビットとして扱われる。

①連接演算を代入文の右辺で使用

Page 24: 第 3 章 文法概略と基本記述スタイル

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 には加算結果が代入される。

②連接演算を代入文の左辺で使用

Page 25: 第 3 章 文法概略と基本記述スタイル

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 ビットに代入。

③繰り返しを記述する連接演算

Page 26: 第 3 章 文法概略と基本記述スタイル

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をとったもの。

Page 27: 第 3 章 文法概略と基本記述スタイル

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 の呼び出し

ビット幅

ファンクション名宣言

ステートメント

Page 28: 第 3 章 文法概略と基本記述スタイル

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に対応(なくてもよい)

Page 29: 第 3 章 文法概略と基本記述スタイル

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