こんにちは!Latticeチーム新人エンジニアのりょすです。
前回は、RTL設計にて、SPI通信モジュールを作成しました。
今回は、作成したモジュールのシミュレーションをおこない波形チェックと実際に実機で確認をおこないます!
初めてこのブログを拝見していただいた方にこのブログの概要を少し紹介します。
このブログでは、温度センサー、7セグをFPGAで制御するものを製作する過程を紹介していきます。
(もし興味があったら、下に他の回のリンクを添付するので見ていただけると嬉しいです!)
シミュレーションって大事なの?
一生懸命考えてRTL設計した、デザインをすぐに実機で評価したい気持ちを抑えて、波形シミュレーションをおこないます。
波形シミュレーションをおこなうことで、自分の意図した理想波形を作ることができているか確認することができます。
Lattice Diamondには、Mentor社のModel Sim for Lattice Eddition(LE)というツールが付属しています。
こちらのModel Sim for LE を用いて波形シミュレーションをおこなっていきます。
シミュレーションとテストベンチ
シミュレーションをおこなうにあたって、自分が作成した回路と別にテストベンチというシミュレーション用のモジュールが必要になります。
このテストベンチは、自分の作成した回路に対して与える信号や条件の記述のことを言います。
言葉での説明だけでは、ちんぷんかんぷんかと思いますので以下にイメージ図を作ってみました!

このように、自分作成したTOPモジュールのもう1つ上の階層にテストベンチモジュールがあるイメージです。
テストベンチ内の記述は、右側のソースコードのように専用の構文があります。
こちらを用いて、自分の意図した信号や条件を入力、出力結果(波形)を観測します。
テストベンチ生成と、Model Simを立ち上げてみる
ざっくりとではありますが、波形シミュレーションとテストベンチのイメージできたでしょうか?
ここからは、Diamondにてどのようにテストベンチを生成するのか、Model Sim foe LEのプロジェクトを作成するか説明します。
テンプレートだけど、テストベンチを楽に生成!
テストベンチは、Diamond上で簡単にテンプレートを作成してくれる機能があります!

Diamond>>Hierarchタブに移動して、Topモジュール上で右クリック、
Verilog Test Fixture Templateを選択することで、File List>> Input Files上に表示されます。
生成されたテンプレートに、入力信号や条件を記述します。
簡単に波形シミュレーションできるテストベンチファイルを共有します!
Diamond より Model Sim Project を生成!
テストベンチを作成し終えたら、いよいよシミュレーションです。
Diamond >> Simulation Wizard より簡単に 5 STEP にてプロジェクトを作成できます。
①プロジェクト名を決める
②新規作成を選択
③RTLを選択
④テストベンチを追加
⑤テストベンチを自動認識
プロジェクト作成後、自動的に Model Sim for LE が立ち上がります。
もし、Model Sim for LEの詳しい操作方法が知りたい方がいましたら、以下URLをご確認ください!






作ったRTLモジュールをシミュレーション波形で確認してみる
ここまで少し説明長くなってしまいましたが、ここからりょすが作成したモジュールの波形を観測していきます。
SPI_STATE モジュール波形観測

まず、spi_stateモジュールの波形から観測していきます。
RESET解除後に、ステートマシンがclk_divを基準に遷移していきます。
順調にステートを進めていき、1回目の18ステート以降 16ステート目へ戻り、16→17→18→16 と繰り返すようになっています。
Chip Selectが落ちてから、SCLKが動くようになっており、Chip SelectとSCLKの関係も問題なさそうです!
正直に言うと、このモジュールが一番難しかったです、、、ここまで理想的な波形にするまで1週間くらいかかりました。。。
わざわざ画用紙に波形を書いて、それを基にRTLを書き直した結果理想の波形にすることができました。

COUNTER モジュール波形観測

次にcounterモジュールです。こちらは一回で作ることができました!
Enable信号に沿って、カウンターが回ります。今回はデバッグ用にカウンターの数を減らして波形に問題ないか確認をしています。
SPI_TX モジュール波形観測

