56
オレオレSystemC入門 @LSI設計雑記帳

SystemC Tutorial

Embed Size (px)

Citation preview

Page 1: SystemC Tutorial

オレオレSystemC入門@LSI設計雑記帳

Page 2: SystemC Tutorial

※注意事項※

本資料は筆者が所属している団体や組織に関係あるものではありません。

本資料内のソースコードを使って問題が起きても筆者は責任取りません。

楽しく見ていただければ幸いです。

Page 3: SystemC Tutorial

自己紹介

Blog:LSI設計雑記帳http://lsifrontend.blog100.fc2.com/

Twitter:@kocha2012https://twitter.com/kocha2012

GitHub:Kocha https://github.com/Kocha

Page 4: SystemC Tutorial

SystemC is 何

Page 5: SystemC Tutorial

C++のクラスライブラリで

Page 6: SystemC Tutorial

HLSの入力言語だったり、 仮想環境モデリング言語 だったりするのです!

※HLS(High Level Synthsis)

Page 7: SystemC Tutorial

ようこそ! SystemCの世界へ

Page 8: SystemC Tutorial

Hello World

#include <systemc.h> !

int sc_main(int argc, char *argv[]) { !

printf("Hello World!!!\n"); !

return 0; }

Page 9: SystemC Tutorial

Hello World

#include <systemc.h> !

int sc_main(int argc, char *argv[]) { !

printf("Hello World!!!\n"); !

return 0; }

SystemCのヘッダーをinclude

main関数は「sc_main」

Page 10: SystemC Tutorial

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^)/できた~

Page 11: SystemC Tutorial

おわり

Page 12: SystemC Tutorial

ってことはなく、 まだまだ続きます!

Page 13: SystemC Tutorial

理解する

設計する

検証する

次回予告

目次

Page 14: SystemC Tutorial

理解する

Page 15: SystemC Tutorial

SystemCとは

SystemCは、プログラム言語であるC++のクラスライブラリとして提供されており、それ自体言語として独立した文法を持つものではない。ライブラリにはハードウェア記述の為の機能、すなわち並列実行の概念やデータ型、それを扱う各種関数が定義されている。それを使って書かれたプログラムは通常のC++コンパイラでコンパイルすることができ、結果生成されたオブジェクトはハードウェアのシミュレータとして動作する。

※Wikipedia(http://ja.wikipedia.org/wiki/SystemC)より

Page 16: SystemC Tutorial

SystemCの適用場面仮想環境:Virtual Platform

ソフトウェア開発環境

トランザクションベース(TLM2.0)

高位合成:High Level Synthsis

SystemC→Verilog HDL/VHDL

サイクルベース

Page 17: SystemC Tutorial

知っておきたいC++基礎

クラスとメンバ

オブジェクト

コンストラクタ

継承(インヘリタンス)

オーバーロード

オーバーライド

多態性       (ポリモフィズム)

テンプレート

※他にもありますが、入門編なので省略

※ポインタ:C言語

Page 18: SystemC Tutorial

SystemCのシステム構成

「モジュール」と呼ばれるデザイン内に

「プロセス」により関数内で機能を記述し

「チャネル」でモジュール間を接続する。

!

各プロセスは同時並列に実行

プロセス内は逐次実行

Page 19: SystemC Tutorial

sc_mainsc_main()

Page 20: SystemC Tutorial

モジュール(SC_MODULE)

sc_main()

モジュール モジュール

モジュール

Page 21: SystemC Tutorial

プロセス(SC_THREAD/SC_METHOD/SC_CTHREAD)

sc_main()

モジュール

プロセス

プロセス

プロセス

モジュール

モジュール

プロセス

Page 22: SystemC Tutorial

チャネル(sc_prim_channel)

sc_main()

モジュール

プロセス

プロセス

プロセス

モジュール

モジュール

プロセス

チャネル

チャネル

プロセス

ポート/インターフェース

Page 23: SystemC Tutorial

設計する

Page 24: SystemC Tutorial

モジュールを作る

プロセスを定義する

機能(処理)を記述する

Page 25: SystemC Tutorial

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; } };

