開発環境![]()
基本は無償ツールをベースに使用しています。
_
|
SFL(Structured Function description Language)
は1980年代初頭にNTT電気通信研究所で開発されたハードウェア記述言語です。
同期式回路を前提としているためクロック記述が不要であり、
C言語ライクな機能記述が可能です。
SFLシミュレーション環境としてPARTHENONが使用できます。
追記: 最近はPARTHENONおよびSFL2VHDLは使用していません。 PARTHENONでのシミュレーションは実行速度が遅く、信号の観測性もあまりよくありません。 またSFL2VHDLに代わって、Shimizu氏が開発したsfl2vlを使用しています (コマンド名のため大文字と小文字が区別されます)。 SFLの構文についても資料を公開されています。 [SFLによるLSI設計入門] 2015/5/15 追記: SFLの便利さを世に知らしめるためにチュートリアル的なものを書く予定でしたが、 なかなか時間が取れず…。 きしもと氏が詳細な解説を公開されていますので、 SFLを使ってみたい方はこちらもご参照ください。 [SFLチュートリアル(NSLにも対応)] | ! |
NTTにある解説は難しいです。ちょっとした例があればいいんですが。
演習でやった方も思い出してください。 C++(C99でもいい)のような拡張が欲しいのう…。 |
さすがに規模が大きくなってくると他言語の便利なところがうらやましくなります。 SFLをちょっと拡張(?)して個人的に使用しています。 自作のsflpコマンドにて.sflpファイルから標準フォーマットの.sflと.hを生成します。 『はじめてのSFL+』としてまとめました!
・制御信号の引数宣言
input io_A<4>, io_D_in<8>; instrin io_write(io_A, io_D_in);
rega sig[32]<8>; sela sp[32];
par(i=0;i<32;i++){ // 並列実行 sig[i] := sig[i]<6:0> || 0b0; } any(i=0;i<32;i++){ // 条件処理 sp[i] : sig[i] := sig[i]<6:0> || 0b0; else : sigm := 0b0000; } alt(i=0;i<32;i++){ // 優先度付き条件処理 sp[i] : sig[i] := sig[i]<6:0> || 0b0; else : sigm := 0b0000; }
if(flag) ggg(); else fff();
sel str<40>; str = "think"; // str = 't'||'h'||'i'||'n'||'k'; に変換 str = "ミカクニン"; // 半角カナもOK
reg csig<8>; csig := 'N'; // 0x4E
switch(adrs){ case 0b00: aaa(); case 0b01: bbb(); default: ccc(); }
a += 0x2; b -= 0x2; c++; d--;
mem gpr[8]<4>; gpr[0xE] := 0x3; gpr[5] := 0x2;
if(a==0b0){ sel depth<4>; // ローカル信号 any{ d==0b0 : depth = 4; d==0b1 : depth = 8; } data := depth; }
sel x<4>; join(i=0;i<4;i++){ x = (a[i] & b<i>) | x; } // x = (a_0 & b<0>) | (a_1 & b<1>) | (a_2 & b<2>) | (a_3 & b<3>); に展開
記述したSFLとテストスクリプトをPARTHENONのSFLシミュレータであるsecondsに食わせます。
構文エラーの場合はtermが起動してエラー個所を表示してくれます。
特にSFLに対してプリプロセッサ(上図のSFLPのようなもの)をかましていると、
行数のみのエラー表示では分かりにくいので重宝しています。
ただし、デフォルトのままではSFLファイルが強制的に更新されているようで、
エディタから「外部で更新しとるよ?」と怒られます。これは、
/usr/local/libexec/に存在するsfl_edit中に
mv $1 $1.bak cp $1.bak $1 xterm -title $1 -vb -e vi -c $2 $1 &
と記述されており、構文エラーなどの場合にこれが実行されるからです。 安全のためとはいえ、 エディタから怒られるわどうせプリプロセッサで生成するしバックアップも取ってるんで、 mvとcpはコメントアウトして使用しています。
SFLを論理合成…といきたいところですが、 XilinxやAlteraなどの標準的なツールはSFLに対応していません(>_<)。 SFLファイルをそれらのツールで使用可能なVHDLやVerilogHDLファイルへ変換してプロジェクトに取り込みます。 SFL2VHDLやSFL2VerilogコマンドはPARTHENONに付属しています。
% SFL2VHDL core.sfl core.vhdにて変換します。 SFLファイルが複数ある場合はそれぞれについて変換し、 プロジェクトに追加します。
SFL2VHDLを使う環境構築が大変?…という状況でしたが、
Naohiko Shimizu氏謹製のsfl2vlにより手軽にSFLを利用できるようになりました。
[sfl2vlサポートページ]
で配布されており、「もうRTL記述には戻れない!」ひと増加中です。
個人利用でも、VerilogHDLやVHDLへの変換を容易に行うことができます。
SFL言語チュートリアルも大変に参考になります。
変換時には最適化も施されます。
SFLで記述する場合、手作業での回路最適化は、SFLの高い可読性を損ないかねません。
sfl2vlでは、可読性を重視した記述さえも回路規模をだいぶ削れます。
使ってみました→SFL2VHDL,SFL2Verilogとsfl2vh,sfl2vlの比較
聞くところによると、sfl2vlの方が実績があり、sfl2vhは順次最適化対応中とのこと。
高速検証環境をあなたに。
verilatorでVerilogHDLをC++に変換することで、
遅延を考慮しないサイクルベースシミュレーションを行うことができます。
PPUの画像生成テストについては、
ModelSim Web Editionよりも6.5倍高速でModelSim SE並です。
(→図、ここではverilatorによるC++への変換とVC++でのコンパイル時間を入れた)
単純にシミュレーション速度だけでの比較ではWeb Editionよりverilatorが140倍高速でした。
またCPUとソフトウェアの協調検証として、
CPUをC++に変換しエミュレータのCPUモデルと交換し実行することで、
CPUのみの高速なソフトウェア検証が可能になりました。
sfl2vlコマンドやverilatorコマンドなどを使用するためにはUNIX環境が必要です。 またmakeコマンドなども便利です。 Windows上でこれらコマンドを使用するためのUNIX環境としてCygwinを使用しています。
トップモジュールについてはクロックやDLL、I/O、シリアルポート、
外部RAMなどの接続が必要なので、はじめからVHDLで記述しておきます。
SFLから変換したモジュールを、このトップモジュール直下のモジュールとして接続します。
はじめXilinxをターゲットとして実装しましたが、
当然ながらAlteraのデバイスでも動かしたい要求もあります。
NESのコアモジュールはどちらの環境にも対応する汎用的な形で記述し、
デバイスのライブラリやプリミティブは使用しない方針です。
トップモジュールのみを取り替えることで、
どの環境でも実装できます。
SFLの単体モジュールとして、module構文とcircuit構文があります。
module構文では"+"などの演算子は使用できず、自前で演算器を接続する必要があります。
circuit構文では基本的な演算子が使用可能となっており、
可読性も向上するので主にこちらを使用します。
%i "slr.h" %i "add.h" module enzan { slr_16 base_slr; // 自前のシフタ add_16 pitch_add; // 自前の加算器 par{ base_slr.con(0x32, wins); // 論理右シフト pitch_add.con(pitch, base_slr.dout); // 加算 pitch := pitch_add.dout; } }circuit構文だとシンプル。 circuit enzan { pitch := pitch + (0x32 >> wins); }SFL+ではこう circuit enzan { pitch += 0x32 >> wins; }
sfl2vlでは演算子サポートも強化されているため使わない手はありません。
| ! | moduleとcircuitの使い分けはPARTHENONシステムにおける論理合成可能かどうかを区別するためのものだったとか。 |
画面がまっくら…アドレスが範囲外…など、観測が不十分なときはよくデバッグ回路を仕込みます。 マスクしたり、想定外の入力があったときに停止したり。 しかしこの回路、不要なときは「削減」されるべきものです。 この「削減」とは、論理合成段階では回路を切り離し固定値出力にするわけですが、 記述段階ではコメントアウト、もしくは出力をゼロレベルと論理積 を取ることで論理合成時に削減されます。 つまりデバッグ回路を使用するかどうかは、 回路の励起信号、もしくは出力にスイッチを記述し切り替えることで対応します。
%d IR_DEBUG 0b1 /*%d IR_DEBUG 0b0*/ ir_def = IR_DEBUG; if(ir_def) par{ if(ir==0b00000010) par{ halt := 0b1; } }
やっていません。Verilog-XLやModelSimなどを起動した記憶さえ無い!
(初期バージョンまではね)
| ! |
大工記述ですから!
というよりも単に波形を見たくなかっただけ。 完全非同期設計でSignalScan(波形ビューワ)とにらめっこするとなんだか変なわらいが込み上げて来る。 |
近年のPCスペックの向上と、適切なモデルによって、
HDLの検証は専用ツールによるRTLシミュレーションで行うよりも、
実行形式にして走らせるのがこれからのトレンド?
という(VTOCは有料のようですが)ことで無償ツールのVerilatorを利用できます。
VerilogHDLをC++へ変換してコンパイルし実行することで、
Verilog-XLなどのインタプリタ型HDL専用シミュレータよりも高速な検証が可能です。
一般的なHDLシミュレータとして、
verilog-XLは遅延情報に基づいたイベントドリブン型のシミュレーションを行っていると思います。
また、Synopsys社のVCSやCadence社のNC-Verilogはコンパイル型ですが、
やはりダイナミックシミュレータですので遅延情報が絡んできます
(それでも高価なだけあってRTLシミュレーションでも高速みたいですが)。
見たところVerilatorはイベント波及型シミュレータでしょうか?
要は遅延情報を含まないシミュレーションだと見ていますが。
使い方によっては、変換したC++コードのカーネルなどへの組み込みによる実機動作検証、
といったことも可能です(懐かしいね)。
「C++コードやMakefileへの変換という手段のひとつですが、
VTOCの代わりにと思っている人はダウンロードしないでください」って。
もう使ってるがな。
verilatorの検証をしていたところ、DMA転送のバグが判明…
verilatorでスプライトがうまく表示されなかったため、
secondsでシミュレーションしたところ多重書き込みしまくってる。
そういやDMA関連はsecondsシミュなしのやっつけだったからなあ…
このバグはModelSimでも再現できるかな?
(というかアピールしてくれるだろうか?)
verilatorはtristateやinoutはサポートしてないのか…。
PARTHENONで20分かかっていたシミュレーション時間も5分程度に短縮できました。
しかしコンパイル時間も5分ほどかかるようで、
このへんverilatorがC++でなくCで出力できればもっと短縮できるのかな?なんでC++なんだよ。
実装規模が増大し、さらにソフトも含めた検証では遅延モデルでのハードウエアシミュレーションではなく、
サイクル精度シミュレーションが有効になりそうです。
異なるクロックを使用する回路がある場合は、その部分をイベントドリブンで行う方法もあります。
2013/8 追記: Verilatorのバージョンも上がって、さらにVisualStudio 2013 Expressなども使用できるようになりました。 PCの性能向上もあって、コンパイル時間、シミュレーション時間もストレスないレベルにまで短縮されました。 いやー便利、便利!
はじめてのFPGAってことでまずはキットを入手しました。
20万ゲート(内部RAM含めて)以上で8万円程度、
といった基準があったようななかで3つほど候補があり、
一番安かったのがCQ出版社から市販されていたSpartan-IIE300評価キットです。
ゲーム機に適しているとかそんなことは考えもつきません。
実装するうちに、クリスタルは66MHzより50MHzがよかったな(VGA出力がしやすい)とか、
拡張ピン位置がまとまっててカートリッジコネクタを実装しやすかったとか、思ったことはあります。
こいつにはFlashメモリやSDRAMが載ってて、デバッグ用途に使用しましたが、
最近はSRAMが多いようで、簡単にRWできるSRAMのほうが楽でよさそうです。
結局、NESの実装には推定ゲート数5万が実装可能+内部BlockRAMが十数個(個々の容量にもよりますが)
+拡張ピン100ピンほどといったところが最低ラインでしょうか。
スパ2E300評価キットは何とか合格ラインだったので、実装できたのです(!)
次に導入したのがAltera DE1ボード。
さまざまなI/O(スイッチ、シリアルポート、FlashROM、SDRAM、SRAM、VGA出力、SDカードコネクタ)
が実装されており、価格も2万円以内と、入門用には面白いボードです。
NESは楽に3つは実装できるくらいの回路規模があり、
さらにSDカードからの読み込みや各種マッパーの実装などいろいろ試すことができました。