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 に選んでいます。 クロック周波数の選定については次回の記事で触れる予定です。