新版FM音源プログラム (14)
プログラムを動作させるマイコン・ボードとしては、オペレータ出力波形をオシロで手軽にチェックするために、手持ちの中で DAC を内蔵するチップを搭載している次のボードを選びました。
- Nucleo-F446RE (STM32F446RET6, Cortex-M4)
- STMF4-Discovery (STM32F407VGT, Cortex-M4)
- Nucleo-F303K8 (STM32F303K8T6, Cortex-M4)
- STM32 Value Line Discovery (STM3F100RBT6, Cortex-M3)
- PSoC 4200 Prototyping Kit (CY8C4245, Cortex-M0)
- PSoC 5LP Prototyping Kit (CY8C5888, Cortex-M3)
それに加え、単体の LPC1114FN28/102 (Cortex-M0) に SPI 接続の DAC、MCP4922 をつないだものを使いました。 (2018 年 2 月 26 日追記: PSoC4 / PSoC5LP を追加しました)
開発ソフトウェアとしては、ARM/Keil の μVision V5.21.1.0 (MDK-Lite V5.21a) と、Atollic TrueSTUDIO for STM32 v9.0.0 とを使いました。
PSoC については PSoC Creator 4.0 Update 1 (gcc 4.9.3) を使いました。
所要サイクル数の測定方法としては、下記のようなプログラムで
#define MAXSLOT (32) op_prop_t op_prop[MAXSLOT]; . . . <中略> . . . int main( void ) { int i; . . . <中略> . . . while (1) { HAL_GPIO_TogglePin(LD6_GPIO_Port, LD6_Pin); // BLUE LED for (i = 0; i < 1024; i++) { calc_slot(&op_prop[0], MAXSLOT); } // for (i = 0; ... } // while } // int main()
メインの無限ループ内で LED をトグルしながら、32 スロット (オペレータ) 、1024 サンプル分の計算を繰り返し行い、LED を駆動しているピンの信号周期を測定し、計算により求めています。
測定された周期を T とし、2 スロット当たりのクロック・サイクル数を cyc_per_2slot、また CPU クロック周波数を f_clk とすると、
T = cyc_per_2slot * 16 * 1024 * 2 / f_clk
cyc_per_2slot = T * f_clk / (32 * 1024)
で求められます。 この中には関数呼び出しのオーバーヘッドや、1024 サンプル分のループ繰り返しの制御のオーバーヘッドなどが含まれていますが、それらの寄与は小さいとして、計算結果を四捨五入して整数化してサイクル数としています。
プログラム・リスト中にコメントとして記載していたものを、あらためて表にまとめました。
「フラッシュ・レイテンシ」は、CPU クロックが高速になるとフラッシュの読み出し動作が追いつかなくなるので、正常動作のために追加されるメモリ・ウェイト・サイクルのことです。
たとえば、STM32F446 では CPU クロックが 30 MHz まではレイテンシ 0 、つまりウェイト・サイクルなしで 1 サイクルでフラッシュから読み出せますが、CPU クロックが 180 MHz になると、レイテンシ 5、つまり全体で 6 サイクルかかってフラッシュから読み出すことになります。
もちろん、そのままでは大幅な速度低下につながってしまいますが、「命令 (I-Code) キャッシュ」、「データ (D-Code) キャッシュ」や「プリフェッチ」などにより性能低下をおさえる仕組みが備わっています。
ちなみに、STM32F100 にはキャッシュの機構がありませんが、CPU クロックを 24 MHz までしか上げられず、その周波数ではフラッシュのレイテンシは「0」なので (命令フェッチによる) 性能低下はありません。 (フラッシュ上のデータ読み出しと命令フェッチとの競合は存在する)
μVision V5.21.1.0
(MDK-Lite V5.21a, armcc.exe v5.06 update 3, -O3)
cycle per 2slot |
評価ボード名 | 搭載チップ名 | アーキテクチャ | clock [MHz] |
flash latency |
---|---|---|---|---|---|
56 | Nucleo-F446RE | STM32F446 | ARMv7-M Cortex-M4 |
30 | 0 |
67 | Nucleo-F446RE | STM32F446 | ARMv7-M Cortex-M4 |
180 | 5 |
56 | STM32F4- Discovery |
STM32F407 | ARMv7-M Cortex-M4 |
30 | 0 |
66 | STM32F4- Discovery |
STM32F407 | ARMv7-M Cortex-M4 |
168 | 5 |
54 | Nucleo-F303K8 | STM32F303 | ARMv7-M Cortex-M4 |
24 | 0 |
61 | Nucleo-F303K8 | STM32F303 | ARMv7-M Cortex-M4 |
64 | 2 |
56 | STM32VL Discovery |
STM32F100 | ARMv7-M Cortex-M3 |
24 | 0 |
67 | (チップ単体) | LPC1114 | ARMv6-M Cortex-M0 |
20 | 0 |
86 | (チップ単体) | LPC1114 | ARMv6-M Cortex-M0 |
48 | 2 |
Atollic TrueSTUDIO for STM32 v9.0.0 (gcc 6.3.1, -Os)
cycle per 2slot |
評価ボード名 | 搭載チップ名 | アーキテクチャ | clock [MHz] |
flash latency |
---|---|---|---|---|---|
53 | Nucleo-F446RE | STM32F446 | ARMv7-M Cortex-M4 |
30 | 0 |
63 | Nucleo-F446RE | STM32F446 | ARMv7-M Cortex-M4 |
180 | 5 |
53 | STM32F4- Discovery |
STM32F407 | ARMv7-M Cortex-M4 |
30 | 0 |
62 | STM32F4- Discovery |
STM32F407 | ARMv7-M Cortex-M4 |
168 | 5 |
51 | Nucleo-F303K8 | STM32F303 | ARMv7-M Cortex-M4 |
24 | 0 |
67 | Nucleo-F303K8 | STM32F303 | ARMv7-M Cortex-M4 |
64 | 2 |
57 | STM32VL Discovery |
STM32F100 | ARMv7-M Cortex-M3 |
24 | 0 |
後で示す、アセンブリ言語で記述した場合の結果も示しておきます。
(2018 年 3 月 3 日追記: アセンブリ言語で書いたプログラムの変更にともない、測定をやり直した結果に差し替えました。 サイン波テーブルを SRAM 上に置いた場合の結果も追加しました)
μVision V5.21.1.0
(MDK-Lite V5.21a, armcc.exe v5.06 update 3)
Embedded Assembly Language function で記述
サイン波テーブルは SRAM 上に配置
cycle per 2slot |
評価ボード名 | 搭載チップ名 | アーキテクチャ | clock [MHz] |
flash latency |
---|---|---|---|---|---|
44 | Nucleo-F446RE | STM32F446 | ARMv7-M Cortex-M4 |
30 | 0 |
44 | Nucleo-F446RE | STM32F446 | ARMv7-M Cortex-M4 |
180 | 5 |
44 | STM32F4- Discovery |
STM32F407 | ARMv7-M Cortex-M4 |
30 | 0 |
44 | STM32F4- Discovery |
STM32F407 | ARMv7-M Cortex-M4 |
168 | 5 |
43 | Nucleo-F303K8 | STM32F303 | ARMv7-M Cortex-M4 |
24 | 0 |
46 | Nucleo-F303K8 | STM32F303 | ARMv7-M Cortex-M4 |
64 | 2 |
μVision V5.21.1.0
(MDK-Lite V5.21a, armcc.exe v5.06 update 3)
Embedded Assembly Language function で記述
サイン波テーブルはフラッシュ・メモリ上に配置
cycle per 2slot |
評価ボード名 | 搭載チップ名 | アーキテクチャ | clock [MHz] |
flash latency |
---|---|---|---|---|---|
47 | Nucleo-F446RE | STM32F446 | ARMv7-M Cortex-M4 |
30 | 0 |
57 | Nucleo-F446RE | STM32F446 | ARMv7-M Cortex-M4 |
180 | 5 |
47 | STM32F4- Discovery |
STM32F407 | ARMv7-M Cortex-M4 |
30 | 0 |
57 | STM32F4- Discovery |
STM32F407 | ARMv7-M Cortex-M4 |
168 | 5 |
46 | Nucleo-F303K8 | STM32F303 | ARMv7-M Cortex-M4 |
24 | 0 |
55 | Nucleo-F303K8 | STM32F303 | ARMv7-M Cortex-M4 |
64 | 2 |
48 | STM32VL Discovery |
STM32F100 | ARMv7-M Cortex-M3 |
24 | 0 |
64 | (チップ単体) | LPC1114 | ARMv6-M Cortex-M0 |
20 | 0 |
84 | (チップ単体) | LPC1114 | ARMv6-M Cortex-M0 |
48 | 2 |
PSoC Creator 4.0 Update 1 (gcc 4.9.3)
Inline Assembly Language で記述
サイン波テーブルはフラッシュ・メモリ上に配置
cycle per 2slot |
評価ボード名 | 搭載チップ名 | アーキテクチャ | clock [MHz] |
flash latency |
---|---|---|---|---|---|
49 | PSoC 5LP Prototyping Kit |
CY8C5888 | ARMv7-M Cortex-M3 |
16 | 0 |
55 | PSoC 5LP Prototyping Kit |
CY8C5888 | ARMv7-M Cortex-M3 |
80 | 4 |
64 | PSoC 4200 Prototyping Kit |
CY8C4245 | ARMv6-M Cortex-M0 |
24 | 0 |
67 | PSoC 4200 Prototyping Kit |
CY8C4245 | ARMv6-M Cortex-M0 |
48 | 1 |