guruguru123’s diary

かなり雑な作業日記です。

SDRAMコントローラの作成とRS232C通信ブロックとの接続

 以前SDRAMコントローラを作ろうとして失敗、その代わりにFPGA内部RAMを使っていた。しかし、SerDesを用いてAD9851用の大量データを蓄えるとなると容量が明らかに足りない。そこで改めてSDRAMコントローラを作成することにした。

今回はZPUinoのソースにあるSDRAMコントローラを参考に作成していった。

以前も書いたが、PapilioProに乗っているSDRAMはMT48LC4M16A2。4バンクでロウアドレス12bit、カラムアドレス8bitで指定し、1アドレスに16bit格納できる。なぜかPapilio Pro上のSpaltan6の配線図を見るとアドレス信号線が13本出ているため、このうち使わない13bit目は'0'としておく。

AD9851チューニングワードは40biであり、おそらく40bitに何ビットか情報を加えることになるため、16bitでは足りない。参考にするソースでは32bitを1セットにするためにカラムアドレスの下位1bitを使って実現していた。今回は練習として、このソースと同じく32bitを格納するとした。

SDRAMコントローラの記述が終わったので、前回使った、コマンド受付用RS232C通信ブロックを書き直した。確認用としてコマンドはrew1,rew2で書き込み、rer1,rer2で読み出しを行うとした。格納する32bitはキーボードから入力する。

rew1,rew2:このコマンドw受け付けた後、データが32bitになるまでデータを受け付 ける。32bitになったらreq_writeを立ち上げ、アドレスを有効にする。

rer1,rer2:このコマンドを受け付けたとき、req_readを立ち上げ、アドレスを指定する。このまま読み出し完了信号(data_validのアサート)を待つ。信号が来たらRS232C通信にてデータをPCへ送る。

動作テストを行ったところ、32bitが正常に書き込み、読み出しができた。

これをSetDesと連携して使って行きたい。

RS232C通信を用いてDDSへデータの書き込み

前回はTeraTermからFPGAへコマンドを送り、wdでデータを保持、rdでデータを返した。今回はこれを使ってRS232C通信を用いてFPGAへコマンドの送信と、コマンドによってDDS用のデータの受信、DDSへのデータのドライブを行った。

DDS用の40bitデータはアスキーコードで10文字とし、これを16進数に変換して用いる。まずはじめにこの変換機構を作成した。複雑なことはせず、受信した8bitのアスキーコードをただcase文で判定し、用意しておいた40bitのレジスタに4bitずつ入れていくだけ。RS232C送信用の変換(16進数からアスキー)も作ったため記述量が多くなってしまったが、データ確認に必要なのでしょうがない。

変換機構ができたので、前に作ったDDSドライブ用のコンポーネントと組み合わせてみた。今回のコマンドは今後複数のDDSを扱うことを見越して、40bit受信をDDS1、DDSへのドライブをout1とした。

試しに手打ちでTeraTermから40bitデータを送って見たところDDSの駆動が確認できた。

今回はDCMをいれずにクロックは32MHのまま作ったが、周波数を上げて動作確認を行いたい。また、LabVIEWをインターフェースとして周波数・位相を制御するといったものができつつあるため、そちらと連携させていきたい。

rs232c通信を用いてコマンド送信:基礎編

AD9851の出力周波数を変えたり、複数動かすためには外部からコマンドを入力して制御することになるため、RS232C通信でコマンドを送ることにした。今回は基礎作り。

今回はTERA TERMを使ってFPGAアスキーでwdと送ると40bit受付待機、rdと送るとその40bitのうち下位8bitを返すというものを作成した。40bitはアスキーで5文字(8bit×5)とした。

動作させてみたが、現在どの状態にあるかわからず入力しづらかったため、状態遷移用4bitレジスタをLEDとつなげて状態遷移がうまくいっていることが確認でき、入力したデータがきちんと返ってきていることも確認できた。

AD9851ドライブ用データのRS232C通信での転送

前回はRS232C通信によって、あらかじめ蓄えられているADF9851ドライブ用データの読み出し先を選択する機構を作った。

今回は蓄えるデータもRS232C通信でFPGA上のRAMに書き込みできるものをつくっていく。データ生成部も後々必要になるが、今回は手打ちでテキストファイルを作成した。このファイルをTeraTermを用いてFPGAに転送、文字列を判定して、内部RAMに書き込みを行う。

一通り作ってみたが、うまく動作しない。原因を調べていると、内部RAM用の信号が、外部からの入力と接続されていないことと、文字列判定がうまくいっていないことがわかった。これらを改善していく。

AD9851ドライブ用データをRS232C通信を用いてPCから選択

そろそろ外部でデータ生成をして、それをRAMに格納して順次読み出し、AD9851をドライブする。といったものを作っていきたい。

今回は、PCからデータを受け渡す機構として、以前も出てきたRS232Cを使って試したいと思う。いきなりデータ生成まで作るのは大変なので、今日はとりあえずRS232Cのブロックを組み込んで、前回の状態選択の入力をPCから行えるものをつくってみた。

状態が5つしかないので、wを0、r1を1、r2を2、r3を3、r4を4のキーを押すことによって指定するようにした。0,1,2,3,4はアスキーコードの16進でX'30'、X'31'、X'32'、X'33、'X'34'であるので、それらが入力されたら指定された状態へ、それ以外の入力は待機状態のままになる。今回もPC側からの入力にはTera_Termを用いた。

とりあえず組んで、書き込みをしたところ、またリクエスト信号が立ち上がりっぱなしになっていたようだ。そこを修正したら、正しい出力が確認できた。

AD9851へのドライブ信号を外部入力から選択

前回、AD9851を100MHzでドライブすることができたため、今回は外部入力から状態遷移(4データのRAMへの書き込み、それぞれのデータの読み出し)を行えるように組み替えた。I/Oポートにそれぞれのリクエスト信号に対応する5つのピンを設け、それをグラウンドから5Vにして、状態を選択するようにした。わかりづらいが、以下の図のようにPapilio上部5本の緑の信号線が各リクエスト信号になっており、そこに今はどこにも刺さっていない黄色い5V電圧ピンを接続して、状態指定を行う。これにより、外部入力からAD9851へのドライブ信号の選択が行えた。

f:id:guruguru123:20170523104534j:plain

AD9851へW_CLKの周波数を上げてドライブ

32MHzの周期を3.125nsだと一桁勘違いしていたため(本当は31.25ns)前回はW_CLKを分周して用いていた。そこで、今回は全ブロックを32MHzで動作するものを作成した。

また、これが動作したため、DCMを用いて、W_CLKの周波数を上げてAD9851へドライブするものを試した。今回は50MHzと100MHzで動作させた。100MHzでも問題なく動作することが確認できた。