2011年02月05日

FPGAボードを使う計画

FPGAボードを設計してみた』わけだが、それ自体を作りたいのが動機だったりする。だが、どのように使うつもりなのか全く計画がないというわけではない。

ここでは、どう使うつもりなのか - なにがしたいのか - について整理していこうと思う。

まずは、どんなものかについて簡単に説明すると

  • FPGA は、安価な 100 ピンの Spartan-3A (200A or 50A)
  • SPI FLASH での Config 可能。
  • SDRAM が付く。(最大 512Mb(64MB) で 16bit幅 / 8bit 幅 )
  • ATMEGA32U2 と 接続してありホストとの連携を強化(JTAG, Config 以外に 通信に 4bit + α)
  • 一方外付け回路用の I/O は貧弱。8bit が標準。(SDRAM を 8bit 幅にすると + 8bit)

  • ボードの名前は決めていない。eagle でのファイル名は xc3s50a-sdram だが長いので、仮に 200Aボード/50A ボードとする。

次にしたいこと (or やるべきこと)をリストして 後で詳細を書いていく。

  • ステップ(1) 200Aボード/50A ボードを使えるようにする。
  • ステップ(2) AVR互換コアを作る (DONE)
  • ステップ(3) AVR互換コアで SPI_FLASH に書き込めるようにする。
  • ステップ(4) AVR互換コアで SDRAM を使えるようにする。
  • ステップ(5a) SDRAM のアプリケーションとして、簡単な フレームバッファ/ロジアナ を 作ってみる。
  • ステップ(5b) FULL-SPEED(12Mbps) USB IP を使ってみる。
  • ステップ(5c) MicroSD を使ってみる。
  • ステップ(6) SDRAM をメインメモリとした CPUコアを動かしてみる。
  • ステップ(7) 200Aボード/50A ボード同士通信できるようにする。
  • ステップ(8) I/O ボードを Spartan-6 で作り、200Aボード/50A ボードから利用できるようにする。

だいたいこんな感じ。

200Aボード/50A ボードを使えるようにする


このボードには、JTAG 用のコネクタはない。その代わりに USB インターフェイスが載った ATMEGA32U2 を接続しているわけである。

だから、JTAG ケーブルにするファームウェアと それを使うホスト側のプログラムを作らないと なにもできない。

Digilent の USB JTAG ケーブル互換のファームウェアを作るのが、ひとつの方法ではある。そうすれば既存のソフトに手を入れず利用できる。それぐらいは困難だと思えないぐらいのレベルに今やなっている。ただ、USB の ID を詐称することになるので、こんなのを作ったとしても 自分で使うことしかできず 公開できない。

自作の JTAG ケーブル用のプロトコルとファームウェアはベースを用意してある(serjtag)。いくつかの オープンソース の ツールを これ(serjtag)に対応するよう改造していこうと思う。

serjtag は、Digilent の プロトコルを参考にしていて、プロトコルそのものは違うが機能的にだいたい互換にしている。移植にはそんなに苦労しないと見ているが、やってみると問題は出てきそうだ。

ステップ(2) AVR互換コアを作る


オープンハードウェアで、AVR互換コアはいくつかあったと思う。これらを利用すれば作る必要はなさそうだが、そもそも作ってみたいのだ。

実を言うと経験がないので、どれぐらい難しいのかよく分かっていない。あまりに困難だったり、飽きたり、面倒になってしまったら、既存のAVR互換コアを改造する方法に切り替えようと思う。
作りたいのは、Tiny10系の コア。レジスタが少なかったりして、リソースを減らせる利点がありながら GCC が利用できる。

    いったい gcc が使える 8bit CPU のコアはどれぐらいあるのだろう? AVR は昔からあるが それ以外だと R8C ? 16bit になると h8300 coldfire PIC24 M16C ? こんな感じ?

      追記: MSP430 が該当するらしい。 FPGA で利用できるコアとして OpenCoresopenMSP430がある。

      また、LatticeMico8 も gcc が利用できるらしい。Mico8 は 自社プリミティブを使いまくっているように思えるが、シミュレータ用の定義も添付されているようで 一応完結している。

      もう AVRコアを作ってしまったので、他の8bitコアに興味はないが 外部インターフェイスやデバイスをどうしているとか 参考にはさせてもらおうと思っている。

    そもそも AVR を使う理由は gcc があるからだし、この中から 慣れ親しんでいる AVR を選ぶのは必然ではある。そして、作ってみるとすれば、普通の AVR を縮小した Tiny10 系を選ぶのも必然だろう。 

    技術的興味から言えば 4 段パイプラインというのは大きい。いったいどういう風にして動かすものなのか 設計できるレベルで理解したいと思う。


