2014年2月25日火曜日

DDR2 SDRAMCの情報

このところ、どういう訳かDDR2 SDRAMコントローラの記事のページビューが多い。
DDR2 SDRAMコントローラを作るのが流行っているんだろうか?

現在時刻のページビュー

日単位のページビュー

週単位のページビュー

月単位のページビュー


閲覧者の内訳はこんな感じ





このブログの稚拙な文章では知りたい情報は得られないかもしれないので、役に立ちそうな情報源を書いておく。

・ DDR2 SDRAMのシミュレーションモデル
 VerilogのシミュレーションモデルがMicronのサイトから入手できる。
 DDR2 SDRAMの使い方や、仕様がよく判らない場合は、シミュレーションして動かしてみるのも一つの手だと思う。 大抵のDRAMはJEDEC規格に準拠している筈なので、実際に使うデバイスがMicron製でなくても仕様的には互換製があると思う。

    http://www.micron.com/products/dram/ddr2-sdram#fullPart

・ JEDEC規格書
 DDR2 SDRAMのJEDEC規格番号はJESD79-2* で、最新版はJESD79-2Fのようだ。
    http://www.jedec.org/standards-documents/docs/jesd-79-2e
    上記リンクアドレスは末尾が2eになっているが、リンク先のページでは2Fと表示されている。

・ Spartan-6のIODELAYやODDR等のハードマクロ
 User Guide UG381 に詳細仕様が記載されている。
    また、Xilinxの開発環境(ISE)をインストールしてある場合、インストール先のディレクトリ配下に各マクロのシミュレーション用モデルもインストールされている筈である。私はLinux版をインストールしており、私の環境では ****/ISE_DS/ISE/verilog/src/unisims/ にverilog版のシュミレーションモデルがインストールされている。  UG381の文書だけでは動きが理解しづらい場合は、このモデルを単体シミュレーションしてみたり、エディタで開いてソースを眺めてみるのも良いと思う。

・ その他
 以前、ELPIDAが「DDR2 SDRAMの使い方」というタイトルのユーザーズマニュアルを出していた。今でもネットで検索すれば見つかるかも知れない。

こんなところかな。

2014年2月23日日曜日

SDRAMCのMachXO2への実装 2

前回、150MHzでSDRAMのクロック系でタイミングエラーが1つ出ていた。
この構成ではクロックと他の信号とのスキューを同程度にしたくて、IOBのODDRXEというDDRレジスタを介してクロック出力していたのだが、このやり方を止めてPLLの出力を直接ピンに出すようにしたところ、タイミングエラーは出なくなった。スキュー調整はPLLの位相設定で行う。

そこで、クロックの上限を探って見たところ、160MHzまではエラー無しで合成できた。

が、しかし、このデザイン(160MHz)をFPGAにロードして動作させてみると、FAILする。
よくよく考えてみれば、実装しているSDRAMのタイミングパラメータは-7 (143MHz)品なので、160MHzはスペックオーバーである。そこで、クロックを140MHzにしてみたところ動作した。また、改めて150MHzを試したところこれも動作した。SDRAMに供給するクロック(下図のCLKOS)の位相は270°にしている。

150MHzは143MHzに対して+4.9%の値なので、動作マージンの範囲なのかも知れない。

動作している様子を動画撮影して、100MHz時と比べてみた。
手前が100MHz動作、奥が150MHz動作である。

ということで、150MHzまでは動作した。  すばらしい!  → MachXO2


2014年2月19日水曜日

SDRAMCのMachXO2への実装

