2012年03月10日

MachXO2コンフィグめも

MachXO2のコンフィグについてのメモ。

rtavr_tools で持っている FPGA の コンフィグが出来るようにしようと思っている。MachXO と LatticeXP2 は、一応書いてみたもの(ただし不動)があるが、MachXO2 は、ほぼこれから。

MachXO2 と MachXO , LatticeXP2 の違い

    MachXO , LatticeXP2 は、RAM にコンフィグするデータがそのまま FLASH に格納されている。ちょっと手続きとか コマンドとかが違うものの、RAM へのアクセスと FLASH へのアクセスを統合できる。jed データを元に RAM に書くこともできる。

    MachXO2 はというと FLASH のデータは圧縮されている。そのデータを FPGA 内部の伸張エンジンで RAM に展開している。伸張アルゴリズムは不明なので、自作の rtavr_tools では、jed は、FLASH のみが対象。

      ... と思ったが、実をいうと RAM への アクセスコードは、MachXO/LatticeXP2 とよく似ていて統合可能で、そういう風にコードは作っていた。

    ついでに書いておくと Xilinx は、FLASH がなく RAM に書くデータだけがある。このデータは SPI FLASH に書くデータと 同じ(bit のオーダーは違う) で、SPI FLASH に対応したとしても 1 種類の内部データで扱える。

    構想では、扱うデータはこんな分類になると思う

    internal FLASH RAM SPI FLASH file format
    Xilinx FPGA x O O bit,mcs
    MachXO,XP2 O O ? jed
    MachXO2 O x ? jed
    MachXO2(RAM) x O ? ? (サポートしない)

    O は作ろうと思っているもの。? は未定だが、やるとしても後回し。

MachXO2 のデータ と FLASH の 読み書き

    MachXO2 のデータには、以下の種類があり、それぞれ別の手続きになる。( () 内は、1200 のサイズ )

    • CFG データ (128bit x 2175 )
    • UFM データ (128bit x 512 )
    • USERCODE ( 32bit)
    • FEATURE (64bit)
    • FEABITS (16bit)

    FLASH は、128bit の column と 2688 の row からなっていて、USERCODE , FEATURE , FEBITS は 最後の row に入っている。UFM は、ユーザ回路で使えるが、CFG データがはみ出す場合がある。また、ブロック RAM の初期データも UFM に圧縮されない形で入っている。

  • CFG データ (128bit x 2175 )

    XO2_INIT_ADDRESS(0x46)
    SDR(0x04);
    idle(10ms)

    # 1 column 分
    XO2_PROG_INCR_NV(0x70)      XO2_READ_INCR_NV(0x73)
    SDR(128 bit)           idle( 1ms)
    idle( 0ms)  SDR(128 bit)           
    idle( 1ms)
    # check busy (10)
    XO2_CHECK_BUSY(0xF0)
    for (i=0; i&ft;10; i++)
    idle(1ms)
    if (SDR (1bit 0) == 0 ) break;


    read の場合、最初の row だけ XO2_INIT_ADDRES を発行し、SDR していく。PROGRAM の場合は、row 毎に XO2_INIT_ADDRES し、SDR 後 CHECK_BUSYする。
    コマンドは、SIR(8bit) コマンドの値は、MachXO2 独自のものがほとんど。

  • UFM データ (128bit x 512 )

    XO2_INIT_ADDR_UFM(0x47)
    idle(10ms)

    UFM の場合、最初の指定のみが変わる。PROG/READ の方法は同じ。

  • USERCODE ( 32bit)

    XO2_USERCODE(0xC0) XO2_USERCODE(0xC0)
    SDR (32bit) SDR (32bit)
    XO2_PROGRAM_USERCODE(0xC2)
    idle(10ms)

    # check status bit
    XO2_READ_STATUS(0x3C)
    idle(1ms)
    SDR (32bit) & 0x00003000 == 0


  • FEATURE (64bit)

    XO2_INIT_ADDRESS(0x46) XO2_READ_FEATURE (0xE7)
    SDR(0x02) idle(1ms)
    idle(10ms) SDR (64bit)

    XO2_PROG_FEATURE( 0xE4)
    SDR (64bit)

    # check busy (略)

  • FEABITS (16bit)

    XO2_PROG_FEABITS(0xF8) XO2_READ_FEABITS(0xFB)
    SDR (16bit) idle(1ms)
    idle(0ms) SDR (16bit)

    # check busy (略)


    これらを実行する前後で、初期化と後処理が必要。あと erase の手続きがある。


    # check IDCODE

     XO2_IDCODE(0xE0)
    SDR(32bbit) == 0x012B2043 (1200の場合)

    # Program Bscan register
    PRELAD(0x1C)
    SDR(208 bit: all 1 , 1200の場合)

    # enable flash
    XO2_ISC_ENABLE(0xC6)
    SDR(0x08)
    idle(10ms)

    (ここまで共通)
    --- erase ----

    # check status bit

    --- program/read

    (Write のみ , erase で実行しないこと)
    # Program DONE bit

    XO2_PROGRAM_DONE(0x5E)
    idle(0ms)
    # check busy (略)

    (ここから program/read 共通)
    # Exit the programming mode
    BYPASS(0xFF)
    XO2_ISC_DISABLE(0x26)
    idle(1000ms)

    BYPASS(0xFF)
    idle(0ms)

    erase 手続き

    XO2_ISC_ENABLE(0xC6)
    SDR(0x00)
    idle(10ms)

    XO2_ISC_ERASE(0x0E)
    SDR(0x01)
    idle(1000ms)

    BYPASS(0xFF)

    XO2_ISC_ENABLE(0xC6)
    SDR(0x08)
    idle(10ms)

    XO2_ISC_ERASE(0x0E)
    SDR(0x0E)

    # check busy (350)


    ちなみに、XP2 や MachXO も似ていると言えば似ている。ただ、共通化できるほどは似ていない。FLASH への書き込みでは UFM はないし、RAM と同じ column , row で書き込むのも違う点。