Page 26: SystemC Tutorial

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; } };

モジュール宣言

#define SC_MODULE(name) struct name : sc_module

※実装はマクロ(struct)

module hoge(...); : endmodule

※Verilog HDL/SystemVerilogでの意味

class hoge : public sc_module { ... };

※classで書く場合(sc_moduleを継承する)

Page 27: SystemC Tutorial

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; } };

モジュール宣言

コンストラクタ宣言

初期化処理を記述する部分

Page 28: SystemC Tutorial

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; } };

コンストラクタ宣言

class hoge; function new(); : endfunction

※SystemVerilogだと new関数

#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 ); ...

※マクロを使わずで書く場合

必ず必要

Page 29: SystemC Tutorial

豆知識:初期化リスト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

※サブモジュールのインスタンス時など  書かないといけない場合もあります

Page 30: SystemC Tutorial

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; } };

プロセスを定義

Page 31: SystemC Tutorial

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; } };

実際の機能(処理)

Page 32: SystemC Tutorial

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; } };

プロセスを定義

引数無しの関数

機能(処理)が動くきっかけを指定 (この例だと in の値が変化したら)

void hoge::process() { out = 0; while(1) { wait(); out = in * x; } };

sensitiveに登録されている 動作待ち

Page 33: SystemC Tutorial

プロセス定義は3種類SC_THREAD

void hoge::process() { ... ... wait(); // wait - in(value) ... ... wait(); // wait - in(value) ... wait(); // wait - in(value) ... }

SC_THREAD( process ); sensitive << in ;

初期動作

Simulation

再度呼び出しなし

・関数から抜けると再度呼び出されないため while文や for文で無限ループを作る

Page 34: SystemC Tutorial

プロセス定義は3種類SC_METHOD

SC_METHOD( process ); sensitive << a << b ;

void hoge::process() { ... ... ... ... ... } !!!初期動作 Simulation

wait - a,b(value)

終了まで繰り返す

・繰り返し実行されるプロセス ・waitは記述出来ない

Page 35: SystemC Tutorial

プロセス定義は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文で無限ループを作る

Page 36: SystemC Tutorial

プロセス定義は3種類SC_THREAD SC_METHOD SC_CTHREAD

void hoge::process() { ... ... wait(); // wait - in(value) ... ... wait(); // wait - in(value) ... wait(); // wait - in(value) ... }

SC_THREAD( process ); sensitive << in ;

SC_METHOD( process ); sensitive << a << b ;

SC_CTHREAD( process, clock.pos() ); reset_signal_is(reset, true);

初期動作

Simulation

再度呼び出しなし

void hoge::process() { ... ... ... ... ... } !!!初期動作 Simulation

wait - a,b(value)

終了まで繰り返す

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();

Page 37: SystemC Tutorial

sensitive記述は様々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() ;

※for文で記述することも出来ます。

Page 38: SystemC Tutorial

(async_)reset_signal_is

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

reset

reset_n

リセット期間

リセット期間

※clock立ち上がりエッジ(posedge)の場合

極性信号名

SystemC-2.3から追加

Page 39: SystemC Tutorial

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; } };

入出力ポート(Interface)宣言

module hoge( input bit[31:0] in, output bit[31:0] out ); : endmodule

※SystemVerilogでの意味

Page 40: SystemC Tutorial

SC_MODULE( hoge ) { ! sc_in<int> in; sc_out<int> out; ! int x; ! void process(); ! SC_CTOR( hoge ) { SC_THREAD( process ); sensitive << in ; } };

void hoge::process() { out = 0; while(1) { wait(); out = in * x; } };

out.write(0); while(1) { wait(); out.write( in.read() * x); }

このように動いてます。

out.initialize(0);っと書くことも可能

Page 41: SystemC Tutorial

ポートとチャネルport/interface 接続するchannel

sc_in/out/inout

sc_signal

sc_buffer

