3.14 SFL言語の形式


以下に SFL言語の形式を示します.形式の表記には表3.5 の BNF (Backus-Naur Form) 表記法を用いています.これによると,たとえば {x1|x2|x3} は「x1 または x2 または x3 が 0 回以上繰り返されること」を,[x1|x2|x3] は「x1 または x2 または x3 が省略され得ること」を表しています.


<表3.5> BNF形式

● シンボル

シンボル ::= 名前||定数|キーワード|予約語

名前 ::= 英文字{英文字|数字}

::= 数字{数字}

定数 ::= 0{x16進数|o8進数|b2進数|X16進数|O8進数|B2進数}

16進数 ::= {16進数字}
8進数 ::= {8進数字}
2進数 ::= {2進数字}

キーワード ::= module|circuit|declare
|input|output|bidirect
|instrin|instrout|instrself
|sel|bus|sel_v|bus_v
|reg|reg_ws|reg_wr|mem
|instr_arg|stage_name|task
|instruct|stage
|state_name|segment_name|first_state
|state|segment
|par|alt|any|if|else
|goto|call|return|generate|relay|finish
|'{|'}|;|,|(|)|.|:|'[|']
|:=|=|==|'||@|&|'|'||+|'>|'<
|'>'>|'<'<|^|/'||/@|/&|/|\|#
予約語 ::= p_reset|m_clock|s_clock|b_clock|VDD|VSS
|scan_in|scan_out|scan_enb|scan_clock|t_adrs_

英文字 ::= A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|_

2進数字 ::= 0|1

8進数字 ::= 0|1|2|3|4|5|6|7

数字 ::= 0|1|2|3|4|5|6|7|8|9

16進数字 ::= 0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|A|B|C|D|E|F