rtavr_tools への実装

    rtavr_tools の内部データは、ただの配列になっている。なので、次の順で格納するようにした。

    CFG 128bit x 2175 = 34800 bytes
    UFM 128bit x 512 = 8192 bytes
    FEATURE 64bit 8 bytes
    FEABITS 16bit 2 bytes
    USERCODE 32bit 4 bytes
    合計 43006 bytes

    デバイスによって CFG,UFM の row が変わるが これは 別にデータベースを持っている。Preload での bit 数も データベースに持つ。

      LCMXO2_1200.tgt_type = lscc
      LCMXO2_1200.device_type = 0x12B2
      LCMXO2_1200.address_size = 333
      LCMXO2_1200.data_width = 1080
      LCMXO2_1200.boundary_width = 208
      LCMXO2_1200.flash_col = 128
      LCMXO2_1200.flash_cfm_row = 2175
      LCMXO2_1200.flash_ufm_row = 512

      こんな形式で config ファイルを作っている。address_size , data_width は RAM の column , row。
      address_size, data_width, boundary_width は、BSDL ファイルに記載がある。
      flash_col, flash_cfm_row, flash_ufm_row は、SVF ファイルを生成すると分かる。( 他の記載は 信用できない。)

    作るべきプリミティブは、erase_flash_xo2 , write_flash_xo2 , read_flash_xo2 。サブルーチンとして xo2_check_busy(ループ数) と xo2_read_status() を作る。

    あと、FEABITS の jed ファイル読み込みが未対応。

