2013年9月4日水曜日

SystemCはじめました、その2

モジュールの話。

まずは手っ取り早く、記述例を挙げてしまおう。入力データを累積するVerilogモジュールと、そのSystemC版。SystemC版は短いので宣言も定義もごった煮にしてしまった。

Verilog版

module acc (
    input           clk,
    input           reset_n,
    input           i_en,
    input           i_clr,
    input   [7:0]   i_d,
    output  [7:0]   o_d
);
reg     [7:0]   r_d;
always @(posedge clk or negedge reset_n) begin
    if (!reset_n)
        r_d[7:0] <= 8'h00;
    else if (i_clr)
        r_d[7:0] <= 8'h00;
    else if (i_en)
        r_d[7:0] <= r_d[7:0] + i_d[7:0];
end
assign o_d[7:0] = r_d[7:0];
endmodule

SystemC版

#include <systemc>
SC_MODULE(acc) {
    sc_core::sc_in<bool> clk;
    sc_core::sc_in<bool> reset_n;
    sc_core::sc_in<bool> i_en;
    sc_core::sc_in<bool> i_clr;
    sc_core::sc_in< sc_dt::sc_uint<8> > i_d;
    sc_core::sc_out< sc_dt::sc_uint<8> > o_d;
    sc_dt::sc_uint<8> r_d;
    SC_CTOR(acc) {
        SC_METHOD(accumlate);
        sensitive << clk.pos() << reset_n.neg();
    }
    void accumlate() {
        if (!reset_n.read()) {
            r_d = 0;
        } else if (i_clr.read()) {
            r_d = 0;
        } else if (i_en.read()) {
            r_d += i_d.read();
        }
        o_d.write(r_d);
    }
};

SystemCの記述を頭からなめて行こう。

まずはSystemCのヘッダsystemcをインクルードしている。互換性のためにsystemc.hも残されているが、systemc.hはやたらめったらusingしまくるので、これから新規で書くコードではsystemcを使った方がいいかな。

モジュール宣言にはSC_MODULEを使う。これはsc_core::sc_moduleのサブクラスを作るマクロで、SystemCのモジュールとはsc_core::sc_moduleのサブクラス。

入力ポートはsc_core::sc_in<>、出力ポートはsc_core::sc_out<>のインスタンスで表す。FFは単純に、モジュールのデータメンバで表現すればよいだろう。

モジュールのコンストラクタは、SC_CTORマクロを使用して定義している。SC_CTORで宣言・定義できるのは、sc_core::sc_module_name型の引数を1つ取るコンストラクタ。引数を変えたい場合は、普通にコンストラクタを定義する。

コンストラクタの中身では、SC_METHODマクロを使用してaccumlate()メソッドをclk入力の立ち上がりかreset_n入力の立ち下がり毎に呼び出すよう、指示している。

accumlate()の中身では、入力に応じて初期化や加算を行い、その結果を出力している。見ての通り、入力ポートから入力されている値を取得するにはread()、出力ポートへ出力する値を設定するにはwrite()を用いる。

0 件のコメント:

コメントを投稿