Trion FPGA Windows11チュートリアル
EfinixのTrion FPGAをWindows11で開発する一連の流れについてです。
現在最新のWindows11上で開発をしてみましょう。
- Trion® FPGA
- T8F81C-DK
- Efinix Trion 8 Development Kit で遊んでみる
- Efinix Trion T20 Development Kitで遊んでみた所感
基板設計方法
T8Q144I4を使用する前提で考えます。
基本的には1.2Vと、3.3Vの電源があれば動作します。
※ (PDF)データシート 48ページ参照
ピン名 | ピン番号 | 概要 |
---|---|---|
GND | 1 | GNDに接続 |
GND | 5 | GNDに接続 |
GND | 9 | GNDに接続 |
GND | 37 | GNDに接続 |
GND | 44 | GNDに接続 |
GND | 50 | GNDに接続 |
GND | 64 | GNDに接続 |
GND | 94 | GNDに接続 |
GND | 104 | GNDに接続 |
GND | 108 | GNDに接続 |
GND | 120 | GNDに接続 |
GND | 121 | GNDに接続 |
GND | 126 | GNDに接続 |
GND | 127 | GNDに接続 |
GND | 129 | GNDに接続 |
GND | 133 | GNDに接続 |
VCC | 13 | 1.2Vに接続 |
VCC | 22 | 1.2Vに接続 |
VCC | 49 | 1.2Vに接続 |
VCC | 57 | 1.2Vに接続 |
VCC | 85 | 1.2Vに接続 |
VCC | 96 | 1.2Vに接続 |
VCC | 125 | 1.2Vに接続 |
VCC | 128 | 1.2Vに接続 |
VCC | 130 | 1.2Vに接続 |
VCCA_BR | 73 | 1.2Vに接続・PLL電源 |
VCCA_TL | 2 | 1.2Vに接続・PLL電源 |
VCCA_TR | 107 | 1.2Vに接続・PLL電源 |
VCCIO1A | 23 | 3.3Vに接続 |
VCCIO1B | 21 | 3.3Vに接続 |
VCCIO1C_1D | 12 | 3.3Vに接続 |
VCCIO1E | 143 | 3.3Vに接続 |
VCCIO3A | 122 | 3.3Vに接続 |
VCCIO3B_3C | 95 | 3.3Vに接続 |
VCCIO3D | 91 | 3.3Vに接続 |
VCCIO3E | 88 | 3.3Vに接続 |
VCCIO4A | 62 | 3.3Vに接続 |
VCCIO4A | 63 | 3.3Vに接続 |
VCCIO4B | 51 | 3.3Vに接続 |
VCCIO4B | 52 | 3.3Vに接続 |
PLL電源はアナログなので、デジタルの1.2Vとは分けるべく、フェライトビーズを経由して供給しています。
TL: Top left, TR: Top right, BR: Bottom rightと場所を示しているようです。
REF_RES(36ピン)には12kΩ±1%の抵抗を接続し、GNDに落としておきます。
LVDSトランスミッターを使用する際に必要になります。
その他、書き込み関係で必要なピンは次のセクションを参考にしてください。
書き込み回路
FPGAは起動時に回路が定義されている情報のビットストリームを読み込んで、その回路へとコンフィギュレーションを行います。
CPLDや、FPGAでもIntelのMAX 10などは、コンフィギュレーションROMが内蔵されているため、外付けする必要はないのですが、 Trion FPGAではコンフィギュレーションROMを外付けする必要があります。
Trion FPGAがSPIマスター(SPI Activeモード)となり、起動時にSPIスレーブのROMからビットストリームを読み込みます。
今回はSPIフラッシュとして W25Q16JVSSIQ を使用。
T8Q144I4ではビットストリームサイズは「5,255,968 bit + 1k byte Header」が最大になるので、8Mbit程度のフラッシュでも問題ないのですが、RP2040など他の用途に転用も考え、16Mbitのフラッシュを選定しています。
ビットストリームの書き込みはSPIバスを使用するのが手っ取り早いです。
JTAGモードや、SPIスレーブ(SPI Passiveモード)での使用もできますが、ひと手間かかりますので解説はしません。
(SPI Passiveモードに興味があればこちらをどうぞ: Efinix SPI Passive Mode Arduino Programmer)
SPIバスへのインターフェースは、FT232H, FT2232H, FT4232Hが想定されているようです。
秋月電子通商から発売されている 「FT232HL ハイスピードUSBシリアル変換モジュール」 を使用することとします。
(追記)Efinix ダウンロードケーブルを作成しました。
ちなみにリセットピン(CRESET_N)の挙動がかなり怪しいです。
T20等の評価ボードの回路図を見ると、324kΩでプルアップし、10uFのコンデンサもGNDに対して2個並列に入っています。
100kΩプルアップで、10uFのコンデンサで落とすぐらいでは、うまくリセットがかからず起動してきませんでした。
FTDI経由で書き込みを行った場合には必ず上がってはくるのですが、単体で電源をいれるとリセットがうまくかからないような挙動です。
ちなみに、FTDIとも、CRESET_NとCCKを接続しっぱなしにしておくと、電源を入れただけではうまく上がってこないような挙動でした。
(追記)回路詳細に関してはこちらにまとめました。
Trion FPGA(T8Q144I4)のピン接続先
SPI Active(x1)モード時
※ (PDF)データシート 49ページ参照
ピン名 | 方向 | ピン番号 | 概要 |
---|---|---|---|
CDONE | I/O | 34 | 抵抗に接続し、プルアップしておく |
CRESET_N | Input | 35 | 抵抗に接続し、プルアップしておく・リセットに接続 |
TCK | Input | 26 | 抵抗に接続し、プルアップしておく |
TMS | Input | 25 | 抵抗に接続し、プルアップしておく |
TDI | Input | 27 | 抵抗に接続し、プルアップしておく |
TDO | Output | 24 | 抵抗に接続し、プルアップしておく |
CBUS2 | Input | 80 | 抵抗に接続し、プルアップしておく |
CBUS1 | Input | 79 | 抵抗に接続し、プルアップしておく |
CBUS0 | Input | 78 | 抵抗に接続し、プルアップしておく |
CCK | I/O | 30 | 抵抗に接続し、プルアップしておく |
CDI0 | Output | 29 | 抵抗に接続し、プルアップしておく |
CDI1 | Input | 28 | 抵抗に接続し、プルアップしておく |
CSI | Input | 32 | 抵抗に接続し、プルアップしておく |
CSO | Output | 33 | 未接続 |
NSTATUS | Output | 136 | 未接続 |
SS_N | Input | 31 | 抵抗に接続し、プルアップしておく |
TEST_N | Input | 74 | 抵抗に接続し、プルアップしておく |
SPIフラッシュ(W25Q16JVSSIQ)のピン接続先
ピン名 | 方向 | ピン番号 | 概要 |
---|---|---|---|
CS | Input | 1 | Trion FPGAの SS_N に接続(Trion側でプルアップ済み) |
DO | I/O | 2 | Trion FPGAの CDI1 に接続(Trion側でプルアップ済み) |
WP | I/O | 3 | 抵抗に接続し、プルアップしておく |
GND | Power | 4 | GNDに接続 |
DI | I/O | 5 | Trion FPGAの CDI0 に接続(Trion側でプルアップ済み) |
CLK | Input | 6 | Trion FPGAの CCK に接続(Trion側でプルアップ済み) |
HOLD | I/O | 7 | FT232Hの AD6 への接続に加え、抵抗に接続し、プルアップしておく |
VCC | Power | 8 | 3.3Vに接続 |
FT232Hのピン接続先
ピン名 | 方向 | 概要 |
---|---|---|
AD0 | Output | Trion FPGAの CCK に接続(Trion側でプルアップ済み) |
AD1 | Output | Trion FPGAの CDI0 に接続(Trion側でプルアップ済み) |
AD2 | Output | Trion FPGAの CDI1 に接続(Trion側でプルアップ済み) |
AD3 | Output | Trion FPGAの SS_N に接続(Trion側でプルアップ済み) |
AD4 | Output | Trion FPGAの CRESET_N に接続(Trion側でプルアップ済み) |
AD5 | Input | Trion FPGAの CDONE に接続(Trion側でプルアップ済み) |
AD6 | Output | SPIフラッシュの HOLD に接続(フラッシュ側でプルアップ済み) |
GND | Power | GNDに接続 |
JTAGモードでの接続の場合は、TCK, TDI, TDO, TMSの4本に加え、CRESET_N, SS_Nが必要になるようです。
開発環境の整備
Trion FPGAの開発を行うには、Efinixより提供されているEfinity IDEというソフトウェアを使用します。
開発キットの裏面には1年間有効なライセンスコードが付属しています。
私はEfinixにアカウントを作成し、開発キット裏面のコードを使用しました。
現在はフォームからユーザー登録すれば無償で使えるようです。(詳細)
今回は2023年5月時点で最新の Efinity IDE 2022.2.322を使用していきます。
プロジェクト作成から書き込みまで
一連の流れを試してみましょう。
参考:Example Design: Trion T8 BGA81 Tutorial
(追記)下記手順でデフォルト設定のFTDIデバイスに対するドライバを書き換えてしまうため、別デバイスとしてのEfinix ダウンロードケーブルを作成しました。
ドライバインストール(T8Q144I4 + FT232H)
Zadig を使用してドライバを入れ替えます。
「Options」→「List All Devices」にてすべてのデバイスを一覧表示。
「Single RS232-HS」に対して「libusb-win32 (v1.2.6.0)」を適用。
「Replace Driver」ボタンを押してしばらく待ちます。
ドライバインストール(Trion 8 BGA81評価ボード)
Zadig を使用してドライバを入れ替えます。
「Options」→「List All Devices」にてすべてのデバイスを一覧表示。
「AVR USB HID DEMO」に対して「libusbK (v3.1.0.0)」を適用。
「Replace Driver」ボタンを押してしばらく待ちます。
新規プロジェクト作成
Efinity Softwareを起動し、「Flie」→「Create Project」の順にクリック。
Nameでプロジェクト名を指定する。
プロジェクトの場所はデフォルトで「$EFINITY_HOME/project/new_project」となるので任意の場所に移動する。
Efinity IDE 2022.2.322でのデフォルトの場所は「C:\Efinity\2022.2\project\new_project」
Projectタブで使用するFPGAの種類に応じてFamily, Device, Timing Modelを編集する。
Trion 8 BGA81評価ボードであれば、Trion, T8F81, C2を指定。
今回は、T8Q144I4を使用するため、Trion, T8Q144, I4を指定。
DesignタブではTop Module/Entityと使用するファイルなどを指定する。
とりあえず今回はTop Module/Entityに「test_top」と入力。
新規プロジェクト作成完了。
Verilog HDLファイルの追加
作成したプロジェクト内のDesignを右クリック、「Create」にてVerilog HDLファイルを追加します。
今回はVerilog Design Fileを選択します。 VHDL等、他の言語を使用したい場合は、別のFileTypeを選択します。
プロジェクトのDesign内にファイルが追加されます。
ダブルクリックでコードエディターが開きます。
module test_top (
input SW,
output LED
);
assign LED = ~SW;
endmodule
適当にこんな記述をしてみました。
ピン配置
Interface Designerで宣言を行います。
「Tools」→「Open Interface Designer」の順にクリックし、Interface Designerを開きます。
GPIOを右クリックし、「Create Block」で単体のIOを追加します。
複数本あるバスを追加する場合は「Create Bus」を使用します。
先程のVerilog HDL記述だと、SWとLEDという信号名を使用していますので、「Create Block」を2回行っておきます。
追加したBlockの信号名を変えます。
SWとLEDという信号名にします。
それぞれ、input / output に設定します。
「Design」→「Check Design」を実行してみましょう。
Resource name is empty.というエラーメッセージが出ます。
これは信号名だけ宣言して実際のピンアサインを定義していないためです。
「Design」→「Show/Hide GPIO Resource Assigner」の順にクリックし、GPIO : Instance Viewを表示します。
定義された信号に対して、Resource欄で実際のピンをアサインしていきます。
これらのピン定義は「File」→「Export Design」でisf/csvファイルとしてエクスポートしておくことも可能です。
プロジェクト内には保存されますので、Saveで保存しておきましょう。
未使用ピンの処理
デフォルト設定ではプルアップされるようです。
Interface Designer内にて設定可能です。
プルアップもしくはプルダウンを選択可能で、デフォルトではプルアップです。
しかし、Interface Designer中、GPIOでinputに指定するとプルアップ無しがデフォルトになっています。
状況に応じて忘れずにPull Optionにて設定しておきましょう。
書き込み
「Flow」→「Synthesize」から論理合成処理をしておきましょう。
(dashboardと書かれている横のボタン「Toggle Automated Flow」が有効もしくは、「Flow」→「Single Step Flow Run」が無効になっているとGenerate Bitstreamまで全部進む)
「Tools」→「Open Programmer」にてプログラマーを開く。
生成されたhexファイルを指定して、「Start Program」ボタンを押すとプログラムが開始される。
これで動作するはずです。
PLLの使い方
Efinix FPGAではInterface DesignerでPLLの設定をします。
T8Q144I4にはAdvanced PLLが5個搭載されています。
※ (PDF)データシート 24ページ参照
Interface Designer中、PLLを右クリックし「Create Block」にてAdvanced PLLを追加します。
PLL Resourceを選択、今回は「PLL_BR0」にします。
Clock Sourceはexternalで、External Clock 1を使用することにします。
ResourceにGPIOR_157と表示されますが、インスタンスを生成していないので、Instanceには何も表示されず結線されていません。
GPIOを右クリックし「Create Block」にてインスタンスを追加することにします。
Instance Nameは適当に「PLL_CLKIN」としました。
Modeはinputのままで、Connection Typeを「pll_clkin」とします。
Resource Assignerで実際のピンをアサインしておきます。
これにてPLLのクロック入力に接続することができます。
出力ピンも「OUT」として作成しておきます。
PLLを確認するとInstanceに先程作成した「PLL_CLKIN」が追加されていると思います。
PLLの出力名、周波数を決めるために先程作成したPLL中の「Automated Clock Calculation」ボタンを押して設定します。
「PLL Clock Calculator」が表示されるので、Input Frequency、Clock 0 Frequency、信号名を入力します。
PLLの入力はExternalとしたので、ピンに接続されている水晶発振器の周波数(この基板は60MHz)を入力します。
Clock 0の出力周波数は10MHzとし、「pll_out」という信号名にしました。
Manual Modeで手動で分周比を設定することもできます。
Interface DesignerはSaveしておきます。
module test_top (
input pll_out,
output OUT
);
reg [3:0] counter;
always @(posedge pll_out) begin
counter <= counter + 4'b0001;
end
assign OUT = counter[0];
endmodule
10MHz(pll_out)から分周してOUTに出力する例です。
reg [3:0]にて4bit幅のカウンターを準備しています。
pll_outのクロックごとに4'b1(4bit幅の"1")を加算しているため、1クロックごとに最下位ビットは0と1を反転動作になります。
そのため、assignにてcounter[0](最下位ビットの0)を当てているため、10MHzから分周された5MHzの出力として観測されるでしょう。
counter[1]をアサインすれば、2.5MHzの出力。
counter[2]をアサインすれば、1.25MHzの出力。
counter[3]をアサインすれば、625kHzの出力。
この例では4bit幅のカウンターしか用意していないためここまでの分周となりますが、それ以上ほしい場合はビット幅を多く取れば良いです。
PLLの出力をそのままピンに出力する場合は、Interface DesignerでGPIOを設定します。
Modeをclkoutにし、Output ClockのPin Nameに「pll_out」と、出力したい信号名を記述します。
Resource Assignerにて出力ピンの設定も忘れずに。
すると、PLLの出力がそのままピンに出力されていきます。
Advanced PLLでは3出力あり位相も設定できるため、ピンに出力して各種クロック源として使用することができます。
LVDSの使い方
参考:Trion® Interfaces User Guide
LVDSのペリフェラルにはシリアライザーが内蔵されています。
ビット数は2~8の間で設定できるようです。
そのため、8bitまでのデータ列で良いのであれば、パラレルで一気に入出力できるようです。
基本的にはInterface DesignerでLVDSを追加することと、PLLの設定をすれば使用できます。
LVDSで使用できるピンは決められているので注意してください。
LVDS TX 8bit出力例
シリアルクロックとしては、シリアライザーのビット数÷2の値を掛けた周波数を入力すれば良いようです。
そのため、シリアルクロック1周期にて2bit分のデータが出ていくイメージです。
デフォルト設定の8bit幅の場合、例えば40MHzで速度でLVDSを出力したい場合は、SlowClock(パラレルクロック)は5MHz(40MHz/8bit)に設定する必要がありますが、FastClock(シリアルクロック)は90°位相をずらした上で20MHz(5MHz*(8bit/2))にする必要があるようです。
シリアライザーがシリアル化して送ってくれるので、記述はパラレルクロックに同期して記述すればOKです。
例としてシリアライザーが8bit設定時に「0b10000000」を繰り返し出す記述例です。
module test_top (
input pll_slow,
output [7:0] TX_DATA
);
reg [7:0] out_data;
always @(posedge pll_slow) begin
out_data <= 8'b10000000;
end
assign TX_DATA = out_data;
endmodule
LVDS TX 5bit出力例
8b10b等で10bitを出力したい場合としてシリアライザーを使う前提で5bitを2回ずつ出力する例です。
この場合、例えば40MHzで速度でLVDSを出力したい場合は、SlowClock(パラレルクロック)は8MHz(40MHz/5bit)に設定する必要があり、FastClock(シリアルクロック)は90°位相をずらした上で20MHz(8MHz*(5bit/2))にする必要があります。
module test_top (
input pll_slow,
output [4:0] TX_DATA
);
reg [4:0] out_data;
reg out_flip;
always @(posedge pll_slow) begin
if(out_flip) begin
out_data <= 5'b10000;
end
else
begin
out_data <= 5'b00000;
end
out_flip <= !out_flip;
end
assign TX_DATA = out_data;
endmodule
LVDS TX 1bit(シリアライザー未使用)出力例
シリアライザーを使わずに出力する方法です。
単純にLVDSトランスミッターとして使用できます。
この場合では、40MHzで速度でLVDSを出力したい場合、40MHzのクロックを使用する必要があるので、PLLをそのように設定します。
位相はずらす必要はありません。
Interface Designer中のLVDSにて、「Enable Serialization」のチェックを外します。
シリアライザーを動作させないためクロックは指定しません。
チェックを外した状態ではそもそもクロック入力が不可能になりますが、Serial ClockとParallel ClockのPin Nameが指定されたままの状態だとエラーになることがあるので、必ずPin Nameの記述を削除した上でシリアライザーを無効にする必要があります。
こういうところだぞ、Efinix!
module test_top (
input pll_out,
output TX_DATA
);
reg [3:0] counter;
always @(posedge pll_out) begin
counter <= counter + 4'b0001;
end
assign TX_DATA = counter[1];
endmodule
1/4周期でトグルする例です。
シリアライザーが無効なので出力は1bitです。
LVDS RX
LVDSレシーバーを使用する際、リファレンスクロックとしては、PLL_BR0が割り当てされています。
クロックデータリカバリ(CDR)が無いため、基本的にはPLL_BR0にクロックを入れて使用するか、自前でCDRを実装するかになると思います。
自前でCDRを実装する場合には、デシリアライザーに入れられると面倒かと思うので、デシリアライザーを無効にした例だけを示します。
100Ωの終端抵抗がオンダイで有効にできるようです。
SFP等で使用する場合はバイアス抵抗だけで良さそうですね。
上記の設定であれば input RX_DATA みたいにして入力させればOKです。
もちろん、デシリアライザーを有効にする場合は、LVDS TXと同様にPLLの設定をする必要があります。