SH-2A 基板 (3)

CQ-FRK-SH2A 基板用の FM 音源プログラム「TGSH2A」で何とか音が出るようになりました。
まだ現在は、基板単体に SPDIF 出力用として TOSLINK の送信モジュール (TOTX178A) を付けただけなので、MIDI 入力はできず、内蔵シーケンサーでデモ曲を演奏するだけです。
プログラム/データとも、すべてを大容量内蔵 RAM 上に置く設定で、高速 RAM は使っていませんが、音が出始めた当初は CPU クロック 144 MHz なのに遅いという印象を持ちました。
キャッシュを有効にすると、大きく改善され、48 kHz サンプリングで同時発音数 16 を実現できました。
その一方で、キャッシュによるトラブルもあったのですが、これは後で述べます。
まず、クロック動作モードと、各種のクロック周波数の表を、最高速のものだけを集めると下のようになります。

クロック
動作
モード
FRQCR
レジスタ
設定値
入力
クロック
 
内部
クロック
(Iφ)
バス
クロック
(Bφ)
周辺
クロック
(Pφ)
1 H'x104 48 MHz 144 MHz 48 MHz 24 MHz
2 H'x003 18 MHz 144 MHz 72 MHz 36 MHz
3 H'x003 48 MHz 128 MHz 64 MHz 32 MHz

クロック動作モードは基板上のジャンパ設定で変更できます。
クロック動作モード「1」がデフォルトの状態で、USB クロックの 48 MHz を入力クロックとして各種クロックが生成されます。
表のように、FRQCR に 0x0104 を書き込めば最高速の 144 MHz の CPU クロックの設定になりますが、大容量内蔵 RAM などのアクセスに使われるバスクロックは 48 MHz と低く、タイマ等の周辺クロックも 24 MHz と低い設定になります。
クロック動作モード「2」は最高速のモードとなりますが、システムクロック用の 18 MHz 水晶振動子を実装する必要があります。
PWM 等の応用で、できるだけ高い周辺クロックが必要で、18 MHz クリスタルは実装したくない場合には、クロック動作モード「3」がいいかも知れません。
CPU クロックは 128 MHz と最高速にはなりませんが、バスクロック 64 MHz、周辺クロック 32 MHz が得られます。
ここでは何も手を加えず、クロック動作モード「1」で FRQCR に 0x0104 を書き込んで動作させています。
この状態では、12 kHz サンプリングで同時発音数 7 程度から出力にノイズが乗りはじめ、処理能力としては 20 MHz クロックの V850 と同レベルという結果になりました。
これでは、あまりにも納得がいかないので調べてみると、デフォルトではキャッシュは OFF になっていることが分かりました。
そこでキャッシュの設定を ON にして試すと性能が向上し、オペランド・キャッシュがライトバック方式の設定では、48 kHz サンプリングでも同時発音数 16 を実現できました。
現在の FM 音源プログラムでは、同時発音数 16 までしか扱えないので、性能の指標として、同時発音数 16 の設定での CPU 負荷率の表を下に示します。

サンプリング
周波数
48 kHz 32 kHz 24 kHz 16 kHz 12 kHz
CPU 負荷率
(ライトバック)
78 % 54 % 41 % 29 % 22 %
CPU 負荷率
(ライトスルー)
71 %
(poly=7)
72 %
(poly=10)
73 %
(poly=14)
60 % 46 %

(poly=) が記されていないところは同時発音数 16 の場合です。
これは同時発音数 3 のデモ曲データの演奏時のものなので、実際に 16 音を同時に発音する場合には負荷率が上がる可能性があります。
ライトスルー方式での性能は、ライトバック方式での性能の約 1/2 になっています。
しかし、ライトバックの設定では、コンパイル/ダウンロード/実行というサイクルを繰り返す場合に問題が生じました。
それは、ソースを修正してコンパイル/ダウンロード/実行しても、修正部分が反映されなかったり、プログラムがうまく実行されないという症状です。
もちろん、いったんデバッガを「接続解除」して、SH-2A 基板を USB から外し、電源オフの状態から再度接続してやり直せば問題ないのですが、それではあまりにも面倒です。
これは、ライトバック・キャッシュに残ったデータが悪さをしているのではないかと思い、「SH-2A キャッシュ」でググると、ルネサスの Web ページ上の e-ラーニングのコースがヒットし、そのサンプル・プログラムのオペランド・キャッシュをパージする関数を実装してみたところ、うまく動作するようになりました。
そのあたりの話は次回に回します。