nao-milkの経験ブログ

25年間の半導体エンジニア経験で知り得た内容を記載したブログです。

FRAMにアクセス (協調シミュレーション編)

f:id:nao-milk:20210426133742p:plain

NIOSを含めたシミュレーションの実行になります。

 

シミュレーション環境の構築方法とNiosのシミュレーション用コードの生成方法、及びシミュレーション波形を添付します。

 

 

NIOSプログラムやテストベンチは、前回の記事をご参照ください。

nao-milk.hatenablog.com

 

シミュレーション環境構築

シミュレーション環境を構築しますが、必要なファイルなどのリストを作成するのが面倒なので、Platform Designer で環境を作成し、生成されたスクリプトファイルを改造して使用します。

 

実行スクリプトファイル生成

Quartusを起動し、「Platform Designer」を立ち上げて作成したQsysファイルを読み込みます。

その後、[Generate]→[Generate Tesetbench System]を選択します。

f:id:nao-milk:20210426100651p:plain

Generation Testbench System

「Generation」Windowが表示され、"Generate"ボタンをクリックします。

以下の選択内容で十分です。(生成されたテストベンチは使用しないので。。。)

f:id:nao-milk:20210426100857p:plain

Generation

"Generate"ボタンをクリックすると、Quartus実行フォルダに以下のフォルダが出来上がります。

フォルダ

 <Platform Designerで作成したモジュール名>/testbench/mentor

 

このフォルダに実行スクリプトファイル(ファイル名:msim_setup.tcl)が出来上がります。

このスクリプトファイルは、「Platform Designerで作成したモジュール」をトップとしたシミュレーション環境になるため、FPGA TOPからシミュレーションする場合は、改造が必要になります。

尚、Platform Designerで作成した必要なIPのリストはあるので、あとは、ユーザの作成したソースを追加するだけとなります。

 

スクリプトファイルの修正

msim_setup.tclの修正内容を説明します。

1、NIOSプログラムファイルのコピー元を変更

  Nios II - Eclipseコンパイルしたデータのコピー元を変更します。

f:id:nao-milk:20210426103124p:plain

コピー元の変更

2、テストベンチのコメントアウト

  Platform Designerが生成したテストベンチをコメントアウトします。

f:id:nao-milk:20210426103602p:plain

テストベンチのコメントアウト

3、ユーザー回路の追加

  ユーザー回路を追加し、テストベンチや必要なファイルを追加します。

 私の場合、alias comとは別に、新しいaliasを作成して追加します。

f:id:nao-milk:20210426104033p:plain

  尚、TB_TOP.vとFRAM_SPI.v(FRAMモデル)は、シミュレーション実行フォルダにあります。

 

4、elab修正

  alias elabでは、vsimを実行しています。

 このままの実行では、Platform Designerが生成したテストベンチとなっているため、修正します。

 TB_TOP.vがテストベンチとなるため、$TOP_LEVEL_NAMEを「TB_TOP」に修正します。

 

以上で、msim_setup.tclの修正は終了となります。

 

NIOSプログラム

NIOSのプログラムデータは、CPU_MEMに格納されるようになっています。

このファイルを作成する方法を説明します。

 

オプション設定

「Nios II - Eclipse」を起動し、プロジェクトを読み込みます。

シミュレーション用のコードにするため、オプションを設定します。

「BSP Editor」を起動し、"enable_sim_option"にチェックを入れます。

※入れない場合は、シミュレーションでNiosが動き出すまでに時間がかかります。

また、「Debug Level」と「Optimization level」を変更するともっと速くなります。

以下は、私の設定です。

f:id:nao-milk:20210426105634p:plain

f:id:nao-milk:20210426105731p:plain

 

コード生成

上記設定を行った後、再度コンパイルを行います。

その後、[Make Targets]→[Build]を選択し、「mem_init_generate」を選択して、"Build"ボタンをクリックします。

f:id:nao-milk:20210426110124p:plain

NiosのCソースを変更し、シミュレーションする場合は必ず実行する必要があります。

また、ここで生成したファイルは「msim_setup.tcl」のfile_copyでシミュレーション環境にコピーされます。

 

以上までが、シミュレーションを実行するまでの準備となります。

 

シミュレーションの実行

ModelSimを起動し、シミュレーションを実行します。

実行方法は、以下の通りです。

1、[File] → [Change Directory]で、

  <Platform Designerで作成したモジュール名>/testbench/mentor

  に移ります。

2、msim_setup.tclを実行します。

  2通りあります。

  [Tools] → [Tcl] → [Execute Macro]から実行する。

  

f:id:nao-milk:20210426111619p:plain

