クリプキクローネ日記帳

ある種の音楽と数学とランニングはミニマルなところが似ていると思う。

HDLによるデジタル設計入門 [桜井至(著)]

SystemCについてちょっと興味があったので読みました。
FPGAをC言語で書くってどういうことなんでしょうか。


とは言うものの、SystemCの本ではなくFPGA全体の本です。

デルタ遅延はその時刻におけるすべての右辺が確定してから左辺に代入される処理のこと。
デルタ遅延を持たない代入文(=)では並行処理されるprocessAとprocessBのどちらが早いか分からないので
レース状態となり、結果が変わる恐れがある。
ノンブロッキング代入文(<=)を用いるとデルタ遅延を伴うので結果に偶然性が入らない。
2つの変数の値がクロスするような代入も可能。
しかし、遅延なので時間は余計にかかる。
ちなみに「デルタ遅延」でググるとデルタ航空の遅延情報しか出てこない。

SystemCはC++のライブラリであり、通常のC++コンパイラでコンパイルしてシミュレーションできる。
SC_MODULE(x) はクラスxの定義のマクロ。
SC_CTOR(x) クラスxのコンストラクタのマクロ。
コンストラクタの中でSC_THREADなどのマクロでprocessを宣言する。
クロック同期のSC_CTHREADと、他のトリガも指定できるSC_THREAD、
1度しか実効しないSC_METHODがある。

"sc_"で始まるデータ型は回路の信号で、read()やwrite()で読み書きできる。
wait()で次のクロックまで待つ。
関数のオーバーロードやテンプレートも使える。すごい。
インスタンスの中にインスタンスを持つことで階層構造を構築できる。
sc_main()から始まる。

Verilogは演算子が割とCと同じなのがうれしい。
デコーダ、エンコーダ、マルチプレクサ、パリティ、コンパレータ、DFF、カウンタ
あたりはVerilogとSystemCで記述ほとんど変わらず。
SystemCの方が若干長いときも多い。

が、ROMやRAMのあたりからSystemCが本領を発揮。
VerilogではROMやRAMの動作をクロックベースで記述する必要があるのに対し、
SystemCではROMもRAMも配列や変数を定義するだけでいい。
ROMはconstつける。

他にもSystemCは長い計算式を書いたときにどこまで同時にやって
どこをパイプライン的にするか、あるいはゲートを共有するか、などを指定しない。
配列を定義したときにそれがRAMなのかレジスタなのかも指定しない。
なのでよりアルゴリズムに集中して記述できる。
画像フィルタの例は全然FPGAな感じがしない。

そして終盤の論理合成と配置配線のところは読み応えあり。
ゲートの固有遅延、信号の立ち上がり立ち下がりによるスロープ遅延、
接続先の入力容量による遷移遅延(なぜか千一円と変換される)、
そして配線の長さによる配線遅延
の合計に、
電源電圧、温度、プロセスによる係数(Kファクタ)をすべてかけると遅延時間が得られる。
計算がさらに複雑になると遅延モデルが非線形になるので、
ゲート固有のLUTを用いて遅延時間を計算する。

特に最近はディープサブミクロンになってきて配線遅延の影響が増大。
遷移遅延はファンアウトが大きくなると長くなるので、
ゲートを増やしてファンアウトを分割したりする。
あるいは充電時間を短くするためにドライブ能力を上げたりする。
Kファクタはゲートの個体差もあるので、
論理合成用のテクノロジ・ライブラリに定義されている
BEST, TYPICAL, WORSTの値でそれぞれ検証したりする。

タイミング解析にはスタティック解析とダイナミック解析がある。
スタティック解析は各ゲートや配線の遅延を別々に加算するので、
実際にはありえないパス(False Path)を含めて解析してしまい、保守的な結果がでる。

ダイナミック解析はテストベクタを元にゲートレベルシミュレーションとして実行する。
False Pathは存在しないが、テストベクタを適切に用意する必要あり。時間もかかる。
したがってスタティック解析が主流。

回路分割をすると回路ブロック内で最適化してから回路ブロック間を扱うので、
回路ブロックの入出力インターフェースが綺麗になっているほうがよい。
具体的には、レジスタを配置して同期をとったり。

消費電力削減のためにはスイッチング消費電力、インターナル消費電力、リーク消費電力を下げる必要がある。
スイッチング消費電力は接続された負荷容量の充放電に伴う消費電力。
インターナル消費電力はCMOSのスイッチ時に一瞬だけ
PMOSの電源からNMOSのグラウンドにショートするときの消費電力。
リークはPN接合部に流れるリーク電流。

このうちスイッチング消費電力とインターナル消費電力は当然ながらトグルの頻度に比例。
リークはトランジスタセルに固有なので動作周波数には依存せず、電源電圧とセル面積に依存する。

したがって、Gated Clockで不使用のサブ回路のクロックを止めることで消費電力削減できる。
CPUのペリフェラルのクロック止めるのと同じか。

テストを容易にするためのスキャン設計というものもある。
テストモードで入力レジスタにシフトレジスタで値を送り、通常どおり動かし、
最後にまたテストモードで出力レジスタからシフトレジスタで値を得る。
スキャンレジスタのせいで5~15%程度面積が増えるが、テストには有効。

レイアウト設計では論理合成とレイアウトを行ったり来たりして最適なレイアウトを模索する。
レイアウト後のタイミング検証の結果、遅延を短くするためによりドライブ能力が必要だったり、
バッファが必要だったり、いろいろするので論理合成をやり直すことになる。
これは大変だ。
すべてやり直すと時間がかかるので、ECO(Engineering Change Order)と呼ばれる、
論理変更が生じたゲート回路のみを再度レイアウトしなおす方法もある。
そのためにはスペアセルをあらかじめ準備しておく方がよい。

SystemCはもっと「無理矢理C言語にしました」みたいな感じかと思ってましたが、
普通にC++だし、RTLよりも上流な記法にしようという明確な意図も感じられていい言語だと思いました。
回路がさらに見えにくくなるから不具合出たとき大変だろうなという気はします。

そして論理合成と配置配線のあたりは本当に厄介だなと改めて思いました。
ツールが自動的にやる部分が多すぎてよく見えないですね。
Cのコンパイラの方がまだなんとなくイメージできる気がします。
まぁ自分でFPGAやる予定まったくないのでいいんですが。
  1. 2017/06/10(土) 00:13:52|
  2. | トラックバック:0
  3. | コメント:0
<<モータ制御 the ビギニング [西田麻美 (著)] | ホーム | NHK「迷宮美術館」巨匠の言葉>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバックURLはこちら
http://myumbrella.blog42.fc2.com/tb.php/380-017f5446
この記事にトラックバックする(FC2ブログユーザー)