必要悪なModular Interface

この記事はHDL Advent Calendar 2013の17日目の記事です。
HDLとか無関係なのに何やっているんだか・・・・

はじめに

SystemCで動作合成をやると出くわす(人も多いであろう)Modular Interfaceですが、
私はこれが割と嫌いです。厳密に言えばある条件を満たすと嫌いです。
嫌いだけどこれがないとどうしようもない・・・ってのもわかります。
だからもうSystemCも割と嫌かもwww

Modular Interfaceとは?

厳密な定義があるのかも知らないけど、まずは次の超簡単なSC_MODULEの例を見てみましょう。

SC_MODULE(test) {
  sc_in<int> i1;
  sc_out<int> o1;
  sc_in_clk clk;
  sc_in<bool> rst;
  int v;

  void proc(void) {
    wait();
    while(1) {
      v = i1->read();
      o1->write(v);
      wait();
    }
  }

  SC_CTOR(test) {
    SC_CTHREAD(proc, clk.pos());
    reset_signal_is(rst, true);
  }
};

動作合成用の記述なんて久しぶりに書きました。
当然環境がないので、合成とかしてません。
面倒なのでOSCIシミュレーションも試してませんm(__)m
ポートi1から入力をそのままポートo1に毎サイクル流し続けるだけの単純な構成です。

これをModular Interfaceを使うとどうなるかと言うと?次のコードを御覧ください。

class my_if
{
  sc_in<int> i1;
  sc_out<int> o1;

 public:
  int read() {
    return i1->read();
  }
  void write(int v) {
    o1->write(v);
  }
};

SC_MODULE(test) {
  my_if p1;
  sc_in_clk clk;
  sc_in<bool> rst;
  int v;

  void proc(void) {
    wait();
    while(1) {
      v = p1.read();
      p1.write(v);
      wait();
    }
  }
};

コンストラクタは省略しました。
要はModular Interfaceは入出力関連のポートと処理を隠蔽するためのものです。
実際にはmy_ifのポートはバスやらに応じて多種用意されますし、
そのバスを利用した外部との通信はここまで単純ではないでしょう。

何が嫌いなの?

はい、ここまで全然嫌いじゃないです。至って普通。
しかし、my_ifクラスが実はSC_MODULEでプロセスを持っていたらどうでしょう?
例えば、クラス内にFIFOバッファを持っていたりして、
read()はその最初の要素を取ってきてとか・・・
私が大嫌いなのはコレです。

SC_MODULEは外部と通信するときは自身の持つポートを介して通信しろ!
と声を大にして言いたい。
ポートを介して外部と通信している癖に、
関数を通じて内部変数にアクセスとか死ねばイイ・・・
という気持ち。心底汚いコードだと思うのです
その辺、ポートを排してしまったBSVとかイイよね!とか思う。

必要なの?

実はMaster側のポートをModular Interfaceに押し込めるだけなら、
例で見たとおりな構成で行けるので不要です。
問題はSlave側です。同じ構成でやろうとするとすぐに無理だと気付きます。
というかSlave側は何かテクニカル過ぎて頭痛くなる。
これをやろうと考えた某社と某社と某社はマジで凄いと思う。
面倒なので気が向いた人はどうすればいいか考えてみればいいと思います。

結論

Modular Interfaceは心底穢らわしいけど必要なのです。。。。orz

どうやって実現するか考えるとこうなるのはわかるけど、
本人たちは汚いとか思わなかったのかな・・・?というのもちょっと気になる。