2016.02.29
前2回の記事で、ディジタルロックインアンプを作る要となる部分の説明をしました。
では、実際にどのような感じになるのか、試してみましょう。
まずは入力に与えている正弦波の振幅やオフセットを振ってみます。

うねうねと気持ち悪いですが、わかりますでしょうか。
- 茶色が入力信号です。
- 灰色が、ファンクションジェネレータのトリガ信号(参照入力)
- 赤が位相
- オレンジがsin、黄色がcos
- 緑と青が乗算結果
です。
次は周波数を振ってみます。

ちゃんと追従してきていますね。
![]()
ロックインアンプたるもの、計測した結果を表示しなければならないので、画面上に表示することにしました。
sinを掛けた成分とcosを掛けた成分の二乗の和をとり平方根を取って求めています。確度は、元の参照入力に対してどれだけずれているかを表したもので、atanで求めています。
平方根やatanはさすがにハードウェアでやる気力はないし、ゆっくりで良い処理なので、ZYNQのPSを使ってソフトウェアで処理しています。
![]()
このできたてほやほやの「ロックインアンプ内蔵 Cosmo-Z」を日曜日に早速、出荷しました。
Cosmo-Zでディジタルロックインアンプを作る(2)
2016.02.28
ロックインアンプの原理は前回のブログで書いたとおり、簡単なのですが、実際に作ろうとすると2つの難しいところがあります。
① 除算器
② 三角関数の生成
まず、除算器ですが、FPGAで除算回路を作るのはとても難しいので、CoreGenを使います。
周期を計るカウンタを16bitにすると、80MHz÷65536=1220Hzなので、1.2kHz以下の信号にロックさせようとすると溢れてしまいますから、16bitでは足りません。
ここでは24bitにしました。すると、除算器に与えるdividendとdivisorも24bit精度にして、24bit/24bitの除算器を作らなければならないことになります。
すごい回路規模なんだろうな・・と想像しながらCoreGenでポチポチと設定します。
赤い枠で囲ったところが設定した項目です。
なお、dividendというのが分子でdivisorというのが分母です。
Output Channelというのが出力のビット幅を指定する部分で、小数点以下の部分をどういうフォーマットにするかを指定するものです。Reminderにすると「余り」が、Fractionalにすると「商」が出てきます。
今回はdividend < divisorで、結果は0~1の範囲ですから、欲しいのは商です。よってFractionalにします。24にすると、出力48bitのうち、24.24の固定小数点形式で出てきます。

こうして24bitの、0~FFFFFFまで周期Nでなめらかにカウントアップするカウンタが作られました。なお、割り算回路は結果が出るまでに20クロックくらいかかります。
![]()
次に、sinとcosを求める回路ですが、入力が24bitカウンタなので、テーブルで持つには大きすぎます。そこで、CORDIC法で求めます。CORDIC法についてはGoogleに聞いてください。
XILINXユーザはCoreGenの中からCORDICを選べばよいので、とても簡単にsin、cosを作ることができます。
CoreGenのMathFunctionから選ぶだけです。
設定は↑の図のように、関数をSin Cosにして、入力幅を24bitに、出力幅を16bitにするだけです。また、Phase FormatはScaled Radiansにします。
このコアは、Scaled Radiansにすると、入力に1と設定するとπとして解釈されます。
入力は固定小数点数ですが、フォーマットは下の図のように符号と整数部で3bit使います。

注意すべき点は、値の範囲は-π~πにすることです。0~2πを入れようとしたら飽和してしまってうまく結果が出ませんでした。
![]()
CORDICコアの出力結果のフォーマットは、こうなっています。

