LRM読解(Chap.6 代入~Assignments)

2008/09/23Verilog::文法import

6. 代入~Assignments

代入は,netや変数に値を設定するための基本的なメカニズムです.2つの基本的な代入の書式があります.

  • netへの値代入である,常時代入(continuous assignment)
  • 変数への値代入である,手続型代入(procedural assignment)

追加の書式が2つあります.LRM9.3で記す手続型常時代入(procedural continuous assignments)と呼ばれる, assign / deassign と force / release です.代入は,等号('=')またはノンブロッキング手続型代入('<=')で分けられた,左辺(LHS)と右辺(RHS)の2つの部分で構成されます.右辺は,評価された結果,値となるどのような式にでもできます.
左辺は,右辺の値を代入するための変数を示します.
左辺は,代入が常時代入か手続型代入かに基づいて,下表に示す書式のうち1つをとることができます.

Statement typeLeft-hand side (LHS)
Continuous assignmentネット(ヴェクタorスカラ) Net (vector or scalar)
ネットのヴェクタのビットセレクト(ビット固定の場合のみ) Constant bit select of a vector net
ネットのヴェクタの部分選択(選択位置固定のみ) Constant part select of a vector net
ネットのヴェクタの要素指定(index固定) Constant indexed part select of a vector net
上記の4つのLHSのいずれかの連結 Concatenation of any of the above four LHS
Procedural assignment変数(ヴェクタorスカラ) Variables (vector or scalar)
reg/integer/time型変数のビットセレクト(ビット固定の場合) Bit-select of a vector reg, integer, or time variable
reg/integer/time型変数のヴェクタの部分選択(選択位置固定) Constant part select of a vector reg, integer, or time variable
メモリワード Memory word
reg/integer/time型変数のヴェクタの要素指定(index固定) Indexed part select of a vector reg, integer, or time variable
bit選択reg/部分選択reg/regの連結 Concatenation of regs; bit or part selects of regs

6.1 常時代入 ~ Continuous assignments

常時代入は,ヴェクタとスカラ両方のネット上を駆動します.この代入は,右辺の値が変化したときに生じます.
常時代入は,ゲートの内部接続を与えることなく,組み合わせロジックをモデル化する方法を提供します.代わりに、モデルはネットを駆動する論理式を指定します.

Syntax:

net_declaration ::= (From Annex A - A.2.1.3)
  net_type [ signed ] [ delay3 ] list_of_net_identifiers ;
  | net_type [ drive_strength ] [ signed ] [ delay3 ] list_of_net_decl_assignments ;
  | net_type [ vectored | scalared ] [ signed ] range [ delay3 ] list_of_net_identifiers ;
  | net_type [ drive_strength ] [ vectored | scalared ] [ signed ] range [ delay3 ] list_of_net_decl_assignments ;
  | trireg [ charge_strength ] [ signed ] [ delay3 ] list_of_net_identifiers ;
  | trireg [ drive_strength ] [ signed ] [ delay3 ] list_of_net_decl_assignments ;
  | trireg [ charge_strength ] [ vectored | scalared ] [ signed ] range [ delay3 ] list_of_net_identifiers ;
  | trireg [ drive_strength ] [ vectored | scalared ] [ signed ] range [ delay3 ] list_of_net_decl_assignments ;

list_of_net_decl_assignments ::= (From Annex A - A.2.3)
  net_decl_assignment { , net_decl_assignment }

net_decl_assignment ::= (From Annex A - A.2.4)
  net_identifier = expression

continuous_assign ::= (From Annex A - A.6.1)
  assign [ drive_strength ] [ delay3 ] list_of_net_assignments ;

list_of_net_assignments ::=
  net_assignment { , net_assignment }

net_assignment ::=
  net_lvalue = expression

6.1.1 ネット宣言代入 The net declaration assignment

最初から二つのネット宣言の選択肢は LRM3.2で議論しました.
ネット宣言代入の三つ目の選択肢は,ネット宣言と同じ文中での常時代入を許可します.

例:下記は,常時代入のネット宣言記述の例です.

  wire (strong1, pull0) mynet = enable ;

注意:
ネットは一度だけ宣言できるので,唯一のネット宣言代入は,特定のネットで作られます.これは常時代入文と酷く違います.1つのネットは,常時代入記述の複数代入を可能とします.


6.1.2 The continuous assignment statement

常時代入文は,ネットデータ型の常時代入を置くものとします.
ネットは,明示的に宣言されるか,LRM 3.5で定義した暗黙的な宣言ルールにしたがって,暗黙的な宣言を継承するでしょう.
ネットにおける代入は,常時でかつ自動的です.これは,右辺式のオペランドの値が変わることを意味します.右辺全体が評価されて,もし新しい値が前の値と異なるならば,新しい値が左辺に代入されます.


6.1.3 遅延 ~ Delays

常時代入に与えられる遅延は,右辺のオペランド値の変化と,左辺への代入との間の時間間隔を指します.
左辺がスカラなネットであれば,ゲート遅延と同様に扱われるものとします.出力の立ち上がり・立下り・ハイインピへの変化時間を異なる遅延で与えることができます.(LRM 7参照)
もし左辺がヴェクタのネット型であれば,最大3つの遅延が適用できます.
以下のルールにより,どの遅延が代入を制御するのかを決定します.

  • 右辺が非ゼロからゼロへ遷移するならば,立下り遅延が使われます.
  • 右辺が'z'へ遷移するならば,ターンオフ遅延が使われます.
  • そのほかの場合,立ち上がり遅延が使われます.

ネット宣言部で,常時代入中に遅延を与えることは,ネット遅延を与えることとは異なるように扱われ,ネットへの常時代入が作られます.

以下の例のように,ネット宣言部での,遅延時間がネットへ適用されることができる.

wire #10 wireA;

このネット遅延と呼ばれる記述は,他の文からwireAに適用される値の変化が,10時間単位だけ遅延することを意味します.

