FPGAでコンピュータ将棋を作る(2)
論理回路設計用の言語(例えばVerilogHDLやVHDL)の特徴を3つだけ挙げて、それを元に、Cのソースコードを自動的にVHDLのソースコードに落とし込むことが可能かどうかを検討する。
1.
いま論理回路設計の主流である同期式回路では、ある時間tにおける変数の状態をもとに次の時間 t+1 の変数の状態を決定する。Xを入力、Qをレジスタの状態とすれば、状態遷移関数をδとして、 Q(t+1) = δ(X(t) , Q(t)) と書ける。
「時間tにおける入力と時間tにおけるレジスタの状態から、時間t+1のときのレジスタの状態が決まりまっせ」と理解すれば良い。
だから、 x = y; と代入文を書いたとき、左辺のxは新しい(時間 t+1の) x で右辺の yは古い(時間 tの) yの値である。つまり、 x(t+1) = y(t); とみなせばわかりやすい。
2.
命令は、並列的に実行される。
x = y;
y = x;
と書いたとき、1.で述べた通り、これは次の意味になる。
x(t+1) = y(t);
y(t+1) = x(t);
よって、中間レジスタなしに変数の値を交換できる。
この二つの代入は並列的に実行される。
3.
(CやC#的に言えば)イベントトリガでメソッドが呼び出される。
例えばVHDLで
process (CLK)
と書けば、CLKが変化したときに(CやC#的に言えば)呼び出される。
C風に書きなおせば、これは
if (CLK(t-1)!=CLK(t))
と等価である。
■ 考察 -- 制作の動機
いま行いたいのは、
・ C風の言語を定義して、Cコンパイラでそれがコンパイルでき、PC上で高速に実行できること。(VHDLで書いたものを、PC上で高速に実行させることは不可能なため。またVHDLのコンパイルにはずいぶん時間を要するので、なるべくならVHDLのコンパイル作業自体したくない。)
・ C風の言語を定義して、その言語から自動的にVHDLのコードが生成されること。(せっかく書いたのだから、そのままVHDLに変換できて、FPGA上で動いて欲しい。)
である。
この二つを満たすためには、上記の1.2.3.の機能をCのソースコード上で実現出来れば良い。CのソースコードなのでCコンパイラでコンパイルして実行できることは自明。1.2.3.の機能を実現しているので、ソースプログラムを注意深く書けば等価なVHDLのコードに変換できる。
■ 考察 -- 実現方法
では、どうやればCのソースコードで1.2.3.が実現できるか考えていく。
1.2.は、代入のときに、左辺値として参照されたときと右辺値として参照されたときとで動作を変更できれば良い。Cならoperator = のoverloadなどで解決できる。
3.のイベントトリガに関しては、事前に変数を登録しておき、時間経過の処理のときにその登録されている変数の(t-1)の時の値が0で、tの時の値が1かどうか判定して事前に登録されているfunctionを呼び出せば良い。
ここまでくれば、Cで書いたものをVHDLへ変換する下準備は整う。
このような観点で考えたとき、SystemCで書かれた次のサンプルプログラムは、上記のアイデアと同じような実装になっているように見えてくる。(調べてないので実際にどうなっているのかは知らないが。)
# include "systemc.h"SC_MODULE(adder) // モジュール (クラス) 宣言
{
sc_in<int> a, b; // ポート
sc_out<int> sum;void do_add() // プロセス
{
sum = a + b;
}SC_CTOR(adder) // コンストラクタ
{
SC_METHOD(do_add); // カーネルへのdo_addの登録
sensitive << a << b; // do_addのセンシビティリスト追加
}
}
■ 考察 -- IFマクロの必要性
if (exp) state1 else state2;
の形式のものもCのソースとして実行してコンパイルするときはこのままで良いが、VHDLのコードをここから生成するときは、state1とstate2との両方が評価されなければならない。(式が評価されたときに、VHDLのコードを1行ずつ出力するようにするため)
そのためには、defineでIFマクロを作って、Cのソースとしてコンパイルするときと VHDL用のコード生成をするときとで処理が切り替わるようにしなければならない。(boostで使われているようなプリプロセッサのテクニックを使う。)
■ 結論
用途をコンピュータ将棋プログラムのFPGA化ぐらいに限定すれば、以上のように、(高価なSystemCの開発環境を使わずとも)工夫することによって、C風の言語 から C / VHDLソースコードの自動生成というのは十分可能である。
VHDLのソースコードの自動生成に関しては、IFマクロやSWITCHマクロのようなものをいっぱい定義していくよりは、自分でparserから書いたほうがいいような気はする。