SC_CTHREADを活かすためにsc_signalに拡張を試みた話

SystemC Advent Calendar2012 の 20日目の記事です。

私が嫌い苦手な SC_CTHREADを使えるように出来ないかなと思い、
sc_signalへの拡張をトライしてみました。っていうお話です。
先に結論だけ書いておくと、面倒臭くなって拡張断念しました。


背景


なぜ SC_CTHREADが嫌い苦手かというと、こちら で書いてますが、
抽象度が低いからになります。では、抽象度が高ければどうなのか?
抽象度がもし高ければ、リセット部分と動作部分が分離されるので、
意外に使えるのではないかと思ってます。

では、抽象度を上げるためにどうすればいいか?
一つの答えが、sensitive リストへの信号をクロックにしなければいいと思いました。


つまり、

SC_CTHREAD(a_cthread, clk.pos());

部分が、

SC_CTHREAD(a_cthread, hoge.event());

みたいになれば、クロック・ドリブンというよりイベント・ドリブンなプロセスに
なると思ったからです。


なぜ sc_signalを拡張対象に?


SC_THREADや SC_METHODは

sensitive << sc_event

というような感じですが、SC_CTHREADは sc_event_finderを使います。
そのため、拡張するなら sc_eventではなく sc_signalのほうが良いと判断しました。

  • sc_event_finder and sc_event_finder_tのクラス定義
    class sc_event_finder implementation-defined ;
    
    template <class IF>
    class sc_event_finder_t
    : public sc_event_finder
    {
      public:
        sc_event_finder_t( const sc_port_base& port_, const sc_event& (IF::*event_method_) () const );
         // Other members
        implementation-defined};

クラス定義を見てもらえば分かるのですが、Interface部分が必要になってます。
sc_signalだと以下のように諸々入っているので OKかなと思ったわけです。

20121220_class_sc_signal.png

sc_signalを拡張する


my_sc_signalクラスにて、pos(), neg()を追加するようなコードを書いてみました。
SystemCのライブラリを覗いてみるとわかるのですが、bool型だけ部分特殊化を使って
個別に定義してあることが多いので、今回は sc_signal<bool>部分を継承してみました。

  • my_sc_signal.h
     1|#include <systemc.h>
     2|
     3|class my_sc_signal : public sc_signal<bool> {
     4|
     5|public:
     6|    // constructors
     7|    my_sc_signal()
     8|    : m_neg_finder_p(0), m_pos_finder_p(0)
     9|    {}
    10| 
    11|    // destructor
    12|    virtual ~my_sc_signal()
    13|    {
    14|        delete m_neg_finder_p;
    15|        delete m_pos_finder_p;
    16|    }
    17|
    18|    // use for positive edge sensitivity
    19|    sc_event_finder& pos() const
    20|    {
    21|        if ( !m_pos_finder_p )
    22|    {
    23|        m_pos_finder_p = new sc_event_finder_t<if_type>(
    24|            *this, &if_type::posedge_event );
    25|    } 
    26|    return *m_pos_finder_p;
    27|    }
    28|
    29|    // use for negative edge sensitivity
    30|    sc_event_finder& neg() const
    31|    {
    32|        if ( !m_neg_finder_p )
    33|    {
    34|        m_neg_finder_p = new sc_event_finder_t<if_type>(
    35|            *this, &if_type::negedge_event );
    36|    } 
    37|    return *m_neg_finder_p;
    38|    }
    39|
    40|private:
    41|    mutable sc_event_finder* m_neg_finder_p;
    42|    mutable sc_event_finder* m_pos_finder_p;
    43|
    44|};

my_sc_signalを作ったところで、コンパイルしてみると以下のようなエラーが出ます。

my_sc_signal.h:24: error: no matching function for call to 
  'sc_core::sc_event_finder_t >
  ::sc_event_finder_t(const my_sc_signal&, const sc_core::sc_event& (
  sc_core::sc_signal_in_if::*)()const)'
...
my_sc_signal.h:35: error: no matching function for call to
  'sc_core::sc_event_finder_t >
  ::sc_event_finder_t(const my_sc_signal&, const sc_core::sc_event& (
  sc_core::sc_signal_in_if::*)()const)'

なにを言っているんだ。。。

そ、そんなバカな。。。

恐る恐る sc_event_finder_tのクラス定義を見ると、

sc_event_finder_t( const sc_port_base& port_, const sc_event& (IF::*event_method_) () const );

第一引数が sc_port_baseになっていますね。
はい。sc_signalは sc_port_baseは継承していません。。。
sc_portだと、モジュールの外との接続が必須になるので、それは嫌だなと。
なんてこったい(´・ω・`)


というような絶望を味わいファントムへ。。。


まとめ


SC_CTHREADが嫌い苦手だが、リセット部分と動作部分をわかりやすく?
記述出来るので、抽象度を上げるために内部で活用出来る信号(イベント)を
定義しようとしたが、sc_port に阻まれて面倒臭くなって止めたというお話でした。


※本記事が愚痴みたいになってしまったかもしれませんが、
 そういう訳ではなく、SC_CTHREADがどう作られているか?
 また、sc_event_finderとは何か?など感じてもらえればと思って書いてます。


次回は衝撃的な展開が待ってます。

関連記事

コメントの投稿

非公開コメント

プロフィール

Kocha

Author:Kocha
なんでもチャレンジ!(^o^)/
E-mail
github:Kocha
イベントカレンダー

カレンダー
10 | 2017/11 | 12
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 - -
カテゴリ
OVP (4)
最新記事
最新コメント
アーカイブ
リンク
Twitter
アクセス人数