(もう上記と違うことを書いて恐縮なのだが..) 作りたいとはいえ、経験がないわけだから、全くの自己流だと無駄が多い。だいたい書き方の流儀すらろくに知らない。ソースがあるもので 練習してみたい。

いくつか OpenCores から リストアップしてみた。

AVR core は昔からあるもの。Navre AVR clone は、SoftUSB と組み合わせて使うことを想定しているらしく興味深い。が、完全に互換ではないようだ。AVR8 は Reduced AVR Core for CPLD となっていて Tiny10 よりさらに単純化したもののようだ。AVR_HP は、Hyper Pipelined AVR Core。-- よく分からないが、4つまでの core が付く -- 興味深いが 今の目的に対して複雑すぎ。

いろいろあるわけだが、Verilogが 多い。VHDL を勉強しようと思っているので他にないかググっていたら、

が (やはり Verilog だが) 見つかった。(このサイト前にも見た記憶がある。そのときは感心して終わりだった)

規模は、KX_AVR が、452スライス+1MULT 。AVR Core が 955スライスだそうだ。50A が 704スライス、200A が 1792 スライスなので入ることは入る。Tiny10 互換だと機能を削るわけだから、もっと小さくはなるだろう。ちなみに Spartan-3 用 PicoBlaze は 96スライスだそうだ。

これらの数字から考えて 出来れば 300 スライス以下になると 嬉しいのかも。一応の目標にしよう。

速度は、KX_AVR が 26.854 ns と書いてある。周波数にすると 37.23 MHz 。4段パイプラインと書いてあるから MIPS 値も 37.23 MIPS だろう。ちなみに PicoBlaze は 88MHz / 44 MIPS だそうだ。

Tiny10 向けに機能を削ると 速くはなっても遅くはならないだろう。だが、入手した 50A/200A (-4 グレード)で、33MHz というのはかなり厳しいのかも知れない。

なにやら KX_AVR は出来が良さそうな感じなので、これで勉強させてもらおうかと思う。

    VHDL ではないが、しょうがないから 混在も OK で検討しよう。

まずは、単純に 論理合成してみた。デバイスは xc3s200a-4ft256 。CPU core だけでメモリが入っていないので、ピンの数が多い。

    Number of occupied Slices 477 1,792 26%
    Number used for Dual Port RAMs 64
    Number of bonded IOBs 104
    Number of BUFGMUXs 1
    Number of MULT18X18SIOs 1

で、MEGA と ELPM の define を外してみた。ひとつエラーが出たが適当に修正。

    Number of occupied Slices 450 1,792 26%
    Number used for Dual Port RAMs 64
    Number of bonded IOBs 104
    Number of BUFGMUXs 1

これぐらいでは、大して変わらないということか。ちなみに、レイテンシはどこ見れば良いか分かっていないので載せられない。

行数は、1868 行。-- 中括弧だけの行みたいなのが、ほとんどないから C だと 3000 行ぐらいの感じか。一から作るなら別だが、削っていくだけなら長大という感じはしない。ちょっといじってみたくなる量。

だが、いまはこれぐらいにしておこう。

メモ: PicoBlaze をぐぐっていたら KX_AVR のひとの KP4 というページもヒットした。プリミティブ一覧が、\Xilinx\doc\japanese\books\docs\lib\lib.pdf にあるそうだ。重要な気がするので、メモ

追記: 2011/04/19

ほぼ完了。実際には残っている作業はあるが、完成と言って良いレベルになった。詳しくは、『AVR互換コア(テスト2)』の記事を参照。

ステップ(1) のボードの製作を 飛ばして (2) をやったわけだが、設計が楽しくなってしまったからしょうがない。まだしばらく (2) の仕上げをやるつもりだが、次はいよいよボード製作か。ただ、(3)も gcc をいじるところからやらないといけなくて大仕事。(3) の目処を先につけるかも。

ところで、XuLA-200 というボードを知った。これは、XC3S200A-VQ100 に SDRAM が付いたボード。価格は $69 。USB も付いていて、ここで検討したボードにかなり近い。USB のコントローラが PIC であることが違う。(こちらは、FT232RL or AVR(mega32u) )。

いろんなツールも提供していて これからどういう風にすべきかの指標になりそうだ。

ステップ(3) AVR互換コアで SPI_FLASH に書き込めるようにする。


AVR互換コアが実際に使えるものなのかどうか判断するには、有用なものを作ってみるのが良いだろう。

(ATMEGA32U2 の )シリアルで接続して、SPI_FLASH に書きこむものを目標としてみよう。こういうものを作るなら、PORT 以外に デバイスも作り込みたいところ。

Tiny20/40 には SPI が付いているので、互換になるようにしてみたい。あと、USART が載った Tiny10系デバイスはないので、Tiny2313 あたりの USART 互換を目標にする。

