FPGA 版 FM 音源 (1)

以前から、ハードウェア版の FM 音源を FPGA/CPLD を使って実現したいと思っていました。
詳細な検討はまだですが、なんとか行けそうなめどがついたので着手することにしました。
一挙に完成まで持っていけるわけではないので、不定期な記事になると思います。
基本的な方針としては、OPL3 / MA-2 相当の機能を

  • ハードウェア並列乗算器は使わない
  • 大容量の ROM は使わない

で実現することを目標とします。
これは、FM 音源チップが発売された当時の状況では、ハードウェア並列乗算器を何個も使ってはいないだろうし、大容量の ROM を内蔵してはいないだろうということで、なるべく当時のハードウェアに近い形で実現したいということです。
その代わり、クロックスピードは速くできるので、処理が間に合わなくなれば、ハードを複雑化するのではなく、クロック周波数を上げて対処します。
現在、手持ちの FPGA/CPLD 基板を列挙すると下の表のようになります。

ファミリ名 型名 LE
(FF)
Block RAM (bit) 乗算器 備考
MAX II EPM240 240 --- --- トラ技
2007/4
ACEX 1K EP1K10 576 12K (4K x 3) --- FPGAボード
で学ぶ
論理回路設計
Cyclone EP1C3 2,910 58.5K (4K x 13) --- DWM 誌
2003/10
Spartan-3 XC3S50 3,840 72K (18K x 4) 4 DWM 誌
2005/1
Spartan-3E XC3S250E 4,896 216K (18K x 12) 12 DWM 誌
2007/7
LatticeXP2 XP2-5 3,480 162K (18K x 9) 12 DDT
2009/Spring

「LE」の欄は、Altera 社の FPGA/CPLD の場合は LE (Logic Element) 数そのものです。
Xilinx 社の FPGA の場合は 1 CLB (Configurable Logic Block) が 4 スライスで構成されており、 1 スライス内には LUT (Look Up Table) 2 個と FF 2 個が含まれるので、CLB 数に 8 を掛けて、(LUT + FF) のユニットがいくつあるかを示しています。
LatticeXP2 の場合には、PFU (Programmable Function Unit) を構成する 4 個のスライスの内、3 個のスライスには FF が含まれ、1 個のスライスには FF が含まれていないので、LUT 数と FF 数が異なっています。
上の表では、FF の数を示してあります。 LUT 数としては LE の欄の値の 4/3 倍になります。
OPL3 では、ホスト CPU とインターフェースするためのレジスタ・アレイが 512 バイトのアドレス空間に割り付けられているので、内蔵ブロック RAM を持たない EPM240 (MAX II) では、LE 数が少ないこともあり、実現不可能です。
また、EP1K10 (ACEX 1K) でも内蔵ブロック RAM 容量が足りないので、ともに CPLD に分類される EPM240 と EP1K10 は脱落です。
FPGA に分類される残りの 4 つのどれでも実現可能であるとは思いますが、まずは、EP1C3 (Cyclone) をターゲットとしてインプリメントを進めることにします。
EP1C3 にはハードウェア並列乗算器は内蔵されていませんが、乗算器を使わない前提ですから、問題ありません。
OPL3 にはオペレータが 36 個内蔵されているので、1 サンプリング周期内に 1 オペレータ分の計算を 36 回繰り返す (36 スロット分) 必要があります。
最初の段階としては、スロットの繰り返し計算の細かいタイミングは抜きにして、とりあえず 1 オペレータ分の基本部分の計算を実現してみました。
現状の使用 LE 数は 265 で、全 LE 数 2,910 の約 9 % です。
ブロック図を下に示します。 (回路図は→こちら)

1 ビットシグマ・デルタ DAC を内蔵し、外部に簡単な LPF をつけてオーディオ信号としています。
1 オペレータなので、 FM 波形 (実際には位相変調) のテストのため、(セルフ)フィードバックをかけています。
簡単のため、バレル・シフタでフィードバック量を設定していますが、50 LE も消費しているので、実際には 2 のべき乗との乗算に置き換える予定です。
エンベロープ・ジェネレータは実装していないので、単なるアップ・カウンタを使って、アタック・タイム 0 の減衰音のエンベロープを作り出しています。
ハードウェア並列乗算器を使わない方針なので、サイン波 ROM 出力は対数値を出力するようにし、対数ドメインで振幅を規定する値と加算したものを、対数から真数へ変換することで「乗算」を実現しています。
サイン波 ROM 部分では、WS (Wave Select) パラメタで選択される 8 種類の波形を作り出しています。(回路図は→こちら)
クロック周波数は実際の 36 スロット動作を考慮し、48 MHz に選んでいます。 クロック周波数の選定については次回の記事で触れる予定です。