以前このブログでSDR -SDRAMコントローラIPを作り、Spartan3E、Cyclone 3 (DE0)、 Lattice XP2に実装してみた。今回はそのコントローラをMachXO2に実装した。  このブログではメモリコントローラを作成することが多い気がするが、別にメモリコントローラが好きで好きでたまらないという訳でもないし、この分野の専門家でも無く、大容量の記憶領域を得ようとするとどうしてもFPGA外付けのメモリが必要になってしまうのでしょうがない。今回、MachXO2に実装しようとしているのも、目的はMachXO2 Breakout Boardを使ってロジアナもどき(なんちゃってロジアナ)を作りたいからだ。  GPIB IPの動作確認をしている時にバスの全信号を観測したいことが多々あったので、next themeとしてなんちゃってロジアナの作成をやってみることにした。

Breakout BoardへのSDR-SDRAMの実装は以前と同様のやり方で行った。
ちなみに、このBreakout BoardはCommunication Boxに組み込んだ物とは別の個体である。
Breakout Boardは予備の意味もあって3枚程所有している。

使用したSDRAMはISSIの128Mb(16MB) SDRAMでデータ幅は16bitである。
この基板のJ3, J5コネクタの信号は差動信号も考慮した配線になっている。

今回作るのはロジアナで想定している測定対象はGP-IBバス等の不平衡信号ではあるのだが、このJ3,J5の信号を信号入力用ポートとして使えば、色々と想定外の使い方の可能性も出てくる。このため、SDRAM用の信号はJ3,J5とは反対側のJ2,J4の端子を使用している。

RTLの方は以前作成したSDRAMCに若干の変更を加えている。
・ DDR2-SDRAMC等ではシミュレーションのために入出力バッファにSTA(静的タイミング解析)で得た伝搬遅延時間を加えているのだが、以前作成したSDRAMCではそれを行っていなかったので今回から加えることにした。  信号端をバッファモジュールに切り出した。

例えば、入出力バッファ(iobuf)は以下の様に記述している。

上位モジュール ... データ系

上位モジュール ... アドレス、コマンド系

iobufのソースをみて判る通り、モジュール内の遅延時間パラメータの値は0.0としている。SDRAMCはFPGAのハードマクロを使用していないので、各社のFPGAにも容易に実装できる。実際、以前のSDRAMC IP作成時にはXilinx Spartan3E、Altera Cyclone 3、 Lattice XP2に実装して動かした。なので、このモジュール内で特定の遅延時間を書いてしまうと、デバイスや実装が変わる度にその値を書き換えることになってしまい旨くない。そこで、モジュール内の値は0.0とし、テストベンチ側でdefparam文で実際の値を設定するようにした。

これ以外の変更点として、SDRAMの容量を64Mbから512Mbまで対応するようにした。


このSDRAMCを2種類のアーキテクチャで実装してみた。

1つ目

合成は成功、タイミングもMetした。

zumi32にメモリ R/Wチェックプログラムをロードして48時間程走らせてみたが問題なかった。

2つ目は、LFSRによるメモリR/Wモジュールの構成で、DDR3 SDRAMCの時に作ったやつの32bitバス版を作成した。

こちらも合成も成功した。


動作している様子


PC側のプログラムからFPGA内部のpass カウンタとfail カウンタの値をポーリングして表示している。FAIL_Cの値はゼロなのでエラーは検出されていない。


このアーキテクチャでSDRAMの駆動周波数を150MHzにして合成してみたところ、1つだけタイミングエラーとなった。

DRAM_CLK端子の最小パルス幅が9.614nsの為、これを越える周波数は設定できないようである。

無理やりコンフィグデータを生成し、FPGAにプログラムして動かしてみたところ結果は以下の様になった。

まったく駄目という訳ではなく、暫く動いてからFAILする。

ということで、このデバイスでSDRAMを動かす場合は100MHz当たりが上限と考えたほうが良さそうである。少なくとも、私のデザインでは。

2014年2月2日日曜日

Communication Box 25 (GPIB IPの作成 14)

今回は、サービスリクエスト、シリアルポールと割込み等の確認をおこなった。

・パラレルポール
パラレルポールであるが、現有GPIB I/F付き装置の資料を参照したところ、何れの装置も非サポートとあるため現状実機確認不可である。それほど積極的に使う機能では無いのかも知れない。

