17 |
BSVによるサウンドFSMの再設計 |
設計方針
前回のBSVによるサウンドFSMの設計においては、ステートベース設計手法により設計しました。ステートベース設計とは、ここでは一連のフローを、クロックサイクルで定義されるステートに分解し、ステートのルールを一つずつ書いていく手法を指します。ただ、Verilogでも同じ手法で設計するため工数は同じであり、高級言語のご利益はありません。
前回の設計では、以前にVerilogでステートベースで設計した経験があるので、階層化ルールを用いて階層化FSMをステートベース設計しました。今回は比較のため、シーケンスベースで設計しようと思います。シーケンスベース設計とは、ここではシナリオを人手でステートに分解せずに、BSVに任せることを指します。
使用コンパイラ
ところが、2021年末にアップグレードのため、bscを再コンパイルしたところ(build 9a7d5e05)、Verilog出力が正しくできなくなりました。具体的にはスタックオーバーフローというエラーが出ます。フォーラムで聞いたところソースを送って欲しいとのことでした。
ソースを送って調べてもらいましたが、スタックを広げるコマンドを実行してもエラーが出るらしく、ソースを改善せよとのことです。ソースは巨大なFSMから構成されるため、FSMを分離したいのはやまやまなのですが、教えられた通り実施しても、bscが一個のFSMにまとめようとするためうまく行きませんでした。やむなく、以前のコンパイラ(build 38534dc)を使い続けることにします。
処理フロー
図54.2は以前の記事に示したもので、FSMはこれをデコードし、音声を出力するものです。
従って、基本的なフローはこのフォーマットどおりのステートベース設計のものを踏襲します。
- コード待ち ---- FSM0~3に応じたコードを受け付ける)
- 例外フラグ ---- UFOの場合はONからOFFまでサウンドをならし続ける等の例外への対処
- コードに応じてROMの先頭+16にポインタを移す
- フォーマットサイズを取得し、ポインタをフォーマット長分だけ増加
- "data"をスキップ
- データサイズを取得しカウンタにセット
- ポインタをデータの先頭に移す
- 終了条件でなければループ
- 音声データを取り出す
- データを出力
- ポインタを進める
- カウンタを1減らす
- ループ終端
ここで前回は、上記ループ内部において、インターポレーションのため4クロックからなるサウンド出力を4回繰り返していました。が、出力はループ内では変わらないので、16サイクルに1回出力すれば良いことになります。よって上記のループは16サイクルになるように設計します。