C++11とC++14とSystemC
C++11やC++14といった新しいC++でSystemCを使ったらどうなるか軽く試したメモ
C++11
C++11でSystemCがどうなるかについては↓の資料にまとめられています。
http://www.nascug.org/events/17th/black_cpp11_2_27_2012.pdf
一番気になったのはテンプレートについて。
C99だと>
が二つ続く際は右シフトと認識しない様にスペースが必要。
でもC++11ではちゃんと判別してくれる様です。
実際にやってみた。
#include <systemc.h> int sc_main(int argc, char *argv[]) { sc_signal<sc_uint<5> > c99; sc_signal<sc_uint<5>> cpp11; //こっちはC++11専用 }
C99環境だと
clang++ -O2 -Wall -I. -I/home/ginnyu-tei/lib/SystemC-2.3.0_Debug//include -c main.cpp main.cpp:6:25: error: use of undeclared identifier 'cpp11' sc_signal<sc_uint<5>> cpp11; ^ main.cpp:6:30: error: expected a type sc_signal<sc_uint<5>> cpp11; ^ 2 errors generated. make: *** [main.o] エラー 1
もちろんエラー
次は同じコードをC++11環境でやってみる。
C++11環境にするにはオプションに-std=c++11
を追加する。
(gccのバージョンによっては-std=c++0x
)
clang++ -O2 -Wall -std=c++11 -I. -I/home/ginnyu-tei/lib/SystemC-2.3.0_Debug//include -c main.cpp clang++ -o run.x -L. -L/home/ginnyu-tei/lib/SystemC-2.3.0_Debug//lib-linux64 -lsystemc -lm main.o
問題なくビルド出来ました。
C++14
C++14では2進数表記が追加される様です。
ドラフト規格ですが、コンパイラが独自規格で実装している様なので試してみました。
#include <systemc.h> int sc_main(int argc, char *argv[]) { sc_uint<5> hoge; sc_uint<32> piyo; hoge = 0b10000; piyo = 0b10101010010101010000000011111111; cout << std::hex << "hoge = " << hoge << endl; cout << std::hex << "piyo = " << piyo << endl; return 0; }
実行結果
[ginnyu-tei@localhost SystemC_Test]$ ./run.x SystemC 2.3.0-ASI --- Mar 9 2014 13:23:24 Copyright (c) 1996-2012 by all Contributors, ALL RIGHTS RESERVED hoge = 10 piyo = 0aa5500ff
C++14の新機能はまだまだあるけどそれは正式な規格になってから調べる
clangでSystemC2.2をビルドしてみた
clangでSystemC2.2がビルドできたのでメモ
ただしこの方法はclangのバージョン3.3のみに有効
clangインストール
インストールは以下ページを参考にしました。
CentOS5にLLVMとclangをインストールする | CentOS・Red Hat Linux実践テクニック - サンプルコードによるPerl入門 〜 伝統と信頼のPerlを学ぼう 〜
automake-1.6.3 インストール
Fedora Coreに入っているautomakeは1.12は新しすぎて
SystemC2.2では使えないので1.6.3をインストール
wget http://ftp.gnu.org/gnu/automake/automake-1.6.3.tar.gz tar zxvf automake-1.6.3.tar.gz cd automake-1.6.3 ./configure make sudo make install
SystemC2.2修正
そのままではビルドできないのでコードに手をいれる。
修正は以下を参照
configure
@@ -3445,7 +3445,7 @@ ;; x86_64*linux*) case "$CXX_COMP" in - c++ | g++) + c++ | g++ | clang++) EXTRA_CXXFLAGS="-Wall" DEBUG_CXXFLAGS="-g" OPT_CXXFLAGS="-O3"
src/sysc/datatypes/bit/sc_bit_proxies.h
@@ -713,7 +713,7 @@ protected: - mutable X& m_obj; + X& m_obj; int m_hi; int m_lo; int m_len; @@ -1190,10 +1190,10 @@ protected: - mutable X& m_left; - mutable Y& m_right; + X& m_left; + Y& m_right; mutable int m_delete; - mutable int& m_refs; + int& m_refs; private:
src/sysc/datatypes/fx/scfx_rep.h
@@ -74,6 +74,7 @@ void multiply( scfx_rep&, const scfx_rep&, const scfx_rep&, int ); scfx_rep* neg_scfx_rep( const scfx_rep& ); scfx_rep* mult_scfx_rep( const scfx_rep&, const scfx_rep&, int ); +scfx_rep* mult_scfx_rep( const scfx_rep& ); scfx_rep* div_scfx_rep( const scfx_rep&, const scfx_rep&, int ); scfx_rep* add_scfx_rep( const scfx_rep&, const scfx_rep&, int ); scfx_rep* sub_scfx_rep( const scfx_rep&, const scfx_rep&, int ); @@ -374,6 +375,15 @@ inline scfx_rep* +mult_scfx_rep( const scfx_rep& a, const scfx_rep& b) +{ + scfx_rep& c = *new scfx_rep; + sc_dt::multiply( c, a, b, SC_DEFAULT_MAX_WL_ ); + return &c; +} + +inline +scfx_rep* lsh_scfx_rep( const scfx_rep& a, int b ) { scfx_rep& c = *new scfx_rep( a );
src/sysc/utils/sc_utils_ids.cpp
@@ -59,6 +59,8 @@ // #include "sysc/utils/sc_report.h" +#include <cstdlib> +#include <cstring> namespace sc_core {
SystemC2.2ビルド&インストール
手順は普通のやり方。
ただし、環境変数でコンパイラをclangにする。
mkdir build cd build env CC=clang CXX=clang++ ../configure --prefix=/home/ginnyu-tei/lib/SystemC-2.2_Clang make sudo make install make check
参考にしたサイト
LSI設計雑記帳 [SystemC] clangでインストール
clang - Installing SystemC 2.2.0, compilation with GCC 4.6 and package for Fedora - Stack Overflow
SystemC+GoogleTestを試してみた
Twitter上でSystemCでテストフレームワークが使えるかの話をしている時に
以下ページを教えてもらったので試してみました。
Using existing unit test frameworks with SystemC - Stack Overflow
ソースコード
まずはページに載っているソースコードをファイルにします。
- exor2.hxx
- main.cxx
- main_1.cxx
- main_2.cxx
- stim.hxx
- mon.hxx
これだけでは足りないので以下サイトに載っているNANDのコードをファイルにする。
ファイル名は「nand2.hxx」
googletest
googletestは以下サイトにあるので最新の1.7をダウンロード
解凍後「./configure」「make」
googletest - Google C++ Testing Framework - Google Project Hosting
cmake
googletestはcmakeを使ってビルド環境を作るっぽいのでCMakeLists.txtを作成する。
cmakeを使った事がないので見よう見まねで作成したのが↓
cmake_minimum_required(VERSION 2.6) project(sc_unit_test) #SystemC Path include_directories(/home/ginnyu-tei/work/google_test/_lib/systemc-2.3.0/include) LINK_DIRECTORIES(/home/ginnyu-tei/work/google_test/_lib/systemc-2.3.0/lib-linux64) #googletest Path include_directories(/home/ginnyu-tei/work/google_test/_lib/gtest-1.7.0/include) LINK_DIRECTORIES(/home/ginnyu-tei/work/google_test/_lib/gtest-1.7.0/lib/.libs) #main build add_executable(main main_1.cxx main_2.cxx main.cxx) target_link_libraries(main pthread systemc gtest)
googletestのライブラリパスは「libgtest.a」があるディレクトリを指定すれば良いですが
ビルド環境によっては「gtest-1.7.0/build」に入っている時があります。
ビルド
ソースコードとCMakeLists.txtを同じフォルダに入れて以下実行
[ginnyu-tei@localhost google_test]$ mkdir build [ginnyu-tei@localhost google_test]$ cd build/ [ginnyu-tei@localhost build]$ cmake .. -- The C compiler identification is GNU 4.7.2 -- The CXX compiler identification is GNU 4.7.2 -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Configuring done -- Generating done -- Build files have been written to: /home/ginnyu-tei/work/google_test/build [ginnyu-tei@localhost build]$ make Scanning dependencies of target main [ 33%] Building CXX object CMakeFiles/main.dir/main_1.cxx.o [ 66%] Building CXX object CMakeFiles/main.dir/main_2.cxx.o [100%] Building CXX object CMakeFiles/main.dir/main.cxx.o /home/ginnyu-tei/work/google_test/main.cxx: 関数 ‘int sc_main(int, char**)’ 内: /home/ginnyu-tei/work/google_test/main.cxx:25:18: 警告: warn_unused_result 属性付きで宣言されている ‘int RUN_ALL_TESTS()’ の戻り値を無視しています [-Wunused-result] Linking CXX executable main [100%] Built target main
Warningが出ているがビルドはできた。
実行ログ
[ginnyu-tei@localhost build]$ ./main SystemC 2.3.0-ASI --- Jan 9 2014 22:05:39 Copyright (c) 1996-2012 by all Contributors, ALL RIGHTS RESERVED Running main() from gtest_main.cc [==========] Running 2 tests from 1 test case. [----------] Global test environment set-up. [----------] 2 tests from systemc_test [ RUN ] systemc_test.test1 Time A B F 0 s 0 0 0 0 s 0 0 1 10 ns 0 1 1 20 ns 1 0 1 30 ns 1 1 0 Info: /OSCI/SystemC: Simulation stopped by user. [ OK ] systemc_test.test1 (1 ms) [ RUN ] systemc_test.test2 unknown file: Failure C++ exception with description "Error: (E113) insert primitive channel failed: elaboration done In file: sc_prim_channel.cpp:216" thrown in the test body. [ FAILED ] systemc_test.test2 (1 ms) [----------] 2 tests from systemc_test (2 ms total) [----------] Global test environment tear-down [==========] 2 tests from 1 test case ran. (2 ms total) [ PASSED ] 1 test. [ FAILED ] 1 test, listed below: [ FAILED ] systemc_test.test2 1 FAILED TEST [ OK ] systemc_test.test2 (2 ms) [----------] 2 tests from systemc_test (3 ms total) [----------] Global test environment tear-down [==========] 2 tests from 1 test case ran. (3 ms total) [ PASSED ] 2 tests. [ OK ] systemc_test.test1 (4 ms) [ RUN ] systemc_test.test2 Time A B F 0 s 0 0 0 0 s 0 0 1 10 ns 0 1 1 20 ns 1 0 1 30 ns 1 1 0 Info: /OSCI/SystemC: Simulation stopped by user. [ OK ] systemc_test.test2 (1 ms) [----------] 2 tests from systemc_test (5 ms total) [----------] Global test environment tear-down [==========] 2 tests from 1 test case ran. (5 ms total) [ PASSED ] 2 tests. [ OK ] systemc_test.test2 (2 ms) [----------] 2 tests from systemc_test (6 ms total) [----------] Global test environment tear-down [==========] 2 tests from 1 test case ran. (6 ms total) [ PASSED ] 2 tests. [ginnyu-tei@localhost build]$
なんかfailしてる・・・
SystemC2.2に変えてみた。
SystemC2.2で実行する際はmain_1.cxxとmain_2.cxxに以下の
includeを追加しないとエラーになった。
(別の環境では追加しなくてもビルドできたので環境依存かも)
#include <unistd.h>
SC2.3と同じ様にビルドして実行
[ginnyu-tei@localhost build]$ ./main SystemC 2.2.0 --- Jan 9 2014 23:02:22 Copyright (c) 1996-2006 by all Contributors ALL RIGHTS RESERVED Running main() from gtest_main.cc [==========] Running 2 tests from 1 test case. [----------] Global test environment set-up. [----------] 2 tests from systemc_test [ RUN ] systemc_test.test1 Time A B F 0 s 0 0 0 0 s 0 0 1 10 ns 0 1 1 20 ns 1 0 1 30 ns 1 1 0 SystemC: simulation stopped by user. [ OK ] systemc_test.test1 (1 ms) [ RUN ] systemc_test.test2 unknown file: Failure C++ exception with description "Error: (E546) sc_start called after sc_stop has been called In file: sc_simcontext.cpp:1315" thrown in the test body. [ FAILED ] systemc_test.test2 (1 ms) [----------] 2 tests from systemc_test (2 ms total) [----------] Global test environment tear-down [==========] 2 tests from 1 test case ran. (2 ms total) [ PASSED ] 1 test. [ FAILED ] 1 test, listed below: [ FAILED ] systemc_test.test2 1 FAILED TEST [ OK ] systemc_test.test2 (2 ms) [----------] 2 tests from systemc_test (3 ms total) [----------] Global test environment tear-down [==========] 2 tests from 1 test case ran. (3 ms total) [ PASSED ] 2 tests. [ OK ] systemc_test.test1 (3 ms) [ RUN ] systemc_test.test2 Time A B F 0 s 0 0 0 0 s 0 0 1 10 ns 0 1 1 20 ns 1 0 1 30 ns 1 1 0 SystemC: simulation stopped by user. [ OK ] systemc_test.test2 (1 ms) [----------] 2 tests from systemc_test (4 ms total) [----------] Global test environment tear-down [==========] 2 tests from 1 test case ran. (4 ms total) [ PASSED ] 2 tests. [ OK ] systemc_test.test2 (1 ms) [----------] 2 tests from systemc_test (5 ms total) [----------] Global test environment tear-down [==========] 2 tests from 1 test case ran. (5 ms total) [ PASSED ] 2 tests.
うーん・・・分からん・・・
STREAM Benchmarkをやってみた
STREAMというメモリ帯域を測定するベンチマークソフトがあるので試してみました。
上記ページにあるFTPサイトにはstream.exeがありますが
Windows32bit版で実行にはCygwin.dllが必要です。
私はWindows7 64bit版なのでソースコードからビルドしました。
ビルドは簡単でstream.cをダウンロードしてMinGWのgccでコンパイルするだけです。
(POSIX準拠になっているのでVisualStudioだと存在しないヘッダーがあります。)
以下が実行結果
------------------------------------------------------------- STREAM version $Revision: 5.10 $ ------------------------------------------------------------- This system uses 8 bytes per array element. ------------------------------------------------------------- Array size = 10000000 (elements), Offset = 0 (elements) Memory per array = 76.3 MiB (= 0.1 GiB). Total memory required = 228.9 MiB (= 0.2 GiB). Each kernel will be executed 10 times. The *best* time for each kernel (excluding the first iteration) will be used to compute the reported bandwidth. ------------------------------------------------------------- Your clock granularity/precision appears to be 999 microseconds. Each test below will take on the order of 24001 microseconds. (= 24 clock ticks) Increase the size of the arrays if this shows that you are not getting at least 20 clock ticks per test. ------------------------------------------------------------- WARNING -- The above is only a rough guideline. For best results, please be sure you know the precision of your system timer. ------------------------------------------------------------- Function Best Rate MB/s Avg time Min time Max time Copy: 8420.6 0.020112 0.019001 0.021001 Scale: 7999.6 0.020446 0.020001 0.021002 Add: 11428.0 0.021668 0.021001 0.026001 Triad: 10434.4 0.023557 0.023001 0.024002 ------------------------------------------------------------- Solution Validates: avg error less than 1.000000e-013 on all three arrays -------------------------------------------------------------
Terasic SoCKitのデモを実行してみた-HPS-
SoCKit System CD(Terasicのページからダウンロード)にデモが入っているので実行してみた。
HPS側は以下デモが入っています。
- hps_gpio
- hps_gsensor
- hps_lcd
- my_first_hps
デモ実行方法は「My_First_HPS.pdf]に記載されています。
my_first_hps実行方法
- C:\altera\13.0sp1\embedded\Embedded_Command_Shell.batを実行 「C:\altera\13.0sp1\embedded」はインストール先とバージョンによって変わるので注意
2.コマンドプロンプトが立ち上がるので「my_first_hps」があるディレクトリまで移動する
ベースはCygwinなので「cd /cygdrive/<ドライブレター>/」でドライブを移動できる。
3.移動後make
を実行
コンパイル済みのmy_first_hpsが入っているので一度make clean
した方がコンパイルの様子が見れます。
arm-linux-gnueabihf-gcc -g -Wall -I C:/altera/13.0sp1/embedded/ip/altera/hps/al tera_hps/hwlib/include -c main.c -o main.o arm-linux-gnueabihf-gcc -g -Wall main.o -o my_first_hps
4.ボードの電源を入れてLinuxを起動しTeraTermを接続する。
「Terasic SoCKitでLinuxをブートしてみた」と同じ
LAN経由でプログラムをSoCKitへ転送するので同一ネットワーク内にLANを接続する。
5.SoCKitのipアドレスを確認する
ifconfig
でIPを確認する。
DHCP環境でIPが割り当てられない場合はudhcpc
で割り当ててもらう
固定IP環境では多分以下コマンドでいけるはず
ifconfig eth0 <固定IPアドレス>
ifconfig eth0 netmask <サブネットマスク>
6.SocKit側のLinuxにパスワードを設定する
ファイル転送にscpを使うのでpasswd
コマンドでパスワードを設定する。
7.SocKit側のLinuxにプログラムを転送する。
scpで実行バイナリを転送する
コマンドプロンプト上で以下コマンドを実行する
scp my_first_hps root@<Soc Kit側のIPアドレス>:/home/root
「my_first_hps」が転送するファイルで「/home/root」が転送先ディレクトリ
8.実行バイナリを実行する。
TeraTerm上で./my_first_hps
root@socfpga_cyclone5:~# ./my_first_hps Hello World!
hps_gpio
H_SW0~3でONになっているSWに対応するLEDD10~13が点灯する
hps_gsensor Gセンサーの測定結果を出力する
root@socfpga_cyclone5:~# ./gsensor ===== gsensor test ===== id=E5h [1]X=-52 mg, Y=-84 mg, Z=932 mg [2]X=-20 mg, Y=-92 mg, Z=924 mg [3]X=44 mg, Y=-80 mg, Z=828 mg [4]X=-56 mg, Y=-900 mg, Z=552 mg [5]X=-20 mg, Y=-1096 mg, Z=-52 mg ・・・
hps_lcd
LCDに文字と図形を表示する
root@socfpga_cyclone5:~# ./hps_lcd Graphic LCD Demo