・シリアルポール
テクトロのオシロはアプリケーションメニュー機能というのがあって、画面にユーザ独自のメニューを表示して操作者がボタンで一つ項目を選択すると、GP-IBのサービスリクエストでイベントを通知させられる。 この機能を利用してサービスリクエスト、シリアルポール、割込みの動作確認をすることにしたのだが、シリアルポールで想定外の事象に遭遇した。またもや、私のGP-IB規格の解釈に誤りがあるのかも知れない。
 シリアルポールの手順は、コントローラがバスをコマンドモードにしてSPEコマンドをバスに送信し、次にTA_nメッセージでポーリングする対象をトーカーに指定する。それからバスのモードをデータモードにすると、指定されたデバイスはステータスバイトをバスに送信する。複数のデバイスをポーリングする場合はTA_n指定、ステータスバイト受信の処理を必要数繰り返し、最後にバスをコマンドモードにしてSPDコマンドを送出してシリアルポールを終了する。(バスに通知する。)
デジタルオシロに対してシリアルポールを行ったところ、以下のようになった。

右端の白い領域がオシロがステータスバイトを出力している部分で、写真の通り複数バイトが連続して出力されている。朝日新聞社編の「プロトコルハンドブック」によれば、このステータスバイトは標準的には1バイト長であるが、多バイト長でもよく最終バイトにはEOIが付加されるとある。

現状のIPはこの記述を参考にして複数バイトにも対応するよう作ってある。
上記で出力されるバイト列は有限長なのか見てみたのだが、何バイト受信しても途切れることが無く、また値はすべて同一であった。 ACタイミング的な問題を疑ってもみたのだが、以下のようにハンドシェイクに問題があるとは思えない。もしあれば通常のハンドシェイクも問題が出る筈だ。

そこで、HPのオシロではどうか見てみたところ同じ動作だった。




GP-620というGP-IBアダプタの場合は1バイト長であった。


GP-620の資料によると、この装置はNIのGP-IBコントローラを使っているようである。もしかすると、両オシロはコントローラが違うのかも知れない。即ち、この動作はコントローラ依存なのかも知れない。オシロの蓋を開けて内部を確認すればハッキリするがそこまではしたくない。
岡村廸夫氏の「標準ディジタル・バス(IEEE-488)とその応用」ではステータスバイトについて以下の様に書かれている。

ということで、この動作は規格上もあり得るものなのかも知れない。 ただ、そうなると一つの疑問が出てくる。 トーカー指定を切り替えるにも、また、シリアルポールを終了するためにも、コントローラはバスのモードをコマンドモードに変更して行う必要がある。しかし、ステータスバイト送出側がその完了を通知しない以上、どのタイミングでそれを行うべきかの判断が難しい。。。気がする。
何も考えずにATN信号を操作すると、ハンドシェイクのど真ん中でそれが行われる可能性もある。そのような場合でも問題なくモードが変わり通信が行われていくか・・・? そうなると、コントローラ側が意図的にハンドシェイクへの応答を止めて停止期間を作り、そのタイミングでモードを変える等の動作が必要になると思われる。 本IPの受信FIFOの深度は32段なので、その分の転送は止めようが無いが、FIFOからの読み出しを行わなければFIFOがFULLになった時点でハンドシェイクを停止させることは可能だ。そこで、このやり方で停止期間を作ってバスのモードを変更することにした。これはソフトウェアでの処理になる。 何とも泥臭い処理である。
また、念のためハンドシェイク停止時はNRFDがLとなるよう、gpib_lsn.vの変更も行った。


上記の処置をして動作確認を続けた。
ソフトウェアは以下の通り。 main()でメニューやサービスリクエストで上げるイベントの種別を設定後割込みを許可し無限ループに入る。  サービスリクエストが発生・即ち、SREQがLになると割込みが発生し、hw_interrupt()が実行される。