ちょっと Tiny40 の I/O レジスタのアドレスマッピングを見てみたが、USART は ADC のところに入りそうだ。PORT は A,B,C の 24bit 分の割り当てができる。タイマーは、8bit の timer0 と 16bit の timer1で標準的。TWI もいずれ使いたいから入れたい。

PORTは、いままでの AVR と違い プルアップ用のレジスタが増えている。どちらが良いか判断できないので、define で切り分けて 従来タイプと 新タイプを分けた方が良いかもしれない。

以上で I/O レジスタの 32 バイト分はだいたい埋まってしまう。

Tiny10 系では、LPM/SPM 命令がなくなったが、フラッシュは 16bit メモリ空間にマップされている。I/O もそれに倣えば (アクセス効率は悪くなるものの) いくらでも増やせる。

ちなみに Tiny40 には、RAMAR/RAMDR という I/O レジスタがあって これ経由で RAM にアクセスできる。これは何だろう? ひょっとしたら core 内部 でも使っているのかも知れない。

ステップ(4) AVR互換コアで SDRAM を使えるようにする。


ここで作りたいのは、SDRAM の メモリコントローラ。これも IP を利用したいのではなく、作ってみたい。

メインの CPU があって キャッシュへの READ/WRITE をしている状況で、DMA が あって 横から I/O できるようなものを目指す。

AVR互換コアはテスト用として使う。

ステップ(5a) 簡単な フレームバッファ/ロジアナ を 作ってみる。


フレームバッファ/ロジアナ が欲しいわけではない。メモリコントローラが使えるようなものになっているかどうかのテスト用。 うまく作れるようなら発展させるのも良いが ... とりあえずはメインにはしない。

DMA の方につないで動かすが、AVR で SDRAM に書き込んだり、データを抜き出したりする。SDRAM を排他的に使うのも良いが、後々再利用できないので、ちゃんと並列にアクセスできるよう作る。

ステップ(5b) FULL-SPEED(12Mbps) USB IP を使ってみる。


これはやってみたいのだが、入れるならこのあたり? すくなくとも DMA が使えないとテストもできないだろう。

ただ、付けるクロックを 33MHz にしようと思っている。x2 しても 66MHz 。USB の 12M Hz の整数倍にはならない。クロックを付け替えたくないし ... V-USB のように違うクロックでドライブできないか考えてみたい。

    クロックのことを考えると Spartan-6 が圧倒的に有利だ。TQG144のLX9 なら 1286円で実際に買えるし。

ステップ(5c) MicroSD を使ってみる


あまり考えていないが、これもやってみたい。ただ、3.3V の I/O 電圧のみで良いのかどうか? 4bit の SD規格で アクセスできるのか? 出来たとしてやって良いものなのかどうか? いろいろ懸案材料がある。

ステップ(6) SDRAM をメインメモリとした CPUコアを動かしてみる。


MIPS あたりの CPUコアを動かしてみたい。いまのところ、CPUコアを作りたいとまでは思っていない。どんなものなのか、既存のものをメモリコントローラにつないで見る。

この時点で CPUコア を設計するのが楽しくなっていれば、自分で作るかも知れない。

ステップ(7) 200Aボード/50A ボード同士通信できるようにする。


通信はもっと早い段階でやりたいのだが、まともに使うには、AVR互換コアでは力不足だろう。

ステップ(8) I/O ボードを Spartan-6 で作る。


ここでようやく、次のボードを作る。この段階まで到達できるかどうか分からないが、現時点の構想をメモしておこう。

200A/50Aボードの HUB になる I/Oボードで、Spartan-6 TQG144 が候補。4 枚までぐらいの 200A/50Aボードをつなげたい。I/O の種類は 大きくわけて 2 種類。

ひとつは、200A/50Aボードのローカルストレージ用。もうひとつは、外部との 接続用。

200A/50Aボードには、メモリ と CPUが載っている(とする) 。通信も できている。-- 足りないのはストレージ。SPI_FLASH は READ/WRITE できるが、WRITE は性能が低いうえに書き込み回数の上限がある。CPU の ファームウェアを置く領域には利用できるが、データ置き場にはできない。

I/O 用のピンは 通信に使ってしまっている。しょうがないので、通信先に ローカルストレージを付ける。

外部との接続 というのは、ネットワークとか DISK とか グラフィックLCD とかキーボードとか ... PC に付いているような種類のもの。

TQG144 といっても よくよく考えないと、ピンが足りなくなる。I/O の電圧も マルチになりそうで、ほんとうに良く考えないと無理そうだ。だからといって、それ以上のピン数のものは利用できない。ピン 拡張用の デバイスを付けることも視野に入れる。

