特電2014年度が終わり
特電は4月決算なので、今日で2014年度が終わりました。
今年度の前半は、組み込みとかやっていたのですが、後半は物理実験系にシフトしていきました。
来年度は、物理実験系で最先端・最高峰・最高性能のものをつくり、組み込みの世界でもその機能や性能が享受できるような形にしたいと思います。
特電は4月決算なので、今日で2014年度が終わりました。
今年度の前半は、組み込みとかやっていたのですが、後半は物理実験系にシフトしていきました。
来年度は、物理実験系で最先端・最高峰・最高性能のものをつくり、組み込みの世界でもその機能や性能が享受できるような形にしたいと思います。
今日はつくばにある高エネルギー加速器研究機構、通称KEKへ行ってきました。
ある回路の基板を作る仕事の打ち合わせだったのですが、いろいろな人にお会いさせていただき、そのままいろいろと見学させていただきました。
KEKでは、現在、SuperKEKBというBelle2実験で使うための加速器や検出器を建設中です。Belle実験では物質と反物質のCP対称性の破れの検証を行いましたが、今度はさらに巨大な加速器を建設しているというわけです。
これが、その検出器だそうです。写真を撮っていいとのことでしたので、ありがたく撮らせていただきました。
ビルの4階建てくらいの高さがあります。上にのっかっている黒いこんもりとしたのは、ケーブルの山です。数万チャネルある検出器からの信号をケーブルで集約しているので、すごいことになっています。
この大きなのがレールに乗っていて、手動のハンドルで開くそうです。開いているときの姿を見れたのは貴重でした。
次の写真は、SuperKEKBの心臓部ともいえる、衝突させる部分のパイプです。
大きさといい、色といい、エヴァンゲリオンでもでてきそうな雰囲気ですね。
上の写真の左に映っている黄緑色と紫色の台の上から2本のパイプが伸びてきていて、真ん中に青い台があります。この部分で電子と陽電子を衝突させるそうです。
衝突させるといっても簡単なことではなく、KEKBでは電子と陽電子の速度が違うのです。速度が同じだと出来たB中間子が移動しないから、あえて違う速度でぶつけなければならないのです。そのため、1本のパイプで電子と陽電子を走らせることはできず、2本のパイプで別々に走らせて、X字型に結んだところでうまくぶつけるのです。
このパイプがクロスする部分が、後ろに映っている検出器の中央に納まるというわけですが、その組み立てがまた難しい作業だそうです。
日本に世界最大級の加速器があるというのは、とても素晴らしいことだと思います。こういう装置は企業に発注して作っているのではなく、細部にわたるまで研究者たちが手造りで作っているということも驚異的なことでした。
私の仕事はKEKBではなく、どちらかというとハドロンのほうなのですが、普段見ることができないものを見ることができ、貴重な体験でした。
CICフィルタを通すと、本当に
出力ビット数 = タップ数 × log2(R + M) + 入力ビット数
でビット数が増えるのかを検証してみることにしました。
まず、12bitの精度でのSIN波を計算で作ります。0~4095まで振れるSIN波です。このSIN波にはσ=1のノイズを乗せておきます。
CICフィルタに通す前の元の信号(緑)と、CICフィルタを通した後の信号(赤)を見比べてみると、フィルタを通したものは少しだけ遅れているのと、スタートのところが少し欠けている以外は、見た目の違いはありません。
では、FFTして、ノイズレベルを見てみましょう。
まずは、元のSIN波。
周波数=100のところにピークがあるほかは、-100dBくらいのところにノイズフロアがあります。このノイズを全部二乗して足し合わせ、SND≒SINADを求めると68.5dBでした。
ちょっとSINADの計算は怪しいかもしれませんが、このまま進めます。
上の波形はコンピュータで作り出したものですが、ADCの信号を想定しているので、有効ビット数(ENOB)=(SINAD-1.76)/6.02で求まります。
有効ビット数は11bitと出ました。12bit精度でSIN波を作っておいて、1LSBのノイズを乗せているのですから、とても妥当な値です。
次に、CICフィルタを通した後のFFT結果を示します。
SINAD=77.5dBと計算できたので、有効ビット数は12.5bitと求まりました。
なんと、有効ビット数が1.4bitも増えました!
これを面白い結果とみるか、つまらない結果とみるかは人それぞれだと思います。
3タップ・4倍デシメーションなので、計算に必要なビット数は6bit増えます。
実際にはそれほど精度は上がっていませんが、時間軸上の情報をデシメーションすることで、分解能を変えられるというのは面白いことだと私は思います。
3タップCICフィルタの各部の計算結果を見てみましょう。
まずはデシメータの左側の部分の最初の積分器の結果をx0とします。このx0の動きを見てみますと、
明らかにオーバーフローしてしまっています。
それどころか、直流(DC)を入れたり、インパルスを入れた場合でも、積分器の出力は何らかの値を出し続けるので、オーバーフローしてしまいます。
次の図は、t=500のときにx=1となるインパルスを入れた場合の、積分器の各段の計算結果です。
たった1つだけのデータが1になっただけでも、時間とともにどんどんオーバーフローしていくのですから、時間軸で追いかけていっても何もわかりません。
このように、CICフィルタの積分器はいつもオーバーフローしています。オーバーフローさせた状態で使い、微分器で、数ポイント前のとの差分を計算して使うという、非常におおざっぱな動きをしています。
じつは今日、実験してみて初めてわかりました。
このオーバーフローをしても計算結果が無意味にならない最低のビット数が、
出力ビット数 = タップ数 × log2(R + M) + 入力ビット数
の式であるようです。
まぁ、時系列で追っていくと何だかわかりませんが、微分した結果を見ればそれなりのものになっているという、不思議な回路です。
次の図は、振幅は1LSBのSIN波だけど、入力データにσ=0.3LSBのノイズが乗っているというデータをCICフィルタに通したものです。
ノイズがあるので、遷移するところがバリバリになっていますが、そのおかげで中間の値を復元できているのがわかります。もし、ノイズが全くない状態だと、CICフィルタを通した値はとてもカクカクしたものになってしまいます。
逆にノイズが多すぎても(σ=1.5)、
出力された結果に多くのノイズが乗るのでよろしくありません。
この結果からわかるのは、ADCに直流が印加された場合に、CICフィルタが中間値を出力するためには適度(σ=0.3くらい)なノイズが必要であるということです。当然といえば当然ですが。
また、CICフィルタの遮断特性は急峻ではないので、ノイズが多いと取り切れません。あまりノイズが多くてもよくないということが言えます。
良いのか悪いのかよくわからないCICフィルタですが、ゆっくりと変化していく信号に対してはもっともらしい結果を出すので、きっと使えるのだと思います。
次回は、ビット数が本当に増えるのかどうかを検証してみることにします。
AD変換器の分解能を向上させる方法があります。
このブログで説明する方法を使うと、同じADCを使いながら500kps 24bitにしたり、100MHz 12bitにしたりすることができます。
それは、AD変換でサンプリングしたデータにディジタル信号処理を施して、ローパスフィルタの演算によってビット数を増やすというものです。ローパスフィルタならFIRフィルタを使えばよいのですが、タップ数が増えると非常にたくさんの係数をかけなけなければならないので回路面積や消費電力が増えてしまいます。
そこで、次の図に示すCICフィルタというのが昔から使われてきました。
CICフィルタの仕組みは http://www.dspguru.net/sites/dspguru/files/cic.pdf で紹介されているとおりです。
加算器と減算器、遅延(メモリ)のみで構成されているので、FIRに比べるととてもコンパクトです。
実際にFPGAで動かす前に、このフィルタの動作をC言語で作って試してみました。
まず、横256ポイント、縦8bitで、1周期分の正弦波をC言語で作ります。
ただし、この正弦波にはノイズが乗っています。ノイズは正規分布(σ=1 LSB)にしたがっている一様乱数に、2点の平均化を行って高域を減衰させたものを使っています。だから、ギザギザしています。
ちょっとノイズが多目のADCの波形はこんなものでしょう。ノイズは乗っていますが、ノイズを加えた後の値はもちろん整数です。
これを、3タップのCICフィルタに入れて4分の1にデシメーションすると・・
この緑の線のように滑らかになって、整数の間の値が出てきます。
ADCで高速にサンプリングしてLPFを通せば当たり前だと言われればそのとおりなのですが、いろいろメリットがあるのです。
まず、どの程度の分解能になるかというと、計算に必要なビット数は、以下の式で求められます。
出力ビット数 = タップ数 × log2(R + M) + 入力ビット数
ここで、Rはデシメーションの比率、Mは微分器の遅延の段数です。
上の構成ではタップ3なので、8bit + 3 * 2 = 14bit となって、計算の結果を保持するのに14bit必要ということになりました。つまり、8bitの入力から14bitの精度を生み出したという非常に胡散臭い結果となるわけです。
※本当に14bitの精度があるかどうかは後で検証します。
実はCICフィルタは昔から使われている手法なので、XILINXのCoreGenのDigital Signal Processing→Filters→CIC Compilerの中に既にあります。
CoreGenでCICフィルタを作ろうとすると、周波数特性まで示してくれるので、それを見てみましょう。
タップ3、デシメーション4だと下の図のような特性なので、それほど急峻ではありません。
タップ5、M=2、デシメーション8にすると、こんなに急峻な特性になります。
計算に28bitの精度が必要になるので、まぁ、実用的ではないですね。本当に28bitの精度があるかどうかは疑わしいです。
急峻な特性を得たいならば、CICの後ろにFIRを組み合わせるのがよいのではないかと思います。
Cosmo-Zの件で東工大のある研究室に行ってきました。
可変解像度なADCと、リアルタイムなFFTと、LabViewとのインタフェースと、高速なDACを作ろうと思いました。
こういったあらゆる実験で使えそうな基本的で重要な要素は、どんどん実装して、世の中に広めていこうと思います。
ついに、ZYNQ搭載ADCボード「Cosmo-Z」の32ch動作に成功しました。
何が苦労したかというと、消費電流と発熱です。
Cosmo-Z本体(ADC 8ch)は、現在のところ7W程度の消費電流ですが、8chの拡張ボードは1枚あたり4W程度も食うのです。32chフルに実装すると20Wにも達します。
5V4Aの電源から供給すればよいのですが、20Wの発熱をする物体がそこにあるともわーっとした空気を感じてしまいます。
拡張基板の何がそんなに無駄な電力をつかっているのかといろいろ調べました。基板のパターンをカットしたり、スイッチング電源を外して各部の電流を測ったりしたのですが・・
結局、無駄な電力を消費しているのはスイッチングレギュレータの後のLDOと、フロントエンドの高速OPアンプでした。
ひとまず、低消費電力化はあきらめ、FPGAの中身の開発を進めることにしました。
すぐに動作確認したいときには、バウンダリスキャンを使ってLVDSの信号が来ているかどうかを調べると便利です。
CH1とCH2.。これはメイン基板です。LVDSの信号はバウンダリスキャンで見てもそれなりに対称的に見えますね。
拡張基板のCH3とCH4。これも問題なく信号が来ています。
最後にCH7とCH8
このように、全チャネルの端子にLVDSの信号が来ていることが確認できました。バウンダリスキャンって、便利ですね。
全チャネルにLVDSが来ていることが確認できたので、ソフトを起動してみたところ・・
バッチリ32個のCHのLVDSの同期が取れました。480MHzの差動信号が64本束ねられて送られてきて、デコードできたのですから、すごいものです。
ADC値を見てみると・・
このように、それなりに2048(0V)付近の値が見えていました。
動作も問題ないようです。.
現在の問題としてはADCのクロックを一番低い80MHzに設定しないとLVDSのロックが取れないことです。電力の問題なのか、それとも、LVDSのラインに誤って47Ω×2個のダンピング抵抗を挿入してしまったので、それが原因なのかもしれません。
Cosmo-Zの開発には若いパワーが必要です。
特電でアルバイトして一緒にCosmo-Zを開発したいという方がいらっしゃいましたら、こちらへどうぞ↓。待ってます!
先月、学会でCosmo-Zを展示した反省点を踏まえ、大規模な機能の整理と向上を行っています。
もともとCosmoZは放射線、とりわけミューオンの検出用に開発したのですが、まずは柔軟なデータロガーとして動くように内部構造を整理しました。
次のようにすっきりとしました。
まず、可変クロック発生器(図の左下)というものがあって、こいつがすべてのADCのクロックの源を出しています。このクロック発生器は、単純に水晶から作っているのではなく、MMCMのダイナミックリコンフィギュレーションを用いて発振周波数を80MHz,100MHz,125MHzに動的に変えるのです。そして、Max 255分周の分周期でADCのサンプリングレートを1MHz~125MHzまで変えられるようにしています。
Gbpsに迫る速度でADCから送られてきたLVDSのデータをデコードするのが、ADC LVDSデコード回路の役割です。デコードされたデータは、オフセットと、ゲインをかけて補正を行い、その後、可変遅延回路に入ります。可変遅延回路というのは要はリングバッファです。
可変遅延回路を出力したデータはマルチプレクスされてメインメモリに格納されるというしくみです。
簡単に書いていますが、AXIバスは4本あります。ZYNQの中のAXI HPポートは高々64bit 250MHzまでしかいかないので、たった4Gbpsの帯域しかないのです。32ch同時に100MHzサンプリングしたらAXIバスが詰まってしまいます。
だから4本のAXIバスに分けてADからのデータをDDR3に送り込んでやろうというわけです。入口は狭いけど、きっと中は広いはず。
実際にどんな感じか、実験してみてみましょう。まず、Cosmo-Zの入力CH1とCH2をショートし、CH1とCH2に同じ信号が入るようにします。
Cosmo-Zを起動したら、helpコマンドを打ってみましょう。
ソフトウェアのバージョンも0.5になって、だいぶん洗練されたと思います。
今回のバージョンからは、cosmozのソフトの中でコンソールを持つようになったので、毎回毎回cosmoz.elfを起動する必要がなくなりました。
adc helpと打つと、ADC関係のコマンドのヘルプが出ます。
adc freq 25と打つと、ADCのサンプリングレートを25MHzに変更できます。
adc dispmodeは、表示をHEXにするかDECにするかを指定します。
adcとだけ打つと、現在の値を表示します。
上の図では8ch分しかありませんが、adc boards コマンドでチャネル数を増やすこともできます。
captureコマンドを打つと、データをキャプチャして画面に表示してくれます。ファイルに保存するモードであれば、レートとチャネル数にもよりますが、数十Mサンプリングまでできます。
見てわかるとおり、信号を入れていないチャネルは信号が±1しか変化しません。ノイズの影響はほとんどありません。
このように、ADCの速度をはじめとした様々なパラメータはLinuxのコンソールから行うのですが、波形はやはり画像で見たいものです。
そこで、Cosmo-ZのIPアドレスをブラウザに入力して、Web画面(のcgi-bin/pngwave.cgi)を開くと、現在のキャプチャされた波形が表示されるようにしました。
綺麗な正弦波ですね。
この波形キャプチャ画像ツールは、縦横の単位やサイズが自由自在に伸び縮みします。例えば、80MHzで10万ポイントをサンプリングして、横8000pixelの画像にすることもできます。
遅延時間や、ゲイン、オフセットはチャネルごとに個別に設定できるので、たとえば遅延時間を2つのチャネルでずらしてやると、同じ波形なのにこう見せたり、
こう見せたりできます。
これが何の役に立つのかというと、2つのチャネルから入ってきた信号を、どちらか一方だけ遅らせてトリガをかけるとか、信号の到達時間の差を補正するというのに使えるかと思います。
4月22日水曜日中には、この新しいデザインをリリースできるよう頑張りたいと思います。
もし、Cosmo-Zにご興味をお持ちいただける方がいらっしゃいましたが、下のリンクをクリックしてCosmo-Zのページにお越しいただけると幸いです。
また、もし、特電でアルバイトして一緒にCosmo-Zを開発したいという方がいらっしゃいましたら、こちらへ
MITOUJTAGのBLOGANA機能を拡張しています。
BLOGANA(ブロガナ)というのは、XILINX FPGA内のBlockRAMに波形データを溜め込む高速なロジアナIPのことです。BLOGANAを埋め込んだFPGAは、MITOUJTAGで波形を読み出すことができます。
ChipScopeやSignalTAPのようなものです。
しかし、いままでのBLOGANAでは、ビット幅が72bit、サンプリング長が最大1024に限られていました。それは、XILINXのBlockRAMが36bit幅で512Wordの深さで、4個まで使うようになっていたからです。
BLOGANAはSpartan-3のころに開発したので、当時はBlockRAMが貴重で、あまりたくさんのメモリをロジアナ用に使えなかったためです。
しかし、AXIバスの動作を見ようとしたりすると、72bitじゃ足りません。SATAのプロトコルを見ようとすると長さが1024では足りまさえん。BLOGANAの機能拡張が望まれてきました。
今のXILINX 7シリーズにはBlockRAMは売るほど入っています。これを有効に活用してみることにしました。
新しいBLOGANAのComponent定義はこうなりました。
entity blogana2 is generic( BIT_WIDTH : integer := 72; --サンプリングする信号のBIT幅を指定(1以上、252以下で指定) SAMPLE_LENGTH : integer := 1024--サンプリングの長さ(word)を指定(1以上、8192以下で指定) ); Port ( CLK : in std_logic; TRIG : in std_logic; USER_OP : out std_logic_vector(19 downto 0); SAMPLE_EN : in std_logic; DIN : in std_logic_vector(255 downto 0); --BIT幅は常に256bit SAMP_FREQ : in integer range 0 to 2147483647; -- サンプリング周波数 BUSY : out std_logic -- 必ずどこかに出力すること ); end blogana2;
入力データ幅は256ビット。(ただしサンプリングできるのは252bitまで)
データ長は8192まで拡張できるようにしました。
データ幅やデータ長はGenericで渡します。
このGeneric文で指定したパラメータを見て、BLOGANA内部のマクロとFOR文が、BlockRAMをこんな形や
最大で、252bit 8192Word(縦7個・横16個)並べることができます。この場合、112個の18K BlockRAMを使います。
それでもArtix-7のXC7A100T中のBlockRAMの約40%しか使いません。
実際にカウンタを作ってBLOGANA_DINのbit251~220につないでキャプチャしてみたところ、
Cosmo-Zの波形Capture機能を実行したときの各部の波形を見てみます。
これは、16bit 8ch 2148ワードのデータをマルチプレクスしながらAXIインターコネクトに対して投げているところの波形です。
AXIバスや、周囲にの制御信号の動きを見る限り、ちゃんとキャプチャできているようです。
これからいろいろな波形を取ってデバッグしていきたいと思います。
Cosmo-ZのADコンバータのサンプリング周波数を動的に変更できるようにしました。
Cosmo-ZのADコンバータはのサンプリング周波数は、80MHz、100MHz、125MHzと3種類の選択肢があります。
このADコンバータのクロックはPLL(MMCM)で作っているので、いままでは、FPGAのソースコードを変更して再ビルドしなければなりませんでした。そこで、この周波数を動的に変更しようと考えました。
基本的なやり方は、過去の記事「XILINX 7 シリーズにおけるMMCM周波数の動的変更」で書いたのですが、MMCMのDRP(ダイナミック・リコンフィギュレーション・ポート)を使います。
基本的にはDRPを通じてレジスタに設定値を送り込めばMMCMは新しい周波数で動作を開始するのですが、望みの周波数で発振させるためにはどんな設定値を書けばよいのか、わからないと思います。
そこで、まず、80MHz、100MHZ、125MHzで動作するMMCMをCoreGenで作って、DRPを通じて現在の値を読み出します。その値をVHDLでハードコーディングして、必要なときに送り込むようにすればよいというわけです。
このようにしてDRPポートに送り込んでいるときの波形は次のとおりです。
こうして作ったクロックによって、Cosmo-ZのADCは80MHz/100MHz/125MHzを動的に切り替えられます。
クロックが変わったら、ADCから送られてくるシリアルデータをデコードする回路をリセットして、やらねばなりません。
次の図は、ISERDESのIDELAY_CEと、BitSlipのパルスです。
80MHzのとき。
100MHzのとき。
125MHzのとき。
このように、動的に周波数を変更し、再同期を行うことができるようにしました。
最近のコメント