2009/01/06(火)[SOPC] 長船さんのMMC/SPIインタフェース

はじめに

SPIコアのコメントで,長船さんからSDカードアクセスまで動作した実績のIPを開示いただいた.これをNEEKに組み込んでみようというネタ.

動作確認ができたのでクローズ.HDL開示は別記事にて予定...



問題発生

いただいたVHDLコードをとりこんで,SOPC Builderで論理合成をパス.しかし,Nios II IDEで作ったコードをダウンロード実行してもSDカードのIDLEへの遷移が確認できず(デバッガによるトレース).

実績のあるIPであることから,端子割付やタイミング設定が怪しまれる.ModelSimは,WEB editionだとVerilog-HDLとVHDLの混在シミュレーションができない*1

勉強もかねて,Verilog-HDLへの移植を行うこととした.


*1 : ModelSIM SE以上でないといけないハズ...?

やったこと/やってること/やろうとしていること

やったこと~1

  • 机上確認
    • Verilog移植\[color:#0000FF:OK@6/Jan./2009]\長船さんから公開していただいたSPI interface IPを元に移植.FatFSも最近のものへと置換した.\レジスタ初期化漏れをsimulationで検出し,修正済み.\(実使用上は問題ない.合成時にロジックが増えるかもしれないので,ゲート数削減のためにリセット時未初期化にしたのかもしれない.)\[color:#0000FF:OK@7/Jan./2009]\tclを手動編集:set_interface_property avalon_slave_0 addressSpan 1024\TOPレベルモジュールのport宣言でin/outを間違っていた.\Timeout検出用のカウンタ(FRC)の実装漏れ….あとで処理しようとして放置していた.ボケとる.
    • Simulation確認\[color:#0000FF:たぶんOK@6/Jan./2009]\制御レジスタへのアクセス,SCKtxdatレジスタの変化を確認できた.
    • ピンアサイン確認\[color:#0000FF:SDまわり問題なしぽい.]@1650訂正\TOP moduleにて,DI/DOを逆に接続していた.下表のようにまとめてみると間違いに気づけるわ….\本日実機を持ってきていないのでここまで.\[small:参考:NEEKの端子一覧(まとめなおして移動するかも?)]
SD pin symbol name Direction HSMC name HSMC pin FPGA pin name
CMD/DIHC_SD_CMDFPGA.outputHSMC_D3HSMC#44FPGA-L6
DAT/DOHC_SD_DATFPGA.inputHSMC_D5HSMC#48FPGA-M3
DAT3/CSHC_SD_DAT3FPGA.outputHSMC_D8HSMC#53FPGA-N8
CLKHC_SD_CLKFPGA.outputHSMC_TX_p8HSMC#101FPGA-M2

  • 実機確認
    • signal測定\[del:レベル確認(アナログ),SCK確認,SDI確認(SD挿入時).(TxDataは0xFFなので変化しない)]
    • タイミング確認(実時間)\\

何か出ているならロジアナで吸い上げてタイミングを確認する.

    • SD応答確認

期待通りならSDカードを取り替えたりして確認する.

やったこと~2

ModelSim(WebEdition)にて,タイミング確認.

  • DMA機能を使わず,SPI部のみを使った動作確認\→正常に動作した
  • DMA機能のステートマシンチェック\→シミュレーションレベルでは正常そう
  • DPRAMアクセス\write機能が無かったのでエイヤで実装した.\byte enableを使ってBYTEアクセスを許容し,write時にもDMA転送ができるように見越しても良いだろう.

最終日のオチ

  • Verilogへの移植の際に実装漏れ,実装ミスがあった.
  • MegaWizardで生成したDualport RAMブロックについても,出力段にレジスタを入れていたため,リードレイテンシ2でのCPU読み出しが成功するときとしないときがあった.\NiosII IDEから8bit/16bit/32bitアクセスを行った際に,連続・ステップ実行・Memory Dumpで読み出せる値が変化したことから明確になった.

※32bit接続のIPであっても,NiosIIのDynamicBUS sizing?により必要な値(BYTE)だけを正しく取得することができた.おそらくarbitorのあたりでうまいことやってるのだろう.



メモ

SPI/MMCインタフェースIPの移植

Avalon-MM I/Fの参考にさせていただきました.Quartus II 8.1の SOPC builderにある,Wizardを使ったりしながら再構築.tclファイルを作らせるために,Wizardを使ったほうが便利かもしれません(慣れればテキストのほうが早いか?).

当初はAvalon-MMの読み出しにレイテンシ2としていたのが不思議であったが,メモリセルのレイテンシであることが理解できた.レジスタリードについては,常にデコードしており,chipselect信号がアサートされればreaddataに正しい値が出力される.

レイテンシ0の場合って,前段のDDがアドレス・制御信号を出した次のクロックで出力をラッチするんですよね...アービタも通るし,配置制約として効いてきそうな気がしますねぇ.

動作としては,SDからリード時に,IP内のDPRAMへ指定ワード数だけデータ転送を行うIPでした.CPUのポーリング動作が要らないので便利そうです.
書き出しはCPU転送になっているようですが,現状読み出ししか考えて無いので問題なし.

拡張してAvalon-ST source portとしてデータクラスタだけ吐き出せると旨いかもしれないですね.ストリーミング再生時,CPUを介さずに音声なり動画なりを再生させることができそう.
まだまだ先の話ですがtp252_shock



モジュールのアドレス空間

offset symbol description
0statusSPIステータス,送受信データ(8bit)
1divideSPI clockに用いるmodule入力クロックの分周比(FofSCK = 入力周波数/divide/2)
2timerタイムアウト検出用ダウンカウンタ(module input clockで動作).0で止まる
3reserved0(予約/現実装ではstatusが見える)
4dmastatusDMAステータス
5~reserved[123](予約)
128~readbuff[128]DMA転送バッファ(現状読み出しのみ)

※offsetは,32bit word指定.CPUからのアドレスは x4して見える.※使用メモリ256Word = 1024Byte = 10bit

ビットフィールド

status(MMC IF status)
bit description mmc_spi.hシンボル
31-16const zero-
15割込み許可フラグ1:mmc_irq_enable
14-13const zero-
12MMC I/F FRCゼロフラグ1:mmc_zf_bitmask
11MMC-Write Protect1:mmc_wp_bitmask
10MMC-Card Detection1:mmc_cd_bitmask
9MMC I/F転送フラグ(0書き込みで転送開始要求)1:mmc_commexit / 0:mmc_commstart
8MMC Chip Select(Active Low)1:mmc_selnegete / 0:mmc_selassert
7-0MMC I/F受信データ8bitデータ.読み出し=RxData,書き込み=TxData(txdataのリードバック不可)
dmastatus
bit description mmc_spi.hシンボル
31-16const zero-
15DMA function IRQ enable bit(1:enable, 0:disable)mmc_dmairq_enable
14assert(0->1) when transfer-endsmmc_dmadone_bitmask
131:受信データエラー@SPImmc_dmade_bitmask
121:受信タイムアウト@SPImmc_dmato_bitmask
11const zero-
10w1:転送開始,r1:転送中/r0:転送終了mmc_dmastart
9const zero-
8-0転送バイト数-
OK キャンセル 確認 その他