rtavr_tools-0.8

  • rtavr_tools-0.8.tar.gz

    とりあえず、最新版。

    これは、MachXO2 用の コンフィグのコードを入れた版。デバッグ中のもの。

    FLASH への書き込みは、

      cmd> fl xxxx.jed
      cmd> w flash

    FLASH からの読み込みは、

      cmd> tl flash

    とかで出来ることを期待したのだが、全然ダメ。読み込みすらちゃんと動かない。

    RAM への読み書きは、以前に作ったコードが大分対応していたので、作ってみた。

      cmd> tl ram

    とすることで、なにやら読める。

      cmd> w ram

    で書き戻す操作になるのだが、ERASE はできるが、書き込みでエラーして ERASE された状態になる。
    ただし、電源を入れなおすことで、元に戻る。

      cmd> w flash

    FLASH についての ERASE も動くようだ。

RAM への コンフィグについてのメモ

    うまく動かないのであれこれ調べていたら、直接は関係ないことがいろいろ分かってきたのでメモしておく。

    SRAM Fast Program というのがあって、

    XO2_BITSTREAM_BURST(0x7A)

    というコマンドで書き込んでいる。このコマンドでは、どうも 圧縮 bit ファイル と 非圧縮 bit ファイル のデータの 2 種類を流し込めるようなのだ。たぶん、FLASH からのパスを利用しているのだろう。

    実際の bit ファイルとどういう関係にあるか調べてみた。
    非圧縮 bit ファイル のデータは、47371 バイトで、 XO2_BITSTREAM_BURST で送りこむデータは、47739 バイト。差分の 368 バイト分の 0xff を先行して 送り 非圧縮 bit ファイル のデータ を送っている。

    ついでに SRAMのデータ 44959 バイト(1080x333/8) と 非圧縮 bit ファイル のデータ の関係も調べてみた。


    0000: ff ff bd cd ff ff dc 00 00 00 ff ff ff ff ff ff
    0010: ff ff 62 00 00 00 41 07 80 b2 00

    非圧縮 bit ファイル は、このような 0x1A(26) バイトが先行して格納され、SRAMのデータ が続く。 残り は、2386 バイトだが、

    2e ce ff ff ff ff ff ff ff ff 43

    こういうデータで始まっている。ブロック RAM に 2KB の初期値を入れたので、2386 バイトのうち 2KB ? (2K x 9bit ?) 分の値もそのなかに含まれているはず。

    圧縮 bit ファイル のデータは、10170 バイト だった。XO2_BITSTREAM_BURST で書き込むデータは、84152 bit(10519 バイト) 349 バイトの差があるが、これも同様で、差分は、0xff が頭につく。

    0000: ff ff bd cd ff ff dc 00 00 00 47 00 00 00 80 d4
    0010: 04 c2 40 00 00 00 50 0a 0c c0 12 14 90 ff 44 00
    |
               :
    2790: fd fb f7 ef df bf 7f ff fe fd fb f7 ef df bf 7f
    27a0: ff fe fd fb f7 ef df bf 7f ff 44 00 00 00 02 00
    27b0: 00 00 7a 00 00 00 ff ff ff ff

    圧縮 bit ファイルはこんな風なデータ。非圧縮同様 0x1A バイトがヘッダなのかも知れない。

    さて、jed ファイルと 圧縮 bit ファイルは 同じなのか? というのが気になったので見てみると... 似ている感じだが、厳密には だいぶ違う。

    0000: ff ff bd cd ff ff dc 00 00 00 40 00 00 00 50 0a
    0010: 0c c0 12 14 90 ff 62 00 00 00 1d 07 80 b2 00 00
    :
    2790: fb f7 ef df bf 7f ff fe fd fb f7 ef df bf 7f ff
    27a0: 44 00 00 00 02 00 00 00 7a 00 00 00 ff ff ff ff

    そもそもヘッダーがちょっと違う。だが、最後は 同じっぽい。もっとも 非圧縮 bit ファイルも同様。

    最後の部分の最初だが、

    jed ファイル:
    1e60: 39 39 00 a4 c3 e7 e4 00 00 00 e9 ee
    1e70: ff ff ff ff ff ff ff ff 43 01 00 00 4a 2a 0c 8c
    1e80: 67 90 44 00 00 00 03 00 00 00 ff ff ff ff 6f 00
    圧縮 bit ファイル:
    1e50: 39 39 00 a4 c3 e7 e4 00 00 00 c8 cc ff ff ff ff
    1e60: ff ff ff ff 43 01 00 00 4a 2a 0c 8c 67 90 44 00

    こんな風にずれている。"e9 ee" と "c8 cc" は、たぶん CRC かチェックサム。ずれるルールは分からないが、ff が挿入されている感じ。

    ところで、圧縮 bit ファイルを生成するのは、意外にも簡単だった。制約ファイルに

    SYSCONFIG GENERATE_BITSTREAM=ENABLE ;

    この行を入れておけば良い。

    ... なんだか、XO2_BITSTREAM_BURST だけが動けば良いような気がしてきた。FPGA を汚さずにコンフィグできるし、ブロックRAM もちゃんと初期化できる(はず) 。しかも 圧縮したデータを一気に書くから高速にできる。SPI-FLASH への書き込みでは、それようの回路をコンフィグしないといけないのだが、実装の目処も立つ。

    bit ファイルの生成が面倒だと思っていたが、簡単ということも分かった。


    XO2_BITSTREAM_BURST

      これが動いた。圧縮 bit ファイル, 非圧縮 bit ファイル ともに OK 。それどころか、jed を読み込んだ内部形式のデータまで OK だった。

      重要なのは、最初に十分な数の 0xff を送ること と 正しいデータを続けて送ることのようだ。後にごみがあっても問題ない。verify はできないが、失敗すると初期化状態のままになる。


        cmd> fl test_hdl.bit
        Lattice Semiconductor Corporation Bitstream
        Version: Diamond_1.4_Production (87)
        Bitstream Status: Final Version 1.80
        Design name: MachXO2_Breakout_test_hdl_xo2.ncd
        Architecture: xo2c00
        Part: LCMXO2-1200ZE-1TQFP144
        Date: Thu Mar 15 23:49:02 2012
        Rows: 333
        Cols: 1080
        Bits: 359640
        Readback: Off
        Security: Off
        Bitstream CRC: 0xA2F6
        memory loaded size = 10170
        cmd> w ram
        Programming :################################################## 1.151 sec
        program success

      書き込みはわずか 1.151 秒。しかも ERASE の待ちが そのうちの 1 秒。

      bit ファイル のフォーマット

        ちょっと説明しておく。

        0xff 0x00 で始まり ストリング 0x00 がいくつか続く。最後に 0xff が来てここまでがヘッダ。その後は バイナリでデータが続くのだが、バイト内の ビットが反転 している。(bit0 ⇔ bit7)。

        もともと、Xilinx 用の bit ファイル の読み込みを作っていたのだが、自動判別して読み込むようにした。内部データは、ビットの反転を元に戻したもので、そのまま XO2_BITSTREAM_BURST(0x7A) にかけられる。


      書き込みは格段に早いが、RAM にしか書かないので、使用目的は主にテスト。複数の config を切り替えて動作を確認するとか...。あとは、仮の回路を組み付けるときに使う。ツールでは、SPI ライタのサポートで使うつもり。

      FLASH への書き込みは、コードは出来たものの全然だめなまま。目的は達したので、当面寝かせるかも。

    rtavr_tools-0.9

    • rtavr_tools-0.9

      最新版を置いておく。

      あと SPI FLASH への書き込みコードを作れば、コードだけは予定していたものをだいたい作ったことになる。自作 Xilinx ボード用のコードは形だけは入っている。

      次は、rtavr のデバッグに進もう。

    rtavr_tools-0.10

    • rtavr_tools-0.10

      最新版を置いておく。

      rtavr のデバッグを少し始めているのだが、なかなか。1回合成するのに、2 時間ぐらいかかるし。

      ちょっと息抜きに、SPI FLASH への書き込みコードを作ってみた。もとは、ATUSB162 で Mass Storage Class を作ったときのコードだが、移植というより書き直しになったので、ちょっとデバッグが必要そう。

      あと、SPI 用の HDL も作っておいた。手順的には、これをまず SRAM に書き込んで 仮コンフィグし、mcs ファイルを読み込んでSPI FLASH に書き込む。ただしオフセット 0 から書き込んでいるので、mcs ファイルによっては、アドレスがずれる。

      ちょっと MCS ファイルの調査:

      UFW で bit ファイルを MCS に 変換できる。0x000000 と 0x010000 という アドレスが表示されている。XO2 や XP2 は、0x010000 から ロードするので、0x010000 に Insert するようだ。

      *** dump ***
      0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
      *
      10000: aa 76 96 6e a6 4e ce 86 36 04 62 96 36 a6 04 ea
      10010: 4e 96 2e a6 4e 04 6a 4c 74 2c 1c 50 22 86 2e a6
      10020: 5c 04 2a 16 ae 04 0c cc f4 4c 4c f4 8c 4c 04 8c
      10030: 0c 5c ac 2c 5c ac ec 04 50 ff ff ff ff ff ff ff
      10040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
      *
      10150: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff bd
      10160: cd ff ff dc 00 00 00 47 00 00 00 80 d4 04 c2 40
      10170: 00 00 00 50 0a 0c c0 12 14 90 ff 44 00 00 00 02
      10180: 00 00 00 ff ff ff ff 62 00 00 00 1d 07 80 b2 00
      10190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

      できたファイルを 見てみるとこんな感じ。10150 からお馴染みの パターンが入っている。... jed ファイルと全く同じような ...

      その上は何かというと テキストなのだった。bit の MSB/LSB を反転すると ...

      Universal File Writer V2.48
      Date: Thu 03/22/12 5:54:57

      こんなようなデータが入っている。ごみはスキップして、ビットストリームだけ取り込んでくれるようだ。

      ところで.... 論理合成する時間が MachXO2 だけ圧倒的に長いことに気がついた。1200 だとぎりぎりなので遅いのかと思っていたのでは、そうではない。XO や XP2 は結構速い。

      ここまで MachXO2 でやったが、rtavr のデバッグの最初は、MachXO breakout を試してみようかと思っている。ただ、結構忘れてしまっている。

        rtavr_tool -p LCMXO2280

      rtavr_tool では、こんな風にチップ名を指定するようにしている。さて、XO の場合は、どこまで出来ていたのだっけか。

      まず、基本的な話から思い出す。

        XO は、flash と ram の構造が一致する。圧縮もない。さらに flash に書くデータと ram に書くデータは同じ。jed ファイルのデータと flash のデータも一致する。ただし、ram から読み込んだデータは、書き込んだデータとは一致しない。svf ファイルを見ても違うデータでベリファイしている。

      で、動作を確認したところ..

      • flash の erase は大丈夫。
      • flash の書き込みも 基本 OK なのだが、USERCODE が何故か一致しない。先頭が 0x00 になっってしまう。そのために config をエラーにしてしまっていた。USERCODE が不一致でも成功扱いにすることで、一応は flash に config できるようだ。
      • flash の read も OK 。正しいデータと jedから読み込んだ内部データは一致した。
      • ram への書き込みは、正しいかチェックできない。コンフィグした回路が動かないことから失敗しているようだ。

      まぁ、こんなところ。flash への操作はひと通り可能にしたので使えないことはない。

      これで、少しやるきが出た。まずは、MachXO2 と同じレベルまでもっていこう。
posted by すz at 12:47| Comment(0) | TrackBack(0) | MachXO2
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/54369419
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック