LRM読解(Chap.9-3)

2008/10/04Verilog::文法import

Behavioral modeling~その3


9.7 手続き型タイミング制御 ~ Procedural timing controls

Verilog HDLは,手続き型命令が現れたときに,必然的に含まれているタイミング制御の2種類を持ちます.1つ目のタイプは遅延制御で,式は,命令文に最初に遭遇したときと,命令文を実際に実行するときの間の時間遅延を与える.遅延式は,回路状態の動的な機能になりますが,時間内に,分割された命令文の実行する簡単な数でしょう.遅延制御は,スティミュラスな波形記述を与えるとき,重要な特徴です.これについてはLRM 9.7.1と9.7.7で記述します.

タイミング制御の2つ目は,イベント式です.イベント式は,ある手続き中,同時実行している手続き内で生じるシミュレーションイベントが起きるまで,命令文の実行を遅延させることができます.
シミュレーションイベントは,net上の値の変化 や 変数の変化(暗黙のうちのイベント),(明白な)他の手続きからトリガされる明示的な名前つきイベントが起きたときとなるでしょう.
より多くは,イベント制御は,クロック信号の立ち上がりまたは立下りエッヂとなります.イベント制御は LRM 9.7.2から LRM 9.7.7にかけて議論されます.

今までのところ遭遇している手続き型命令文の全ては,シミュレーションを進めないで実行します.

シミュレーション時間は,以下の3つの方法の1つで進められます.

  • 遅延制御,シンボル'#'で紹介されます.
  • イベント制御,シンボル'@'で紹介されます.
  • wait文,イベント制御とwhileループの組み合わせのように機能します.

Syntax

delay_control ::= (From Annex A - A.6.5)
    # delay_value
  | # ( mintypmax_expression )

delay_or_event_control ::=
    delay_control
  | event_control
  | repeat ( expression ) event_control

event_control ::=
    @ event_identifier
  | @ ( event_expression )
  | @*
  | @ (*)

event_expression ::=
    expression
  | hierarchical_identifier
  | posedge expression
  | negedge expression
  | event_expression or event_expression
  | event_expression , event_expression

gateとnetの遅延もまた,6章で議論したようにシミュレーション時間を進めます.次節では,3つの手続き型タイミング制御方法について議論します.


9.7.1 遅延制御 ~ Delay control

遅延制御に続く手続き文は,与えられた遅延に先立って遅延制御を行う手続き文に関して,実行するのを遅らされます.

  • 遅延式が不定またはハイインピーダンス値として評価された場合は,ゼロ遅延のように解釈されるでしょう.
  • 遅延式が負の値と評価された場合は,時間変数(time variable)と同じサイズの符号無し整数(unsigned int)の2の補数と解釈されるでしょう.

与えられたパラメータは,遅延式中で許されます.式が再評価される場合には,SDFアノテーションにより上書きされます.

例1
以下の例は,10時間単位だけ代入の実行を遅延します.The following example delays the execution of the assignment by 10 time units:

#10 rega = regb;

例2
次の3つの例は,サイン('#')に続く式を与えます.代入処理は,式の値で与えられたシミュレーション時間の間だけ,遅延されます.Execution of the assignment is delayed by the amount of simulation time specified by the value of the expression.

#d rega = regb; // d is defined as a parameter
#((d+e)/2) rega = regb;// delay is average of d and e
#regr regr = regr + 1; // delay is the value in regr

9.7.2 イベント制御 ~ Event control

手続き文の実行は,net上の値の変化 や 変数の変化(暗黙のうちのイベント),(明白な)他の手続きからトリガされる明示的な名前つきイベントが起きたときに同期されるでしょう.
The value changes on nets and variable can be used as events to trigger the execution of a statement. netや変数の値の変化は,命令文の実行トリガのイベントのように使われます.This is known as detecting an implicit event.これは,暗黙のイベント検出として知られます.The event can also be based on the direction of the change that is, towards the value 1 ( posedge) or towards the value 0 (negedge).イベントは,変化の方向(1への変化(posedge)か0への変化(negedge))を元にも使われます.The behavior of posedge and negedge event is shown in Table 43 and can be described as follows: posedgeとnegedgeイベントのビヘイビアは,次の表に示され,以下のように記せます.

  • negedgeは,1からx/z/0,x/zから0への変化で検出されます.
  • posedgeは,0からx/z/1,x/zから1への変化で検出されます.

