ダイレクトディジタルシンセサイザ

Xilinx社のProgramable Logicである「XC95108」を使って
1Hz刻みで正弦波を発生するDDSブロックを作って
見ました



【概要】
ROMに正弦波のディジタルデータを書き込んでおき、それをカウンタでぐるぐる
繰り返すことで正弦波を発生させることが出来ます。しかしこのままでは一定の
周波数の正弦波しか発生させることは出来ません。そこで、これにアダーを加える
ことで、1Hz単位の任意の周波数の正弦波を発生させることが出来ます。
これがDirect Digital Sybthsizerの原理ですが、CPLDを使ってこれを実現してみました。

CPLDの規模制限で、十分ではないですが、最高6ビットの64分解能の正弦波を、
1Hzから約260kHzまで1Hzステップで設定し発生させることが出来ます。
これにPICなどを付加すれば、パソコンと接続してリモートコントロールで、任意の
周波数を発生させることが可能となります。

下記はこれを応用した低周波発信器のモジュールで、PICとパソコンをシリアルインタ
フェースで接続してリモートコントロールが出来るようにしたものです。


DDSを組み込んだXC95108を中心に
PIC16F876を制御用チップとして構成。
D/A変換にはDAC0808を使用しています。



JTAGで何時でもVHDLの結果を書き込んで
CPLDの内部回路を変更することが出来る



《低周波発振器の製作例紹介》
 上記の基板をPICのプログラム、パソコンのプログラムを一緒にして、PIC活用製作例
 に解説しています。下記にあります。

   ★ CPLD応用低周波発振器の製作


【全体の構成】

DDSを構成するCPLDの内部構成は下図のようになっています。これをVHDLで記述して
実装していることになります。
まず、ブロックは大きく、6ビットの正弦波データを格納しているROMの部分と、22ビット
のアダー部分に分かれます。
ROMデータからは、アダーの上位6ビットをアドレスデータとして使って、これで指定された
アドレスのROMデータが出力され、ラッチされて外部への出力となります。
この出力が外部のD/A変換器に接続されてアナログデータとして正弦波を作り出します。

入力側は、18ビットのシフトレジスタとなっていて、これで1Hz単位の周波数を設定する
ことになります。このデータは外部からのsetの信号によりラッチされて、上位4ビットに
0を追加した上でアダーの入力となります。
 もう片方のアダー入力は、アダーの前回の出力値が22ビットラッチとして入力されます。
これで、毎クロックの度に、前回の加算結果にさらに周波数指定の値が加算されることに
なります。
加算結果のラッチの上位6ビットがROM部分へのアドレスとなるのですが、周波数指定の
値の大きさにより6ビットがフルカウントする周期が変わることになり、出力正弦波の周波数
が比例して変わります。
このアドレスが1回転する毎にROMとして作成されている1周期の正弦波データが出力
されるので、結果的に周波数設定に比例した正弦波データが出力されることになります。










22ビットのアダーとなっていて、上位6ビットがD/A変換用アドレスになりますから、
6ビットが一周する時間は、下位16ビットで決まります。
従って、clockに4.194304MHzを使うと、 4194304 = 2の22乗ですから
ちょうど22ビット分になりますので、下位16ビットを使えば、1Hzから65535Hzまで
1Hz単位で指定できることになります。

またさらに出力を4ビットの分解能で我慢すれば、下位18ビットが周波数設定用に
使えますから、1Hzから262143Hzまで1Hz単位で指定することが出来ます。
結果的に、18ビットを周波数設定用とすれば下表のような分解能で動作することに
なります。
周波数範囲 D/A出力分解能
1Hz〜65535Hz 6ビット
 65536Hzから131071Hz  5ビット
 131072Hz〜262143Hz  4ビット




【動作タイミング】

動作タイミングとしては、2つの要素があります。

(1)周波数設定の入力となるシフトレジスタへのクロックとデータのタイミング
  シフト用のクロックであるsclkの立ち上がりで、シフトデータのsdataをシフトレジスタ
  に取り込み、シフトレジスタを1ビットシフトします。
  そして、ラッチ用のset信号の立ち上がりで、シフトレジスタの内容をラッチに保持
  します。この関係を図示すると下図のようになります。時間的にはsclkのパルス幅が
  50nsec以上あれば問題なく動作し、パルス幅に上限はありません。
  シフトレジスタはsclkの度に、最上位ビットを捨てますので、18ビット以上のデータを
  入力しても問題なく、最後の18ビットが残ります。





(2) システムクロックと動作のタイミング
  システムクロックのclock信号の立上がり毎にアダーが動作し、
  立下りで、ROMの出力データを出力ラッチに保持します。




【VHDLの内容】

上記のブロックを実際のVHDLで記述したものが下記となっています。
このVHDLリストはダウンロードできますのでお使い下さい。
このVHDLを実装したのは、ザイリンクスのXC95108ですが、かなり目一杯の容量
となっています。

  ★ DDSブロックVHDLリスト


以下はVHDLの解説です。

(1) エンティティ宣言部分
  実際の入出力ピンを定義します。入力はclockとresetが元で、
  あとはシフトレジスタへの周波数設定用の信号が3本です。
  出力は、正弦波生成用のD/Aコンバータ用6ビットの出力と、周波数表示用
  の矩形波出力です。
  CPLDのピン数に比較して実際に使うピン数は少ないので、外部配線は楽です。






(2) 信号定義とROMデータ定義
  まず内部信号宣言の部分で内部のラッチ出力を定義します。
  そのあとで、配列の多重定義を使って、正弦波のROMデータを定義して
  います。この正弦波データは1周期分が定義されています。






(3) 入力シフトレジスタとラッチ、アダー部分
  sclkの立上がりエッジ毎にsdataを取り込む18ビットのシフトレジスタ
  の記述と、setの立上がりでラッチする18ビットのラッチの記述です。
  強制RESETによりそれぞれ0クリアしています。
  さらにこのラッチに0を4ビット追加して22ビットとした上で、22ビット
  アダーの加算をしています。
  加算のもう片方は前回の加算結果のラッチのデータです。





(4) アダー出力ラッチとROMアドレス生成
  アダーで加算した結果を同じクロックの立上がりエッジで22ビットの
  ラッチに保持します。このラッチ結果が次のクロックでのアダーへの
  片方の入力になります。
  さらにラッチの上位6ビットをROM用のアドレス信号として出力します。





(5) ROMデータのラッチと出力
  ROMアドレスで指定されたROMからの出力データをクロックの立下りで
  出力ラッチに保持します。この立下りにしたのは、ROMデータの出力が
  遅れることを想定したものです。
  そして出力ラッチの出力を出力ピンに接続して完成です。
  正弦波と同時に、同じ周波数の矩形波をロジックレベルで出力するように
  します。これは外部の周波数カウンタへの入力として使うことを想定して
  います。








  目次ページに戻る