記号 ::= !|"|#|$|%|&|'|(|)|*|+|,|-|.|/|:|;
|'<|=|'>|?|@|'[|\|']|^|`|'{|'||'}|~

空白文字 ::= ブランク(space) | タブ(tab) | 復改文字(newline)


シンボルシンボル を区切るために 1個以上の空白文字 が必要です.ただし,記号列はもっとも長いキーワード に該当する部分ごとにシンボル とされ,前後のシンボル との間に空白文字 は不要です.たとえば ":===" は ":=","=="とされます.

名前 の先頭の英文字 に'_'を使用することはできません.

予約語 は合成された回路の中で固定的に使われる外部端子の名称です.表3.6 に簡単な説明と,どのプログラムが生成するかをまとめました(表右側のスキャンおよびテスト関係の予約語は,ワークステーション版 PARTHENONに備わっているテスト合成機能の使用時に有意となる).SFLEXPが生成するリセットとクロック関係の端子がどう使われるかは,6.3節を参照して下さい.なお,キーワード予約語 と同じ名前 は使用できません.


<表3.6> 論理合成で使用されるSFLレベルの予約語

● SFL記述

SFL記述 ::=
{モジュールの宣言|モジュールの定義|機能回路の定義}

モジュールの宣言 ::=
declare モジュール名 '{
{外部端子の定義}
{被利用時の制御端子の仮引き数の定義}
'}

外部端子の定義 ::=
input データ入力端子名['<ビット幅 '>]{,データ入力端子名['<ビット幅'>]};
| output データ出力端子名['<ビット幅 '>]{,データ出力端子名['<ビット幅 '>]};
| bidirect データ双方向端子名['<ビット幅 '>]{,データ双方向端子名['<ビット幅 '>]};
| instrin 制御入力端子名{,制御入力端子名};
| instrout 制御出力端子名{,制御出力端子名};

被利用時の制御端子の仮引き数の定義 ::=
instr_arg 制御入力端子名([入力となる端子名{,入力となる端子名}]);

モジュールの定義 ::=
module モジュール名 '{
{モジュールの宣言}
{外部端子の定義|構成要素の定義}
{制御端子の仮引き数の定義}
{ステージとタスクと仮引き数の定義}
[共通動作の定義]
{制御端子による動作の定義}
{ステージの動作手順の定義}
'}

機能回路の定義 ::=
circuit 機能回路名 '{
{モジュールの宣言}
{外部端子の定義|構成要素の定義}
{制御端子の仮引き数の定義}
{ステージとタスクと仮引き数の定義}
[共通動作の定義]
{制御端子による動作の定義}
{ステージの動作手順の定義}
'}

引き数が存在しないとき被利用時の制御端子の仮引き数の定義 は省略できます.

● 構成要素

構成要素の定義 ::=
instrself 制御内部端子名{,制御内部端子名};
| bus データ内部端子名['<ビット幅 '>]{,データ内部端子名['<ビット幅 '>]};
| sel データ内部端子名['<ビット幅 '>]{,データ内部端子名['<ビット幅 '>]};
| bus_v データ内部端子名['<ビット幅 '>]{,データ内部端子名['<ビット幅 '>]};
| sel_v データ内部端子名['<ビット幅 '>]{,データ内部端子名['<ビット幅 '>]};
| reg レジスタ名['<ビット幅 '>]{,レジスタ名['<ビット幅 '>]};
| reg_ws レジスタ名['<ビット幅 '>]{,レジスタ名['<ビット幅 '>]};
| reg_wr レジスタ名['<ビット幅 '>]{,レジスタ名['<ビット幅 '>]};
| mem メモリ名 '[ワ−ド数 ']['<ビット幅 '>]{,メモリ名 '[ワ−ド数 ']['<ビット幅 '>]};
| モジュール名 サブモジュール名{,サブモジュール名};

● 仮引き数

制御端子の仮引き数の定義 ::=
instr_arg 制御出力端子名([出力となる端子名{,出力となる端子名}]);
| instr_arg サブモジュール名.制御入力端子名([入力となる端子名{,入力となる端子名}]);
| instr_arg 制御内部端子名([データ内部端子名{,データ内部端子名}]);

入力となる端子名 ::=
データ入力端子名
| データ双方向端子名

出力となる端子名 ::=
データ出力端子名
| データ双方向端子名

ステージとタスクと仮引き数の定義 ::=
stage_name ステージ名 '{
{task タスク名([レジスタ名{,レジスタ名}]);}
'}

引き数が存在しないとき制御端子の仮引き数の定義 は省略できます.

● 動作の主体

共通動作の定義 ::= 動作

制御端子による動作の定義 ::=
instruct 制御入力端子名 動作
| instruct 制御内部端子名 動作
| instruct サブモジュール名.制御出力端子名 動作

ステージの動作手順の定義 ::=
stage ステージ名 '{
{状態名の定義}
{セグメント名の定義}
[初期状態の定義]
[共通動作の定義]
{状態の動作の定義}
{セグメントの動作手順の定義}
'}

セグメントの動作手順の定義 ::=
segment セグメント名 '{
{状態名の定義}
初期状態の定義
[共通動作の定義]
{状態の動作の定義}
'}

状態名の定義 ::= state_name 状態名{,状態名};

セグメント名の定義 ::= segment_name セグメント名{,セグメント名};

初期状態の定義 ::= first_state 状態名;

状態の動作の定義 ::= state 状態名 動作

ステージを状態やセグメントを定義せずに使うとき初期状態の定義 は省略できます.

● 動作

動作 ::=
parブロック
| altブロック
| anyブロック
| ifブロック
| 単位動作

parブロック ::= par'{{動作}'}

altブロック ::= alt'{条件付き動作{条件付き動作}[else動作]'}

anyブロック ::= any'{条件付き動作{条件付き動作}[else動作]'}

ifブロック ::= if(条件)動作

条件付き動作 ::= 条件:動作

else動作 ::= else: 動作

条件 ::=

● 単位動作

単位動作 ::=
端子への値の出力
| レジスタへの書き込み
| メモリへの書き込み
| 状態遷移
| セグメント呼び出し
| 戻り状態を指定しないセグメント呼び出し
| セグメントからの復帰
| ジョブの生成
| ジョブの転送
| ジョブの終了
| 制御端子の起動
| 空文

端子への値の出力 ::=
データ内部端子名=;
| データ出力端子名=;
| データ双方向端子名=;
| サブモジュール名.データ入力端子名=;
| サブモジュール名.データ双方向端子名=;

レジスタへの書き込み ::= レジスタ名:=;

メモリへの書き込み ::= メモリ名 '[ ']:=;

状態遷移 ::= goto 状態名;

セグメント呼び出し ::= call セグメント名(戻り状態名);

戻り状態を指定しないセグメント呼び出し ::= call セグメント名();

セグメントからの復帰 ::= return;

ジョブの生成 ::= generate ステージ名.タスク名([実引き数{,実引き数}]);

ジョブの転送 ::= relay ステージ名.タスク名([実引き数{,実引き数}]);

ジョブの終了 ::= finish;

制御端子の起動 ::=
制御出力端子名([実引き数{,実引き数}]);
| サブモジュール名.制御入力端子名([実引き数{,実引き数}]);
| 制御内部端子名([実引き数{,実引き数}]);

空文 ::= ;

戻り状態名 ::= 状態名

実引き数 ::=

空文 は,

alt {
a : ;
b : ;
else : goto x ;
}

のように使います.これは「a でも b でもないときは x へ状態遷移する」という意味になりま
す.

● 式,演算子

 ::=
単項式 '| /* or */
| 単項式 @ /* eor */
| 単項式 & /* and */
| 単項式 '|'| /* 連結 */
| 単項式 + /* 加算 */
| 単項式 '>'> /* ビット右シフト */
| 単項式 '<'< /* ビット左シフト */
| 単項式 == /* 一致判定 */
| 単項式

単項式 ::=
^単項式 /* 否定 */
| /'|単項式 /* 桁方向の or */
| /@単項式 /* 桁方向の eor */
| /&単項式 /* 桁方向の and */
| /単項式 /* デコード */
| \単項式 /* エンコード */
| 結果の桁数 #単項式 /* 符号拡張 */
| 要素 '<最上位桁位置[:最下位桁位置]'> /* ビット切り出し */
| 要素

● 要素

要素 ::=
()
| 定数
| レジスタ名
| メモリ名 '[アドレス ']
| ステージ名.タスク名
| データ内部端子名
| 制御内部端子名

| データ入力端子名
| データ出力端子名
| データ双方向端子名
| 制御入力端子名
| 制御出力端子名

| サブモジュール名.データ入力端子名
| サブモジュール名.データ出力端子名
| サブモジュール名.データ双方向端子名
| サブモジュール名.制御入力端子名
| サブモジュール名.制御出力端子名

| サブモジュール名.制御入力端子名([実引き数{,実引き数}]).データ出力端子名
| サブモジュール名.制御入力端子名([実引き数{,実引き数}]).データ双方向端子名

| 制御内部端子名([実引き数{,実引き数}]).データ内部端子名

| 制御出力端子名([実引き数{,実引き数}]).データ入力端子名
| 制御出力端子名([実引き数{,実引き数}]).データ双方向端子名

アドレス ::=

● 名前,数

モジュール名 ::= 名前
機能回路名 ::= 名前
データ入力端子名 ::= 名前
データ出力端子名 ::= 名前
データ双方向端子名 ::= 名前
データ内部端子名 ::= 名前
制御入力端子名 ::= 名前
制御出力端子名 ::= 名前
制御内部端子名 ::= 名前
サブモジュール名 ::= 名前
レジスタ名 ::= 名前
メモリ名 ::= 名前
ステージ名 ::= 名前

タスク名 ::= 名前
セグメント名 ::= 名前
状態名 ::= 名前

ビット幅 ::=
ワ−ド数 ::=
結果の桁数 ::=
最上位桁位置 ::=
最下位桁位置 ::=

モジュール名機能回路名 は設計の全体で一意でなければなりません.モジュールの構成要素の名前であるデータ入力端子名データ出力端子名データ双方向端子名データ内部端子名制御入力端子名制御出力端子名制御内部端子名サブモジュール名レジスタ名メモリ名ステージ名 は,モジュールの中で一意でなければなりません.ステージのタスク名セグメント名状態名 はステージ内で,セグメントの状態名 はセグメント内で一意でなければなりません.


ハードウェア動作の記述言語〜 SFL のページへ戻る

ホームページに戻る