from|to 0 1 x z
0No edgeposedgeposedgeposedge
1negedgeNo edgenegedgenegedge
xnegedgeposedgeNo edgeNo edge
znegedgeposedgeNo edgeNo edge

もし,式が1bitより長い結果を評価するならば,エッヂの遷移は,結果のLSB(最下位ビット)において検出されるでしょう.式の結果のLSBの値の変化を除いた,どのオペランドの値の変化もエッヂの検出はされない.


例:
The following example shows illustrations of edge-controlled statements.以下の例は,エッヂ制御分を図示します.

@r rega = regb; // レジスタrのどのような変化にでも制御される
@(posedge clock) rega = regb; // clockの立上がりエッヂに制御される
forever @(negedge clock) rega = regb; // 立下りエッヂに制御される

9.7.3 名前つきイベント ~ Named events

net型とvariable型に加えて,event型と呼ばれる新しいデータ型を宣言することができる.event data型の識別子の宣言は,named eventと呼ばれる.

LRM 9.7.1で議論したイベント制御のようなやり方と同様に,手続き命令文の実行を制御するために,イベント式で使うことができる.

named eventsは,手続きから起こすことができます.これは,ほかの手続きにおける,複数の動作を可能にすることの制御を許容します.
イベント名は,使用する前に明示的に宣言されます.文法を以下に示します.

event_declaration ::= (From Annex A - A.2.1.3)
  event list_of_event_identifiers ;

list_of_event_identifiers ::= (From Annex A - A.2.3)
  event_identifier [ dimension { dimension }]
  { , event_identifier [ dimension { dimension }] }

dimension ::= (From Annex A - A.2.5)
  [ dimension_constant_expression : dimension_constant_expression ]

イベントは,データを保持しません.named eventの特徴を以下に列挙します.

  • 特定のいつでも起こすことができる.
  • 時間間隔を持たない.(It has no time duration)
  • 説明したイベント制御構文を用いて,発生を認識できます。

宣言されたeventは,以下の構文のイベントトリガ命令文の活性化(actrivation)により,起こされます.eventは,イベント制御式中のevent arratのindexの変化によっては,起こされません.(どゆこと?)

An event is not made to occur by changing the index of an event array in an event control expression.
event_trigger ::= (From Annex A - A.6.5)
  -> hierarchical_event_identifier ;

イベント制御命令文(例えば,@trig rega = regb;)は,手続きに含まれるシミュレーションを,ほかの手続きが特定のイベントトリガ命令文(例えば, -> trig)を実行するまで,待たせる.

named eventとイベント制御は,強力で効果的な,複数同時実行されるプロセス間の同期やコミュニケーション記述を与える.

この基本的な例は,回路がイベントを待っている間,定期的に明示的なイベントが起きたことを通知することによって同期回路の同期制御をするような小さな波形クロック生成器です.


9.7.4 イベント 'or'演算子 ~ Event or operator

The logical or of any number of events
 can be expressed such that
  the occurrence of any one of the events triggers the execution of the procedural statement that follows it.