sc_clock

sc_fifo_in/out sc_fifo

sc_mutex_if sc_mutex

sc_semaphrore_if sc_semaphore

Page 42: SystemC Tutorial

チャネルはレジスタ(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

シミュレーション時刻の経過により値が更新される。

(代入はノンブロッキング代入)

Page 43: SystemC Tutorial

チャネルはWire sc_signal<int> x0y0; ! laplacian_filter dut("dut"); testbench tb("tb"); ! dut.clk(clk); dut.x0y0(x0y0); // input : dut.out(y); tb.clk(clk); tb.x0y0(x0y0); // output :

チャネルは用途において、regもしくはwireとなる。

接続(wire)

Page 44: SystemC Tutorial

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; } };

データ型

Page 45: SystemC Tutorial

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; } };

データ型

SystemCはC++なので、 C++のデータ型は全て使えます。

Page 46: SystemC Tutorial

SystemCで追加された型データ型 説明 記述例

sc_int<N> Nビット整数 sc_int<8> a = -123;

sc_uint<N> Nビット符号なし整数 sc_uint<8> a = 0xab;

sc_bigint<N> 64ビット以上のsc_int sc_bigint<128> = “0xaaa...”;

sc_biguint<N> 64ビット以上のsc_uint sc_biguint<128> = “0xaaa...”;

sc_bit ’0’, ’1’ の2値 (使用は非推奨) sc_bit a = ‘1’;

sc_logic ’0’, ’1’, ’x’, ’z’の4値 sc_logic a = ‘z’;

sc_bv<N> Nビットの sc_bit sc_bv<8> a = “10101010”;

sc_lv<N> Nビットの sc_logic sc_lv<8> a = “1x101z10”;

sc_fixed<NW, NI> 固定小数点 sc_fixed<8,4> a = -0.25;

sc_ufixed<NW, NI> 符号なし固定小数点 sc_uifixed<8,4> a = -1.75;

Page 47: SystemC Tutorial

独自のデータ型(MyType)

比較演算子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 ) {

class/structに必ず実装するメンバ関数

Page 48: SystemC Tutorial

検証する

Page 49: SystemC Tutorial

sc_main

モジュールをインスタンスする

信号を生成する

変数の値を表示する

タイミング波形を取得する

Page 50: SystemC Tutorial

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; }

Page 51: SystemC Tutorial

モジュールをインスタンス#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; }

hoge *m_hoge; m_hoge = new hoge(“m_hoge”); m_hoge->in(s_in); m_hoge->out(s_out);

※別の書き方

Page 52: SystemC Tutorial

信号を生成#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; }

※sc_in/outの接続は sc_signal

※sc_startでシミュレーション開始

Page 53: SystemC Tutorial

変数の値を表示する

s_in = 0; sc_start(10, SC_NS); cout << "in = " << s_in << ", out = " << s_out << endl; s_in = 10; sc_start(10, SC_NS); cout << "in = " << s_in << ", out = " << s_out << endl; return 0; }

■cout sc_signal - << operator sc_intなど- a.to_string()関数が存在 ■printf sc_intなど- a.to_int()関数が存在 ■sc_report SystemC定義の表示形式関数 !

★sc_time_stamp() で時刻も表示!

Page 54: SystemC Tutorial

タイミング波形を取得#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; 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"); cout << "in = " << s_in sc_trace(tf, s_out, "out"); << ", out = " << s_out << endl; hoge m_hoge(“m_hoge”); sc_close_vcd_trace_file(tf); m_hoge.in(s_in); return 0; m_hoge.out(s_out); } ※閉じることを忘れずに

Page 55: SystemC Tutorial

余談SystemCのシミュレータは無償なので、いつでもシミュレーションできます。Webでも → http://www.edaplayground.com

仮想環境(Virtual Platform/TLM2.0)については別スライドを作成する予定です。

最近、SystemC流行ってます!(ステマ)この機会に是⾮非トライしてみてください!

Page 56: SystemC Tutorial

おわり