EfinixのFPGAがちょっと気になっていたところに,周囲からもEfinixという話題が聞こえてきたので遊んでみました.実機で遊ぶ前にツール使ってみるかなーとか思ったのだけど,ツールは有償または,評価ボードを買ってライセンス取得の必要があるとのことでボードを購入.購入したのは,Trion 8 Development Kit(T8F81C-DK).Digi-Keyで1万3千円くらいでした.
今回は,お決まりのLチカと,Trion 8ってどのくらいの周波数で動くのかなー?という味見をしてみました,という話です.
とりあえずのLチカ
T8F81C-DKの場合,
- ボード上の33.333MHzのクロック
- ボード上の33.333MHzのクロックを入力とするPLL
- Trion 8内蔵のオシレータ(10KHz)
の3種類のクロックが使えるので,まとめてLチカに使ってみました.
ソースコード
ソースコードはこんな感じ.
module top
(
input wire clk,
input wire reset,
input wire pll_clk,
output wire pll_reset,
input wire pll_locked,
input wire osc_inst1,
output wire [4:0] led
);
assign pll_reset = reset;
// on-board 33.333MHz
reg [31:0] counter;
always @(posedge clk) begin
counter <= counter + 1;
end
assign led[4] = ~counter[24];
// PLL output 66.666MHz (= 33.333MHz * 32 / 16)
reg [31:0] pll_counter;
always @(posedge pll_clk) begin
if(pll_locked == 0) begin
pll_counter <= 0;
end else begin
pll_counter <= pll_counter + 1;
end
end
assign led[3:2] = ~pll_counter[25:24];
// Internal Oscillator 10kHz)
reg [12:0] osc_counter;
always @(posedge osc_inst1) begin
osc_counter <= osc_counter + 1;
end
assign led[1:0] = ~osc_counter[12:11];
endmodule // top
普段Xilinx/AMDやIntelのFPGAを使っている身からすると,ちょっと不思議な感じがするのがPLLの扱い.Efinixでは,PLLはトップモジュールの外に存在するものらしい.
ピン定義・制約ファイルの記述
一度,合成から配置配線まで一通りのフローを実行すると「未割り当てピンがあるよ」「タイミング制約満たしてないよ」というエラーがでる.ピン割り当てはInterface Designerで,タイミング制約はsdcファイルで指定する.ちなみに,制約を指定しない場合は,遅延1nsを想定して合成がかけられるみたい.
Interface Designerの設定は次の通り.上から順にGPIOの設定,PLLの設定,内蔵オシレータの設定.
GPIOに何もエントリが出てこなかったので最初どうするのかな?とおもったけど,自分でCreate BlockやらCreate GPIO Busでインスタンスを生成してVerilogコードに合わせて名前とピン名を指定してことなきを得ました.
Verilogコードから抽出してくれてもよさそうなものなのに…という気持ち.PLLとか内蔵OSCみたいに必ずしもピンに割り当てられるわけではないということなのか,何かツールの使い方を間違っているのか.
Interface Designerの設定値はisfという拡張子のファイルにエクスポートしておいて,次のプロジェクトでインポートすることもできるみたい.ツールのマニュアルにはPythonで云々という記述もあったので,今度試してみよう.
タイミング制約のsdcファイルは次の通り.こちらはあっさり.
create_clock -period 30 clk
create_clock -period 15 pll_clk
create_clock -period 100000 osc_inst1
で,再度合成すると,今度は警告なしでFPGAコンフィギュレーションファイルとFlash ROM用のHexファイルが生成されました.
書き込みと実行
T8F81C-DKはUSBでプログラミングできるけど,一旦ROMにHexファイルを書き込んでコンフィギュレーションするしかできなさそう.
なお,Linuxだと,開発ツールインストール後に設定スクリプトを使って,USBデバイスが接続されたときの動作を指定するおなじみのスクリプトを /etc/udev/rules.d/
以下に設置しておく必要があります.Windowsでは, Zadig を使ってEfinixボードが接続されたときに適切なドライバがアタッチされるように設定しておく必要があります.
Zadig知らなかったけど,他のちょっと特殊な設定が必要なUSBデバイス使う時にも便利そうだなー,とか.
HexファイルがROMに書き込み終わるとFPGAがROMからイメージを読んで動作を開始します.
ボード上のオシレータ出力をFPGAに供給するためのJ27のジャンパをはずしみてると,内蔵オシレータでまわしているカウンタに対応したLEDだけが点滅する様子を楽しめます.また,オンボードクロックを供給している状態で,SW2を押すとPLLにリセットがかかって対応するLEDの点滅が止まる様子が確認できます.
Trion 8のカウンタってどのくらいで動くのかな?
合成後のレポートをみてみると,
Maximum possible analyzed clocks frequency
Clock Name Period (ns) Frequency (MHz) Edge
clk 7.615 131.320 (R-R)
pll_clk 12.095 82.679 (R-R)
osc_inst1 4.719 211.921 (R-R)
という結果が表示されていました.あれ?あんまり動作周波数高くできない??というわけで,カウンタのサイズを振って動作周波数を見てみました.とりあえずこんな感じのコードで COUNTER_WIDTH
を変えて試してみることにします.
`define COUNTER_WIDTH 32
reg [`COUNTER_WIDTH-1:0] counter;
always @(posedge clk) begin
counter <= counter + 1;
end
assign led[4] = ~counter[`COUNTER_WIDTH-1];
結果は次の通り.
びっくりする程遅いというわけでもないけど,なるほど,こんなものかー,という感じ.ちなみに,どんな感じに配置されるのか,View Floorplanで見てみた.8bitカウンタのときはこんな感じで
32bitカウンタのときはこんな感じ.
データシートみてみると,ひとつのLogic Cellは4入力LUTとFF,Adderから構成されるている.ということで,納得の結果ですね.
おわりに
というわけで,EfinixのFPGA,Trion 8で遊んでみました.次は,Latticeとの使い勝手を比較してみる,かなあ.
また,IPカタログをみてみると,Processor and Peripherals
っていうグループに,Sapphire SoCなどのVexRiscvなSoCっていうソフトコアがならんでいるのも気になるので,試してみたいところです.