公開日:2025/03/01
title.png

33rd Season


#33-9 Blocklyの数学関数整備

 Cmod A7ボード(FPGA)を使って、オリジナル16ビットCPUコアMoscoviumの開発を進めています。

 独自仕様のマイコンだけではなく、その開発環境としてBlockly for Moscoviumの整備も進めてきました(詳細はこちらから)。今回は、Blocklyで数学関数を使うための拡張がテーマです。

数学関数

 Moscovium用に数学関数を整備した以下記事がありますので、それを基本として、Blocklyに実装して行こうと思います(以下リンク参照)。

  「#16-9 数学関数を整備しよう

 上の記事では、半精度浮動小数演算コプロセッサH-FPUを使いました。半精度浮動小数は16ビット長で、10進数換算の有効数字約3桁です。有効数字が小さいため、テイラー展開で実装するにも、より少ない項数で収束していました。

 Blockly for Moscoviumは、Nihoniumコア+単精度浮動小数演算コプロセッサS-FPUにも、対応しています。つまり、上の記事では半分(H-FPU)しか対応しておらず、S-FPU対応が未実施です。
 単精度浮動小数は32ビット長で、10進数換算の有効数字約7桁なので、テイラー展開の項数を少し多くとれば良いだけかな?と、言う印象です。今回、テイラー展開の項数以外に考慮する必要のあった、指数exp()関数についての追加考察をしておきます。

指数exp()関数

 exp()関数の求め方については、引数xの整数部分と小数部分に分けてexp()関数を計算するという方法までは解説済みです。以下にまとめておきます。

 exp (xi)はネイピア数eとした時、√eの正数べき乗なのでループを回して掛け算すれば良い、と、結論しておりました(こちらの記事を参照)。確かにH-FPU版ならば、そういう手もあったかもしれないのですが、それでも最大23回(※)もの掛け算が必要です。1回のexp()関数を求めるのに、これではあまりに遅すぎて使い物になりません。
 H-FPU版では、使い得るxi値の範囲が高々24個だったため、16ビット×24個=48バイトのテーブル参照で実装しました。

※16ビット半精度浮動小数では、int (2×x)≧23で、exp (xi)→∞に発散する為。

 一方、S-FPUでは、int (2×x)が178以上でexp (int (2×x)÷2)→∞(無限大、INF)へ発散します。つまりS-FPU版では、なんと、最大178回の掛け算が必要となります。更に輪をかけて遅くなります。看過できません。
 H-FPU版と同様なテーブル参照に持ち込むと、32ビット×178個=712バイトのテーブルが必要となり、これも少々否定的です(テーブルサイズが大き過ぎます)。何か別な手段でexp (xi)を求める必要が生じました。

 そこで、Aa1+a0=(Aa1)×(Aa0)の関係式を使う事にしました。

 最大178回の乗算が、最大8回の乗算に帰着しました。
 bjで場合分けした最後の式に於いて、bj=0または1です。exp (2j−1)は定数なのでテーブル参照に持ち込むことができます。テーブルサイズは32ビット×8個=32バイトと、こちらも現実的なサイズですね。これで実現可能な水準に到達しました。

その他の関数

 テイラー展開等を使って求める「基本関数」と、基本関数の組み合わせで求めることのできる「派生関数」に分類してみると以下となります。

 ああ、派生関数の何と多き事か!こちら「#16-9 数学関数を整備しよう」の記事では、基本関数だけを作っておいて、派生関数については「各自対応」って、ことで放置していました。今回はBlocklyに組み込もうというのですから、派生関数も全部作らないとなりません。
 作り方は解っているので「作業だけ」、なのですが、評価(デバッグ)は必要だったし、地味に疲れました……。

Blockly拡張

 関数を求めるプログラムはランタイムライブラリとして、アセンブラで記述しておきました。以下、Blocklyに適応させて行きたいと思います。

数学関数ブロック

 今回追加しようとするのは計12種類の関数です。ドロップダウンリストが長くなると使い難いと思いますので、適切な数に分割して実装します。形式や関連性などに従って、以下3種類に分類してみました。

 上の分類に従って、BlocklyのMathカテゴリに以下の通り追加しました。

a316_blky_math.png

 動作仕様などについての詳細は、こちらのリンクからご確認ください。

Blockly.XML→Moscovium.ASM変換環境更新

 Blockly.XML→Moscovium.ASM変換スクリプトを更新すると共に、数学関数ライブラリを追加しました。まとめて、こちらからダウンロードしてください。

 以下のバナーからGitHubを参照しても、必要ファイルにアクセスする事が可能です。

btn_moscovium.png

 Blockly for Moscovium開発環境の構築については、こちらの記事をご参照ください。

評価用プログラム

 追加した数学関数ブロックを評価(デバッグ)するために以下プログラムを作成しました。

  実験用プログラム:test_func_plot.xml

※ブラウザによっては、XMLファイルをレンダリングして表示してしまうので、「右クリック ⇒ リンク先を保存」などしてください。

 Blockly for MoscoviumのXMLタブに貼り付けて、ご利用ください。Blockly.XML→Moscovium.ASM変換手順を参照して、Moscoviumマイコンに書き込んでください。
 数学関数ブロックを使って、指定範囲の関数値を計算して表示するプログラムと、なっています。出力された数値データをExcel等に貼り付けると、グラフを描いたり期待値との比較が実行できます。

実験と言うか評価

 FPUを搭載したMoscoviumまたはNihoniumマイコン(例えば以下)のデザインでシミュレーションして、評価します。Vivadoを使ったシミュレーションの実行方法についてはこちらをご覧ください。

  FPU搭載マイコン例:

 半精度浮動小数演算コプロセッサH-FPU用の数学関数の評価については、こちら「#16-9 数学関数を整備しよう」の記事で実施済みなので省略します。単精度浮動小数演算コプロセッサS-FPUでの評価を実施してみましょう。

  実験サンプル:シミュレーション結果ログ
  PLOT
  00000000 00000000
  3da14285 3e8fabb0
  3e214285 3ecb2e56
  3e71e3c7 3ef8d84a
  :
  : (中略)
  :
  411c3870 4047fb28
  411d7af5 4048c92d
  411ebd7a 4049965f
  41200000 404a62c1
  END
  Test Pass
  CPI: 39385/ 22961( 0)= 1715/1000
  finish: 1595240 ns


 ログ出力されたのは、32ビット単精度浮動小数のバイナリデータです。VivadoのVerilogシミュレータで浮動小数を表示すると有効数字6桁ほどに丸められてしまい、期待値との比較で誤差の評価ができない(※)ため、バイナリデータで出力しておいて、適切な有効数字の浮動小数に変換して評価を実施しました。

単精度浮動小数float型の有効数字は約6.9桁なので、6桁では桁数不足。

 S-FPUでの評価結果をド〜ン🎆と、以下図に示して考察を続けます。

a339_mathfnc.png

  評価結果考察:

 「地味に疲れた」理由がご理解いただけたら幸いです(1^^;)。


 皆様のアプリケーションで、どの様な浮動小数演算が必要なのか?は存じ上げませんが、一通りの数学関数を用意したので、大抵の用途には耐え得るはずです。Good job → 自分d(1^−^)v。


btn_arduino.png

btn_prev.png btn_next.png

home