Trion FPGA コンフィギュレーション方法
Efinix社のTrion FPGAをコンフィギュレーションするにあたっての情報です。
Efinix社は2024年現在、公式でダウンロードケーブルを提供していません。
FTDI社のデバイスを用いるようにドキュメントに記載があります。
しかし、FTDIのデフォルトのUSB VID/PIDを使用する前提での開発環境が提供されているため、別途FTDIデバイスを使用したい場合にドライバ周りで面倒なことになります。
(USB機器は判別のためにベンダーIDとプロダクトIDという決まり事があり、ID取得のためには最低でも100万円近い金額が発生します)
こういうことはメーカー側でUSBのベンダーIDを用意し、公式ダウンロードケーブルを用意するなど何かしらケアをしてほしいのですが、提供されていない以上は使用者側で何とかするしかありません。
かなり時間がかかりましたが、何とかすることが出来ましたので皆さんに紹介します。
Efinity IDE・Programmerのインストールについて
Efinix社のFPGA開発環境のインストールからおさらいしましょう。
サポートセンターにアカウントを作成済みで、Efinity IDEがダウンロード出来る状態で話を進めます。
(アカウント登録すれば無料でダウンロードできるのでまず最初にアカウントを作成しておきます)
Efinity IDEのインストール方法
2024年03月時点、最新のEfinity IDE Full Release(Version: 2023.2.307)をダウンロードしてインストールを開始します。
インストール方法についてのPDFファイルを確認すると、Visual C++ 2019 x64 再頒布可能パッケージが必要とあるので、事前に入れておきます。
Efinity IDEのインストーラーを起動して、インストールを進めます。
デフォルトのまま進めると「C:\Efinity\2023.2」にインストールされます。
Efinity IDEパッチのインストール方法
最新状態にするためのパッチを適用します。
現時点でのバージョンはEfinity Patch(Version: 2023.2.307.2.17)です。
Readmeに従うと、環境変数をセットしてからrun.batを実行しろとあります。
コマンドプロンプトを起動し、「C:\Efinity\2023.2\bin\setup.bat」を実行(環境変数がセットされます)。
その後、ダウンロードしたパッチのrun.batを続けて実行します。
FTDIデバイスのドライバとZadigの関係
Efinity IDEのプログラマがサポートしているチップについて以下に示します。
- FT232H
- FT2232H
- FT4232H
- AT90USB162(一部評価ボードに搭載されています)
ファームウェアのプログラムが必要なAT90USBは除外するとして、FTDI社のUSBシリアル変換チップが利用可能です。
その中でも、FT232Hは使えるチャンネル数が1、FT2232Hは2、FT4232Hが4となっています。
SPIモードでのプログラム(フラッシュにコンフィギュレーションデータを書く)用途では1チャンネルしか必要ありません。
しかし、JTAGモードでT4から一部のT20までのTrion FPGAを使用するには、JTAGの信号線に加えてSPIモードの一部信号線が必要で、合計2チャンネル必須となります。
(AN 006: Configuring Trion FPGAs PDF内、41ページ参照)
よって、JTAGモードも配慮すると、使用可能なUSBシリアル変換チップはFT2232Hまたは、FT4232Hに絞られます。
FT2232Hのボード
以上のことから、FT2232Hをダウンロードケーブルとして使用することにします。
- ストロベリー・リナックス - FT2232H(2ch)高速USBシリアル変換モジュールキット
- マルツオンライン - FTDI Chip 通信 / ワイヤレス開発ツール、FT2232H MINI MODULE【FT2232H-MINI-MODULE】
- RS - FTDI Chip 開発ボード FT2232H MINI MODULE
- Digikey - FT2232H MINI MODULE
- Mouser - FT2232H MINI MODULE
- ノーブランドのFT2232H開発ボード(AliExpressやAmazon等)
- 自作のFT2232Hボード
このどれかを使用することになると思われます。
Zadigでのドライバ入れ替え
USBドライバのインストール支援のフリーソフト、Zadigを使用することと公式のドキュメントに記載があります。
Efinity Programmerではlibusb-win32(汎用ドライバ)を使用する前提の設計になっています。
それ以外のドライバ(FTDIのVCP/D2XXドライバ)が当たっているとダウンロードケーブルの認識がされません。
そのため、Zadigでドライバを入れ替える必要がありますが、ここで1つ問題が起きます。
FTDI社のチップは汎用的に良く使われます。
ドライバを入れ替えてしまうと他にFT2232Hが使用されている製品等を使用するときに認識されなくなる問題が起こります。
WindowsにはFTDIのVCPドライバが収録されているために、FT2232Hの初回接続時には、FTDIのVCPドライバが当たりシリアルポートが2チャンネル見える状態になります。
それをZadigでlibusb-win32ドライバに入れ替える、ということです。
他のFT2232Hを接続すると、同様にlibusb-win32ドライバが当たってしまい、本来の2ポートシリアルとしての動作は不可能です。
ZadigでVCPドライバが当たったFT2232Hにlibusb-win32を当てる方法
Zadig を使用してドライバを入れ替えます。
「Options」→「List All Devices」にてすべてのデバイスを一覧表示。
「Dual RS232-HS」に対して「libusb-win32 (v1.2.7.3)」を適用。
「Replace Driver」ボタンを押してしばらく待ちます。
libusb-win32ドライバが当たったFT2232Hを標準のFTDI VCPドライバに戻す方法
デバイスマネージャーからドライバーを削除する必要があります。
libusb-win32 devices内に表示されているデバイスを全てアンインストールします。
アンインストール時のダイアログで「このデバイスのドライバーを削除しようとしました。」にチェックを入れないとドライバが削除されません。
必ずチェックを入れてアンインストールします。
デバイスを抜き差しすれば、ドライバが当たっていない状態になるはずです。
複数のドライバを過去に当てた場合は、順にそのドライバが当たる可能性があります。
標準のFTDIドライバに戻るまで上記操作を繰り返す必要があります。
Zadigを使用して「USB Serial(CDC)」ドライバに入れ替えても、標準のFTDIドライバに戻るわけではありません。
FT2232Hに搭載されているEEPROMについて
以上のことを踏まえると、尚更、Efinix社がUSBのベンダーIDを取得し、ダウンロードケーブルを用意していれば解決することと思われます。
FTDIのデフォルトのVID/PIDをそのまま利用していることに問題があるのです。
FT2232HではEEPROMを接続すると、カスタム値のVID/PIDを始めとして設定値を保存できるようになります。
よって、デフォルトのVID/PID以外のデバイスとして振る舞うことが出来るということです。
なぜデフォルトのVID/PIDを使用しているか?
これはドライバ署名の関係があると思われます。
一部の評価ボードではFT4232Hを採用し、SPI/JTAGポート以外にUARTのポートを用意しています。
ドキュメントを見ると、そのポートのみFTDI社のドライバを適用し、それ以外のドライバを入れ替えるとあります。
デバイスのVID/PIDを変更してしまうと、そのVID/PIDに対応したドライバが必要になります。
この際、ドライバ署名が無いとインストールが非常に厄介になり、ドライバ署名を行うにもお金がかかるためデフォルトの状態で使用しているものと思われます。
FT_PROGって何?
こちらからダウンロード出来る、FTDI社の設定変更ユーティリティです。
EEPROMを搭載したFTDI社のデバイスの設定を変更してプログラムすることが出来ます。
このソフトウェアを使用するとVID/PIDを変更することが出来ます。
注意点としては、FTDIのドライバが当たっている状態でないと通信できないということです。
そのため、VID/PIDの変更は慎重にやらないといけません。
もし、間違った値を設定した等で戻す必要がある場合は、FT_PROGに認識される状態に持っていく必要があります。
EEPROMを外してデフォルトのVID/PIDにするか、変更したVID/PIDに対応するFTDIドライバを作成してインストールする方法です。
FTDIドライバを作成する場合、ドライバ署名が無いとインストールすることが出来ません。
ドライバ署名は年間10万円前後のお金がかかるので一時的に使用するためにドライバ署名することは現実的ではありません。
OS自体の設定で、ドライバ署名を強制しない設定に変更することもできますが、セキュリティレベルも下がるためオススメはしません。
EEPROMを外してデフォルトのVID/PIDで起動した後、電源が入ったままでEEPROMを接続して書き換えるという手法が一番簡単かもしれません。
93LC46Bに対応したEEPROMライターをお持ちであれば、イレースして設定値を全て消し、再度EEPROMを取り付けるという手法も取れると思います。
私は、XGecu T56で実験しました。
もしくは、何も値が書き込まれていない新品のEEPROMに付け替えるという方法でも良いかもしれません。
Efinity IDE・Programmer 内部動作の詳細について
Efinity IDE また、内蔵されているProgrammerに関して、珍しいことにPythonでソフトウェアが書かれています。
「C:\Efinity\2023.2\pgm\bin\efx_pgm\efinity_pgm.py」がプログラマの本体です。
Pythonで書かれているので、適当なテキストエディタで開いて、内部のプログラムを見ることが出来ます。
「C:\Efinity\2023.2\bin\efinity_pgm.bat」にもあるように、環境変数をセットした後、Pythonに「efinity_pgm.py」を渡すことでプログラマの起動が可能です。
実際にソースコードを読んで解説している方もいます。
HiFTDI(eblot/PyFtdiフォーク)での動作
FTDI社のデバイスをPythonから叩くために、PyFtdiというライブラリを使用しているようです。
フォークしてHiFTDIという名前で「C:\Efinity\2023.2\pgm\bin\efx_pgm\hiftdi」に収録されています。
基本的に、PyFtdiの説明がそのまま適用できます。
こちらを見ると、任意のVID/PIDを登録できそうです。
usb_resolver.pyでの動作
PyFtdiライブラリはあくまでも利用しているライブラリの意味しか持っていません。
実際の処理は「C:\Efinity\2023.2\pgm\bin\efx_pgm\usb_resolver.py」に書かれています。
このPythonスクリプトでは、使用するVID/PIDのペアを事前にリスト化しているため、任意のVID/PIDを利用するにはここも何とかしないといけません。
ボードプロファイル
FTDIチップが乗った様々な開発ボードなどが提供されているため、ボードごとのプロファイルの仕組みがあるようです。
「C:\Efinity\2023.2\pgm\bin\efx_pgm\efx_hw_common\boards」以下にあるJSONファイルでFTDIの動作ピンの指定などをしているようです。
任意のVID/PIDを利用するにはプロファイルを作成する必要があります。
USBのベンダーIDに関して
では、何か使えるUSBベンダーIDは存在するのか?
このようなものが見つかります。
FTDI社でもPIDの割り当てを行っているようなのですが、生産計画を持ったある程度大きなプロダクトを想定しているようです。
Efinix ダウンロードケーブルの作成
これまでの情報を踏まえて、Efinix ダウンロードケーブルを作成しました。
以下のページをご覧ください。
実際の書き込み波形
FTDIを使用した際に、データバスを確認してみました。
SPIアクティブモードでの波形。FTDIと直接繋いだ場合の波形につき、FTDI内部のプルアップが存在しています。
JTAGモードでの波形。FTDIと直接繋いだ場合の波形につき、FTDI内部のプルアップが存在しています。
Trionボードの作成方法
ボードの作成にあたり、プログラミング周りの配線についてメモをしておきます。
基本の回路になります。
SPI Passiveって何?
FPGAの側がROMに対して読み込みに行くのではなく、外部からFPGAに書き込まれるためのモードです。
テストしたコード類はこちらに置いてあります。
マイコンからFPGAの書き込みができるようになります。
SPI Passiveを考慮に入れたプログラミング周りの配線
もし、マイコンから書き込み動作をするSPI Passiveモードでの実装を考慮にいれる場合、FTDI_RST信号を使う必要があります。
マイコンからのプログラミング線をハイインピーダンスで切り離す必要があります。
でないと、外部からのプログラマーが使用不可になってしまいます。また、マイコンからの信号とプログラマーからの信号がぶつかるため、ショートの原因になります。
FTDI_RSTはプログラマー側でGNDに落とされていることが期待されます。
FPGAボード側ではプルアップしておき、FTDIを実装する場合にはRESETに、そうでない場合はバスを切り離す実装にしないといけません。
FTDIはRESET状態のときは弱プルアップが内蔵されたハイインピーダンス状態となります。
しかし、マイコン等でSPI Passiveを利用する場合には、プログラマーが接続されたタイミングで確実にバスを開放できるでしょうか?
ロジックICを使用して確実にバスを切り離す実装を考えてみたいと思います。
バスを切り離すためには3ステートバッファ等を用いて、ハイインピーダンスにする必要があります。
3.3Vしかない環境であれば、SN74LVC244APWR等の3ステートバッファで安価に実装するか、IO電圧が違う場合には、SN74AVC4T774PWRを使用しても良いと思います。
プログラマー接続のヘッダにはFTDI_RSTの信号がありますので、これを利用するのが良いでしょう。
FTDI_RSTがGNDに落とされたときにプログラマーが接続されていますから、そのときには必ずバスを開放します。
それ以外の書き込み時には、マイコンに接続されるような回路です。
SN74AVC4T774PWR を2個使用してレベル変換とバスの切り離しを行う回路の例です。
DIRは信号の方向を設定してあり、MCU_の表記があるものがマイコンに繋がるイメージとなっています。
OEを制御することによって、バスを開放することができますが、プログラマーの接続タイミングはマイコン側での書き込み動作は考慮しません。
つまり、マイコン側でプログラマーが接続されているかどうか判定をしておく必要があります。
また、マイコンから書き込み動作をする場合にのみ接続したいため、マイコン側からその信号も得る必要があります。
そこで、SN74LVC1T45DBVR を2個使用します。
SN74LVC2G07DBVR にプログラマー接続の信号(DETECT)と、マイコンからの書き込み有効信号(ENABLE)を入力します。
これは、オープンドレインのバッファのため、出力をプルアップして束ねることができます。
出力信号を(CONF)として真理値表を書くと以下のようになるでしょう。
DETECT | ENABLE | CONF |
---|---|---|
0(接続) | 0(有効) | 0 |
0(接続) | 1 | 0 |
1 | 0(有効) | 0 |
1 | 1 | 1 |
アクティブLOWのワイヤードOR(アクティブHIGHのワイヤードAND)ということになります。
DETECTがアクティブLOWなのは回路の都合上仕方なく、揃えるとENABLEもアクティブLOWにするのが扱いやすいと思います。
この出力(CONF)にNOTをつなげると、OEを駆動することができます。
SN74LVC2G14DBVR でのNOTを挟むと、出力(OE)として以下のような真理値表になるでしょう。
DETECT | ENABLE | CONF | OE |
---|---|---|---|
0(接続) | 0(有効) | 0 | 1 |
0(接続) | 1 | 0 | 1 |
1 | 0(有効) | 0 | 1 |
1 | 1 | 1 | 0 |
SN74AVC4T774PWR は OE が HIGH のときに出力がHi-Zになります。
つまり、アクティブLOWでの、DETECTとENABLEに対して、バスの切り離しが実現できます。
プログラマーが接続されたとき(DETECT:0)と、マイコンから書き込みするとき(ENABLE:0)に、OEが1となり、バスが切り離されます。
ENABLEはアクティブLOWになるため、マイコンの起動時を考えるとレベル変換前のマイコン側でプルアップしておいたほうが良さそうです。
レベル変換を入れない例です。
FPGAもMCUも3.3Vで駆動する回路例です。
マイコンのSPIバスを使用した際に念の為切り離せるように間に3ステートバッファを入れてあります。
また、前述の通り、OE制御のために SN74LVC2G07DBVR と SN74LVC2G14DBVR を入れてあります。
SN74LVC2G14DBVR の余ったゲートに対して、DETECT信号を入れているので、マイコン側ではアクティブHIGHでプログラマー検出の信号が使えます。
SPIパッシブモードでのプログラム方法をドキュメントで確認すると、CCK, CDI0, CDONE, CSI, CRESET_Nの5本の信号線でやりとりしています。
CDI1の配線は念の為入れているだけで実際には必要ないでしょう。
(SPIで読み出す必要性が出てくれば使用するとは思います)
また、SS_Nを入れているのは、SPIアクティブモード、SPIパッシブモードの切り替えのためです。
どちらかのモードしか使用しないのであれば、ドキュメントの通りにプルアップまたはプルダウンで固定してしまって良いと思われます。