宣言時に常時代入があるとき,その遅延は常時代入の一部であり,ネット遅延ではありません.
したがって,ネット上の他のドライバの遅延を加算しません.
なお,その代入がヴェクタネット型であれば,立ち上がりと立下り遅延は,宣言時に代入が含まれているならば,個々のビットには適用されません.
前の変化が左辺に伝播する時間がある前に,右辺のオペランドが変化するような場合,以下のステップがとられます.

  1. 右辺式の値が評価されます
  2. 右辺の値が,左辺への伝播が予定されていた値と異なる場合,現時刻のスケジューリングからはずします.
  3. 新しい右辺の値が,左辺の値と同じ場合,イベントはスケジューリングされません.
  4. 新しい右辺の値が,現在の左辺の値と異なる場合,遅延は,左辺の現在の値と右辺の新しく計算された値と命令文で示された値を用いて,通常の方法で計算されます.新しい伝播イベントは,未来の遅延時間単位で起きるようにスケジューリングされます.

6.1.4 強度 ~ Strength

常時代入の駆動強度(driving strength)は,ユーザにより指定されます.
以下の型のスカラネット方への代入でのみ適用されます.

wire  tri  trireg  wand  triand  tri0  wor  trior  tri1

常時代入の駆動強度は,キーワード'assign'を用いることで,ネット宣言中または単独の代入で指定できます.
強度仕様が与えられるならば,ネット型もしくはassign文の後のすぐ近くで遅延指定よりも前に無ければならない.

駆動強度仕様は,ネットに1が代入されるときに適用される1つの強さの値と,0が代入されるときに適用される2つ目の強さの値とからなる.以下のキーワードは,1の代入のための強さの値を示す.

supply1  strong1  pull1  weak1  highz1

以下のキーワードは,0の代入のための強さの値を示す.

supply0  strong0  pull0  weak0  highz0

2つの強さ指定の順序は,調停される.以下の2つのルールが駆動強度仕様の使い方を制限する.

  • 強さ定義((highz1, highz0) と (highz0, highz1))は,異常な構成(illegal constructs)として扱う.
  • 駆動強度指定がない場合は,(strong1, strong0)をデフォルトとして扱う.


6.2 手続型代入 ~ Procedural assignments

手続型代入の主な議論は LRM9.2で行う.しかし,本節では,基本思想の記述は,常時代入と手続型代入との間の違いを明らかにします.
LRM 6.1で述べらているように,常時代入は,ゲートがネットを駆動する方法と似たようなマナーでネットを駆動します.右辺式は,ネットを常時駆動するような組み合わせ回路のようなものが考えられるでしょう.
対照的に,手続型代入は変数に値を代入します.代入は期間を持ちません.変わりに,変数は,次の手続型代入まで,代入の値を保持します.

手続代入は,always文, initial文, task文, function文のような手続き中にあり,トリガ代入と考えられます.

シミュレーション中,実行の流れが手順の中で代入に達すると,トリガは現れます.条件文は,代入に達するのを制御できます.
イベント制御,遅延制御,if文,case文,ループ文は,全て代入文が評価されるかどうかの制御に使えます.LRM 9で詳細を与え,例示します.


6.2.1 変数宣言代入 ~ Variable declaration assignment

変数宣言代入は,値を変数に代入するような,手続型代入の特殊なケースです.変数宣言と同じ命令文中に,変数に初期値をおくことができます.

  • 代入は,定数式とします.
  • 代入に期間はありませんが,代わりに変数は次の代入まで値を保持します.
  • アレイ型への変数宣言代入は許可されません.
  • 変数宣言代入は,モジュールレベルにおいてのみ許されます.

例文

Example 1 Declare a 4 bit reg and assign it the value 4.
  reg[3:0] a = 4'h4;
  This is equivalent to writing:
  reg[3:0] a;
  initial a = 4'h4;

Example 2 The following example is not legal.
  reg [3:0] array [3:0] = 0;

Example 3 Declare two integers, the first is assigned the value of 0.
  integer i = 0, j;

Example 4 Declare two real variables, assigned to the values 2.5 and 300,000.
  real r1 = 2.5, n300k = 3E6;

Example 5 Declare a time variable and realtime variable with initial values.
  time t1 = 25;
  realtime rt1 = 2.5;

注意:
同じ変数が,initialブロックと変数宣言代入の両方で異なる値を代入されるとき,評価順序は未定義です.
# initial blockのしょっぱなと,変数宣言のしょっぱなは,時間的には同じで,かつシミュレーション時間のゼロからだけど,仕様上は優先順位を設けない,ということですね.(はまったきがするなぁ)
# initial blockの先頭で '#1'とかしておくと良いかも,かも,かも... (その前にmodule resetかけたほうがよいよぃょぃ...


6.2.2 Variable declaration syntax

syntax

integer_declaration ::= (From Annex A - A.2.1.3)
  integer list_of_variable_identifiers ;

real_declaration ::=
  real list_of_real_identifiers ;

realtime_declaration ::=
  realtime list_of_real_identifiers ;

reg_declaration ::=
  reg [ signed ] [ range ] list_of_variable_identifiers ;

time_declaration ::=
  time list_of_variable_identifiers ;

real_type ::= (From Annex A - A.2.2.1)
  real_identifier [ = constant_expression ]
  | real_identifier dimension { dimension }

variable_type ::=
  variable_identifier [ = constant_expression ]
  | variable_identifier dimension { dimension }

list_of_real_identifiers ::= (From Annex A - A.2.3)
  real_type { , real_type }

list_of_variable_identifiers ::=
  variable_type { , variable_type }

LRM読解(Chap.5 Scheduling semantics)

2008/09/16Verilog::文法import

LRM 5. スケジューリング意味論?(Scheduling semantics)

5.1 モデルの実行(Execution of a model)

本章では,エレメント間の振る舞いを示す.特にイベントスケジューリングと実行について.
Verilog-HDLの処理構造は,ブロックやプロセスの並列実行にあります.
そのため,処理順序の決定方法等をユーザに明確に示す必要があります.が,simulator依存です,といっているみたい...?(勝手な意訳)




5.2 イベントシミュレーション(Event simulation)

1つのデザインは,接続された実行またはプロセスのスレッドから成る.

プロセスは,以下の特徴を持つobjectである.

  • 評価されることができる
  • ステート(状態)を持てる
  • 入力の変化に対して出力を出すことができる

また,プロセスは以下を含む:

  • primitives
  • modules
  • initial procedural blocks
  • always procedural blocks
  • continuous assignments
  • asynchronous tasks
  • procedural assignment statements

