約 2,643,807 件
https://w.atwiki.jp/bambooflow/pages/131.html
SystemC Visual C++2008 Express EditionでのHello World!!! SystemCライブラリのインストールが完了したら、やっぱりまずはハロー プログラムでしょう。 プロジェクトの作成から設定の仕方、「Hello, SystemC!!!」と表示させるまでの流れをここで説明する。 ここで、SystemCのバージョンは2.2.0で、インストール先はC \systemc-2.2.0として説明する。 SystemCライブラリの生成方法がわからない場合はこちらを参照。 SystemC Visual C++2008 Express EditionでのHello World!!!プロジェクト作成 プログラム準備 プロジェクトの設定(プロパティ設定) SystemCライブラリの追加 コンパイル(ビルド) 実行 もしも、コンパイルでこんなエラーがでたら プロジェクト作成 ファイルから新規作成→プロジェクトを選択。 新しいプロジェクト ウィンドウで、プロジェクトの種類をVisual C++のWin32を選択して、Win32コンソール アプリケーションを選ぶ。 各項目を設定プロジェクトファイル名:Hello01 場所:C \systemc-2.2.0\MySrc ソリューション:新しいソリューションを作成するソリューションのディレクトリを作成のチェックボックスは解除(付けない) 設定が完了したらOKをクリック。 次へをクリック。 アプリケーションの設定コンソール アプリケーションを選択 追加のオプションは、空のプロジェクトをチェック 完了をクリック。 プログラム準備 作成したプロジェクトのフォルダに、プログラム「Hello01.cpp」を準備する。準備方法はどのようにでもかまわない。(ファイル→新規作成→ファイル から作っても良いし、メモ帳で作ってもよい) 作成したプログラムは、プロジェクトのソースファイルとして登録する。登録の仕方はツリー上のソースファイルを右クリックして「追加→既存の項目」で選択してもよいし、ファイルをDrag Dropで追加してもよい。 hello01.cpp #include systemc.h int sc_main( int argc, char* argv[] ) { printf( "Hello, SystemC!!!\n" ); return 0; } プロジェクトの設定(プロパティ設定) メニュのプロジェクトからプロパティを選択。 全般の構成の種類は、アプリケーション(.exe)であることを確認する。 C/C++の追加のインクルード ディレクトリに、"C \systemc-2.2.0\src\"を追加する。 C/C++の簡易リビルドを行なうは"いいえ"を選択。 C/C++のランタイム ライブラリは"マルチスレッド デバッグ(/MTd)"を選択。(SystemC.libの作成時と同じ設定でなければならない) これで、プロパティの設定は完了。 SystemCライブラリの追加 SystemCライブラリをDrap Dropでプロジェクトのソースファイルに追加する。プロパティとして設定もできるが、面倒くさかったので今回これで済ませた。 コンパイル(ビルド) メニューのビルドからソリューションのビルドを選択。 コンパイルが正常に完了したことを確認する。 実行 メニュのデバッグからデバッグなしで開始を選択。するとコマンドプロンプトが実行されるはず。 コマンドプロンプト上に「Hello, SystemC!!!」が表示されたら成功!! 終わり。 もしも、コンパイルでこんなエラーがでたら リンク時に次のようなエラーが出た。 1 LIBCMTD.lib(dbgheap.obj) error LNK2005 __heap_alloc は既に LIBCMT.lib(malloc.obj) で定義されています。 1 LIBCMTD.lib(dbgheap.obj) error LNK2005 __recalloc は既に LIBCMT.lib(recalloc.obj) で定義されています。 ・・・ C/C++のコード生成で、ランタイム ライブラリの選択が誤っている可能性がある。 ランタイムライブラリの設定はSystemC.lib生成時とプログラムのコンパイル時で合わせないといけない。 今回のエラーでは、SystemC.lib生成時に"マルチスレッド (/MT)"を選択して、プログラムのコンパイル時に、"マルチスレッド デバッグ(/MTd)"を選択したことが原因。 VC初心者の私は、このエラーにかなり悩まされた。 以上
https://w.atwiki.jp/bambooflow/pages/113.html
SystemCの検証環境モデル構成 SystemCの検証環境モデル構成1.小規模なモデルテストサンプルプログラム 2.中規模なモデルテストサンプルプログラム 3.大規模なモデルテストサンプルプログラム おそらく3.のモデル構成が多くに記述する形になる。 1.小規模なモデルテスト 比較的小さなモデルの検証をしたいときのモデル構成。 #ref error :ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (verif_model_s.png) sc_mainのところで、 検証モデルのオブジェクトを実体化 クロック信号を生成、接続 入出力信号の接続 テストパタン用意 シミュレーション時間の更新 必要があれば、テストパタン用意、時間更新を繰り返す。 をする。 メインとモデルの2ファイルで済む。 しかし、シミュレーションがしにくかったり拡張しにくかったりする。 サンプルプログラム template_s.tgz 階層構造 sc_main |== myModel(MyModel) MyModel機能クロックなし 4つの値を入力(in_a, in_b, in_c, in_d) 合計出力(out_total) 平均出力(out_ave) 最小値出力(out_min) 最大値出力(out_max) 2.中規模なモデルテスト モデルが複雑になり、テストパタンが大きくなったとき、 別にテストベンチを用意して検証を実施するようなモデル構成。 #ref error :ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (verif_model_m.png) sc_mainでは、 モデルの実体化 テストベンチの実体化 クロック信号生成、接続 モデル間信号接続 シミュレーション開始sc_start() をする。 シミュレーションの終了は、テストベンチのプロセス内にsc_stop()を入れて、必要なタイミングで終了するようにする。 テストモデルとテストベンチとメインで構成する。 メインプログラムに接続等を記述するので、環境を移動させるのが難がある。 サンプルプログラム template_clk_m.tgz 階層構造 sc_main |== myModel(MyModel) |== testBench(TestBench) MyModel機能クロック動作 4つの値を入力(in_a, in_b, in_c, in_d) 合計出力(out_total) 平均出力(out_ave) 最小値出力(out_min) 最大値出力(out_max) 3.大規模なモデルテスト 検証環境が複雑になったときのモデル構成。 テストベンチとモデルの上にトップモジュールをおく。 #ref error :ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (verif_model_l.png) sc_mainでは、 TOPモジュールの実体化 シミュレーション開始sc_start() TOPモジュールでは、 モデルの実体化 テストベンチの実体化 クロック信号生成、接続 モデル間信号接続 をする。 ファイルが多くなって複雑にみえるかもしれないが、一度覚えてしまえばモデル追加や検証するのが容易。 この形は、sc_mainで1つのオブジェクト(TOPモジュール)を実体化するだけで済むので、規模の小さいモデル構成でもはじめからこの形にしたほうがよい。 サンプルプログラム template_clk_l.tgz 階層構造 sc_main |== syscTop(SyscTop) |== myModel(MyModel) |== testBench(TestBench) MyModel機能クロック動作 4つの値を入力(in_a, in_b, in_c, in_d) 合計出力(out_total) 平均出力(out_ave) 最小値出力(out_min) 最大値出力(out_max)
https://w.atwiki.jp/systemc/pages/17.html
SystemCは、プログラム言語c++のライブラリなのでc++の理解が欠かせない。また、sc2veriのようなユーティリティも作りたい。SystemCではなくてc++に関する事項だと思う事柄は、ここに記述する。 boost研究
https://w.atwiki.jp/bambooflow/pages/160.html
SCVとは SCVとは? SCVでなにができる? SCVとは? SCVはSystemC Verification Standardの略。 SystemC検証のための拡張クラスライブラリ。 Socデザインのためのテストベンチと検証IPを開発するために提供されている。 Cadence社のTestBuilderとForte社のQuickBenchがベースらしい。 SCVでなにができる? トランザクション・ベース検証(Transaction-based Verification) データの内観(Data Introspection) ランダム生成、制限付ランダム(Constrained randamization)、重み付ランダム(Weighted randomization) トランザクション・レコーディング(Transaction Recording) スパース・アレイ(疎な配列, Spare Array) HDLシミュレータへの接続(PLI,VPI等を経由) カバレッジとアサーションはまだ無い。
https://w.atwiki.jp/systemc/pages/13.html
トップページ メニュー systemc_install systemc_begin TLM_install ams_install SystemC-AMS紹介 SystemCと高位合成 c++研究 暫定メニュー リンク @wiki @wikiご利用ガイド ここを編集
https://w.atwiki.jp/systemc/pages/2.html
トップページ メニュー systemc_install systemc_begin TLM_install ams_install SystemC-AMS紹介 SystemCと高位合成 c++研究 暫定メニュー リンク @wiki @wikiご利用ガイド ここを編集
https://w.atwiki.jp/bambooflow/pages/141.html
C++標準テンプレートライブラリSTLの利用 C++標準テンプレートライブラリSTLの利用STLとは STLの構成 コンテナの種類 vector の利用vectorへのおもなアクセス メモリとしてのvectorの利用例 STLとは STL Standard Template Library C++のテンプレート機能を最大限に利用した標準ライブラリ。 STLは簡単にいうと配列のような要素の集合(コンテナ)を扱いやすくしたもの。 たとえば、動的な配列の確保を繰り返したり、ソートしたり、FIFOの構成を作ったり、連想配列を構成したりがSTLを使うことで容易になる。また、速度も早い。 現在すべてのC++のコンパイラで提供されている。 SystemCはVerilog-HDLと違って、C++で記述できるものは制限なく使うことができるのが利点。なので、活用できる便利な機能は存分に使うべし。 STLの構成 次のもので構成されている。 コンテナ 共通アルゴリズム イテレータ 関数オブジェクト ここでは、最低限使えればとりあえずよしとし、あまり詳しく説明しない。 もし、興味があるようであれば、別のサイトを参照のこと。 コンテナの種類 代表的なものは以下のとおり。 コンテナ 説明 vector 動的配列、ランダムアクセスが可能、Cの配列と互換がある deque 動的配列、両端キュー map 連想配列、バイナリツリーに要素を持ちソートされた状態で取り出せる list 双方向リンクドリスト、要素の入れ換えが得意 vector の利用 vectorは動的配列。 ランダムアクセスに向いているが、要素の追加・削除は要素数に比例して時間がかかる。 配列の代わりに使用するとよい。 vectorコンテナを利用するには次をインクルードする必要がある。 #include vector 必要なら次のおまじないをかく。 using namespace std; もし、ネームスペースがわかる人であれば、いちいちstd を書くことをすすめる。 vectorへのおもなアクセス 以下は全てではないが、よく使いそうなものを挙げた。 メソッド・書式 説明 iterator begin() 先頭を表すイタレータを返す iterator end() 末尾を表すイタレータを返す bool empty() vectorの要素が空なら"true"、空でなければ"false"を返す int size() 要素数を返す void clear() すべての要素を削除 reference at( size_type pos ) pos番目の要素を返す reference operator[]( size_type pos ) pos番目の要素を返す。「at」を使用することを推奨) void assign( const iterator first, const iterator last ) vectorの内容をfirstからlastに置き換え void assign( size_type n, const T x = T() ) vectorの内容をn個のxに置き換え void swap( vector x ) vectorの内容をxと交換 void resize(size_type new_size, T x = T()) 大きさを変える。必要なら領域を拡張し、拡張分はxで初期化される コンストラクタ 書式 説明(例) vector(); 例) vector int vect;長さ0のint型のvectorを作る vector( size_type size ); 例) vector int vect2(20);長さ20のint型vectorを作る vector( size_type size, const TYPE val ); 例) vector int vect3(10, 100);長さ10のint型vectorを作り、すべての要素を100で初期化する vector( const vector from ); 例) vector int vect4(vect1);vect1をコピーし、vect4とする メモリとしてのvectorの利用例 std vector unsigned int mem( 1024, 0 ); // RAM、1024個用意し、すべて0で初期化 // Write mem.at(addr) = w_data; // mem[addr] = w_data; でもOK // Read mem[addr] = mem.at(addr); // r_data = mem[addr]; でもOK
https://w.atwiki.jp/bambooflow/pages/123.html
SystemC TLM-2.0について SystemC TLM-2.0についてはじめに背景 TLM-2.0で重視されていること TLMへの要求 TLM-2コーディングスタイルLoosely-timed(LT) Approximately-timed(AT) TLM-2.0正式版の機能テンポラルデカップリング(Temporal Decoupling) Direct Memory Interface(DMI) TLMインタフェースtlm_fw_transport_if<>(ターゲット側I/F) tlm_bw_transport_if<>(イニシエータ側I/F) インタフェースコールb_transport(FW) nb_transport_fw(FW) nb_transport_bw(BW) get_direct_mem_ptr(FW) invalidate_direct_mem_ptr(FW,BW) transport_dbg(FW) ソケット TLM-2.0クラスについて ジェネリック・ペイロードについて b_transportについて はじめに 背景 TLM-1標準では、トランザクション通信のためのコア・インタフェース群を定義した。 このインタフェース群はいくつかのアプリケーションにおいて成功したものの、メモリ・マップ バスのモデリングと他のon-chip通信ネットワークの観点3つの欠点を持つ。 TLM-1は標準トランザクションを持たない TLM-1はタイミング・アノテーションをサポートしない TLM-1インタフェースは全てのトランザクション・オブジェクトとデータを要求し、シミュレーションが低速となる。若干のアプリケーションはトランザクションオブジェクトで組込形ポインタでこの制約上で動くが、これは標準ではなくそして共通性がない。TLM-2はライフタイムがいくつかのトランスポート・コールで受け渡すトランザクションオブジェクトでこの欠点についてたいしょした。新しい通信インタフェースによりサポートした。 TLM-2では、 共通のトランザクション、ジェネリック・ペイロードが用意された テンポラル・デカップリング、ウォンタム・キーパーが用意された バックドア(DMI)が用意された TLM-2.0で重視されていること シミュレーション速度 インターオペラビリティ(モデルの共通したインタフェース、モデルの接続性の向上) TLMへの要求 ソフトウェア解析 ソフトウェア・パフォーマンス アーキテクチャ解析 ハードウェア検証 TLM-2コーディングスタイル TLM2.0Draft2まで次の3つがあった Un-Timed(UT) -- TLM-2.0正式版でLTに合わせられた Loosely-timed(LT) Approximately-timed(AT) TLM-2.0正式版は2つのコーディングスタイルとなっている Loosely-timed(LT) Approximately-timed(AT) Loosely-timed(LT) O/S起動とマルチコアシステム実行のための十分なタイミング精度 プロセスはシミュレーション時間の前に実行可能(テンポラル・デカップリング) 各トランザクションは開始と終了の2つのタイミング・ポイントを持つ ダイレクト・メモリ・インターフェース(DMI)の使用 b_transport(推奨) nb_transport Loosely おおまか Approximately-timed(AT) 別名、cycle-approximate(サイクル-アプロクシメイト)、または、cycle-count-accurate(サイクル-カウント-アキュレート) アーキテクチャの調査に十分な精度 プロセスはシミュレーション時間と横並びに実行 各トランザクションは4つのタイミング・ポイントを持つ(拡張可能) nb_transport_fw、nb_transport_bw Approximately おおよそ TLM-2.0正式版の機能 テンポラルデカップリング(Temporal Decoupling) wait()関数コールを少なくして、シミュレーション高速化を図る仕組み LTモデリングで採用 イニシエータもしくはターゲットでおおよその処理遅延を計算する b_transportもしくは、nb_transportによりトランザクションと一緒に処理遅延を渡し、あるタイミングでシミュレーション時間を更新する方法 Direct Memory Interface(DMI) トランザクションを発生させないで実メモリアドレスを直接取得する方法 SW検証環境向けに高速化を図るために有効 TLMインタフェース 次の2つのI/Fが使えれば、TLM-2.0はとりあえずOKかも。 ターゲットモデルはフォワード(FW)インタフェースを継承する(tlm_fw_transport_if ) イニシエータはバックワード(BW)インタフェースを継承する(tlm_bw_transport_if ) バスモデルは両方のインターフェースを継承する tlm_fw_transport_if<>(ターゲット側I/F) 次のクラスを継承している。 tlm_blocking_transport_if<> tlm_fw_nonblocking_transport_if<> tlm_fw_direct_mem_if<> tlm_transport_dbg_if<> 次は純粋仮想関数。 void b_transport (TRANS trans, sc_core sc_time t) tlm_sync_enum nb_transport_fw (TRANS trans, PHASE phase, sc_core sc_time t) bool get_direct_mem_ptr (TRANS trans, tlm_dmi dmi_data) unsigned int transport_dbg (TRANS trans) よって、tlm_fw_transport_ifを使用する場合は、最低でも上記4つの関数を定義する必要がある。 tlm_bw_transport_if<>(イニシエータ側I/F) 次のクラスを継承している。 tlm_bw_nonblocking_transport_if<> tlm_bw_direct_mem_if 次は純粋仮想関数。 tlm_sync_enum nb_transport_bw (TRANS trans, PHASE phase, sc_core sc_time t) void invalidate_direct_mem_ptr (sc_dt uint64 start_range, sc_dt uint64 end_range) よって、tlm_bw_transport_ifを使用する場合は、最低でも上記2つの関数を定義する必要がある。 インタフェースコール b_transport(FW) void b_transport (TRANS trans, sc_core sc_time t) イニシエータからターゲットにデータ転送(ブロッキング) TRANSは通常tlm_generic_payload tはタイミングアノテーション nb_transport_fw(FW) tlm_sync_enum nb_transport_fw (TRANS trans, PHASE phase, sc_core sc_time t) イニシエータからターゲットにデータ転送(ノン・ブロッキング) TRANSは通常tlm_generic_payload PHASEはtlm_phase、処理状況のフェーズ tはタイミングアノテーション nb_transport_bw(BW) tlm_sync_enum nb_transport_bw (TRANS trans, PHASE phase, sc_core sc_time t) ターゲットからイニシエータに対して処理状況を通知(ノン・ブロッキング) get_direct_mem_ptr(FW) bool get_direct_mem_ptr (TRANS trans, tlm_dmi dmi_data) 直接メモリの中身をイニシエータから読み書きするためのI/F(DMI) イニシエータからターゲットのじメモリのポインタを取得 トランザクションを介さない、通常の手続きとは異なるデータのやりとり サポートしない場合はfalseを返す invalidate_direct_mem_ptr(FW,BW) void invalidate_direct_mem_ptr (sc_dt uint64 start_range, sc_dt uint64 end_range) イニシエータ側にターゲットのメモリマップのポインタが使用不可能な状況になっていることを通知する DMI用関数 transport_dbg(FW) デバッグ用I/F Read/Write等の処理を行わないでデータを取得する イニシエータからターゲットの関数を呼ぶ サポートしない場合には、0を返す ソケット ソケットはイニシエータ - ターゲット間を通信するためのポート。sc_portとsc_exportをまとめたもにに近い。 インタフェースコールはソケットを介して使用する。 ソケットはすでにいくつか用意されているが、自分専用のソケットを作成してもOK。 tlm_utilsにConvenience socketsとしていくつか用意されている。 基本ソケットtlm_initiator_socket<BUSWIDTH, TYPES, N, POL> tlm_target_socket<BUSWIDTH, TYPES, N, POL>
https://w.atwiki.jp/bambooflow/pages/147.html
サンプル --シンプルFIFO-- systemcのディレクトリにexamplesがあって、その中のsimple_fifoをみてみた。 これは、おおよそsc_fifoを自分で作るようなサンプルとなっているようだ(若干簡単にしている)。 このサンプルが理解できればsc_fifoの動作もわかるようだ。 インターフェース、チャネル、ポートの関係はSystemCを理解する上でかなり重要なところ。 サンプル --シンプルFIFO--simple_fifoサンプル場所 FIFO作成について インターフェースとチャネルの関係 インターフェースとチャネルとポートの接続関係 インターフェース作成出力側インターフェース(write_if) 入力側インターフェース(read_if) チャネル作成(fifo) writeとreadのブロッキング動作 ポート作成、接続、アクセス送信側[producer](sc_port write_if ) 受信側[consumer](sc_port read_if ) トップ接続 write,read動作説明 まとめ simple_fifoサンプル場所 SystemCのパッケージを展開した以下の場所。 systemc-2.2.0/examples/sysc/simple_fifo/ FIFO作成について このサンプルで作成するFIFOは階層チャネルになる(sc_channelを継承する)。 通信に必要なものはつぎのとおり。 インターフェース(write_if, read_if) チャネル(fifo) また、送受信するモジュールはポート(sc_port write_if , sc_port read_if )を準備する必要がある。 インターフェースとチャネルの関係 クラス図 sc_interface ↑ ┌──┴──┐ write_if read_if ↑ ↑ sc_channel └──┬──┘ ↑ ├────────┘ │ fifo インターフェースとチャネルとポートの接続関係 《送信側》 《受信側》 sc_port write_if ==== fifo ==== sc_port read_if インターフェース作成 インターフェースは次の2つのルールで作成する。 sc_interfaceを継承する 純粋仮想関数(virtual=0)のみをpublicで宣言する 出力側インターフェース(write_if) 値をFIFOへ書き込む側のインターフェース。 class write_if virtual public sc_interface { public virtual void write(char) = 0; virtual void reset() = 0; }; 出力側はwriteとresetメソッドを準備している。sc_fifoでは、ノンブロッキングで書き込むnb_writeメソッドやFIFOが満杯かどうか取得するためのnum_freeメソッドがあるが、このサンプルは最小限のものだけにしているようだ。 入力側インターフェース(read_if) 値をFIFOから取り出すインターフェース。 class read_if virtual public sc_interface { public virtual void read(char ) = 0; virtual int num_available() = 0; }; 入力側ではreadとnum_availableメソッドを準備している。num_availableはFIFOに溜っている数を返す。sc_fifoにあるnb_fifoメソッド等は宣言していない。 チャネル作成(fifo) class fifo public sc_channel, public write_if, public read_if { public fifo(sc_module_name name) sc_channel(name), num_elements(0), first(0) {} void write(char c) { wait(read_event); data[(first + num_elements) % max] = c; ++ num_elements; write_event.notify(); } void read(char c){ if (num_elements == 0) wait(write_event); c = data[first]; -- num_elements; first = (first + 1) % max; read_event.notify(); } void reset() { num_elements = first = 0; } private enum e { max = 10 }; char data[max]; int num_elements, first; sc_event write_event, read_event; チャネルfifoはインターフェースであるwrite_ifとread_if、ならびにsc_channelを継承する。 そして、write_ifとread_ifを継承したので、インターフェースの純粋仮想関数の中身を書く必要がある。 このチャネルのFIFO数は、最大10個固定のようだ。(sc_fifoの場合は、コンストラクタの第2引数にFIFO数を設定できる) writeとreadのブロッキング動作 fifoに記述されたwrite、readメソッドはwait()が含まれているのでブロッキング・メソッドである。 writeの動作は、FIFOが満杯のとき、送信側の処理を一時停止する。 readの動作は、FIFOが空のとき、受信側の処理を一時停止する。 以下にwriteとreadのブロッキング動作を説明するために必要な部分を抜き出してみた。 sc_event write_event, read_event; int num_elements; void write(char c) { if (num_elements == max) wait(read_event); // FIFOが満杯のとき、readイベント通知を待つ ++ num_elements; write_event.notify(); // writeイベントを通知する } void read(char c){ if (num_elements == 0) wait(write_event); // FIFOが空のとき、writeイベント通知を待つ -- num_elements; read_event.notify(); // readイベントを通知する } write側では、readイベントを待ち、writeイベントを通知する。 read側では、writeイベントを待ち、readイベントを通知する。 この処理では時間概念はない。デルタ遅延で処理される。 ポート作成、接続、アクセス 送信側[producer](sc_port write_if ) producerモジュール記述を部分的に抜粋 class producer public sc_module { public sc_port write_if out; // ポート作成 ... void main() // SC_THREAD { ... while (*str) out- write(*str++); // writeアクセス } }; インターフェースwrite_ifのAPIにアクセスするためには"- "を使う。 writeを呼ぶと、実際にはfifoチャネルのwriteが呼ぶことになる。 受信側[consumer](sc_port read_if ) consumerモジュール記述を部分的に抜粋 class consumer public sc_module { public sc_port read_if in; // ポート作成 ... void main() // SC_THREAD { while (true) { in- read(c); // readアクセス } } }; インターフェースread_ifのAPIにアクセスするためには"- "を使う。 readを呼ぶと、実際にはfifoチャネルのreadが呼ぶことになる。 トップ接続 class top public sc_module { public fifo *fifo_inst; producer *prod_inst; consumer *cons_inst; top(sc_module_name name) sc_module(name) { fifo_inst = new fifo("Fifo1"); prod_inst = new producer("Producer1"); prod_inst- out(*fifo_inst); cons_inst = new consumer("Consumer1"); cons_inst- in(*fifo_inst); } }; 接続はsc_fifoやsc_signalのやりかたと変わらない。 モジュール- ポート( チャネル ) write,read動作説明 シミュレーションが開始されると、prod_inst(producer)とcons_inst(consumer)のプロセスが同時に処理を始める。 はじめに、cons_inst側のプロセスが動作したとすると、readが呼ばれ、FIFO数がゼロのためwaitで一時停止する。 (*1) 次に、prod_inst側のプロセスが動作をはじめ、writeが呼ばれる。 writeはFIFOが満杯になるまで繰り返し、満杯(10回書込み)になるとwait()で一時停止する。 このとき、writeイベントを(何度か)通知する。 (*2) const_inst側のプロセスでwriteイベントの通知を受けることで、動作を再開する。 FIFOはゼロでないので、ゼロになるまでreadを繰り返す。 FIFOがゼロになるとread内のwait()で一時停止する。 このとき、readイベントを(何度か)通知する。 (*3) 繰り返し ・・・ まとめ インターフェースとチャネルとポートの関係はSystemCの特徴の1つ。 SystemCでTLMを覚える一歩は、このsimple_fifoの動作を理解することから始まると思う。
https://w.atwiki.jp/bambooflow/pages/72.html
sc_clock sc_clockはモジュールにクロック信号を与えるためのシグナル。 sc_clockはsc_signalを継承しているので、基本的な扱いはsc_signalと同じ。 ただし、コンストラクタで周期とかデューティ比とかスタート時間とかを設定するようになる。 sc_clockクロック信号記述設定例 クロックの位置 テストベンチからクロックを供給する方法 クロック信号記述 sc_clock sc_clock( "信号名", 周期,[単位,] デューディ比 (初期値=0.5), スタート時間 (初期値=SC_ZERO_TIME),[単位,] スタートエッジ (初期値=true) ); 設定例 信号名CLK、クロック周期25[ns]、デューティ比0.5、立ち上がりエッジ5[ns]スタート sc_clock CLK( "CLK", 25, SC_NS, 0.5, 5, SC_NS, true ); デューティ比、立ち上がりエッジ設定は省略可能。 信号名CLK、クロック周期10[ns] (デューティ比、エッジ省略) sc_clock CLK( "CLK", 10, SC_NS ); 信号名CLK、クロック周期20[us]、デューティ比0.6 (エッジ省略) sc_clock CLK( "CLK", 20, SC_US, 0.6 ); クロック入力記述 sc_in_clk CLK; sc_in bool CLK; sc_in_clkはsc_in bool のtypedefなので、どちらでも使えます。でも、クロックの入力としてわかりやすくするならばsc_in_clkを使ったほうがよいと思います。 クロックの位置 sc_clockによりクロック信号を生成する場合、mainかTOPに置きます。 テストベンチにには置けません。 普通は、mainで生成します。 もし、テストベンチでクロック信号を生成したい場合は、Verilog-HDL記述のような記述が必要になります。 main int sc_main( int argc, char* argv[] ) { sc_clock CLK( "CLK", 10, SC_NS, 0.5, 5, SC_NS, true ); TOP uTOP( "uTOP" ); uTOP.CLK( CLK ); ・・・ sc_start(); return 0; } TOP SC_MODULE( TOP ) { sc_in_clk CLK; ・・・ TEST_BENCH *uTEST_BENCH; MOD *uMOD; SC_CTOR( TOP ) { uTEST_BENCH = new TEST_BENCH( "uTEST_BENCH" ); uTEST_BENCH- CLK( CLK ); ・・・ uMOD = new MOD( "uMOD" ); uMOD- CLK( CLK ); ・・・ } }; MOD SC_MODULE( MOD ) { sc_in_clk CLK; ・・・ }; TEST_BENCH SC_MODULE( TEST_BENCH ) { sc_in_clk CLK; ・・・ }; テストベンチからクロックを供給する方法 クロック信号であるsc_clockはsc_signalを継承している。このため、sc_clockはプリミティブ・チャネルであるといえる。 そのため、通常はテストベンチからクロックを供給するのではなく、モデルとテストベンチを接続するトップモジュールから供給する。 荒技としてsc_exportを使用したテストベンチからのクロック供給する方法を紹介する。 -TestBench.h SC_MODULE( TestBench ) { sc_export sc_signal_in_if bool clk_p; sc_clock clk; SC_CTOR( TestBench ) clk( "clk", 10.0, SC_NS ) { clk_p( clk ); } }; これで、clk_pポートはTestBenchのトップモジュールからみると、clk_pはsc_out bool と同じようにみえる。 余計な処理が増えるので、遅くなるし、わかりにくいのであまりやらない。