2019年1月27日日曜日

SystemC で $clog2 を使う

ハードウェア設計では,メモリサイズに対するアドレスバスの bit 幅等で log2 を使いたい場面が出てくる (bit 幅の指定に使うので,コンパイル時定数であることが重要).
いつからか Verilog では $clog2() が使えるようになって便利だが,SystemC でそれに該当するものはなさげ.

仕方がないので,ダメ元で std::log() を使ってみる.
●定義
#define BIT_WIDTH( n ) (( int )( log(( n ) * 2 - 1 ) / log( 2 )))

●使用
#define HOGE 1024
sc_uint<BIT_WIDTH( HOGE )> HOGE_t;

●VivadoHLS のログ
./hoge.h:39:27: error: non-type template argument of type 'int' is not an integral constant expression
typedef sc_uint<(( int )( log(( HOGE ) * 2 - 1 ) / log( 2 )))> HOGE_t;
                ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
シミュレーションでは (g++ の最適化が強力なので) コンパイル時定数になってくれるので ok なんだけど,VivadoHLS の高位合成コンパイラでは怒られた.

んー,と思っていたら,テンプレートメタプログラミングなる手法があること発見!
template<int num> struct BitWidthTmplate { enum { Val = BitWidthTmplate<num / 2>::Val + 1 }; };
template<> struct BitWidthTmplate<0> { enum { Val = 0 }; };
#define BIT_WIDTH( n ) ( BitWidthTmplate<( n ) - 1>::Val )
これだと VivadoHLS でも通ったヽ(´ー`)ノ

constexpr 使ったら std::log() でも行けそうな気がするけど,Vivado の C++ 高位合成コンパイラは C++11 ですら無いので使えない.┐('~`;)┌

2019年1月12日土曜日

Intel の嫌がらせ

Intel 謹製の高速正規表現ライブラリであるところの hyperscan を使ってみようと思った.
ここ見ながら build してサンプル作って実行してみたら,

「ハンドルされない例外が 0x00007FF6BF7B5E4C (sample.exe) で発生しました: 0xC000001D: Illegal Instruction。」

オウフ.なかなか見ないエラーだな.

エラー起こしたアドレスの逆アセをみると「shlx」,これはどうやら BMI2 命令セット (AVX2 と同時に追加?) に含まれる命令っぽいのだが,うちの AMD A8 に載ってるわけがない.cmake が AVX2 の有無を認識してコンパイラオプション等をよきにはからってくれると思ってるんだけど,違うのだろうか? Intel CPU にしか hyperscan を使わせない嫌がらせか何か?

んーと思ったら,CMakeLists.txt で AVX2 を強制的に ON にしてるっぽい?
set(ARCH_C_FLAGS "/arch:AVX2")
set(ARCH_CXX_FLAGS "/arch:AVX2")
これをコメントアウトしたら,無事 AMD A8 でも動いたヽ(´ー`)ノ

2019年1月3日木曜日

ふゆやすみのこうさく

あけおめ.

超久々に車載データロガーを update.

自作データロガーのハードを 2号機にしてから,ラップタイマの磁気センサの感度が極端に悪くなって,ラップ計測できなくなってしまった.車からデータロガーのハードを外して調査・修理しようかと思ったが,
妥協発動

GPS ラップタイマ機能を自作データロガーの Android アプリに組み込んでしまうことにした.普通は GPS Laps とか使えば済むんだけど,自作データロガーの機能も無いと困るので (ここは妥協しないw).

Bluetooth 通信 (外部 GPS と通信) と,GPS ログからラップタイム算出するのは既に別のソフトで実装済みなのでサクッと移植.
問題はコントロールラインを設定する UI をどうしよう? というとこで,理想は Google マップなんかを表示させて GUI で設定することだけど,

妥協発動

一度サーキット毎に設定してしまえばそうそう変えるものではないし,凝った GUI は不要! というわけで,
←こういうのを Google マイマップ (PC) で作って kml にエクスポートして,

Android アプリでは
←こういうふうにその kml を選択できるようにしておいた.

磁気センサのラップタイマが動かなくなったのは残念だけど,GPS でも 3/100秒 くらいの精度が出るのはわかってるしね.サンデードライバーにはこれで十分っす.

ま,人生何事も妥協が大事ということで.