LRM読解(Chap.9-2 Behavioral/case,loop)
Behavioral modeling~その2
9.5 case文 ~ Case statement
case文は,式が多くの他の式の1つとマッチするか,分岐するかどうかに関係なくテストする,複数判断命令文です.
case_statement ::= (From Annex A - A.6.7) case ( expression ) case_item { case_item } endcase | casez ( expression ) case_item { case_item } endcase | casex ( expression ) case_item { case_item } endcase case_item ::= expression { , expression } : statement_or_null | default [ : ] statement_or_null function_case_statement ::= case ( expression ) function_case_item { function_case_item } endcase | casez ( expression ) function_case_item { function_case_item } endcase | casex ( expression ) function_case_item { function_case_item } endcase function_case_item ::= expression { , expression } : function_statement_or_null | default [ : ] function_statement_or_null
default文は,オプションです.1つのcase文で複数のdefault文を使うのは不当です.
The case expression and the case item expression can be computed at runtime;
neither expression is required to be a constant expression.
case式とcase item式は,実行時に計算されます.どちらの式も,定数式になるには必要ではありません.
(例)
case-item式は,与えられた順に性格に,評価・比較されます.
線形探索において,case item式のひとつが,丸括弧(parentheses)で与えられたcase式にマッチするならば,case-itemに対応する命令文が実行されます.
全ての比較が失敗し,default-itemが与えられているならば,default-itemの命令文が実行されます.
もし,default文が無くて,全ての比較が失敗したならば,どのcase-item文も実行されません.構文は別として,case文はif-else-if構造に比べて2つの重要な違いがあります.
- if-else-if構造の状態式のほうが,case文のように1つの式をその他と比較するよりも一般的(general)です.
- case文は,式中の'x'や'z'が存在する時に,決定的な結果を提供します.
case式の比較において,比較は,各ビットが値'0', '1', 'x', 'z'に関して厳密にマッチするときにのみ成功します.
結果として,case文中の式を与えることには,注意が必要です.
全ての式のbit長は,正確なbit-wiseマッチングができるように,等しくなるでしょう.
全てのcase-item式の長さと丸括弧のcase式は,case式とcase-item式の最長のものと等しくするものとします.
注意
'x'と'z'のデフォルトの長さは,integerのデフォルト長と同じです.
'x'と'z'の値をハンドリングするようなcase式比較を提供する理由は,そのような値を検出し,それらの(値の)存在によって発生する悲観主義(pessimism)を減少させるためのメカニズムを提供するためです.
9.5.1 "don't care"ありのcase文 ~ Case statement with don't-cares
2つの種類の異なるcase文は,case比較演算子中のdon't case状態のハンドリングを提供する.1つは,ハイインピーダンス(z)をdon't careとして扱い,他方はハイインピーダンス(z)と不定(x)とをdon't careとして扱う.
これらのcase文は,慣例的なcase文と同じように使うことができる.しかし,それら(z,zxをdon't careとして扱うcase文)はそれぞれcasezとcasexで始まる.
case式かcase itemのどんなbitの中のdon't care値(casezではz, casexではz/x)は,比較演算時にdon't care状態として扱われ,考慮されないでしょう.
case式のdon't care状態は,どんなときでも比較すべきビットを動的に制御することに使えるでしょう.
字句構文は,case文中のzをクエスチョンマーク'?'に置き換えて使うことができる.これは,case文中でdon't care bitを与えるために,便利な書式を提供します.
例1. casez文の例を以下に示す.
殿タスクを呼ぶべきかをMSBの値が選択する,命令デコーダのデモです.irのMSBが1ならば,irのほかのbitに関係なくtask instruction1が呼ばれます.
reg [7:0] ir; casez (ir) 8’b1???????: instruction1(ir); 8’b01??????: instruction2(ir); 8’b00010???: instruction3(ir); 8’b000001??: instruction4(ir); endcase
例2. casex文の例を以下に示す.
この例の場合,r=8'b01100110であれば,task stat2が呼ばれます.(不定値演算は不定のままになりそうだけれど.)
reg [7:0] r, mask; mask = 8’bx0x0x0x0; casex (r ^ mask) 8’b001100xx: stat1; 8’b1100xx00: stat2; 8’b00xx0011: stat3; 8’bxx010100: stat4; endcase
01100110 x0x0x0x0
- 0-1-0-=
- 1-0-=-0
- 0-=-0-1
- =-1-1-0
# stat1,3がぶつかりそうな気がするのだけれど.8'x0x1x0x1 のとき,どっちにもあたるよな?
9.5.2 case文での定数式 ~ Constant expression in case statement
定数式をcase式として使えます.定数式の値は,case item式に対して比較されます.
例
以下の例は,3bit priority encoderのモデリングを例示します.
reg [2:0] encode ; case (1) encode[2] : $display(“Select Line 2”) ; encode[1] : $display(“Select Line 1”) ; encode[0] : $display(“Select Line 0”) ; default $display(“Error: One of the bits expected ON”); endcase
Note注意
case式は定数式(1)です.case itemは,式(bit-select)で,定数式に対して一致が比較されます.
9.6 ループ構文 ~ Looping statements
ループ文として4種類あります(下表に示す).これらの命令文は,0,1,それ以上の命令の実行を制御する手段をを提供する.
forever | 命令文を継続的に実行する. |
repeat | 固定回数だけ命令文を実行する.もし,式が不定かハイインピーダンスと評価されたなら,ゼロとして扱われ,命令文は実行されない. |
while | 式がfalseになるまで,命令文を実行する.もし式がfalseで始まるならば,命令文はまったく実行されません. |
for | {以下のように3段階の手順で,関連する命令の実行を制御します. |
a) 一般的には,ループの実行回数を制御する変数の初期化に使われる代入を実行します.b) 式評価し,結果がゼロであれば forループを終了し,ゼロでなければ関係する命令を実行してstep cへ進む.もし式が不定またはハイインピーダンスと評価されれば,ゼロとして扱う(ループを抜ける).c) 通常,ループ制御変数の値を更新するための代入に用いる.その後,step bへ戻る.}|
function_loop_statement ::= (From Annex A - A.6.8) forever function_statement | repeat ( expression ) function_statement | while ( expression ) function_statement | for ( variable_assignment ; expression ; variable_assignment ) function_statement loop_statement ::= forever statement | repeat ( expression ) statement | while ( expression ) statement | for ( variable_assignment ; expression ; variable_assignment ) statement
The rest of this clause presents examples for three of the looping statements.この節の残りでは,ループ文の3つの例を挙げます.The forever loop should be used /in conjunction with/ the timing controls or the disable statement, therefore, this example is presented in 9.7.2.
foreverループは,タイミング制御かdisable命令と同時に使われます.それ故,その例は9.7.2で紹介します.
例1
:
Repeat文: 以下repeatループの例は,addとshift演算が乗算器を実装する例です.
parameter size = 8, longsize = 16; reg [size:1] opa, opb; reg [longsize:1] result; begin : mult reg [longsize:1] shift_opa, shift_opb; shift_opa = opa; shift_opb = opb; result = 0; repeat (size) begin if (shift_opb[1]) result = result + shift_opa; shift_opa = shift_opa << 1; shift_opb = shift_opb >> 1; end end
例2
While文: 以下の例は,rega内の論理1の値を数えます.
begin : count1s reg [7:0] tempreg; count = 0; tempreg = rega; while (tempreg) begin if (tempreg[0]) count = count + 1; tempreg = tempreg >> 1; end end
例3
For 文: for命令は,whileループを基にした下記の擬似命令のような同じ結果を成し遂げる.
begin initial_assignment; while (condition) begin statement step_assignment; end end
forループは,以下に示すような擬似命令で,たった2行を使うだけでこのロジックを実装します.
for (initial_assignment; condition; step_assignment) statement