プロシージャの宣言
プロシージャは状態遷移や、パイプライン、順序回路を用いた制御を提供する構文です。
共通アクション記述以外でプロシージャ専用の単位アクションを記述する領域があります。
プロシージャは一度起動すると他のプロシージャに遷移するか、終了を宣言するまで動作し続けます。
プロシージャを宣言するには、以下のような記述方法を行います。
宣言時に仮引数を付帯することも可能で、カンマで区切って複数の仮引数を与えることもできます。
proc_name プロシージャ名(仮引数, 仮引数2, 仮引数3, …)
プロシージャに付帯することができる仮引数はレジスタに限ります。
プロシージャを起動する場合、
またはプロシージャアクションで別のプロシージャに遷移する場合は以下のように記述します。
プロシージャ名()
上記のコマンドはプロシージャアクション内で使用した場合、
元のプロシージャが終了し、遷移先のプロシージャが起動します。
プロシージャは起動を実行した次クロックから実際に起動を始めます。
また、プロシージャを終了せずに別のプロシージャを起動する場合は、invokeを使用します。
invokeは以下の記述方法で使用します。
プロシージャ名.invoke()
また、invokeは指定したプロシージャに実引数を渡すことができます。
invokeで実引数を使用する場合は以下のように使用します。
プロシージャ名.invoke(<実引数>
<実引数>, <実引数>, <実引数>… )
プロシージャを終了する場合は、プロシージャアクションで以下のように記述します。
プロシージャ名.finish()
finishはプロシージャ名を指定して終了することが可能です。
プロシージャは”finish”を宣言した次クロックで、アクションを停止します。
また、プロシージャアクションを記述する場合は以下のように記述します。
proc プロシージャ名 {
単位アクション1
単位アクション2
単位アクション3
…
単位アクションX
}
プロシージャの起動例として例題34を見てみましょう。
【例題34.プロシージャ起動例】 |
declare ex34 { func_out cnt_end_call ; } module ex34 { reg r1=0, r2=0, r3=0 ; reg cnt_reg[4]=0; proc_name proc_count ; //式1 r1 := r2 ; r2 := r3 ; r3 := 0b1 ; if(~r1&r2&r3) proc_count() ; //式2 proc proc_count { //式3 any { cnt_reg == 0b1000 : { cnt_reg := 0b0000 ; cnt_end_call() ; } else : cnt_reg++ ; } } } |
例題34はプロシージャの起動例です。
ex34は内部にプロシージャproc_countを持っています。
proc_countの宣言は式1で行っています。
式2はif条件文が真の場合、proc_countを起動するという意味のアクションです。
式2で起動したproc_countのプロシージャアクションは式3から開始します。
proc_countのプロシージャアクションは、レジスタのカウントアップしています。
まず、anyブロックによりレジスタcnt_regを0b0000から1ずつカウントアップします。
次にcnt_regが0b1000に到達すると、cnt_regに0b0000を書き戻してから、
制御出力端子cnt_end_callを呼び出します。
ex34には、proc_countを終了するアクションを記述していないので、
proc_countは一度起動すると、プロシージャアクションを実行し続けます。
例題34のシミュレーション結果を見てみましょう。
次にプロシージャの引数を利用した例として、
以下の例題35を見てみましょう。
【例題35.プロシージャ引数使用例】 |
declare ex35 { output f[4] ; } module ex35 { wire w_result[4] ; reg r1=0, r2=0, r3=0 ; reg opr1[4], opr2[4] ; reg result[4] ; proc_name proc_fetch() ; //式1 proc_name proc_add(opr1, opr2) ; //式2 proc_name proc_writeback(result) ; //式3 r1:=r2; r2:=r3; r3:=0b1; if(~r1&r2&r3) proc_fetch() ; //式4 proc proc_fetch { //式5 proc_add(0b0101, 0b1010) ; } proc proc_add { //式6 w_result = opr1 + opr2 ; proc_writeback(w_result) ; } proc proc_writeback { //式7 f = result ; finish ; } } |
例題35は、プロシージャの引数使用例です。
モジュールex35は3つのプロシージャを持っていて、
式1・2・3はそれぞれプロシージャproc_fetch,proc_add,proc_writebackの宣言です。
式2・3は宣言と同時に、レジスタを仮引数として宣言しています。
ex35では、式4がきっかけとなってproc_fetchを起動します。
式4は、if条件文が真の場合、proc_fetchを起動するアクションです。
式6のproc_fetchが起動すると、プロシージャアクションを実行します。
proc_fetchのプロシージャアクションは、proc_addを実引数0b0101,0b1010をつけて起動します。
proc_addの実引数は仮引数で宣言したレジスタに代入します。
式6のproc_addが起動すると、プロシージャアクションを実行します。
式6のプロシージャアクションは、
・opr1,opr2の加算結果をw_resultに代入
・proc_writebackを実引数w_resultをつけて起動
の2つを実行しています。
そして、式7から始まるproc_writebackのプロシージャアクションは、
resultをfに代入するアクションです。
例題35のシミュレーション結果を見てみましょう。