Tcl実行

  "Transcript"から実行する。

f:id:nao-milk:20210426111904p:plain

doで実行

3、コンパイルと実行

  msim_setup.tclを実行後、"Transcript"でコンパイルし、エラボレートします。

  尚、msim_setup.tclを実行すると、file_copyが実行されています。

 コマンドの順番は以下の通りです。

 > com

 > com_user

 > com_tb

 > elab

 となります。

 あとは、"run"してシミュレーションを実行するだけです。

 

シミュレーション結果

シミュレーション波形を添付します。

 

全体波形

Niosソース内で、port_aにステップ番号を出力しているので、それを目安にどの部分を実行しているか分かります。

波形の「port_a_export」がそれにあたります。

リセット解除後、約400usでNIOSの動作が開始します。(port_aが0x00 → 0x01に変化)

また、ソースの終了は、port_a=0xFFになり、FRAM_WP_N=1になると終了となります。

(0xFFの期間が長いのは、printfを実行しているためです。)

f:id:nao-milk:20210426114552p:plain

全体波形

マスタモード Load

リセット解除後、マスタモードによるロード動作になります。

入力信号MST_SLVとPRM_???はテストベンチからforceで値を入力し、動作させています。(ブート制御回路を作成するのが面倒だったので、外部から動かしました。)

ここでは、FRAMのDevice ID、Serial No、特殊セクタ、通常メモリをメモリPARAMETERに保存しています。

f:id:nao-milk:20210426115405p:plain

マスタモード Load

ステータスリード

FRAMのステータスレジスタをリードし、メモリPARAMETERの指定した番地へ保存し、リードしていることが確認できます。(変数FramSTは、メモリPARAMETERの0x920番地に関連付け)

尚、データバス幅は32bitとなるため、アドレスは「÷4」した値になります。

f:id:nao-milk:20210426120442p:plain

ステータスリード

Device ID及びSerial No確認

メモリPARAMETERの指定した番地をリードしています。

f:id:nao-milk:20210426120739p:plain

Device ID確認

f:id:nao-milk:20210426120858p:plain

Serial No確認

データ書き換え

メモリPARAMETERの指定した番地をリードし、リードしたデータを加工し書き戻しています。

f:id:nao-milk:20210426121848p:plain

データ書き換え

尚、FramSS,FramDTも書き換えています。

メモリPARAMETERからFRAM I/Fへ転送

メモリPARAMETERの指定した番地をリードし、FRAM I/Fへライトしています。

f:id:nao-milk:20210426123409p:plain

FRAM I/Fへ転送

FRAM I/FからメモリPARAMETERへ転送

FRAM I/Fからデータをリードし、メモリPARAMETERへ保存しています。

メモリPARAMETERの保存は、FramTMとなります。

f:id:nao-milk:20210426123741p:plain

FRAM I/Fから転送

割り込み動作

FRAMへのアクセスが完了し、割り込み(irq[0])が発生。

その後、割り込みクリアして割り込みが解除されます。

f:id:nao-milk:20210426124412p:plain

割り込み動作

比較結果

Niosソース及びテストベンチでの比較結果は、動作が終了するとerror数を表示します。

以下が結果表示内容です。

f:id:nao-milk:20210426124738p:plain

比較結果

比較結果のerror数が0を表示したため、データエラーは無しになります。

 

最後に

実機があれば、SignalTapでFPGAの内部波形を確認してデバッグが可能ですが、上記のように接続関係や基本動作を確認する上では、シミュレーションが速いと思います。

SignalTapでは、保存する信号と保存期間はRAMの空き容量に依存し、見たい所が見れない場合もあります。

また、クロックが何系統もあると、保存クロックに悩んでしまいます。

 

今回、「__attribute__」を使って別メモリに変数を関連付けました。

それが思い通りになっているかも、波形で確認ができます。

 

「FRAMにアクセス」をテーマに、半導体(FPGAですが)を実機で動かす手前までの工程をざっくりですがブログに記載しました。

ここまで2回のシミュレーションを行い、動作確認をしています。

FRAM I/Fブロックのシミュレーションでは、ブロック自体にバグが無いかの確認のため。

FPGA TOPからのシミュレーションでは、各ブロックの接続関係と矛盾点が無いかの確認のため。

このあとは、基板上のデバイス間接続を確認するため、Niosコードをそれ用に変更していきます。

 

もし上記シミュレーション無しで、基板で確認すると、どこが悪いのかの切り分けができず、余計に時間がかかります。

Niosを含めたシミュレーション環境構築は非常に簡単です。

もし実機で動かない場合は、シミュレーションで確認してみるのも良いかもしれません。