Available
Used Slice Logic
Utilization
boost::serialization の機能
• boost:: serialization
–
インスタンスされたクラスの状態をファイルに書き出したり、読み出した りするためのライブラリ• http://www.boost.org/libs/serialization/doc/index.html
–
次世代C++
標準ライブラリBoost
のInput/Output
のカテゴリー–
ライセンスBoost Software License
• http://www.boost.org/more/license_info.html
– BSD
ライセンスをベースとしたライセンス• 参考 :
C++ ライブラリ Boost
Web
サイトhttp://www.boost.org/
プローブポイントの定義 (1/3)
#ifndef _H264_DCT8x8_t_H
#define _H264_DCT8x8_t_H 1
#include <stdint.h>
#ifdef __cplusplus extern "C" {
#endif
void h264_DCT8x8_set_mode( int _cmode ) ; void h264_DCT8x8_dump( int16_t dct[4][4][4],
uint8_t *pix1, uint8_t *pix2 , int fenc_strid , int fdec_strid ) ;
#ifdef __cplusplus }
#endif
#ifdef __cplusplus
#include <string>
#include <fstream>
H264_DCT8x8_t.h
class H264_DCT8x8_t { public:
/// プローブポイントの定義 int record ;
int cmode ; uint8_t mPIX1[8][8] ; uint8_t mPIX2[8][8] ;
int16_t mDCT8x8_REF[8][8] ;
private:
friend class boost::serialization::access ; /// プローブポイントの書き出し
template<class Archive>
void serialize(Archive& ar, const unsigned int version) {
ar & record ; ar & cmode ;
プローブポイント の定義
プローブポイントの定義 (2/3)
#include "H264_dump.h"
int fx( int pos , int k ) {
return ( pos & 0x01 ) << 2 | ( k & 0x03 ) ; }
int fy( int pos , int k ) {
return ( pos & 0x02 ) << 1 | ( k & 0x0c ) << 2 ; }
int fix( int pos , int ix ) {
return ( pos & 0x01 ) << 2 | ix ; }
int fiy( int pos , int iy ) {
return ( pos & 0x02 ) << 1 | iy ; }
H264_DCT8x8_t.h
void dump_block_n( char *message , int n ,uint8_t *v , int stride ) {
int x , y ;
int gl_dump_level = 1 ; if ( gl_dump_level >= 1 )
{
fprintf( stderr , "%s stride=%d¥n" , message , stride ) ; for ( y = 0 ; y < n ; y++ )
{
fprintf( stderr , "%s y=%d [" , message , y ) ; for ( x = 0 ; x < n ; x++ )
{
fprintf( stderr , "%6d" , v[x+ y * stride ] ) ; }
fprintf( stderr , "]¥n" ) ; }
} }
プローブポイントの定義 (3/3)
/// コンストラクタ(読み出し用) H264_DCT8x8_t()
{
; }
/// コンストラクタ(書き込み用)
H264_DCT8x8_t( int _record , int _cmode , int16_t dct[4][4][4],
uint8_t *pix1, uint8_t *pix2 , int fenc_strid , int fdec_strid ) {
int pos ;
record = _record ; cmode = _cmode ;
for ( int iy = 0 ; iy < 8 ; iy++ ) {
for ( int ix = 0 ; ix < 8 ; ix++ ) {
for ( pos = 0 ; pos < 4 ; pos++ ) {
for ( int iy = 0 ; iy < 4 ; iy++ ) {
for ( int ix = 0 ; ix < 4 ; ix++ ) {
mDCT8x8_REF[fiy(pos,iy)][fix(pos,ix)] = dct[pos][iy][ix] ; }
} }
DEBUG_fprintf( stderr , "fenc_strid=%d fdec_strid=%d¥n" , fenc_strid , fdec_strid ) ;
DEBUG_fprintf( stderr , "record=%d¥n" , record ) ; dump_block( "H264_DCT8x8_t::mPIX1" , mPIX1 ) ; dump_block( "H264_DCT8x8_t::mPIX2" , mPIX2 ) ;
dump_block_n( "H264_DCT8x8_t::pix1" , 8 , pix1 , fenc_strid ) ; dump_block_n( "H264_DCT8x8_t::pix2" , 8 , pix2 , fdec_strid ) ;
x264 リファレンスコードにて
プローブポイントのデータをファイルに書き出し
#include "../debug/H264_DCT8x8_t.h"
static void sub8x8_dct( int16_t dct[4][4][4], uint8_t *pix1, uint8_t *pix2 ) {
sub4x4_dct( dct[0], &pix1[0], &pix2[0] );
sub4x4_dct( dct[1], &pix1[4], &pix2[4] );
sub4x4_dct( dct[2], &pix1[4*FENC_STRIDE+0], &pix2[4*FDEC_STRIDE+0] );
sub4x4_dct( dct[3], &pix1[4*FENC_STRIDE+4], &pix2[4*FDEC_STRIDE+4] );
// 追加
h264_DCT8x8_dump( dct , pix1 , pix2 , FENC_STRIDE , FDEC_STRIDE ) ; }
./common/dct.c
事例 H.264 変換量子化回路 Stimulus ( プローブポイントクラスのインスタンス )
#ifndef _DCT8x8_stimulus_H
#define _DCT8x8_stimulus_H
#include <systemc.h>
#include <cstdio>
#include "my_debug.h"
#include "H264_cqm_t.h"
#include "H264_DCT8x8_t.h"
#include "H264_DCT8x8_quant_t.h"
SC_MODULE(DCT8x8_stimulus) { sc_in_clk clk;
sc_out<bool> reset;
….
private:
std::ifstream *iop_H264_cqm ; std::ifstream *iop_H264_DCT8x8 ;
std::ifstream *iop_H264_DCT8x8_quant ; DCT8x8_stimulus.h
プローブポイントクラス のインスタンス ファイルストリームの
ポインタの宣言
事例 H.264 変換量子化回路 Stimulus ( プローブポイントのファイルをオープン )
#include "DCT8x8_stimulus.h"
#define U_H264_DCT8x8 u_H264_DCT8x8_quant
void DCT8x8_stimulus::entity() { int i ;
bool bank ;
uint32_t cmode ;
// 入力ファイルをオープン
iop_H264_cqm = new std::ifstream("H264_cqm.in" ) ; iop_H264_DCT8x8 = new std::ifstream("H264_DCT8x8.in")
iop_H264_DCT8x8_quant = new std::ifstream("H264_DCT8x8_quant.in" ) ;
DCT8x8_stimulus.cppプローブポイントのファイルを オープン
事例 H.264 変換量子化回路 Stimulus
( プローブポイントのデータを1レコード読み出し )
DCT8x8_stimulus.cpp
プローブポイントの データを1レコード 読み出し
void DCT8x8_stimulus::load_data( uint32_t *mode ) {
boost::archive::text_iarchive ia( *iop_H264_DCT8x8 ) ; ia >> u_H264_DCT8x8 ;
*mode = u_H264_DCT8x8.cmode ;
DEBUG_fprintf( stdout , "u_H264_DCT8x8.cmode=%d mode=%u¥n" , u_H264_DCT8x8.cmode , *mode ) ;
dump_block( "u_H264_DCT8x8.mPIX1" , u_H264_DCT8x8.mPIX1 ) ; dump_block( "u_H264_DCT8x8.mPIX2" , u_H264_DCT8x8.mPIX2 ) ; dump_block( "u_H264_DCT8x8.mDCT8x8_REF" ,
u_H264_DCT8x8.mDCT8x8_REF ) ;
事例 H.264 変換量子化回路 Stimulus ( プローブポイントのメンバー変数の参照 )
void DCT8x8_stimulus::mPIX1_write( bool bank , uint32_t iy ) {
unsigned int ad = ( bank << 4 ) | iy << 1 ; wait() ;
mPIX1_wraddress.write( ad ) ;
mPIX1_data0.write( u_H264_DCT8x8.mPIX1[iy][0] ) ; mPIX1_data1.write( u_H264_DCT8x8.mPIX1[iy][1] ) ; mPIX1_data2.write( u_H264_DCT8x8.mPIX1[iy][2] ) ; mPIX1_data3.write( u_H264_DCT8x8.mPIX1[iy][3] ) ; mPIX1_wren.write( true ) ;
wait() ;
mPIX1_wren.write( false ) ; wait() ;
ad++ ;
mPIX1_wraddress.write( ad ) ;
mPIX1_data0.write( u_H264_DCT8x8.mPIX1[iy][4] ) ; mPIX1_data1.write( u_H264_DCT8x8.mPIX1[iy][5] ) ; mPIX1_data2.write( u_H264_DCT8x8.mPIX1[iy][6] ) ; mPIX1_data3.write( u_H264_DCT8x8.mPIX1[iy][7] ) ; mPIX1_wren.write( true ) ;
wait() ;
mPIX1_wren.write( false ) ; wait() ;
}
DCT8x8_stimulus.cpp
プローブポイントのデータに 容易にアクセス可能
ポイントクラス
のメンバー変数を参照
wait_until( dct8x8_done.delayed() == true ) ; time_done = sc_simulation_time() ;
for( int iy = 0 ; iy < 8 ; iy++ ) {
mDCT8x8_read( bank , iy ) ; }
int unmatch_count = compare_block(
"mDCT8x8 vs u_H264_DCT8x8.mDCT8x8_REF" , mDCT8x8 , u_H264_DCT8x8.mDCT8x8_REF ) ; if ( unmatch_count == 0 )
{
DEBUG_fprintf( stdout , "MATCH compare_block count=%d¥n" , unmatch_count ) ; }
else {
事例 H.264 変換量子化回路 Stimulus( 期待値との照合 )
DCT8x8_stimulus.cpp
期待値との照合も簡単
Boost::serialization のメリット
•
定型的なコーデイングスタイルでプローブポイントの定義が可能–
プローブポイントクラスのscript
による自動生成も可能•
プローブポイントのメンバー変数の追加,
変更が容易•
ファイル形式にバイナリーも使用可能•
ブロック単体テストベンチ作成の省力化が可能•
複雑なデータ構造を扱う処理のハードウェア化が容易に•
汎用性・互換性の高い検証システムの構築が可能–
特定のESL
ツールに依存しない• SystemC
のみでなく、HDL
のテストベンチでも活用可能(C/C++/PLI,VPI,DPI,FLI)
単なるコーディング上のテクニックだけど
アルゴリズムコードと実装用コードの Missing-link を
結ぶ道具として有用
□動作合成ツール DesignPrototyper の特徴
□デザイン事例
□ USBlink IO Bridge( プロトコル変換回路 ) □ JPEG CODEC
□ デモンストレーション
□ boost::serialization を活用した効率的な検証手法
■まとめ
まとめ
•
動作合成ツール、SystemC/C++/ANSI-Cはハードウェア化の際の実装用 のアルゴリズム、方式を検討するための道具として非常に有用–
実行可能なモデル•
動作記述,
アルゴリズム記述により段階的な実装が可能–
最初からすべてRTLを用意するのは大変–
プローブポイントクラス(Boost::serialization)によりアルゴリズムコードからハー ドウェアブロックの切り出し、設計、検証が容易に実現可能•
オープンソースのSystemC/Verilog RTL混在シミュレーション環境により、ANSI-C,C++/SystemC,Verilog RTLを混在して機能レベルの検証が可能
•
ハードウェアアクセレータiPROVEにより、ブロック単位にハードウェア化し、SystemC環境でC/C++/Verilog RTLとの混在検証が可能
•ANSI-Cをフルサポート
•SystemCのBCA(バスサイクル精度)の動作記述に 対応
•強力な自動及びユーザ制約に基づくアーキテクチャ 探索
•コメント記述(ディレクティブ)によるハード化のため の詳細情報の付加が可能
•アルゴリズム、I/Oアキュレート、サイクルアキュレー トの3つの抽象レベルをサポートし,既存のIPやモジュー ルと容易にインターフェースすることが可能