FPGAのPLLとNCO

FPGAのPLLとNCO

 FPGAで回路を設計するにあたり、クロック信号は必須の信号です。一般的には水晶発振器や水晶発振子で作った方形波をFPGAのクロック専用ピンに入力します。

 クロック専用ピンの使い方は使用するFPGAによって違うのでFPGAのデータシートで確認してください。どのピンにクロックを入力するのか。というのはFPGAを設計する上で一番最初に悩む場面です。軽く悩むポイントを示します。

  • PLLを使うのであれば、何個必要か?
  • PLLの入力クロックと出力クロックは何Hzにするのか?
  • 使うPLLにはどうやってクロックを入力するのか?
  • クロックを入力するピンがあるブロックは何Vのブロックか?
  • FPGAの中で全部で何種類のクロックを使うのか?
  • PLLで作ったクロックを外部に供給する必要があるのか?
  • ダイナミック(電源投入後に変えたいか?)にクロック位相を可変する必要があるか?

 これらを検討して、FPGAの中のクロック経路をある程度予想しておく必要があります。そうしないと、設計が進んでから、クロックが足りないとか、プリント基板を変更する必要が生じる等の問題が発生します。

 FPGAの内部PLLとクロックについての説明は選択したFPGA専用の解説になってしまうので、本稿で解説することができません。構想設計の段階でFPGAを選定したなら、必ずそのFPGAのクロックとPLLと専用ピンについて上記のリストを思い浮かべながら検討してください。非常に重要な事なので、これらについて、別のデータシートを用意しているメーカーもあります。

 今回はNCOの説明をして、実際に設計したいと思います。NCOはNumerically Controlled Oscillatorの略で、日本語では数値制御発振器と呼びますが、日本語で言うエンジニアに逢ったことがありません。

 NCOは技術としては古いのですが、よく使われるようになったのは最近です。地上デジタルテレビとか、スマートホンなどが普及したのと時期は同じです。これには理由があって、NCOを設計するにあたり、高速なデジタル加算回路が必要になるからです。FPGAにDSPが搭載されて高速に乗算・加算ができるようになったために使われるようになりました。

 もしかすると、NCOというよりもDDSの方が馴染みのある方が居るかも知れません。DDSはDirect Digital Synthesizerの略で一つのクロック周波数から任意の波形を作る回路です。市販されているシグナルジェネレータというのはDDSを使っている事が多いです。

 DDSはNCOと波形生成用の回路を直結した回路になります。次のようなブロックで示すことができます。

 市販されているDDSでは、波形ROMの後にDAコンバータが内蔵されており、アナログ信号として出力される物が多いです。最近はGHzまで出力できるDDSがあり、スマートホンなどのRF回路に使われています。

 たとえば、ラジオのチューニングは昔はアナログでしたが、昭和後期になってPLLを使うようになりました。最近はDDSを使う事が多くなっています。

 NCOのブロック図を下に示します。回路的にはレジスタ(DFF)と加算回路だけの簡単な回路です。デジタルで加算回路というのはロジックが複雑になり、高速な回路設計が難しかったのですが、各社FPGAにはDSPという乗算・加算の専用回路が搭載されるようになり、高速なNCOを作ることができるようになりました。

 これだけの回路ですから、HDLでの記述は1行で済みます。

    rADDFF <= rSETDATA + rADDFF;

 最新のFPGAにはNCOもIPとして用意されている事が多いのですが、IPを使うと、FPGAを変更する際に設計し直す必要がある。というデメリットが生じます。簡単なNCOであれば、上記のように作れるので、VHDLやVerilogで記述してしまう。というのが良いと思います。

 次に、具体的な値でNCOを設計してみます。出力周波数は以下の式で計算することができます。計算例として、入力クロック周波数が10MHzで16ビットの時、1234(hex)をセットした場合を計算してみます。

 このように約700kHzの周波数を生成することができます。通常はDDSの例のように、NCO_outの値をアドレスとして、Sin波形のテーブルを読み出して使用しますが、私が多く使うのはNCO_outの最上位ビットのみを1bitとして使います。

 そうすることで、約700kHzの方形波になるので、FPGAの中でその波形を元に様々なタイミングに使用します。rSETDATAを変化させると、出力周波数も変化するので、CPU等から変更するように作ると、動作途中で周波数が変化する信号を作ることができます。

 このようにNCOは非常に便利な反面、信号としてノイズが発生するという欠点を持っています。

 NCOを動作させている信号は元のクロックです。上の例では10MHzです。なので、10MHz単位で700kHzの信号を作っている。という事になり、700kHzの中に多くの10MHz成分のノイズが発生します。しかも、rSETDATAの値によって変化します。

 このノイズはDDSの場合DDSノイズとして、最後まで残ります。この事を良く理解して使うとNCOは非常に使いやすい信号発生器になります。