いったいどれぐらい必要なのか 数だけ見積もってみよう。

  • 200A/50A との通信ポート

    単純に 4 ポートにすると 8x4 ピン必要になる。通信ポートの使い方はだいたい決めたので、それに従うと

    I2C (共通 2 ピン)
    高速 I/O (それぞれ 4ピン 差動 x 2)
    クロック 1 ピン
    未定 1 ピン (入力専用)

    こうなるので、最大は、24 + 2 = 26 ピン。最小は 入力専用ピンを使わないことにして、クロックも (200A/50A ボードから見て)入力専用にすると、16+3 = 19 ピン。クロックは個別にした方が良いかも知れないが、バッファを外付けする手もあるし保留。

    (追記) LPC(Low Pin Count) というインターフェイスがあった。リンク先(Wikipedia) の リンク -- Intel のサイトに 仕様がある。必須なのは 7 ピンで、

    LAD 4 ピン データとアドレス 4bit I/O
    LFRAME# 1 ピン 新しいサイクルが開始されたことを示す (ホスト → 装置)
    LRESET# 1 ピン リセット
    LCLK 1 ピン 33MHz

    で、SUPER-IO と呼ばれる IC が(今も)存在しているのだった。どちらがホストか決まっている必要があるが、これも使えるかも知れない。

  • ローカルストレージ用

    MicroSD で良いと思っている。ただ、MicroSD のもつ 性能を利用したいのなら、6 ピン必要なだけではなく、I/O 電圧 を変えられないといけないらしい。

    悩ましそうな気がするが、とりあえず 6 ピンでカウントして 6x4 = 24 ピン。

    ある SDXC コントローラのデータシートを見てみると

    • DS (Default Speed) 25MHz まで 3.3V I/O 電圧
    • HS (Hi-Speed) 50MHz まで 3.3V I/O 電圧 (ここまで従来規格)
    • SDR12 SDR 25MHz まで 1.8V I/O 電圧
    • SDR25 SDR 50MHz まで 1.8V I/O 電圧
    • SDR50 SDR 100MHz まで 1.8V I/O 電圧
    • DDR50 DDR 50MHz まで 1.8V I/O 電圧

    .. とまぁいっぱい増えている。

    いくら FPGA でも I/O 電圧を個別に しかも動的には切り替えられないから、TXS02612 を使うとか考えた方が良いかも知れない。ただ、それで物理的に接続できても、SD規格は使えないような..

  • グラフィック LCD

    16(or 18) パラレルだったりして、普通に接続すると ピン数を消費する。ただ、帯域は (FPGA の能力から比べると)それほどでもない(はず)。

    仮に最大を 800x480x24bpp としてみよう。これを 70Hz で書き換えるなら 77MB/sec 。-- あ、これは厳しい。8bit シリアルRGB とかでないと無理そうだ。

    もっと 小さいもの 480x320ぐらいならどうだろう?

    とにかく、液晶は どういうものであれ WRITE Only で扱えるのが普通。CPLD とかで シリアルパラレル変換させて ピン数を節約する方向で検討しよう。CPLD は XC2C32A で十分だし。

  • HI-SPEED USB / FULL-SPEED USB

    USB さえ付いていれば、大体のデバイスはなんとかなる。そして 他のPC向け高速 I/O は 帯域が高すぎて無理。480M bps の HI-SPEED USB がせいぜいという気がしてきた。

    HI-SPEED USB をつなぐには、ULPI という標準インターフェイスの PHY を使う。 USB33XX といったデバイスをつなぐことになりそう。

    USB33XX は 8bit I/O で、リファレンスクロックに 13MHz(or 26MHz) が必要で、あと 電源も必要。結構ピンが必要になる。

    2ch 欲しいところだが、付くのだろうか?

    一方 FULL-SPEED USB なら、直接ハンドリングできそうだ。PHY というか ドライバ・レシーバ? を付けても良いかも知れない。良くは知らないが USB1T11, MIC2550 , MIC2551 -- このあたり?

  • SDRAM

    (無印)SDRAM は 39pin 使う。ただ、これには DDR ぐらいは載せたくなるから、専用の I/O バンクを割り当て 2.5V 電源も用意しないといけない。ちなみに TQG144 には Spartan-6 のメモリコントーラは付いていない。

    ちなみに 1.8V I/O 電圧の DDR2 が 具合が良さそうだが、BGA ばかりで電子工作レベルでは無理。PC 用のメモリモジュールは安く手に入るが、相当なオーバースペックで電力もくう。

    まぁ I/O だけでも厳しいのに 無理としか思えないが、一応メモ。

... とまぁ全然見積もれていないが、先の話なのでこれぐらいにしておこう。
posted by すz at 17:04| Comment(0) | TrackBack(0) | artemis
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

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


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

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