2018年5月20日日曜日

ここがヘンだよ SystemC

SystemC は新規に設計された言語ではなく,C++ にライブラリを追加する形で実現されているため,いろいろと記述的にヘンであったり,煩雑なところがある.

(1) センシティビティリスト記述を,動作を記述している場所の近くに書けない (普通に書くと別ファイルになる)
(2) 信号を定義したら,その信号名を「文字列で」教えてやる必要がある.
(3) 前回の blog に書いた sc_trace() の問題.(2) と合わせると,信号の宣言,信号名の設定,トレースの設定,と同じような情報を 3箇所に書く必要がある.
(4) Verilog-2001 の always@(*) のようなセンシティビティリスト省略が出来ない
(5) Verilog-200x (いつの規格かわすれた) のインスタンス接続の省略表記「.*」が出来ない

こういうのって設計の頭使うところ以外で時間を食うことになるので,上記を改善するための SystemC preprocessor を作ってみた.

scpp.pl - SystemC preprocessor

我ながら SystemC のイライラポイントが大分改善されて満足ヽ(´ー`)ノ
下記の処理前後の diff を見てもられば,処理前の記述が大分削減されていることがわかってもらえると思う.
#include "common.h" #include "common.h"
#include "SimpleDmaReg.h" #include "SimpleDmaReg.h"
#include "SimpleDmaCore.h" #include "SimpleDmaCore.h"
template<int CH_NUM = 1> template<int CH_NUM = 1>
SC_MODULE( SimpleDma ){ SC_MODULE( SimpleDma ){
sc_in_clk clk; sc_in_clk clk;
sc_in<bool> nrst; sc_in<bool> nrst;
// register bus // register bus
sc_in<sc_uint<32>> RegAddr; sc_in<sc_uint<32>> RegAddr;
sc_in<sc_uint<32>> RegWData; sc_in<sc_uint<32>> RegWData;
sc_in<bool> RegNce; sc_in<bool> RegNce;
sc_in<bool> RegWrite; sc_in<bool> RegWrite;
sc_out<sc_uint<32>> RegRData; sc_out<sc_uint<32>> RegRData;
// SRAM bus // SRAM bus
sc_out<sc_uint<32>> SramAddr; sc_out<sc_uint<32>> SramAddr;
sc_out<sc_uint<32>> SramWData; sc_out<sc_uint<32>> SramWData;
sc_out<bool> SramNce; sc_out<bool> SramNce;
sc_out<bool> SramWrite; sc_out<bool> SramWrite;
sc_in<sc_uint<32>> SramRData; sc_in<sc_uint<32>> SramRData;
// $ScppAutoMember | // $ScppAutoMember Begin
> sc_signal<sc_uint<32>> SrcAddr;
> sc_signal<sc_uint<32>> DstAddr;
> sc_signal<sc_uint<32>> XferCnt;
> sc_signal<bool> Run;
> sc_signal<bool> Done;
> sc_signal<bool> NceCh[CH_NUM];
> sc_signal<sc_uint<32>> RegRDataCh[CH_NUM];
> sc_signal<sc_uint<32>> SrcAddrCh[CH_NUM];
> sc_signal<sc_uint<32>> DstAddrCh[CH_NUM];
> sc_signal<sc_uint<32>> XferCntCh[CH_NUM];
> sc_signal<bool> RunCh[CH_NUM];
> sc_signal<bool> DoneCh[CH_NUM];
> SimpleDmaCore *u_SimpleDmaCore;
> SimpleDmaReg *u_SimpleDmaReg[CH_NUM];
> void AddrDecorder( void );
> void ArbiterSelector( void );
> void RDataSelector( void );
> // $ScppEnd
SC_CTOR( SimpleDma ) : SC_CTOR( SimpleDma ) :
// $ScppInitializer | // $ScppInitializer Begin
> clk( "clk" ),
> nrst( "nrst" ),
> RegAddr( "RegAddr" ),
> RegWData( "RegWData" ),
> RegNce( "RegNce" ),
> RegWrite( "RegWrite" ),
> RegRData( "RegRData" ),
> SramAddr( "SramAddr" ),
> SramWData( "SramWData" ),
> SramNce( "SramNce" ),
> SramWrite( "SramWrite" ),
> SramRData( "SramRData" ),
> SrcAddr( "SrcAddr" ),
> DstAddr( "DstAddr" ),
> XferCnt( "XferCnt" ),
> Run( "Run" ),
> Done( "Done" )
> // $ScppEnd
{ {
// $ScppSensitive( "." ) | // $ScppSensitive( "." ) Begin
> SC_METHOD( AddrDecorder );
> sensitive << RegAddr << RegNce;
>
> SC_METHOD( ArbiterSelector );
> for( int i = 0; i < CH_NUM; ++i ){
> sensitive << DstAddrCh[i] << RunCh[i] << SrcAddrC
> }
> sensitive << Done;
>
> SC_METHOD( RDataSelector );
> for( int i = 0; i < CH_NUM; ++i ) sensitive << RegRDa
>
> // $ScppEnd
/* $ScppInstance( /* $ScppInstance(
SimpleDmaCore, u_SimpleDmaCore, "SimpleDmaCore.h" SimpleDmaCore, u_SimpleDmaCore, "SimpleDmaCore.h"
"@clk|nrst|Sram.*@@", "@clk|nrst|Sram.*@@",
"///W", "///W",
) */ | ) Begin */
> u_SimpleDmaCore = new SimpleDmaCore( "u_SimpleDmaCore
> u_SimpleDmaCore->clk( clk );
> u_SimpleDmaCore->nrst( nrst );
> u_SimpleDmaCore->SrcAddr( SrcAddr );
> u_SimpleDmaCore->DstAddr( DstAddr );
> u_SimpleDmaCore->XferCnt( XferCnt );
> u_SimpleDmaCore->Run( Run );
> u_SimpleDmaCore->Done( Done );
> u_SimpleDmaCore->SramAddr( SramAddr );
> u_SimpleDmaCore->SramWData( SramWData );
> u_SimpleDmaCore->SramNce( SramNce );
> u_SimpleDmaCore->SramWrite( SramWrite );
> u_SimpleDmaCore->SramRData( SramRData );
> // $ScppEnd
/* $ScppInstance( /* $ScppInstance(
SimpleDmaReg, u_SimpleDmaReg[ CH_NUM ], "SimpleDm SimpleDmaReg, u_SimpleDmaReg[ CH_NUM ], "SimpleDm
"/clk|nrst//", "/clk|nrst//",
"/(Addr|WData|Write)/Reg$1/", "/(Addr|WData|Write)/Reg$1/",
"/(RData)/Reg$1Ch[]/W", "/(RData)/Reg$1Ch[]/W",
"//$1Ch[]/W", "//$1Ch[]/W",
) */ | ) Begin */
> for( int _i_0 = 0; _i_0 < CH_NUM; ++_i_0 ){
> u_SimpleDmaReg[_i_0] = new SimpleDmaReg(( std::st
> u_SimpleDmaReg[_i_0]->clk( clk );
> u_SimpleDmaReg[_i_0]->nrst( nrst );
> u_SimpleDmaReg[_i_0]->Addr( RegAddr );
> u_SimpleDmaReg[_i_0]->WData( RegWData );
> u_SimpleDmaReg[_i_0]->Nce( NceCh[_i_0] );
> u_SimpleDmaReg[_i_0]->Write( RegWrite );
> u_SimpleDmaReg[_i_0]->RData( RegRDataCh[_i_0] );
> u_SimpleDmaReg[_i_0]->SrcAddr( SrcAddrCh[_i_0] );
> u_SimpleDmaReg[_i_0]->DstAddr( DstAddrCh[_i_0] );
> u_SimpleDmaReg[_i_0]->XferCnt( XferCntCh[_i_0] );
> u_SimpleDmaReg[_i_0]->Run( RunCh[_i_0] );
> u_SimpleDmaReg[_i_0]->Done( DoneCh[_i_0] );
> }
> // $ScppEnd
// $ScppSigTrace | // $ScppSigTrace Begin
> #ifdef VCD_WAVE
> sc_trace( ScppTraceFile, clk, std::string( this->name
> sc_trace( ScppTraceFile, nrst, std::string( this->nam
> sc_trace( ScppTraceFile, RegAddr, std::string( this->
> sc_trace( ScppTraceFile, RegWData, std::string( this-
> sc_trace( ScppTraceFile, RegNce, std::string( this->n
> sc_trace( ScppTraceFile, RegWrite, std::string( this-
> sc_trace( ScppTraceFile, RegRData, std::string( this-
> sc_trace( ScppTraceFile, SramAddr, std::string( this-
> sc_trace( ScppTraceFile, SramWData, std::string( this
> sc_trace( ScppTraceFile, SramNce, std::string( this->
> sc_trace( ScppTraceFile, SramWrite, std::string( this
> sc_trace( ScppTraceFile, SramRData, std::string( this
> sc_trace( ScppTraceFile, SrcAddr, std::string( this->
> sc_trace( ScppTraceFile, DstAddr, std::string( this->
> sc_trace( ScppTraceFile, XferCnt, std::string( this->
> sc_trace( ScppTraceFile, Run, std::string( this->name
> sc_trace( ScppTraceFile, Done, std::string( this->nam
> #endif // VCD_WAVE
> // $ScppEnd
} }
}; };
view raw scpp_diff.cpp hosted with ❤ by GitHub

0 件のコメント:

コメントを投稿