電子工作/XC9572XLで作るROMライタ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SuzTiki:電子工作 CPLD (XC9572XL) で ROM ライタを作る。 広く使われている 29LV系の Flush ROM は、特別な電圧を必要とせず 3.3V 系の論理回 路だけで制御すれば良い。ということは、CPLD の I/O 線を ROM のソケットにとにかく つないでいって ・ CPLD の中の回路をどうするか ・ CPLD をどう config するか ・ HOST とどう通信するか を考えてやれば、ROM ライタになってしまうわけだ。こうやって作った回路は CPLD の 中味しだいで他の回路にもなる。 ・ CPLD をどう config するか ・ HOST とどう通信するか という問題はクリアになっている(はずな)ので、ROM をいれるべき ROM ソケットを単な るコネクタと見立てて別の回路を載せたりできるはず。 CPLD をどう config するかについては、JTAG に決まっている。 NAXJP を使えば、PC のパラレルポートの線を直結するだけで書き込むことができる。 それを前堤とすれば、HOST とどう通信するかということもだいぶ決まって来る。パラレ ルポートの別の信号線を使うわけだ。JTAG の制御と SPI の制御は似ているので、SPI がまあ妥当だろう。 さて、それだけできたら良いのだろうか?パラレルポートでは、別電源が必要だし、信 号にノイズが載ってうまく書けない場合があるという話を聞いている。そして、そうい ったこと以上に PC のパラレルポートが壊れると厭だ。( 自分ではPC のパラレルポート 自体使ったことないんだけども、壊れるとこのROMライタ自身が使えなくなるから困る。 そして相手はCPLD なので、バグっていたらやっぱり壊れる可能性があるんじゃないかと いう気がしている) そうすると USB が使えたら良いのではないかという気になってくる。ただ他の FPGA/ CPLD を使うときも有用なので、 USB との通信は、独立したものの方が良い。これは、 電子工作/XC9572XLと8U245AMで作るUSBシリアルIOで考えることにする。 以下、CPLD の中の回路をどうするかについて考えることにする。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 作ろうとするもの ・ XC9572XL-VQ64 をつかって ROM ライタになるボード。対応 ROM は、 29LV400(512K Bytes),29LV800(1M bytes) ,29LV160(2M Bytes)を ROM ボードに載せたもの。 ・ インターフェイスは、SPI ・ 高速化のためにできるだけ、上位レベルで、同期を取らなくて良いようにする。そ の上で、できるだけ転送量が減るように工夫する。 想定インターフェイス ・ CLK +---+ +---+ +---+ +--- ___| |___| |___| |___| DIN --------<>------<>------<>------ DOUT --------< >< >< > 3 線によるインターフェイス。 クロックの立ち下がりでデータを取りこむのと同時に データを出力 ( 単純なシフト動作 ) 要するにパラレル I/O ではなくて、シリアルによる I/O。 基本的な考えかた +------------+ +---- | カウンタ | | +------------+ | IN | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +----------------------------------------------------------+ ----> CLK| | ----> IN | | <--- OUT| | +----------------------------------------------------------+ | | | | | | | | | | | | | | | | | | | | | | | | | | | OUT | | | | | +-----------------+ | 制御線ラッチ | +-----------------+ | | | | | 固定長のデータフォーマットを考えると、長いシフトレジスタを1つ考えて CLK ととも にシフトさせる。 元あったデータがホスト側に行って、ホストから送られたデータがあたらしい状態にな る。CLK をカウントしておいて、全部入れ換わったら所定の動作をすれば良い。 こういう単純な構成で ROM ライタを考えると、いくつかの制御用の信号線が、シフト動 作で変わってしまうのはまずい。そういう理由でラッチをかませている。ただし全部で はなく、アドレス線などは、このシフトレジスタの OUT を直接接続しても良い。データ 線は入出力があるので、制御線ラッチの状態を使って動作を規定させる必要がある。 シフトレジスタの長さを Flush ROM の信号線に合わせて取るとすれば、アドレス 24bit データ 16bit その他数ビット。全部で 48 bit ぐらい。制御線用ラッチが 8bit 、カウ ンタが 8bit とすれば、トータルで、64bit。XC9572 は 72 bit 分あるので、入ること は入る。 ただし、ほんとうにこのように作ってしまうと RD# を Low レベルにして データ方向を切り替える。 RD# を Hi レベルにして、データの内容を取りこむ。 データ方向を切り替える。 といった操作で、シフトレジスタ長の内容の転送が 3 回発生する。 48 bitx3 で 18 バイトのやりとりをして、 16 bit のデータが読める ... まあ、3回の転送の間で同期を取る必要はなく、どんどん転送すれば良いから、それでも 良いという考えもあるのだが ... もうすこし工夫をいれたい。それが、主なテーマとい うことになる。 ちなみに、なにかの間違いで、シリアルの bit がずれてしまったりしたときは、どうす るんだろうか? これに対応するには、たぶんチップセレクト CS# というのを考えて、その立ち下がりで 、カウンタを 0 にすれば良いのだろう。チップセレクトという概念にするなら、もうす こし付加的な機能も必要。だいたい下のような感じか。 ・ CS# ----------------+ +---------------- |____________________| - ↓ で カウンタを 0 にする - Low の間だけ、CLK による動作を行うようにする - Low の間だけ OUT のトライステートゲートを開く ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 構成を考える ・ IN/ +-------------------+ OUT---+----| 制御レジスタ入力 | | +-------------------+ | ↓ | +-------------------+ +-------------+-------------+ | | 制御レジスタ | | 状態 | シフト数 | | +-------------------+ | レジスタ | カウンタ | | +-------------+-------------+ | +-------------------+ +----| 転送数カウンタ | | +-------------------+ | +-------------------+ +----| アドレスレジスタ#0| | +-------------------+ | +-------------------+ +----| アドレスレジスタ#1| | +-------------------+ | +-------------------+ +----| アドレスレジスタ#2| | +-------------------+ | +-------------------+ +----| データレジスタ#0 | +-------------------+ どう工夫しても上記より必要な情報量が劇的に減るということはないが、いくつかのス テージに分けることによって、制御できれば、効率良く転送できるようになる。 考えてみたのは、アドレスレジスタにカウンタ機能を付け、転送数カウンタの数だけ、 くり返し READ/WRITE 操作をできるようにすること。 なお、基本構成ではデータバスを 16bit としていたが、くり返しの操作ができるのなら 、性能的なインパクトはないので、 8 bit モードにすることにする。 これでだいたい 64 bit ぐらい使う見積り。多少減らせる見込みがあるが、 CS の制御 なども必要。結果としてぎりぎりになるんではないかと思っている。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 転送フォーマット 受信 送信 +---------------+ +---------------+ | コマンド | | 0 | +---------------+ +---------------+ | 転送数 | | コマンド | +---------------+ +---------------+ | アドレス#0 | | 転送数 | +---------------+ +---------------+ | アドレス#1 | | アドレス#0 | +---------------+ +---------------+ | アドレス#2 | | アドレス#1 | +---------------+ +---------------+ | 0 | | アドレス#2 | +---------------+ +---------------+ ----------------------------------------- Option : データ転送フェーズ +---------------+ +---------------+ | データ1 | | 0 | +---------------+ +---------------+ | | | データ 1 | | : | +---------------+ | | | | +---------------+ | | | データN | | | +---------------+ +---------------+ +---------------+ +---------------+ | 0 | | データN | +---------------+ +---------------+ 実はちょっと面倒なことがある。それは、1 CLK の操作で、READ/WRITE なりができない こと。たとえば、WRITE なら、データを受け取った後に書き込み操作が入る。それは次 のフェーズにずれ込んでしまう。 また、READ の場合アドレス確定後すぐに読みこんだデータを送ることはできない。 最後にダミーデータを送ってもらうことにして、 1 バイトづつずらしてデータを返すと いうのがわかりやすくて良いかもしれない。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ちょっとここで観想。 XC9572XL ってなかなか良いバランスかも知れない。XC9536XL クラスなら、規模が小さ すぎて簡単なステートマシンも作れそうにないが、これならちょっとしたものなら入る ようだ。 もうすこし沢山のデータが扱えたらいいなぁとは思うので、 XC95144XL-TQ100 もいいか もしれない。値段も XC9572XL-VQ64 の倍はしない。 ただ、ステートマシンの勉強としては、この規模を卒業したら、 1ケタ上を考えたいの で、XC95144XL-TQ100 で遊ぶことはたぶんないだろう。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ (最終更新 Fri Jul 5 00:23:53 2002)