次にspi_txモジュールです。ここはspi_stateの次に難しかったと思っています。
Enable信号に沿ってレジスターに値を保存し、シフトレジスターを用いてシリアルで出力します。
シフトレジスターのところ問題なさそうですが、少し心配が残ります。実機確認に期待です。。。
SPI_RX モジュール波形観測

次にspi_rxモジュールです。
Enable信号に沿ってシフトレジスターを動かします。SCLKの立下りエッジで、入力されるデータをラッチします。
データラッチ後に、別のレジスタに値を格納し、データを確定させます。
今回、テストベンチモジュールでは16b'0000101100010000 を入力しています。
データ確定後のレジスタの値を見てみると、同じ値が格納されていそうです!
SPI_TOP モジュール波形観測

最後にspi_topモジュールです。
RESET解除後から、データを受け取るまでの一連の流れをシミュレーションしています。
All 0 → All 1 → コマンド送信 → データ受信のように動く回路になっていそうです!よかった!!
ちなみに、上手く波形シミュレーションできていない場合、
変に不定となったり、ステートが遷移しない、カウンターが回らない、レジスターに値が保存されないなど
様々な現象が起きます。一度にTOPモジュールからシミュレーションをおこなうのではなく、それぞれのモジュールから確認することで
小さいミスを見つけやすくなります。(先輩 Fさんから教えてもらいました!)
spi_topモジュールで一連の動きを見ても問題なさそうなので、次は実機での動作確認をしたいと思います。
実機デバッグ、そして、、、
波形シミュレーションまで終わり、いよいよ実機での確認へ移ります。
実機確認では、Diamondに付属している内部ノード観測ツール「Reveal Analyzer」を用いて
データ確定後のレジスタを見て、そのデータが室内の温度に近いか確認をします。
Reveal Analyzerを使って内部ノードを観測
内部ノードを観測するにあたり、以下の手順で作業をおこないます。
①Reveal Inserterで各種設定をおこない、Diamondプロジェクトに読み込む
②再度Export Filesまでコンパイルする
③コンパイル後、Reveal Analyzerを立ち上げる
④観測スタート
内部ノードを観測するためのデザイン(Revealコア)を既存のデザインに追加するのですが、
約300LUTほどのリソースを使用します。リソースには注意が必要です。
もし、Revealの詳しい操作方法を知りたい方がいましたら、以下に資料を載せているので確認してみてください!






観測したい信号を、選択します。その後、サンプリングクロックの選択と観測条件を追加していきます。
今回は温度データ確定後のレジスタを見たいので、このレジスタに関係しそうな信号を条件として追加しています。
デザインルールチェックをおこない、特に問題なければ Diamond Project にRevealファイルを追加してコンパイルをおこないます。
Dimaond ProgrammerにてFPGAにデザインファイルを書き込み、いよいよ内部ノードを観測します!(ドキドキ)
温度データー確定後のレジスタを見るために、「tmp_data_fix_en」というイネーブル信号をトリガー条件として観測します。
トリガー条件は、「Low → High へ遷移したときを観測」とします。

無事にトリガー条件にて観測できました!果たして温度らしいデータは取れているでしょうか、、、
データ確定後の16bitのバイナリデータは「0000101111011000」です。
温度に直してみると、23℃となり室温に近い温度であることが分かりました!!
ここまでめっちゃ時間かかった~良かった!!!
何回か観測しましたが、無事に温度情報を取れていそうです!
今回は、作成したRTLモジュールの波形シミュレーションと実機での確認をおこないました。
感想としては、
デバッグが一番つらい!笑
波形確認 → おかしいことに気づく → RTL修正 →波形確認の作業を永遠と、1週間ほど繰り返していました。
ただ、上手くできたときの達成感はすごいものがあります。クセになってしまいそうです!
次回は、取得した温度データを7セグLED表示に表示させるための回路を考えていきます。
では、また次回! See ya!