2011年07月02日

FPGAライタの設計(3)

もはや FPGAライタというのは適切ではないのだが、前タイトルを継承して続ける。

いままでの経緯

    ARTEMIS ボードを設計し、その上で動かすなにか.. を考えて AVR互換コアを設計してきた。AVR互換コアは出来上がったのだが、ARTEMIS ボードの JTAG インターフェイスは特殊で それを扱うツールもまた作らなくてはならない。

    それは想定内だったのだが、『MachXO 2280 Breakout ボード』 を最初のターゲットに変更したので、サポートする内容が随分増えた。

      MachXO 2280 Breakout ボード』は、安価なだけでなく、安易に使える。rtavr のリファレンス・ボードとして使えると思ったのが変更した理由。

      ボードもツールも信用できない状況でデバッグするのは、苦痛なので 確実に動作するボードが欲しかったのだ。

      ここで、Xilinx を選ばないというのには理由がある。MachXO2 に興味が出てきたので、将来サポートしたいと思っていた。幅広いデバイスに対応できるようにツールを設計する必要が出てきたので、最初から タイプの違う 2 種類のデバイスをサポートして 後々困らないようにするのが、狙い。

    さて、最低限必要な機能は以下のもの

    • (AE-UM232R の) BitBang で Spartan-3/6 に Config できる。
    • BitBang を使った JTAG通信で(Spartan-3/6 に接続された )SPI_FLASH に書き込める。
    • BitBang を使った JTAG通信で rtavr のデバッグができる。(ISP と シリアルのような通信)

    Config できることは、ARTEMIS ボードのみ必須。JTAG通信で 設計した回路と通信できることが重要で、それはターゲットが変わっても変わらない。

    あと、いろいろなファイルをいろいろな方法で 送り込む必要がある。(Config と SPI_FLASH と ISP) この操作方法は統一感があるようにしたい。

現状

  • rtavr_tools-0.2.tar.gz

    これが今できているものの一式

  • 設定ファイルの読み込み
  • ft245r/ft232r の BitBang Cable ドライバ (FT2232H 対応)
  • SVF ファイルで使うような JTAG 操作のプリミティブ
  • MachXO 2280 の IDCODE の確認と JTAG通信への移行
  • テスト用 HDL (同梱) との JTAG通信

    これが今確認できたことのすべて。

    動作確認できていないが、ツールを作るたみに必要なパーツのかなりの部分は作成済み。

今後の作業

    ここからが本題。

    これから、作ったパーツをくみ上げていく予定なのだが、どのようにくみ上げるかが悩ましい。この記事で整理しておこうと思う。

    ずっと悩んでいたが、avrdude と良く似た インターフェイスにするのが良さそうという結論。avrdude をコマンドラインで使うことが多いので、似て非なるオプションにすると混乱しそうだ。

    必須のコマンドライン・パラメータ。


    -c CABLE名
    -P CABLE の PORT 名
    -B bit clock
    -b baud
    -i テイテンシ パラメータ

    -p TARGET FPGA名


    自分の Bitbang ライタのコードをベースにしているし、CABLE のパラメータはこんな感じで良いだろう。あと FPGA名 も指定しないと。

    このあたりは、最初にパラメータとして指定しないと、認識ができない。

    CABLE名 や FPGA名 は、設定ファイルに記述する。どのように記述するかはきっちりとは決まっていない。また、なんでもかんでも設定できるわけではない。コードを作る都合で、外にだすだけ。例えば、FPGA の IDCODE は、設定ファイルに記述するが、サポートできる Family はハードコーディング。Lattice の場合、知っている IDCODE しかサポートできないし、Xilinx でも 知っているもの以外は受け入れないようにする。

    さて、必須以外のパラメータは動作を指定するもの。... なのだが当面決めないでおこうと思う。

    どうするか..というと コマンドモードを作り そのモードに入って操作する。

    最終的には、動作を指定するパラメータは コマンドモードでのコマンドに変換しようと考えている。

    最初に作るのは、spi terminal モード。

      コマンドラインモードから さらに terminal モードに入る。テスト用のHDL を使うと 入力した文字がエコーバックされる。

      ここから抜けるのは、~. か +++ をすばやく入力。... というのが今のコード。操作できないかも知れないので、動かして詰めていく。



