SystemC Tutorial

5,345 views
5,230 views

Published on

Published in: Technology, Design
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
5,345
On SlideShare
0
From Embeds
0
Number of Embeds
3,214
Actions
Shares
0
Downloads
24
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

SystemC Tutorial

  1. 1. オレオレSystemC入門 @LSI設計雑記帳
  2. 2. ※注意事項※ 本資料は筆者が所属している団体や組織に関 係あるものではありません。 本資料内のソースコードを使って問題が起き ても筆者は責任取りません。 楽しく見ていただければ幸いです。
  3. 3. 自己紹介 Blog:LSI設計雑記帳
 http:/ /lsifrontend.blog100.fc2.com/ Twitter:@kocha2012
 https:/ /twitter.com/kocha2012 GitHub:Kocha
 https:/ /github.com/Kocha
  4. 4. SystemC is 何
  5. 5. C++のクラスライブラリで
  6. 6. HLSの入力言語だったり、 仮想環境モデリング言語 だったりするのです! ※HLS(High Level Synthsis)
  7. 7. ようこそ! SystemCの世界へ
  8. 8. Hello World #include <systemc.h> ! int sc_main(int argc, char *argv[]) { ! printf("Hello World!!!n"); ! return 0; }
  9. 9. Hello World SystemCのヘッダーをinclude #include <systemc.h> ! int sc_main(int argc, char *argv[]) { ! main関数は「sc_main」 printf("Hello World!!!n"); ! return 0; }
  10. 10. Hello World $> ./main ! SystemC 2.3.0-ASI --- Jul 13 2012 06:33:43 Copyright (c) 1996-2012 by all Contributors, ALL RIGHTS RESERVED ! Hello World!!! \(^o^)/ できた∼
  11. 11. おわり
  12. 12. ってことはなく、 まだまだ続きます!
  13. 13. 目次 理解する 設計する 検証する 次回予告
  14. 14. 理解する
  15. 15. SystemCとは SystemCは、プログラム言語であるC++のクラスライブラリ として提供されており、それ自体言語として独立した文法 を持つものではない。ライブラリにはハードウェア記述の 為の機能、すなわち並列実行の概念やデータ型、それを扱 う各種関数が定義されている。それを使って書かれたプロ グラムは通常のC++コンパイラでコンパイルすることがで き、結果生成されたオブジェクトはハードウェアのシミュ レータとして動作する。 ※Wikipedia(http:/ /ja.wikipedia.org/wiki/SystemC)より
  16. 16. SystemCの適用場面 仮想環境:Virtual Platform ソフトウェア開発環境 トランザクションベース(TLM2.0) 高位合成:High Level Synthsis SystemC→Verilog HDL/VHDL サイクルベース
  17. 17. 知っておきたいC++基礎 ※ポインタ:C言語 クラスとメンバ オーバーロード オブジェクト オーバーライド コンストラクタ 多態性        継承
 (インヘリタンス) (ポリモフィズム) テンプレート ※他にもありますが、入門編なので省略
  18. 18. SystemCのシステム構成 「モジュール」と呼ばれるデザイン内に 「プロセス」により関数内で機能を記述し 「チャネル」でモジュール間を接続する。 ! 各プロセスは同時並列に実行 プロセス内は逐次実行
  19. 19. sc_main sc_main()
  20. 20. モジュール (SC_MODULE) sc_main() モジュール モジュール モジュール
  21. 21. プロセス (SC_THREAD/SC_METHOD/SC_CTHREAD) sc_main() モジュール プロセス モジュール プロセス モジュール プロセス プロセス
  22. 22. チャネル (sc_prim_channel) sc_main() モジュール プロセス モジュール チャネル チャネル プロセス プロセス モジュール プロセス プロセス ポート/インターフェース
  23. 23. 設計する
  24. 24. モジュールを作る プロセスを定義する 機能(処理)を記述する
  25. 25. SC_MODULE( hoge ) { ! sc_in<int> in; sc_out<int> out; ! int x; ! void process(); ! }; SC_CTOR( hoge ) { SC_THREAD( process ); sensitive << in ; x = 10; } void hoge::process() { out = 0; while(1) { wait(); out = in * x; } };
  26. 26. SC_MODULE( hoge ) { モジュール宣言 ! sc_in<int> in; sc_out<int> out; int x; ! void process(); }; #define SC_MODULE(name) struct name : sc_module ※classで書く場合(sc_moduleを継承する) ! ! ※実装はマクロ(struct) class hoge : public sc_module { ... }; ※Verilog HDL/SystemVerilogでの意味 module hoge(...); : endmodule SC_CTOR( hoge ) { SC_THREAD( process ); sensitive << in ; x = 10; }
  27. 27. SC_MODULE( hoge ) { モジュール宣言 ! sc_in<int> in; sc_out<int> out; ! int x; 初期化処理を記述する部分 ! void process(); ! }; SC_CTOR( hoge ) コンストラクタ宣言 { SC_THREAD( process ); sensitive << in ; x = 10; }
  28. 28. SC_MODULE( hoge ) { ※実装はマクロ ! sc_in<int> in; sc_out<int> out; ! int x; ! void process(); ! }; #define SC_CTOR(name) implementation-defined; name(sc_module_name) ※マクロを使わずで書く場合 SC_MODULE( hoge ) { 必ず必要 ... SC_HAS_PROCESS(hoge); hoge( sc_module_name n) : sc_module_name(n) { SC_THREAD( processs ); ... SC_CTOR( hoge ) コンストラクタ宣言 { SC_THREAD( process ); sensitive << in ; ※SystemVerilogだと new関数 class hoge; x = 10; function new(); } : endfunction
  29. 29. 豆知識:初期化リスト ※サブモジュールのインスタンス時など SC_MODULE( hoge ) { ! sc_in<int> in; sc_out<int> out; ! int x; ! void process(); ! SC_CTOR( hoge ) { SC_THREAD( process ); sensitive << in ; x = 10; } };  書かないといけない場合もあります 書いておくと良いことあるかも! SC_CTOR( hoge ): in(“in”), out(“out”) { http:/ /lsifrontend.blog100.fc2.com/blog-entry-432.html
  30. 30. SC_MODULE( hoge ) { ! sc_in<int> in; sc_out<int> out; ! int x; ! void process(); ! }; SC_CTOR( hoge ) { SC_THREAD( process ); プロセスを定義 sensitive << in ; x = 10; }
  31. 31. SC_MODULE( hoge ) { ! sc_in<int> in; sc_out<int> out; ! int x; ! void process(); ! }; 実際の機能(処理) void hoge::process() { out = 0; while(1) { wait(); out = in * x; } }; SC_CTOR( hoge ) 機能(処理)が記述されている関数 { SC_THREAD( process ); プロセスを定義 sensitive << in ; x = 10; }
  32. 32. SC_MODULE( hoge ) { ! sc_in<int> in; sc_out<int> out; ! int x; ! 引数無しの関数 void process(); ! }; void hoge::process() { out = 0; while(1) { wait(); sensitiveに登録されている 動作待ち out = in * x; } }; SC_CTOR( hoge ) { SC_THREAD( process ); プロセスを定義 sensitive << in ; x = 10; 機能(処理)が動くきっかけを指定 } (この例だと in の値が変化したら)
  33. 33. プロセス定義は3種類 SC_THREAD SC_THREAD( process ); sensitive << in ; void hoge::process() { ... 初期動作 ... wait(); / wait - in(value) / ... Simulation ... wait(); / wait - in(value) / ... wait(); / wait - in(value) / ... } 再度呼び出しなし ・関数から抜けると再度呼び出されないため
 while文や for文で無限ループを作る
  34. 34. プロセス定義は3種類 SC_METHOD SC_METHOD( process ); sensitive << a << b ; void hoge::process() { wait - a,b(value) ... ... ... ... ... } ! ! ! 初期動作 Simulation 終了まで繰り返す ・繰り返し実行されるプロセス ・waitは記述出来ない
  35. 35. プロセス定義は3種類 SC_CTHREAD SC_CTHREAD( process, clock.pos() ); reset_signal_is(reset, true); void hoge::process() { ... 初期動作 ... ... while(1) { wait(); / wait - prosedge clock / ... wait(); / wait - posedge clock / ... } reset_signal_isで 設定されていれば強制的に } ・SC_THREADをクロックイベント用にしたもの ・関数から抜けると再度呼び出されないため
 while文や for文で無限ループを作る
  36. 36. プロセス定義は3種類 SC_THREAD SC_METHOD SC_THREAD( process ); sensitive << in ; SC_METHOD( process ); sensitive << a << b ; void hoge::process() { ... 初期動作 ... wait(); / wait - in(value) / ... Simulation ... wait(); / wait - in(value) / ... wait(); / wait - in(value) / ... } 再度呼び出しなし void hoge::process() { wait - a,b(value) ... ... ... ... ... } ! ! ! 初期動作 Simulation 終了まで繰り返す SC_CTHREAD SC_CTHREAD( process, clock.pos() ); reset_signal_is(reset, true); void hoge::process() { ... 初期動作 ... ... while(1) { wait(); / wait - prosedge clock / ... wait(); / wait - posedge clock / ... } reset_signal_isで 設定されていれば強制的に } 初期動作は dont_initialize();で抑制可能 例)SC_THREAD( process ); sensitive << in ; dont_initialize();
  37. 37. sensitive記述は様々 ※for文で記述することも出来ます。 SC_THREAD( process ); sensitive << in ; SC_THREAD( process ); sensitive << in1 << in2 ; SC_THREAD( process ); sensitive << in1.pos() ; sensitive << in2.neg() ; SC_THREAD( process ); sensitive << in1.posedge() ; sensitive << in2.negeage() ;
  38. 38. (async_)reset_signal_is SystemC-2.3から追加 reset_signal_is async_reset_signal_is SC_THREAD( process ); reset_signal_is( reset, true); SC_THREAD( process ); 信号名 極性 async_reset_signal_is( reset_n, false); ※clock立ち上がりエッジ(posedge)の場合 clock reset リセット期間 reset_n リセット期間
  39. 39. SC_MODULE( hoge ) { ! sc_in<int> in; 入出力ポート(Interface)宣言 sc_out<int> out; ※SystemVerilogでの意味 ! int x; ! void process(); ! }; module hoge( input bit[31:0] in, output bit[31:0] out ); : endmodule SC_CTOR( hoge ) { SC_THREAD( process ); sensitive << in ; x = 10; }
  40. 40. SC_MODULE( hoge ) { ! sc_in<int> in; sc_out<int> out; ! int x; ! void process(); ! }; SC_CTOR( hoge ) { SC_THREAD( process ); sensitive << in ; out.initialize(0); っと書くことも可能 } void hoge::process() { out = 0; while(1) { wait(); out = in * x; } }; このように動いてます。 out.write(0); while(1) { wait(); out.write( in.read() * x); }
  41. 41. ポートとチャネル port/interface 接続するchannel sc_signal sc_in/out/inout sc_buffer sc_clock sc_fifo_in/out sc_fifo sc_mutex_if sc_mutex sc_semaphrore_if sc_semaphore
  42. 42. チャネルはレジスタ(FF) #include <systemc.h> ! int sc_main(int argc, char *argv[]) { int a; sc_signal<int> b; ! a = 10; b = 10; std::cout << "a = " << a << ", b = " << b << std::endl; ! sc_start(1, sc_core::SC_NS); std::cout << "a = " << a << ", b = " << b << std::endl; ! return 0; } 実行結果 a = 10, b = 0 a = 10, b = 10 シミュレーション時刻の経過により値が更新される。
 (代入はノンブロッキング代入)
  43. 43. チャネルはWire sc_signal<int> x0y0; ! laplacian_filter dut("dut"); testbench tb("tb"); ! dut.clk(clk); dut.x0y0(x0y0); / input / : dut.out(y); 接続(wire) tb.clk(clk); tb.x0y0(x0y0); / output / : チャネルは用途において、regもしくはwireとなる。
  44. 44. SC_MODULE( hoge ) { ! sc_in<int> in; sc_out<int> out; ! データ型 int x; ! void process(); ! }; SC_CTOR( hoge ) { SC_THREAD( process ); sensitive << in ; x = 10; }
  45. 45. SC_MODULE( hoge ) { ! sc_in<int> in; sc_out<int> out; ! データ型 int x; SystemCはC++なので、 ! void process(); C++のデータ型は全て使えます。 SC_CTOR( hoge ) ! { }; } SC_THREAD( process ); sensitive << in ; x = 10;
  46. 46. SystemCで追加された型 データ型 sc_int<N> sc_uint<N> sc_bigint<N> sc_biguint<N> sc_bit sc_logic sc_bv<N> sc_lv<N> sc_fixed<NW, NI> sc_ufixed<NW, NI> 説明 記述例 Nビット整数 sc_int<8> a = -123; Nビット符号なし整数 sc_uint<8> a = 0xab; 64ビット以上のsc_int sc_bigint<128> = “0xaaa...”; 64ビット以上のsc_uint sc_biguint<128> = “0xaaa...”; ’0’, ’1’ の2値 (使用は非推奨) sc_bit a = ‘1’; ’0’, ’1’, ’x’, ’z’の4値 sc_logic a = ‘z’; Nビットの sc_bit sc_bv<8> a = “10101010”; Nビットの sc_logic sc_lv<8> a = “1x101z10”; 固定小数点 sc_fixed<8,4> a = -0.25; 符号なし固定小数点 sc_uifixed<8,4> a = -1.75;
  47. 47. 独自のデータ型(MyType) class/structに必ず実装するメンバ関数 比較演算子
 bool operator == (const MyType & rhs) const { 代入演算子
 MyType& operator = (const MyType& rhs) { トレース関数
 void sc_trace(sc_trace_file *tf, const MyType & v,
 const std::string & NAME ) { 出力演算子
 ostream& operator << ( ostream& os, MyType const & v ) {
  48. 48. 検証する
  49. 49. sc_main モジュールをインスタンスする 信号を生成する 変数の値を表示する タイミング波形を取得する
  50. 50. sc_mainは必須 #include <systemc.h> s_in = 0; sc_start(10, SC_NS); int sc_main(int argc, char *argv[]) { cout << "in = " << s_in << ", out = " << s_out << endl; sc_signal<int> s_in, s_out; hoge m_hoge(“m_hoge”); s_in = 10; m_hoge.in(s_in); sc_start(10, SC_NS); m_hoge.out(s_out); cout << "in = " << s_in << ", out = " << s_out << endl; return 0; }
  51. 51. モジュールをインスタンス #include <systemc.h> s_in = 0; sc_start(10, SC_NS); cout << "in = " << s_in << ", out = " << s_out << endl; int sc_main(int argc, char *argv[]) { sc_signal<int> s_in, s_out; hoge m_hoge(“m_hoge”); m_hoge.in(s_in); m_hoge.out(s_out); ※別の書き方 hoge *m_hoge; m_hoge = new hoge(“m_hoge”); m_hoge->in(s_in); m_hoge->out(s_out); } s_in = 10; sc_start(10, SC_NS); cout << "in = " << s_in << ", out = " << s_out << endl; return 0;
  52. 52. 信号を生成 #include <systemc.h> s_in = 0; sc_start(10, SC_NS); cout << "in = " << s_in << ", out = " << s_out << endl; int sc_main(int argc, char *argv[]) { ※sc_in/outの接続は sc_signal sc_signal<int> s_in, s_out; ※sc_startでシミュレーション開始 hoge m_hoge(“m_hoge”); m_hoge.in(s_in); m_hoge.out(s_out); } s_in = 10; sc_start(10, SC_NS); cout << "in = " << s_in << ", out = " << s_out << endl; return 0;
  53. 53. 変数の値を表示する ■cout sc_signal - << operator sc_intなど- a.to_string()関数が存在 s_in = 0; ■printf sc_start(10, SC_NS); sc_intなど- a.to_int()関数が存在 cout << "in = " << s_in << ", out = " << s_out << endl; ■sc_report SystemC定義の表示形式関数 s_in = 10; sc_start(10, SC_NS); ! cout << "in = " << s_in ★ sc_time_stamp() で
 << ", out = " << s_out << endl; 時刻も表示! return 0; }
  54. 54. タイミング波形を取得 #include <systemc.h> s_in = 0; sc_start(10, SC_NS); cout << "in = " << s_in << ", out = " << s_out << endl; int sc_main(int argc, char *argv[]) { sc_signal<int> s_in, s_out; sc_trace_file *tf; s_in = 10; tf = sc_create_vcd_trace_file("waves"); sc_start(10, SC_NS); sc_trace(tf, s_in, "in"); sc_trace(tf, s_out, "out"); hoge m_hoge(“m_hoge”); m_hoge.in(s_in); m_hoge.out(s_out); cout << "in = " << s_in << ", out = " << s_out << endl; sc_close_vcd_trace_file(tf); return 0; ※閉じることを忘れずに }
  55. 55. 余談 SystemCのシミュレータは無償なので、
 いつでもシミュレーションできます。
 Webでも → http:/ /www.edaplayground.com 仮想環境(Virtual Platform/TLM2.0)について は別スライドを作成する予定です。 最近、SystemC流行ってます!(ステマ)
 この機会に是⾮非トライしてみてください!
  56. 56. おわり

×