シリアルポール処理部

ここに示したプログラムはあくまでも動作確認のためのものなので、余計なprintfがあったり、関数の戻り値に実用性が無かったりする。

オシロの画面
 
メニューの右側のボタンを押下するとイベントが発生する。

プログラムの出力


一応、サービスリクエスト、シリアルポール、割込みも全ての要因ではないが確認は取れた。
後は測定器を制御したり測定値を吸い上げたりといったソフトウェアを作成していくことになるが、これは追々やっていくことにする。 ということで、これでGP-IB IPとCommunication Box作成のプロジェクトは終えようと思う。

今回のプロジェクトでは必要な部・機材関係を格安で入手出来る等、幾つもの幸運なことがあった。
LatticeのMachXO2を初めて使ってみたが使いやすい良いデバイスだと感じた。と言っても性能限界まで使っている訳ではないが。。。 もっと色々なものを作ってみたいと思わせてくれるデバイスではある。

RTL置き場 (http://www.hi-ho.ne.jp/bravo-fpga/)のsnapshotは最新版に更新した。



2014年1月27日月曜日

Communication Box 24 (GPIB IPの作成 13)

GP-IB I/Fの基本的動作確認もとれ、Communication Boxのハードウェアとしては問題無いと判断できるので以下の様に設置した。

我がpoor man's labはFLUKEのマルチメータも所有している。この測定器の外部I/FはRS232CなのでCommunication BoxのCOMポートと接続した。これで電源、オシロスコープ、マルチメータをCommunication Box経由で制御できる環境が整った。

GP-IB IPだが、若干の仕様変更してトーカ・オンリーモードとリスン・オンリモードも使えるようにした。 具体的にはCONFIGレジスタのTLK_EN、LSN_ENビットをそれぞれR/W可能とし、そこで設定するようにした。


GP-IBバスに接続する機器がトーカ役とリスナ役の2台のみの場合は、最初からその役割専用モードにして使用する場合もある。そのような使い方にも対応できるようにした。

2014年1月26日日曜日

Communication Box 23 (GPIB IPの作成 12)

問合せコマンド(query command)が連続して実行できない理由が判った。
GPIBバスのIFC、REN、ATN、EOI、SRQの信号は基本的にLINEレジスタから制御する。


この内、EOIはやや特殊である。
ライトはIPがコントローラとして動作していて且つコマンドモードの場合に有効となる。つまり、その場合にライトした値がバスに出力される。これに対してリードは常にバスの信号の状態を返す。問合せコマンドに対する応答データを受信後バスをコマンドモードに戻す際に、ソフトウェアを以下のように記述していた。

  pGPIB->LINE |= LINE_ATN

これで、ATNのみをTRUEにしているつもりだった。GPIBバスのコマンドモードとデータモードはATNのレベル(HかLか)によって決まる。また、上記のとおりEOIはリードとライトで参照する対象が異なるのでこの記述だと、データモード側のEOI値(現在のバスの状態)が、コマンドモード側のEOIに設定されてしまう。 問合せの応答データの最終バイトにはデリミタとしてEOIがアサートされるが、このEOIがネゲートされるタイミング次第では上記のモード切替のリードでアサートされたEOIがリードされることになり、それがコマンドモードで設定されることになる。これが原因で、以降のコマンド送出が滞ってしまっていた。コマンドモードでEOIに1をライトするのはパラレルポールを行う場合のみであり、それ以外ではEOIは0をライトしなければならない。したがって、上記は以下のように記述すべきであった。

       pGPIB->LINE = (pGPIB->LINE & ~LINE_EOI) | LINE_ATN

つまり、リード値のEOIの部分をマスクしてATNの部分を1にする。このようにソフトウェアを修正することで連続実行も可能となった。この部分はレジスタの仕様を変更したほうがいいかな。。。コマンドモード時以外は0になるようにした。

オシロ2台をGPIBバスに接続して、それぞれに問合せコマンドを発行してみた。


プログラム


結果


それぞれで3回づつ連続した場合




FIFOの閾値とか、割込み、シリアル/パラレルポール等々、まだ確認すべきものはあるが、一応これで基本的な送受信の確認は取れたと思う。


2014年1月25日土曜日

Communication Box 22 (GPIB IPの作成 11)

先日入手したGPIBアダプタを相手にして動作確認を始めたところ、コマンドモードでのハンドシェイクは行うのだが、データモードになるとNDACがHレベルに上がりっぱなしになりハンドシェイクしない。 このGPIBアダプタはレギュレータ電源用GPIBアダプタだが電源本体は持って無いので、アダプタ単体のみを通信相手として使ってみている。それが原因かとも思ったのだが、どうもおかしい。こちらのIPからGPIBアダプタに対してLA_MSGでリスナ指定をしているのだが、それが正しく行われないためにGPIBアダプタがリスナにならず、NDACをLにドライブしていないようだ。やはり、原因はこちらのIP側にある筈である。。。。あれこれ思案した結果、データバスの論理が逆なのでは無いか?との考えに至った。  GPIBバスの信号は負論理なのだが、データバスに関してはデータなのだから正論理も負論理も無いだろう、だからそのまま、つまり正論理だろうと思い込んでいたのだ。ところが、実際はデータバスも負論理にする必要があるようだ。 実際、改めて参考資料を読み直したところ、プロトコルハンドブックにDIOも負論理との記述があった。つまり、GPIBの規格について一つ誤解していた。そこで、データバスを負論理に修正した結果データモードでもハンドシェイクするようになった。

以下はハンドシェイクの波形で、上がDAV、下がNRFDである。


こちらは、上がDAV、下がNDAC


測定は以下の状態で行った。 GPIBアダプタ側のコネクタ側から1.5mのケーブルで信号を引いてきてその先の(治具)基板の信号をオシロで観測している。上記で信号反射のような波形が見えているのはその所為ではないかと思う。


ハンドシェイクが正常に行われるようになったので、GPIBアダプタにPWIBという問い合わせコマンドを送って機種名を取得できるかやってみたが、結果は取得できなかった。 電源装置が繋がっていないのだから返信すべき機種情報が判るはずもないので、この反応は当然といえば当然であろう。

ということで、今度は通信相手をAgilentのE3631Aに変えて動作確認するしてみることにした。
以下のプログラムで6Vチャンネルの出力電圧を制御してみた。


電源側の動作の様子


出力


電圧設定部をforループにして繰り返してみた。


プログラム通りの出力が得られている。

今度は、HPの54616C(デジタルオシロ)と通信を試してみた。
以下のようにしてオシロの画面に文字列を表示させる。




以下のプログラムで*IDN?コマンドを送って機種名を取得してみた。


取得できた。


一応通信は出来ていそうであるが、一つ不可解な現象が見つかった。
問い合わせコマンドを連続すると2回目のコマンド通信時にハンドシェイクが上手くいかなくなるようで、いつまで待ってもコマンドFIFOが空にならない。




うーむ…

でも、まぁ、昨年の8月頃に始めてから漸く実機で通信ができる段階まで来れた。いつものIP作成と違い今回は筐体の加工や回路作成もあったのでそれなりに時間がかかってしまったが、あともう少しで完成しそうだ。

先日入手したTektronixのデジタルオシロだが非常に使いやすい。
いやーー、良い買い物をした! って言う感じだ。

ERROR: Failed to spawn fakeroot worker to run ...

なにかと忙しくてなかなか趣味の時間を確保できない。 ...orz  家の開発機のOSはLinux Mintなのだが、最近バージョンを22に更新したところ、myCNC用のpetalinuxをビルドできなくなってしまった。ビルドの途中で ERROR: Failed to spawn ...