わがらん('A`

キーワード'OR'かコンマ文字','が,イベント論理OR演算子として使われます.この組み合わせは,同じイベント式で用いることができます.コンマ分割のセンシビリティリストは,OR分割のセンシビリティリストと同値です.


次の二つの例は,それぞれ2つと3つのイベント論理ORを示します.

@(trig or enable) rega = regb; // trig か enable によって制御される.
@(posedge clk_a or posedge clk_b or trig) rega = regb;

以下の例は,イベント論理OR演算子として,コンマを使用することを示します.

always @(a, b, c, d, e)
always @(posedge clk, negedge rstn)
always @(a or b, c, d or e)

9.7.5 暗黙的な イベント式リスト ~ Implicit event_expression list

The event_expression list of an event control is a common source of bugs in RTL simulations.イベント制御のイベント式リストは,RTLシミュレーションにおけるバグの元凶です.

Users tend to forget to add some of the nets or variables read in the timing control statement.ユーザは,タイミング制御文中に読み出すnetやvariableを追加することを忘れることに応対する(直面する?)

This is often found when comparing RTL and gate level versions of a design.これは,しばしばRTLとゲートレベル設計との比較で見つけられる.

The implicit event_expression, @*, is a convenient shorthand that eliminates these problems by adding all nets and variables which are read by the statement (which can be a statement group) of a procedural_timing_control_statement to the event_expression.暗黙的なイベント式(@*)は,手続きタイミング制御命令文の命令文(命令文グループでも良い)によって読み出される,全てのnet/variableを追加することによる問題を省略するための,便利な略記です.


命令文中に現れる全てのnet/variable識別子は,自動的に以下の式以外がイベント式に追加されます.

  • wait式,event式中にのみ現れる識別子
  • 代入の左辺のレジスタ(reg_lvalue)中にのみ現れる,hierarchical_reg_identifierのような識別子

代入式の右辺,functionやtask呼び出し,case/状態式に現れるnet/variableは,すべてこのルールに当てはまります.


例1

always @(*) // equivalent to @(a or b or c or d or f)
  y = (a & b) | (c & d) | myfunction(f);

例2

always @* begin // equivalent to @(a or b or c or d or tmp1 or tmp2)
  tmp1 = a & b;
  tmp2 = c & d;
  y = tmp1 | tmp2;
end

例3

always @* begin // equivalent to @(b)
  @(i) kid = b; // i is not added to @*
end

例4

always @* begin // equivalent to @(a or b or c or d)
  x = a ^ b;
  @* // equivalent to @(c or d)
    x = c ^ d;
end

9.7.6 レベルセンシティブイベント制御 ~ Level-sensitive event control

手続き命令文の実行もまた,状態がtrueになるまで遅延されることができます.これは,特別な形式のイベントコントロールである,wait命令文を使うことに優れています.

wait命令文の本質は,('@'文字で与えられる)エッヂセンシティブな基本イベント制御に反対である,レベルセンシティブです.
wait命令文は,状態を評価し,falseであれば,wait命令文に続く手続き命令は,続ける前に,状態がtrueになるまで,ブロックされ,とどまります.

wait命令文は以下の書式を持ちます.

wait_statement ::= (From Annex A - A.6.5)
  wait ( expression ) statement_or_null


以下の例は,レベルセンシティブイベントコントロールを果たすためのwait命令文の使い方を示す.

begin
  wait (!enable) #10 a = b;
  #10 c = d;
end

blockに入ったとき,enableの値が1ならば,enableの値が0に変化するまで,wait命令文は次の命令文(#10 a = b;)の評価を遅延します.
blockに入ったとき,enableがすでに 0であったならば,10の遅延の後に代入(a = b;)は評価され,追加の遅延は起きません.


9.7.7 内部代入タイミング制御 ~ Intra-assignment timing controls

前述したdelay/event制御構造は,命令文の前置きをして,その実行を遅延させます.
対照的に,intra-assignment delayとevent controlsは,代入文と異なる方法のアクティビティの流れを修正することを含みます.

この節では,intra-assignmentのタイミング制御と,intra-assignment delayで使えるrepeatタイミング制御の目的について記す.
intra-assignment delayまたはイベント制御は,新しい値を左辺に代入することを遅らせます.しかし,右辺式は,遅延の後の変わりに,遅延の前に評価されます.
intra-assignment delayとイベント制御のの構文を以下に示す.

blocking_assignment ::= (From Annex A - A.6.2)
  variable_lvalue = [ delay_or_event_control ] expression

nonblocking_assignment ::=
  variable_lvalue <= [ delay_or_event_control ] expression

delay_control ::= (From Annex A - A.6.5)
    # delay_value
  | # ( mintypmax_expression )

delay_or_event_control ::=
    delay_control
  | event_control
  | repeat ( expression ) event_control

event_control ::=
    @ event_identifier
  | @ ( event_expression )
  | @*
  | @ (*)

event_expression ::=
    expression
  | hierarchical_identifier
  | posedge expression
  | negedge expression
  | event_expression or event_expression
  | event_expression , event_expression

intra-assignment delayとイベント制御は,ブロッキング代入とノンブロッキング代入の双方に適用可能です.
イベント式は,1bitの値として結果を得ます.
repeatイベント制御は,与えられたイベントの発生回数のintra-assignment delayにより与えられます.
もし,繰り返し回数リテラルまたは繰り返し数を保持したsignedのreg型が,評価時に0以下である場合,まるでrepeat構文が無いかのように代入処理がおきます.
# 例と本文が違うような... 原文を引用しておきます. 翻訳が間違ってる?

If the repeat count literal, or signed reg holding the repeat count,
 is less than or equal to 0 at the time of evaluation,
  the assignment occurs as if there is no repeat construct.

Examples:

repeat (-3) @ (event_expression)
  // will not execute event_expression. イベント式は実行されません
repeat (a) @ (event_expression)
  // if a is assigned -3 it will execute the event_expression. aに-3が代入されていれば,イベント式は実行されます.
  // if a is declared as an unsigned reg but not if it is signed. もしaがunsigned regで宣言されていれば,の話.

この構造は,イベントがクロック信号のカウントに同期する必要がある時に便利です.

Examples:
以下の表は,intra-assignmentを使わずに,同じタイミング効果を成就できるコードを示すことで,intra-assignmentタイミング制御の原理を図解しています.

Intra-assignment timing control
With intra-assignment constructWithout intra-assignment construct
a = #5 b;begin<BR>temp = b;<BR>#5 a = temp;<BR>end
a = @(posedge clk) b;begin<BR>temp = b;<BR>@(posedge clk) a = temp;<BR>end
a = repeat(3) @(posedge clk) b;begin<BR>temp = b;<BR>@(posedge clk);<BR>@(posedge clk);<BR>@(posedge clk) a = temp;<BR>end

次の3つの例は,fork-joinビヘイビア構造を使います.forkとjoinの間の全ての命令文は,同時に実行します.この構造は,LRM 9.8.2で,より詳しく記述されます.

以下の例は,intra-assignmentタイミング制御を使うことで予防できるレースコンディションを示します.

fork
  #5 a = b;
  #5 b = a;
join

この例のコードは,同じシミュレーション時間において,aとbの双方の値を,参照・設定します.次の例で用いられるタイミング制御のintra-assignment様式は,このレースコンディションを防げます.

fork // data swap
  a = #5 b;
  b = #5 a;
join

intra-assignmentタイミング制御は,動きます.というのも,intra-assignment遅延は,aとbの値を遅延前に評価させて,遅延後に代入させるからです.

intra-assignmentタイミング制御の実装をしている,多くの既存ツールは,各右辺式の評価において,一時的な記憶領域を使います.

イベント待ちであるintra-assignmentもまた,有効です.以下の例において,右辺式は,代入文にエンカウントしたときに評価されますが,代入はクロック信号の立ち上がりエッヂまで遅延されます.

fork // data shift
  a = @(posedge clk) b;
  b = @(posedge clk) c;
join

以下は,ノンブロッキング代入のintra-assignment遅延のようなrepeatイベント制御の例です.

a <= repeat(5) @(posedge clk) data;

Figure 31 illustrates the activities that result from this repeat event control.

(図省略)この例において,dataの値は,代入がエンカウントされたときに評価されます.clkの立ち上がりエッヂの5回発生後に,aはdataの値を代入されます.以下は,手続き代入のintra-assignment遅延のような repeatイベント制御の例です.

a = repeat(num) @(clk) data;

この例では,dataの値は,代入が演歌ぬとされたときに評価されます.clkの遷移回数がnumの値と一致した後,aはdataの値を代入される.以下は,イベント発生回数と,カウントされたイベントの両方を演算に含んだrepeatイベント制御の例です.

a <= repeat(a+b) @(posedge phi1 or negedge phi2) data;

In this example,この例において,dataの値は代入にエンカウントされたときに評価される.phi1の立ち上がりエッヂとphi2の立下りエッヂの総和が,aとbの和と等しくなった後,aはdataの値を代入される.
もし,phi1の立ち上がりエッヂとphi2の立下りエッヂとが,同じシミュレーション時間に生じても,それぞれ分けて検出されます.