符号と整数部で2bitあることに注意してください。
上16bitと下16bitで取り出したとき、最大値が0x4000までしかいきません。
![]()
除算とか三角関数とかいかにも複雑な回路なので、どのくらいのレイテンシがかかるかを見ておいたほうが良いでしょう。
ISim(シミュレータ)を使って調べてみました。
なんと、24bitの除算で50クロック、24bit→16bitのCORDICで20クロック。合わせて70クロックもかかっています。
しかし、これらの回路は内部で完全にパイプライン化されているので、連続でデータを与え続けても大丈夫なようです。
![]()
こうして、80MHzで1クロックごとに更新されるsinとcosのデータを作ることができました。
これを波形で見てみましょう。
・灰色が、ファンクションジェネレータのトリガ信号(参照入力)
・赤が位相
・オレンジがsin、黄色がcos
です。
Cosmo-Zでディジタル・ロックイン・アンプを作る(1)
2016.02.27
ZYNQ搭載のADCボード「Cosmo-Z」のFPGAは自由にカスタマイズできるので、お客様からの要望があったロックインアンプを作ってみました。
ロックインアンプというのは、ノイズに埋もれた微弱な信号を計測するためのものです。入力信号があらかじめ何らかの周波数に同期している場合に、極めて強力なツールとなります。
原理は、入力信号とsin波、cos波の「参照信号」を掛け算して、それを長時間積分する、あるいはLPFを通すというものです。

ノイズ成分はランダムに生じているわけなので、∫n(t)×sin(t)dt = 0に近づきます。2倍の周波数成分や3倍の周波数成分も、∫a×sin(2t)×sin(t)dt = 0となります。
そして、内部で生成したsin波・cos波と一致した周波数の成分のみが残るというわけです。つまり、フーリエ変換をどこか特定の周波数でのみやっているようなものです。
レーザとかを使った実験ではとても良く使います。下の図のような構成の場合、検出器から検出される信号は何らかの変調がかかっているので、検出された信号をロックインアンプにいれれば、参照入力の成分の大きさが見えるというわけです。

![]()
これをFPGAでやるには、どうしたらよいでしょう。
まず、入力信号と、参照入力を用意します。参照入力からトリガ信号を作って、そのトリガ信号の周期を測ります。
参照信号の周期はクロックN個分・・というふうに測ります。

この部分の目的は、周期Nに合わせて0~2πまでカウントアップするカウンタを作ることです。しかし、Nの値は周期ですから、実験によって異なります。どんな周期であっても最大値までカウントアップさせるのは意外と難しいことです。
そこで、除算器を使います。

このような構成にすれば、トリガの周期に合わせて0~N-1までカウントアップするカウンタが作られます。そして、除算器によって、0~1まで周期Nでカウントアップする出力(位相)が得られます。
そして、位相カウンタの値に2πをかけて、sinとcosを生成します。テーブルを引いたりCORDIC法で作ればよいでしょう。
得られたsinとcosは、元のトリガ(参照入力)に同期しているので、このsin,cosと入力信号を掛け算して積分すればよいというわけです。

以上がディジタル式のロックインアンプのおおまかな仕組みです。
では、実際にFPGAに実装してみましょう。
Cosmo-Z 12台の実装が上がってきた
2016.02.22
今日、実装屋さんからCosmo-Z 12台が上がってきました。
内訳は、Cosmo-Z 80が3台、105が6台、125が3台です。
半分ほどは既に行き先が決まっていますが、在庫として持っておく分も若干あります。
いまご注文いただければ、今年度中に納品いたします。
もし、品切れになってしまうと、次の製造は3月末に間に合わないかもしれないので、お早目にお願いします。
Cosmo-ZのShaperのGUIインタフェース
2016.02.09
波形整形回路をGUIで操作できるようにしています。
波形が出ているときに、ツールボタンの「歯車ボタン」を押すと、

波形整形回路の時定数を設定できるようになります。
τ=1.5usにすると、綺麗な台形になりました。
m1/m2 = Mとして、
M = 1 / (exp(Tclk/τ) - 1)
の関係があります。
簡単に言うと、m1が比例成分、m2が積分された時間遅れ成分です。m1とm2の値が大きすぎるとオーバーフローします。
m1とm2とτの関係は結構厳しいので、τを細かく設定できるようにするにはm1の値をもっと大きくする必要がありそうです。
Cosmo-ZにハードウェアMCAを搭載
2016.02.07
Cosmo-ZにハードウェアMCAを搭載しました。MCAというのは、マルチチャネルアナライザのことで、パルスの高さのヒストグラムを作るものです。
まず、テスト波形をFPGA内で作り出します。
exp(-t/τ)で減衰する波形なのですが、少しだけローパスフィルタをかけて鈍らせています。
このパルスの高さを横軸に、頻度を縦軸にしてヒストグラムを作ると、
こうなります。


















