FRAMにアクセス (ブロック仕様編)
FRAM(強誘電体RAM)をアクセスするためのFPGAをテーマに、FPGAを設計するまでの一連の工程を記載して行こうと思います。
- ブロック仕様
- Verilog-HDLによるコーディング
- シミュレーション(RTLシミュレーション)
- Platform DesignerとFPGA Topの作成
- 論理合成とインプリメント
- NiosIIのコーディング
- NiosIIを含めたシミュレーション
本記事では、まずはブロックの仕様を記載します。
(後半に、FRAMとインターフェイスを行うSPIブロックのVerilogコードも記載しています。)
※FRAMのモデルは「CY15B102QN」となります。
(ちょうど、verilogのシミュレーションモデルがあったので。。。)
【背景】
昔の案件でFRAMにアクセスする機能が必要で、しかも、アクセス時間を短くしたかったため、バーストアクセスができるIPを探したのですが、見当たらなかったため、verilogで作りました。
その時は、必要な機能に限定して作成しましたが、今回は依頼されたものではないので、私の好きなように作ろうと思います。
ポイントとしては、色々なコマンド(Opcode)が発行でき、且つ ブートローダとして使えそうな機能も考慮してしみました。
- 概要
- 機能
- ブロック構成
- 入出力信号一覧
- 入出力タイミング
- 動作説明
- 内蔵RAMとFRAMアクセスの関係
- レジスタ詳細
- 設定例
- SPI I/Fのソースコード(記述:verilog-HDL)
- 使用ツール
- 最後に
概要
FRAM(CY15B102QN)デバイスに対し、リード/ライトを行います。
リード/ライト方法はSPIプロトコルで行います。
以下にFRAMデバイスの通信フォーマット例を示します。
機能
【CPU I/F (Avalon-MM)】
- MasterとSlaveに分かれ、入力信号MST_SLV(0:Master 1:Slave)により選択が可能。
- Masterを選択した場合、入力信号PRM_???に従って、FRAMから取得したデータをAvalon-MM(Master側)のブロックから出力します。
- Slaveを選択した場合、Avalon-MM(Slave側)でCPUから設定されたレジスタ値に従い、アクセスを行います。
- FRAMへの転送が完了すると、割り込みを発生します。尚、割り込みマスクが可能であり、割り込みステータスに"1"を書き込むことでクリアします。(割り込み信号はレベル信号)
- アクセスバイト数(バーストサイズ)は、レジスタREG_ASC[20:0]又は入力信号PRM_ASC[20:0]で設定が可能。尚、スレーブモード時の最大アクセスバイト数は内蔵RAMサイズに依存します。
- 出力(送信)バイト数は、レジスタREG_OTC又は入力信号PRM_OTC[1:0]で設定が可能。
- シリアルクロック(出力信号FRAM_SCLK)は内部クロックSYS_SLK[200MHz]を分周して生成し、最大50MHz(SYS_CLKの1/4分周)を出力。
- シリアルクロックの周波数は、レジスタREG_DIV[3:0]又は入力信号PRM_DIV[3:0]で設定が可能。
- 入力シリアルデータ(入力信号FRAM_MISO)は、SYS_CLK↑に同期してラッチし、レジスタREG_TAK[1:0]又は入力信号PRM_TAK[1:0]により、取り込みタイミングを調整することが可能。
ブロック構成
FRAMとI/Fを行うブロック(ブロック名:NML_FRAMIF)の構成図を以下に示します。
※CPUブロックは50MHzで動作します。
※TOPは、FPGAのTOPを示します。
入出力信号一覧
FRAM I/Fブロックの入出力信号の一覧を以下に示します。
入出力タイミング
FRAM I/Fブロックの入出力タイミングを以下に示します。
FRAM I/F信号
タイミング波形とレジスタ設定値との関係を以下に示します。
※出力信号FRAM_OUTEは、FRAMへのシリアルデータを出力しない場合はHi-Zしたいことも想定して補足信号としてあります。
FRAMデータ取り込みタイミング
シリアルクロックの最大周波数は50MHz[最小周期は20ns]となるため、FFから出力してFRAMへ届くまでの時間(シリアルクロックが届くまでの時間) と 届いてからFRAM I/Fブロックの入力FFまでの届く時間の合計が20ns以上の場合もあると考え、基準取り込みポイントから最大3クロック遅延させて取り込むことが可能です。
以下に経路遅延イメージを示します。また、取り込みタイミング図も示します。
Avalon-MM(Slave側)
リード時は、出力データを準備するためにWait信号(出力信号SAV_WIT)をアサートします。
また、レジスタと内蔵RAMをリードする場合でWait信号のアサート期間が変わります。
Avalon-MM(Master側)
wait信号(入力信号MAV_WIT)のアサート期間中は出力を保持します。
動作説明
FRAM I/Fブロックの動作に関して説明します。
マスタモード(入力信号MST_SLV=0)
マスタモードは入力信号による制御を可能とし、FRAMからの取得したデータをAvalon-MM Masterとしてライト制御します。
尚、このモードはFRAMのリード系コマンド(READ,SSRDなど)のみを想定しています。
- 入力信号PRM_DIV、PRM_POL、PRM_TAK、PRM_ACS、PRM_OTC、PRM_STA、PRM_CMD、PRM_ADDを設定します。
- PRM_ENBを"0"から"1"に設定します。これにより、動作を開始します。
- FRAMへコマンド(PRM_CMDの内容)発行を行い、PRM_OTC[1:0]に応じてアドレス発行(PRM_ADDの内容)を行います。
- FRAMから取得したシリアルデータを8bitパラレルデータに変換し、FIFOに格納します。
- FIFOがNot Emptyになると、Avalon-MM I/F(Master側)がFIFOをリードし、Avalon-MMライト動作を行います。尚、ライトアドレスは入力信号PRM_STAを加算して出力します。
- FRAMへのアクセスが完了すると、出力信号CPU_IRQをアサートします。尚、PRM_CLRを"1"にすることでクリアします。
※動作中は、出力信号MON_ENBが"1"になります。
スレーブモード(入力信号MST_SLV=1)
CPUからのレジスタ設定に応じて動作を行い、内蔵RAMに格納されたデータをFRAMへ出力し、FRAMから出力したデータを内蔵RAMに格納します。
従って、1回のFRAMへのリード又はライトはRAMサイズに依存します。
(内蔵RAMのサイズを大きくすることで、アクセスバイト数は大きくできます)
尚、内蔵RAMサイズは4096バイトとしています。
- レジスタに初期設定を行います。(REG_DIV、REG_POL、REG_TAK、REG_ACS、REG_OTC)
- FRAMへ出力したいデータをCPUから内蔵RAMへ格納します。(コマンドやアドレス、ライトデータなど)
- 処理イネーブルを"1"にします(レジスタREG_ENB)。これにより、動作を開始します。
- FRAMへの出力時は内蔵RAMからデータを取得してFRAMへ出力します。またFRAMから取得したデータは、8bitのパラレルデータに変換してRAMへ保存します。
- FRAMへのアクセスが完了すると、出力信号CPU_IRQをアサートします。尚、レジスタREG_ENBも自動的に"0"になるため、割り込みマスクを行い、レジスタREG_ENBの状態をポーリングすることにより、動作中か否かを知ることが可能です。
- CPUがFRAMから取得したデータを内蔵RAMから読み出す。(レジスタREG_BDT)
内蔵RAMとFRAMアクセスの関係
スレーブモード時の内蔵RAMとFRAM SPI通信のデータ構成の関係を以下に示します。
尚、FRAMアクセスの最初はCommand(Opcode)の出力となります。
※Command= "SSWR"と"SSRD"は特殊セクタアクセスとなり、256バイト以上のアクセスを行った場合は、特殊セクタの先頭アドレスに戻るため、グレーにしています。
マスタモード時は、内蔵RAMを介さず、取得したデータをそのままAvalon-MM Master側でFRAM I/Fブロック外部にライトします。
レジスタ詳細
FRAM I/Fのレジスタ詳細を以下に示します。
設定例
FRAM SPI通信のバイト数設定例を以下に示します。
スレーブモード
マスタモード
SPI I/Fのソースコード(記述:verilog-HDL)
FRAM I/Fの内部ブロックSPI I/F(モジュール名:NML_FRAMIF_SPI)のソースコードを以下に示します。
入出力信号の宣言と処理イネーブルがアサートされ内蔵RAMから最初のデータ(Command)をリードするための期間を生成します。
SPI通信期間を示すasc_enblを生成し、またアクセス終了後のWait期間を生成します。
シリアルクロックの生成、bitカウンタとByteカウンタを生成します。
尚、Byteカウンタは、CY16B102以上のデバイスでも対応できるよう、余分にbit幅をとっています。
SPI通信の出力と入力を示すフラグを生成し、内蔵RAMのアクセス制御を行います。
ベースとなるFRAM制御信号(base_*)を生成し、FFでラッチして出力します。
これにより、FPGAの出力FFを使用します。
FRAMからの入力シリアルデータラッチ(in_miso)し、基準取り込みタイミング信号を生成します。(入力FFを使用します)
基準取り込みタイミングを遅延します。
レジスタREG_TAKの設定値に応じて、取り込みタイミングを選択し、シリアルデータをパラレルデータに変換します。
変換したデータは、上記BUF_WDTでラッチします。
FRAMアクセス完了後、レジスタREG_ENBを"0"にするための信号REG_FINを生成します。
尚、この信号は後段ブロックでCPU_CLK(50MHz)で使用するため、High幅をSYS_CLKの8クロック分にしています。(CPU_CLKの2クロック分)
使用ツール
- 言語:verilog-HDL(ハードウェア用)、C言語(ソフトウェア用[NiosII用])
- シミュレータ:ModelSim Intel FPGA Starter Edition 10.5b
- 論理合成/インプリメント:Quartus Prime 18.1 Lite Edition
最後に
マスタモードとスレーブモードに分けたのは、試作を意図しています。
FRAMへのライトとリードも、マスタモードで行うことも可能ですが、リードだけに止めました。
機能試作や基板試作時は、スレーブモードを使ってFRAMに対して色々なコマンドを発行して、機能検討や基板変更を考えると思います。
その為、なるべく自由度が高いと思われるスレーブモードを入れました。