付録: JTAG の API


    void jtag_go(CABLE cbl,int state);
    void jtag_init(CABLE cbl);
    void jtag_reset(CABLE cbl);
    void jtag_IDLE(CABLE cbl, int ms, int count);
    void jtag_SIR(CABLE cbl, uint8_t *buf, int bit_len, int flags, uint8_t *rcv_buf)
    ;
    void jtag_SDR(CABLE cbl, uint8_t *buf, int bit_len, int flags, uint8_t *rcv_buf)
    ;

    void jtag_SIR32(CABLE cbl, uint32_t code, int bit_len, int flags, uint32_t *rcv_
    data);
    void jtag_SDR32(CABLE cbl, uint32_t code, int bit_len, int flags, uint32_t *rcv_
    data);
    void jtag_SDR32R(CABLE cbl, uint32_t code, int bit_len, int flags, uint32_t *rcv
    _data);

    32bit までなら コードが書きやすく分かりやすいように tag_SDR32 などを作っている。jtag_SDR32R は、SPI 通信用で MSB first 。

    flags は、1 : 受信も行う。2: 状態を移行しない。(最後の TMS==0)。

    いまのところ、API 間で非同期にI/O はしていない。受信をしない jtag_SDR を連続で call するような場合しか有効でないが、jtag_SDR を 1 つにまとめたほうが最適化になる。要するに非同期してわずかに高速化してもあまり意味はない。

rtavr_tools-0.3.tar.gz

    少し前進。コマンドモードを作り、コマンドのテストに入っている。

    cmd mode usage:
    (fl|file_load) [filetype] file
    filetype: bit jed mcs mem
    (tl|target_load) memtype [size]
    memtype: fpga_ram fpga_flash spi_flash rtavr_isp
    ram flash spi isp
    (d|dump) [addr size flags] [! outfile]
    flags: 1 reverse bit (in byte)
    (w|program) memtype
    (v|verify) memtype
    (t|terminal) [bitclock]
    (q|quit)

    こんなコマンド体系になった。

    fl file名 で 内部メモリバッファに読み込み、
    v flash で XO の flash と同じかチェックする。

    jed ファイルを使って flash の内容と一致することを確認できた。

    v ram は、RAM の内容をチェックするのだが、一致しないどころか、毎回違う。
    これは ... 今動いている回路の状態を読み取っているのだろうか?

    dump コマンドも動く。! を付けるとファイルに log することもできる。

    RAM を見たいときは、tl ram として、内部メモリバッファに読み込んでから dump 。

    terminal は全然だめだし、rtavr_isp もダメ。.. まぁボチボチ 完成させていこう。

    書き忘れたのだが、jtag_SDR の start bit 位置が 8bit アラインという制限になっている。これだととても具合が悪いことが分かったので、

    void jtag_SDR_EX(CABLE cbl, uint8_t *buf, int off, int bit_len, int flags, uint8
    _t *rcv_buf, int roff);

    というのを新設した。off/roff は 開始位置で bit 単位。これを実装するために CABLE のインターフェイスも変更。

    あと、xp2 用のコードも マージしつつ変更しているんだが、0.3 では最後にバグをいれてしまい、書いた通りには動かなくなっている。

rtavr_tools-0.4.tar.gz

    また少し前進。erase コマンドを作成して動作を確認。

    そして MachXO に対して flash に書き込めるようになった。ただし、ちょっとバグがあって USERCODE の 最下位バイトが書けない。

    cmd> e flash
    erase success
    cmd> w flash
    Programming :################################################## 29.278 sec
    Verifying :################################################## 12.660 sec
    program success
    user_id = 0x52543031
    user_id unmached 0x52543031 0x52543000
    cmd> v flash
    Reading :################################################## 12.644 sec
    verify error at 60822 0x31 != 0x00
    address_size 1116 data_width = 436
    cmd> v flash
    Reading :################################################## 12.761 sec
    verify error at 60822 0x31 != 0x00
    address_size 1116 data_width = 436
    cmd> e flash
    erase success
    cmd> w ram
    Programming :################################################## 23.747 sec
    Verifying : 0.034 sec
    program error
    user_id = 0x52543031
    cmd>

    実行したときのログ -- ram への書き込みは verify でエラー。

    flash への書き込みはされていない。エラーになったとき ISC_PROGRAM_DONE をしないようにしているが、その場合 書き込んだ内容が有効にならないことも確認できている。

    あと、ちょっと遅い。たぶん jtag_IDLE に時間がかかっているのだろう。そういえば、時間も合っていない。gettimeofday() 使うようにしないと。

    ちなみに、xp2 は持っていない。コードは書いておくが、テストは先の話。MachXO2 Pico Dev kit は入手済みでテストは出来るが、肝心のコードが出来ていない。(ちょっと難しいのだ)

    追記: DDT #1 FPGA超入門は、まだ入手可能なようだ。Amazon, マルツで買える。一応 押さえておくことにした。

関連記事
posted by すz at 15:25| Comment(0) | TrackBack(0) | artemis