命名されたイベントと同様にシミュレートされる回路の NETや変数の値の変化がアップデートイベントであると考えられます。
(自力:シミュレーション対象の回路内の,全てのnetや変数の値の変化は,update eventを考慮している.(excite翻訳のほうが正しそうだな..)プロセスは、イベントをアップデートするために敏感(sensitive)です。
アップデートイベントが実行されるとき、そのイベントに敏感なすべてのプロセスが任意のオーダーで評価されます。
また、プロセスの評価は,evaluation eventとして知られているイベントです。

イベントに加えて、シミュレータの別のキーは時間です。
"simulation time"は、それがシミュレートされる回路にかかる実際の時間をモデル化するためにシミュレータによって保持された時間の値を参照するために使用されます。

この章では,"time"は,シミュレーション時間と共に互換性を持って使用されます。(おなじっちゅうこっちゃ?)


イベントは,異なる時間に起こりえます.
イベントの動向(track)をおさえて、それらが正しいオーダーで処理されるのを確実にするために、イベントは,要求された"simulation time"まで,イベント待ち行列に保たれます。(意訳)
イベントを待ち行列(queue)に置くのは,"scheduling an event"と呼ばれます。

In order to keep track of the events and to make sure they are processed in the correct order,
the events are kept on an event queue, ordered by simulation time.



5.3 階層状のイベント待ち行列(The stratified event queue)

表形式で順序,トリガを引くやつ,負荷情報を記載すると良い.Verilogイベントキューは,論理的に5つの異なる領域に分割されています.イベントは5つのどの領域にも追加できますが,削除はアクティブな領域からのみ可能です.

event name remark
active現在の"simulation time"で起きた,順不同に処理ができる*1イベント
inactive現在の"simulation time"で起きたが,activeイベントのあとに処理ができるイベント
non blocking assign update以前の"simulation time"で評価されたが,現在の"simulation time"でassignedされるイベント.active/inactive処理は先.
monitor上の3つのイベントが終わってから処理されるイベント
future未来の"simulation time"で起こるイベント."future inactive events"と"future non blocking assignment update events"に分けられる.

※処理優先度は上位から.

すべてのアクティブなイベント処理は,"simulation cycle"と呼ばれます.
即時処理のためのあらゆるアクティブなイベントを選ぶ自由度は,Verilog HDLの「非-決定論」の不可欠の源です。
明白なゼロ遅延(#0記述)が、processの中断と,現在時刻のinactive eventとして加えられることを要求します.
そのため,processは,現在の時刻の次のシミュレーションサイクルに再開されます.

ノンブロッキング代入(9.2.2参照)は,現在または後のシミュレーション時刻にスケジューリングされた,ノンブロッキング代入更新イベントを作り出します.
$monitorと$strobeのシステムタスク(17.1参照)は,各々の引数のためにモニタイベントを作成します.
これらのイベントはあらゆる連続した時間間隔で,絶え間なく再始動(be re-enabled)にされます.
モニターイベントは,いかなる他のイベントも引き起こすことができないので,独立です.
tf_synchronize() (25.58参照) や vpi_register_cb(cb_readwrite) (27.33参照)のようなPLI関数によってスケジューリングされたcall back proceduresは,inactiveイベントとして扱われるものとします.




5.4 Verilogシミュレーションのリファレンスモデル(The Verilog simulation reference model)

前節までのまとめで,事例を示す.簡単なイベント処理フローを示し,その説明を補足している.シミュレータを作る方,HDL記述をどのように解釈されるのかを理解するのに有用であろう.

5.4.1 Determinism

begin-end blockを1単位として,イベントqueで処理の停止/再開を行う.ノンブロッキング代入で,代入先が同じ変数の場合,記述順に"ノンブロッキング代入イベント"が生成され,queueに入る.したがって,イベント処理時には,一瞬前の値が入るが,最終的には最後に記述している値を保持することになる.


5.4.2 Nondeterminism

非決定の一例は, active eventがqueueから取り出され,あらゆるオーダで実行されることにより発生する.
ビヘイビアブロック内の,時間制御制約の無い命令文が,1つのイベントで実行してはならないときに生じる(意訳)
時間制御(命令)文は,#式・@式構文である(9.7参照)
ビヘイビア文を評価しいている全ての時には,シミュレータは実行を停止し,イベントキュー上のペンディングしているactive eventのような完了したイベントをおき続けるべきである.(意訳:キューの話が意味を取り違えているかもしれない.)
この効果は,プロセス実行のインタリーブを可能にする.インタリーブ実行の順序は,非決定論者的で,ユーザ制御下にはない.




5.5 レースコンディション(Race conditions)

式評価や,ネット更新イベントの実行は,混ぜられるので,レースコンディションが起こりえる.

assign p = q;
initial begin
     q = 1;
  #1 q = 0;
     $display(p);
end

シミュレータは,1か0を表示することは正しい.
qに対する0代入は,pに対する更新イベントを有効にする.
シミュレータは,連続して,$displayタスクを実行するか,$displayタスクが後に続いたpのための更新を実行するでしょう.




5.6 Scheduling implication of assignments

代入は,以下のようにプロセスとイベントに変換される.

5.6.1 連続代入文(Continuous assignment)

連続代入文(6章参照)は,プロセスと式中のソース要素の感度(sensitive)に対応する.
式の値が変化したとき,目標を決定するため,現在の値を用いて,active update eventをイベント待ち行列に追加します.


5.6.2 手続き上の連続した代入(Procedural continuous assignment)

手続き上の連続した代入(assign文かforce代入文(9.3参照))は,式中のソース要素の感度プロセスに対応します.
式の値が変化したとき,目標を決定するため,現在の値を用いて,active update eventをイベント待ち行列に追加します.
deassign文やrelease文は,対応する代入やforce文を無効にする.


5.6.3 Blocking assignment

遅延付きブロッキング代入文(9.2.1参照)は,右辺の値を現在の値を用いて計算ます.そのあと,実行中のプロセスを中断し,未来のイベントとしてスケジューリングされます.
もし,遅延がゼロならば,そのプロセスは現在時刻のinactiveイベントとしてスケジューリングされます.
プロセスから返ってきたとき,(または,遅延指定が無かったとき,即時に返ってきたとき),そのプロセスは左辺への代入を評価し,左辺の更新に基づくイベントを有効にします.
プロセスが再開したときの値は,目標を決定するために使われる.
実行は,その後,次のシーケンシャル文か他のアクティブイベントに続くでしょう.


5.6.4 Non blocking assignment

このtime stepでdelayがゼロのときで,かつ future eventでdelayがゼロではないときのノンブロッキング代入更新イベントでは,ノンブロッキング代入文(9.2.2参照)は,常に更新された値を計算し,更新のスケジュールをします.(ごめん わからん)
更新がイベント待ち行列に置かれると,有効な値は右辺の値と左辺の目標の両方を計算するのに使用されます.

A NON BLOCKING ASSIGNMENT STATEMENT  always computes the updated value and schedules the update
as a NON BLOCKING ASSIGN UPDATE EVENT, either in this TIME STEP if the delay is zero or as a future event if the delay is nonzero.

5.6.5 Switch (transistor) processing

LRM 5.4で示すイベントドリブンシミュレーションアルゴリズムは,片方向信号のフローに依存し,各々のイベントに対して独立に処理可能です.入力が読まれ,結果が計算され,そして更新がスケジュールされます.
Verilog HDLは,ビヘイビアとゲートレベルモデリングに加えて,スイッチレベルモデリングを提供します.
スイッチは双方向信号のフローを提供し,スイッチによって接続されたノードの連携処理を必要とします.
スイッチをモデル化するVerilog HDLソース要素は,tran, tranif0, tranif1, rtran, rtranif0, and rtranif1と呼ばれる様々な形式のトランジスタです.
スイッチ処理は,入力と出力が相互作用するので,ネットの全てのノードのために適切な値を決定する前に,双方向のスイッチで接続されたネットですべてのデバイスを考えるものとします.
シミュレータは,リラクゼーションテクニックを用いることで,これを可能にします.
そのシミュレータは,どのようなときにでも,tran処理ができます.
それは他のアクティブなイベントの実行で混ぜ合わされた特定の時に,tran-connected eventのサブセットとして処理できます.(意訳あやしい. 全部怪しいけれどw)

いくつかのトランジスタにゲート値xがあると、さらなる改善が必要です。

概念的に簡単なテクニックは,完全に伝導・非伝導のトランジスタのすべての可能な組み合わせに設定した,これらのトランジスタで,繰り返してネットワークを解決することです。(意訳:スイッチON/OFFの状態組み合わせを全部見ればOKということでしょう)
すべての場合におけるユニークなロジックレベルを持っているどんなノードも,このレベルと等しい定常応答(steady-state)を持ちます.他のすべてのノードには、定常応答Xがあります.(直訳そのまま.理解できてません.>< )


5.6.6 Port connections

ポート接続手順は,暗黙の連続したassign文か,暗黙の双方向の接続で処理します.
双方向接続は,2つのネットの間で常にenableにされたtran接続に類似していますが,(信号)強度の減少を伴いません.
ポート接続ルールは,値を受け取るのが,ネットまたは構造的なネット式(structural net expression)であることを要求します.ポートは,以下に示すような接続されたオブジェクトを宣言することで,常に表すことができます.

  • input port:外側の式から,ローカルのネット(input)への連続代入(continuous assignment*2
  • output port:ローカルのoutput式から,外側のネットへの連続代入
  • inout:ローカルネットから外側のネットへの,強度減衰の無いトランジスタ接続

5.6.7 Functions and tasks

task parameterとfunction parameterは値渡しとなり,起動時にコピーインされ,リターン時にコピーアウトされます.
functionリターン時のコピーアウトは,どんなブロッキング代入のように同じ挙動で振る舞います.
※意味が通じないナ... functionの値を貰うのは,ノンブロッキング代入と同じ扱いよ,ということかな.

*1 : activeより後ろで処理できないイベント,という意味だろう

*2 : "continuous"とわざわざ着いているのはなんだろう….moduleのポート接続のことかと思ったけど違うのかな...portという型があるんだっけ(汗

LRM読解

2008/09/10Verilogimport

LRM読解

wikiコンテンツとして,Verilogの配下におきます.
気ままに翻訳・転記しているので,結構なボリュームになってきましたので,章ごとにページを分けることにします.それでも結構大きい章があるので悩みどころですが・・・.

あと,私は英語力が弱いので,誤訳も多いと思います.よろしければ指摘いただくと幸いです.あくまでもreferenceですので,使用される処理系依存となっているところもあるかと思います.そのアタリの情報も併記できると良いかな,と考えております.

Xilinx WebPack ISEであれば,言語資料が公開されているのを見た記憶があります.あとはALTERAのQuartus IIでしょうか.
個人で触れるのはそこらへんまでと思いますので,業務で御利用の場合は自社のサポート部門等をあたってください・・・.

といいいつつ,LRM追いかけている途中で力尽きるかもしれませんが..

何も順序どおりに見ていく必要は無いんだ.必要そうなところだけ,かいつまんでもいいんだ・・・(挫折気味(笑

1. 概要 ~ Overview (13)
2. 語彙規約 ~ Lexical conventions 	(14)
3. データ型 ~ Data types	(20)
4. 式 ~ Expressions 	(24)
5. スケジューリング意味ネット? ~ Scheduling semantics	(5)
6. 代入 ~ Assignments	(6)
7. gate/switchレベルモデリング ~ Gate and switch level modeling	(32)
8. ユーザ定義primitive ~ User-defined primitives (UDPs) 	(11)
9. ビヘイビアモデリング ~ Behavioral modeling	(33)
10. taskとfunction ~ Tasks and functions	(11)
11. 名前つきブロックとタスクの無効化 ~ Disabling of named blocks and tasks	(3)
12. 階層構造 ~ Hierarchical structures 	(34)
13. 設計コンテンツのコンフィギュレーション ~ Configuring the contents of a design	(12)
14. Specifyブロック ~ Specify blocks	(26)
15. タイミングチェック ~ Timing checks	(32)
16. SDFを使ったバックアノテーション ~ Backannotation using the Standard Delay Format (SDF)	(8)
17. システムtaskとシステムfunction ~ System tasks and functions 	(47)
18.  ~ Value change dump (VCD) files	(26)
19. コンパイラディレクティブ ~ Compiler directives	(11)

20.  ~ PLI overview	(3)
21.  ~ PLI TF and ACC interface mechanism	(4)
22.  ~ Using ACC routines	(35)
23.  ~ ACC routine definitions	(161)
24.  ~ Using TF routines 	(4)
25.  ~ TF routine definitions 	(55)

26.  ~ Using VPI routines	(41)
27.  ~ VPI routine definitions	(47)

Annex A (normative) Formal syntax definition	(25)
Annex B (normative) List of keywords 	(2)
Annex C (informative) System tasks and functions 	(7)
Annex D (informative) Compiler directives 	(2)
Annex E (normative) acc_user.h	(9)
Annex F (normative) veriuser.h	(8)
Annex G (normative) vpi_user.h 	(14)
Annex H (informative) Bibliography	(1)

LRM読解(Chap.4 式 - Expression)

2008/09/09Verilog::文法import

式 - Expression [LRM 4]

LRM 4.1 Operators

式のまとめ

演算子と,実数(real型? integerとか)・論理型(login型? regとか)に対して演算可能かどうかの対応表を以下に記す.
詳細な説明は4.1.xに記載されているので参照されたい.個人的に気になった部分だけ抜粋し,紹介する.

expressionoperation namefor Realfor Logic
{} {{}}データ連結, 括り(Concatenation, replication)xo
+ - * / **算術演算(和/差/積/商/累乗)(Arithmetic)oo
%モジュロ演算子(Modulus)xo
> >= < <=比較演算子(Relational)oo
!論理否定(Logical negation)oo
&&論理積(Logical and)oo
||論理和(Logical or)oo
==論理一致(Logical equality)oo
!=論理不一致(Logical inequality)oo
===case一致(Case equality)xo
!==case不一致(Case inequality)xo
~Bit的な否定(Bit-wise negation)xo
&Bit的な論理積(Bit-wise and)xo
|Bit的な論理和(Bit-wise inclusive or)xo
Bit的な排他的論理和(Bit-wise exclusive or)xo
^~ or ~^Bit的な一致 (Bit-wise equivalence)xo
&圧縮論理積(Reduction and)xo
~&圧縮論理積/出力否定(NAND)(Reduction nand)xo
|圧縮論理和(Reduction or)xo
~|圧縮論理和/出力否定(NOR)(Reduction nor)xo
^圧縮排他的論理和(XOR)(Reduction xor)xo
~^ or ^~圧縮排他的論理和/否定(XNOR)(Reduction xnor)xo
<<論理的左シフト(Logical left shift)xo
>>論理的右シフト(Logical right shift)xo
<<<算術左シフト(Arithmetic left shift)xo
>>>算術右シフト(Arithmetic right shift)xo
? :3項演算子(Conditional)oo
orイベント和(Event or)oo

real数の論理式・関係演算結果は,1bitのスカラー値として得られます.


LRM 4.1.2 Binary operator precedence // 演算子の優先度

演算子優先度
+ - ! ~ (unary:単項演算子)
**
* / %
+ - (binary)
<< >> <<< >>>
< <= > >=
== != === !==*1
& ~&
^ ^~ ~^
| ~|
&&
||
? : (conditional operator)

LRM 4.1.8 Equality operators(同等式?)

数式例を表形式で示す.ただし,以下の点に注意すること.

  • 同等式の優先度は,関係式よりも低い.
  • 比較時にa,bのbit幅が異なる場合,短いほうの上位bitを拡張し,ゼロフィルして比較する.
  • 関係式の比較値に'x'/'z'が含まれている場合,結果はあいまいとなるので,比較結果としても'1'bx'を返す.
  • 同等式の場合,'x'/'z'の比較も行われるため,結果は必ず真(1)/偽(0)が返る

※resultは1bitであることに変わりは無い.

説明補足
a === b同等式, 一致bitごとに 0,1,z,x を比較. 全部一致で真(1)
a !== b同等式, 不一致bitごとに 0,1,z,x を比較. 全部一致で偽(0)
a == b関係式, 一致bitごとに 0,1 を比較. 全部一致で真(1).
a != b関係式, 不一致bitごとに 0,1 を比較. 全部一致で偽(0).

4.1.10 Bit-wise operators bit演算の真理値表を以下に示す.ANDは0が強く,ORは1が強く,その他は演算を行うと不定になる.→ハイインピは伝播しない.

  • binary AND
& 0 1 x z
00000
101xx
x0xxx
z0xxx
  • binary OR
| 0 1 x z
001xx
11111
xxxxx
zxxxx
  • binary EXOR
0 1 x z
001xx
110xx
xxxxx
zxxxx
  • binary EXNOR
^~ ~^ 0 1 x z
010xx
101xx
xxxxx
zxxxx
  • 単項演算子
~
01
10
xx
zx
LRM 4.1.12 Shift operators

論理シフトは,<<.>>です.算術シフトは,<<<,>>>です.
Verilog HDLでは,シフト演算子の定義はそれぞれ明確になっています.算術演算子は,演算結果がsignedである場合にだけ,MSB bitをシフトしてあいたビットに埋めます.それ以外の全てのケースでは,シフト後のあいたビットをゼロフィルします.

また,演算子の右辺について,下記の注意書きがありました.

If the right operand has an unknown or high impedence value, then the result shall be unknown.
The right operand is always treated as an unsigned number and has no effect on the signedness of the result.
The result signedness is determined by the left-hand operand and the remainder of the expression, as outlined in 4.5.1.


LRM 4.1.13 Conditional operator

3項演算子についての記載です.ここでもz,xの値が存在するため,注意が必要なようです.

syntax

conditional_expression ::= (From Annex A - A.8.3)
  expression1 ? { attribute_instance } expression2 : expression3

expression1 ::=
  expression

expression2 ::=
  expression

expression3 ::=
  expression

expression1を評価し,真(非0)ならばexpression2を評価し,結果を左辺に渡す.
偽(0)ならば,expression3を評価し,結果を左辺に渡す.
expression1が'x'や'z'の場合,expression2とexpression3を評価して,それぞれの結果をビットごとに下記の表に基づいて演算し,左辺に渡す.ただし,実数型ではないことを前提とする.(実数の場合は0となるでしょう?)
演算時にbit幅が異なる場合,短いほうの上位にゼロビットを埋めて長さをあわせる.

both expression2 and expression3 shall be evaluated and their results shall be combined, bit by bit,
using Table 28 to calculate the final result unless expression2 or expression3 is real,
in which case the result shall be 0.
?: 0 1 x z
00xxx
1x1xx
xxxxx
zxxxx

※どちらも同じ値のときだけ値が返る.それ以外はどちらとも考えられるため,不定を返す.
おそらく論理合成するとどちらかの値が出るとは思うのだけれど.

注意
If~Then~Elseと同等と思ったら大間違い!!
exp1の結果に依存するが,不定が入らないように!!!
回路を作る側から考えると,入力不定なのだから,出力はいずれかの値を返すとしかいえない.セレクタのセレクト信号が不定な状態をイメージすればよいのだろう.if文だと,不定の場合はelseに流れてくれるので,ある意味シミュレーション不足になるのかもしれない.シミュレーション結果の不定は,原則は撲滅しましょう,ということでしょうね.


LRM 4.1.14 Concatenations

{}を用いると,bitレベルの結合ができる.ここで,繰り返し指定も可能である.書式は{}の前に繰り返し回数を記述する.ただし,不定値を返すようなものや,0は指定してはいけない(自然数だけ).
例を以下に示す.

{4{w}} // This is equivalent to {w, w, w, w}
a[31:0] = {1’b1, {0{1’b0}} }; //illegal. RHS becomes {1’b1,;
a[31:0] = {1’b1, {1’bz{1’b0}} }; //illegal. RHS becomes {1’b1,;
a[31:0] = {1’b1, {1’bx{1’b0}} }; //illegal. RHS becomes {1’b1,;



*1 : 関係式のほうが強い.同等式は弱いLRM4.1.8

4.2 Operands [4.2]

4.2.1 Vector bit-select and part-select addressing [4.2.1]

real型/realtime型で宣言された変数のビット選択・部分選択は不正と判断されます.

constant part-select

vector net, vector regのみ可.

  vect[msb_expr:lsb_expr]

ただし,いずれの式(msb_expr,lsb_expr)も定数を返す必要がある.変数になった場合は不定を返すことになるだろう.また,msb_exprのほうが,lsb_exprよりも重いbit(more significant bit)をアサインする必要がある.*2


indexed part-select

vector net, vector reg, integer variable, time variableが可.

reg [15:0] big_vect;    // Big endian
reg [0:15] little_vect; // Little endian

    big_vect[lsb_base_expr +: width_expr]
 little_vect[msb_base_expr +: width_expr]
    big_vect[msb_base_expr -: width_expr]
 little_vect[lsb_base_expr -: width_expr]

ただし,width_exprは定数式で,実行時に決定することは許されない.lsb_base_exprとmsb_base_exprは実行時に決定されても良い*3

例を張っておく.宣言時にMSB:LSBで指定しているはずなので,指定した単項演算子+と-がどちらに伸びていくかは把握できるはず.伸びていかないほうの数字を固定して,伸びていく方向にwidthだけビットが取り出されると,理解すればよさそう.

initial begin
if ( big_vect[0 +:8] == big_vect[7 : 0]) begin end
if (little_vect[0 +:8] == little_vect[0 : 7]) begin end
if ( big_vect[15 -:8] == big_vect[15 : 8]) begin end
if (little_vect[15 -:8] == little_vect[8 :15]) begin end
if (sel >0 && sel < 8)
  dword[8*sel +:8] = big_vect[7:0]; // Replace the byte selected.

LRM 4.2.3 Strings

4.2.3.3 Null string handling

ダブルクォートで囲った文字には NULL文字(\0)が付かないけれども,ダブルクォートだけで中身が無い場合("")は,'\0'となるらしい.


4.3 Minimum, typical, and maximum delay expressions

表題のとおり,遅延時間のmin./typ./max.を演算する.



4.4 Expression bit lengths

ビット長拡張について.和算のときは,左辺を含めた演算対象のビット幅のうち,最も大きい幅を用いる.

Expression Bit length Comments
Unsized constant number*4Same as integer
Sized constant numberAs given
i op j, where op is: + - * / % & | ^ ^~ ~^max(L(i),L(j))
op i, where op is: + - ~L(i)
i op j, where op is: === !== == != && || > >= < <=1 bitOperands are sized to max(L(i),L(j))
op i, where op is: & ~& | ~| ^ ~^ ^~ !1 bitAll operands are self-determined
i op j, where op is: >> << **L(i)j is self-determined
i ? j : kmax(L(j),L(k))i is self-determined
{i,...,j}L(i)+..+L(j)All operands are self-determined
{i{j,..,k}}i * (L(j)+..+L(k))All operands are self-determined

乗算時のビット幅に注意.積の場合は,(L(i) + L(j))を期待するが,表のとおり拡張はされない.結果を受ける側(左辺)で必要なビットを用意してasignすること.

例を見たが,納得できない.三つ目.

reg [3:0] a;
reg [5:0] b;
reg [15:0] c;

initial begin
  a = 4’hF;
  b = 6’ha;
  $display("a*b=%x", a*b); // expression size is self determined
  c = {a**b};              // expression a**b is self determined
  $display("a**b=%x", c);  // due to {}
  c = a**b;                // expression size is determined by c
  $display("c=%x", c);
end

//Result:
//  a*b=16 // 96 was truncated since expression size is 6
//  a**b=1 // expression size is 4 bits (size of a)
//  c=21   // example size is 16 bits (size of c)
//  コレ, なぜ21? 4'hF の 10乗だよねぇ?

4.5 Signed expressions

符号拡張について.C言語のキャストと同じように,Verilog-HDLにも型変換のためのシステム関数がある.

$signed - 返り値は符号つきである.
$unsigned - 返り値は符号なしである.
4.5.1 Rules for expressions types
  • operandにのみ依存し,左辺の影響は受けない.
  • 10進数はsigned(符号あり)とみなす.
  • 基数書式つきはunsigned(符号なし)とみなす.ただし,明示的に's'がついている場合は符号ありとする.
  • Bit-selectの結果は,operandにかかわらず,unsigned(符号なし)とみなす.
  • Part-selectの結果は,operandにかかわらず,unsigned(符号なし)とみなす.端から端まで選択した場合も,符号ナシとして扱われる.
Note:
 Concatenate results are unsigned, regardless of the operands.
 Comparison results (1, 0) are unsigned, regardless of the operands.
 Reals converted to integers by type coercion are signed
 The sign and size of any self-determined operand is determined by the operand itself and independent of the remainder of the expression.
 For non-self-determined operands the following rules apply:
 if any operand is real, the result is real;
 if any operand is unsigned, the result is unsigned, regardless of the operator;
 if all operands are signed, the result will be signed, regardless of operator, except as noted.

4.5.2 Steps for evaluating an expression
  • 基本ルールにのっとって,数式のビット長を決定する.
  • 4.5.1のルールを用いて,式の符号を決定する.
  • 式のoperandの型を,式にあわせて強制する.ただし,self-determinedしていないoperandのみ.
  • 同様に,self-determinedしていないbit長を拡張する.必要であれば,符号拡張処理を行う.
-Determine the expression size based upon the standard rules of expression size determination.
-Determine the sign of the expression using the rules outlined in 4.5.1.
-Coerce the type of each operand of the expression (excepting those which are self-determined) to the type of the expression.
-Extend the size of each operand (excepting those which are self-determined) to the size of the expression.
 Perform sign extension if and only if the operand type (after type coercion) is signed.

まともに訳せていないようだな....bit長決定→符号決定→演算のために項ごとに型キャスト→演算のためにbit長拡張/符号拡張


4.5.3 Steps for evaluating an assignment
  • LRM 4.4のルールに基づいて,右辺のサイズを決定する.
  • 必要であれば,右辺のサイズを拡張する.このとき,右辺がsignedで,かつbit長拡張が必要な場合に符号拡張を行う.
  • Determine the size of the RHS by the standard assignment size determination rules (see 4.4)
  • If needed, extend the size of the RHS, performing sign extension if and only if the type of the RHS is signed.

4.5.4 x,zを含むときの符号拡張

signed bitにx,zが入っているときは,bit拡張するときに それぞれx,zで埋める.signed bit以外のx,zについては,触れずにおいておく.

*2 : 添え字の値の大小ではなく,複数ビットとして値を扱う際のbitの並び,だろう.

*3 : 合成結果は,バレルシフタになるんでしょうねぇ.

*4 : 32bitを超える場合はMSBが不定となる.

LRM読解(Chap.3 データタイプ~型の種類)

2008/09/02Verilog::文法import

データタイプ~型の種類[LRM Chap.3]

値 [3.1]

Verilog-HDLには下記の4つの値しか存在しません. *1ただし,NET型では論理値に強度(Strength)を与えることができます.(LRM Chap.7)

文字説明
0論理値0,もしくはfalse状態を示す
1論理値1,もしくはtrue状態を示す
x論理値不定を示す
zHigh Impedance状態を示す

NET型とVariable型 [3.2]

NET

値を保持することは無く,PAD間をつなぐための配線材相当である.syntaxを引用する.

net_declaration ::= (From Annex A - A.2.1.3)
    net_type [ signed ] [ delay3 ] list_of_net_identifiers ;
  | net_type [ drive_strength ] [ signed ] [ delay3 ] list_of_net_decl_assignments ;
  | net_type [ vectored | scalared ] [ signed ] range [ delay3 ] list_of_net_identifiers ;
  | net_type [ drive_strength ] [ vectored | scalared ] [ signed ] range [ delay3 ] list_of_net_decl_assignments ;
  | trireg [ charge_strength ] [ signed ] [ delay3 ] list_of_net_identifiers ;
  | trireg [ drive_strength ] [ signed ] [ delay3 ] list_of_net_decl_assignments ;
  | trireg [ charge_strength ] [ vectored | scalared ] [ signed ] range [ delay3 ] list_of_net_identifiers ;
  | trireg [ drive_strength ] [ vectored | scalared ] [ signed ] range [ delay3 ] list_of_net_decl_assignments ;

net_type ::= (From Annex A - A.2.2.1)
    supply0 | supply1
  | tri | triand | trior | tri0 | tri1
  | wire | wand | wor

drive_strength ::= (From Annex A - A.2.2.2)
   ( strength0 , strength1 )
  | ( strength1 , strength0 )
  | ( strength0 , highz1 )
  | ( strength1 , highz0 )
  | ( highz0 , strength1 )
  | ( highz1 , strength0 )

strength0 ::= supply0 | strong0 | pull0 | weak0

strength1 ::= supply1 | strong1 | pull1 | weak1

charge_strength ::= ( small ) | ( medium ) | ( large )

delay3 ::= (From Annex A - A.2.2.3)
  # delay_value | # ( delay_value [ , delay_value [ , delay_value ] ] )

delay2 ::=
  # delay_value | # ( delay_value [ , delay_value ] )

delay_value ::=
    unsigned_number
  | parameter_identifier
  | specparam_identifier
  | mintypmax_expression

list_of_net_decl_assignments ::= (From Annex A - A.2.3)
  net_decl_assignment { , net_decl_assignment }

list_of_net_identifiers ::=
  net_identifier [ dimension { dimension }]
  { , net_identifier [ dimension { dimension }] }

net_decl_assignment ::= (From Annex A - A.2.4)
  net_identifier = expression

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

range ::=
  [ msb_constant_expression : lsb_constant_expression ]

(かなりテキトウな理解)
要は,配線と思えばよい?.

  • wire - 単純に端子?間を結ぶ
  • tri - tri-state?何に使うんだろうな...

Variable

syntaxを引用する.値を保持できる器となります.

integer_declaration ::= (From Annex A - A.2.1.3)
  integer list_of_variable_identifiers ;

real_declaration ::=
  real list_of_real_identifiers ;

realtime_declaration ::=
  realtime list_of_real_identifiers ;

reg_declaration ::=
  reg [ signed ] [ range ] list_of_variable_identifiers ;

time_declaration ::=
  time list_of_variable_identifiers ;

real_type ::= (From Annex A - A.2.2.1)
    real_identifier [ = constant_expression ]
  | real_identifier dimension { dimension }

variable_type ::=
    variable_identifier [ = constant_expression ]
  | variable_identifier dimension { dimension }

list_of_real_identifiers ::= (From Annex A - A.2.3)
  real_type { , real_type }

list_of_variable_identifiers ::=
  variable_type { , variable_type }

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

range ::=
  [ msb_constant_expression : lsb_constant_expression ]

変数としては,下記の種類がある.integer, real, realtime, reg, time.



Vector [3.3]

NET/Variable宣言時に,型とシンボルの間に記述する.書式では'range'と記していたもの.VectorのReg/Netは,2を法とする,2^nの演算に従う.(n=ベクタのビット長)

range ::=
  [ msb_constant_expression : lsb_constant_expression ]

MSB>LSBである必要は無い.,2^(abs(MSB-LSB)).Noteにて,ここで確保可能なサイズについて記されている.

1) Implementations may set a limit on the maximum length of a vector, but they will at least be 65536 (216) bits.
2) Implementations do not have to detect overflow of integer operations.

1)最低でも,ベクタ長は 2^16(65536) をサポートすること.
2)整数演算のオーバフローは検出する必要は無い.



Arrays [3.10]

net/variable宣言時に,シンボル名の後ろに"[mm:ll]"で指定する.また,LRM 3.10.noteより,

Implementations may limit the maximum size of an array, but they shall at least be 16777216 (224).

Parameters [3.11]

Parametersは,variable型にも,net型にも属さない.また,変数ではなく,定数である.
module parameters と specify parameters とがある.Parameter宣言は,net型/parameter型/variable型で,既に宣言された名称で再定義することはできない.

Parameters

syntax

local_parameter_declaration ::= (From Annex A - A.2.1.1)
  localparam [ signed ] [ range ] list_of_param_assignments ;
  | localparam integer list_of_param_assignments ;
  | localparam real list_of_param_assignments ;
  | localparam realtime list_of_param_assignments ;
  | localparam time list_of_param_assignments ;

parameter_declaration ::=
  parameter [ signed ] [ range ] list_of_param_assignments ;
  | parameter integer list_of_param_assignments ;
  | parameter real list_of_param_assignments ;
  | parameter realtime list_of_param_assignments ;
  | parameter time list_of_param_assignments ;

list_of_param_assignments ::= (From Annex A - A.2.3)
  param_assignment { , param_assignment }

param_assignment ::= (From Annex A - A.2.4)
  parameter_identifier = constant_expression

range ::= (From Annex A - A.2.5)
  [ msb_constant_expression : lsb_constant_expression ]
  • list_of_param_assignmentsは,module itemの中か,module_parameter_port_list*2の中のみ記述可能.
  • param_assignmentsが,module_parameter_port_list内に存在しない場合,param_assignmentsはlocal parameterとなり,どんな手段でもoverride不可能となる.

Parameterの定数再定義について

runtimeに書き換えることはできません.しかし,module parameterは,compilation時に,module定義時の値と異なる値に書き換えることは可能です.これはmodule instanceのカスタムを許容します.
parameterの修正は,defparam文か,module instance文で修正可能です.

parameter文の代表的な使い方は,delay(遅延時間)や変数のビット幅(width)を定義するのに使います.Chap..12で詳細に記します.


module parameterはタイプ指定とrange指定(range)を持つことができます。以下の規則に従って、module parameterのタイプとrange(range)があるものとします.

  • タイプもrange指定もないparameter宣言は,すべての値のオーバーライドも適用された後の,パラメタに割り当てられた最終値のタイプとrangeをデフォルトとするものとします。
  • range指定はあるが,タイプ指定のないパラメタは,符号なしのパラメタ定義rangeになるでしょう.
    符号とrangeは,値のオーバーライドによる影響を受けさせないものとします.
  • range指定が無い,タイプ指定を伴うパラメタは,タイプ指定になるでしょう。
  • 符号ありparameterは,全ての値のオーバーライドを適用した後に,パラメタに割り当てられた最終値のrangeをデフォルトとするものとします、。
  • 符号あり,型指定ありかつrange指定ありのparameterは,符号あり・定義されたrangeとなるでしょう.符号・rangeは,値のオーヴァーライドによる影響を受けない.
  • range指定が無く,かつ,(符号あり型指定されているか,型指定が無い)parameter宣言は,LSB=0, MSBは最終的にparametaにアサインされた値が収まる大きさ以下となるでしょう.
  • range指定が無く,かつ,(符号あり型指定されているか,型指定が無い),かつ最終的にparametaにアサインされた値が符号なしとなるようなparameter宣言は,LSB=0, MSBは31となるでしょう.

// an implied range with an lsb equal to 0 and an msb equal to an implementation-dependent value of at least 31.

※直訳すぎてスミマセン.宣言時に省略した場合や上書きしたときのコンパイラの挙動について仕様が切られているようです.



Local parameters - localparam [3.11.2]

Verilog HDL localparamについて.local parameterは,defparam文や,並び順または名前付きの直接書き換えができません.local parameterは, - local parameter(s) are identical to parameters except that they can not directly be modified with the defparam statement or by the ordered or named parameter value assignment.

Local parameters can be assigned to a constant expression containing a parameter which can be modified with the defparam statement or by the ordered or named parameter value assignment.

See 12.1.3 for details. The syntax for local parameter declarations is given in Syntax 3-4.


Specify parameters[3.11.3]
specparam_declaration ::= (From Annex A - A.2.2.1)
  specparam [ range ] list_of_specparam_assignments ;

list_of_specparam_assignments ::= (From Annex A- A.2.3)
  specparam_assignment { , specparam_assignment }

specparam_assignment ::= (From Annex A - A.2.4)
  specparam_identifier = constant_mintypmax_expression
  | pulse_control_specparam

pulse_control_specparam ::=
  PATHPULSE$ = ( reject_limit_value [ , error_limit_value ] ) ;
  | PATHPULSE$specify_input_terminal_descriptor$specify_output_terminal_descriptor
  = ( reject_limit_value [ , error_limit_value ] ) ;

error_limit_value ::=
  limit_value

reject_limit_value ::=
  limit_value

limit_value ::=
  constant_mintypmax_expression

range ::= (From Annex A - A.2.5)
  [ msb_constant_expression : lsb_constant_expression ]

Table 8. Differences between specparams and parameters

Specparams(specify parameter)Specparams(specify parameter)
Use keyword specparamUse keyword parameter
Shall be declared inside a module or specify blockShall be declared outside specify blocks
May only be used inside a module or specify blockMay not be used inside specify blocks
May be assigned specparams and parametersMay not be assigned specparams
Use SDF annotation to override valuesUse defparam or instance declaration parameter value passing to override values


Name spaces [3.12]

*1 : 例外としてevent型(LRM9.7.3)があります.

*2 : referto SS.12