1月を振り返って
1月は早いですね。あっという間です。
溜まっていた受託案件にも大分手を付けることができました。32ch化された波形整形回路付のCosmo-Zももう少しで完成すると思います。
FFTの案件も2つありますが、どちらもめどが付いてきました。
この1月の間に、新しい事務のスタッフが2名も入ってくれました。二人ともてきぱきと仕事をしてくれる方なので、特電のスピードアップが期待できます。
そのうちの1名はマンガも描けるとのこと、とても期待しています。
1月は早いですね。あっという間です。
溜まっていた受託案件にも大分手を付けることができました。32ch化された波形整形回路付のCosmo-Zももう少しで完成すると思います。
FFTの案件も2つありますが、どちらもめどが付いてきました。
この1月の間に、新しい事務のスタッフが2名も入ってくれました。二人ともてきぱきと仕事をしてくれる方なので、特電のスピードアップが期待できます。
そのうちの1名はマンガも描けるとのこと、とても期待しています。
18bitのA/D変換ボードを8台製造しました。
生基板の在庫が尽きてしまっていたのと、お正月を挟んだのと、いろいろなトラブルで、およそ2か月くらい納期がかかってしまいました。誠に申し訳ございません。
30日(土)の朝、私の自宅に実装済み基板が届いたので、夜中に自転車に乗って会社に行ってテストしていました。
嬉しいことに、全部、一発で動作OKでした。
ノイズも±2.4LSB(≒46μV)に収まっているし、
INL(積分直線性誤差)も、入力が±1Vの範囲内では±25μV程度で、≒1.3LSBの範囲内でした。±1Vを超えると大きくなっているように見えますが、これは電圧源に使っているYOKOGAWA7651という精密電圧発生器のせいです。
ひずみ率も-100dB以下でした。下のグラフは、50kHzの正弦波をFFTしたものですが、高調波も非常に小さくなっているのがわかります。
95kHz付近にあるのは高調波ではなく、発振器か、もしくはケーブルが拾っているノイズです。
よかった。もし異常があったら徹夜しなければならないところでした。
今、FPGAでハードウェアFFTを行わなければならない案件を2つ抱えています。そのうちの1つは、65536ポイント~1Mポイント程度のFFTをつなぎ目なく行うというものです。
FFTのアルゴリズムですが、もっとも基本的な基数2のCooley-Tukeyアルゴリズムを考えてみます。
これは基数2の16ポイントFFTなので、ステージ0,1,2,3と4つあります。
ごく普通のFFTなのですが、これを65536ポイントや1Mポイントでやろうとした場合、厄介なことが生じます。それは、FFTする途中経過のデータを格納するアドレスが連続しないという問題です。
最初のステージでは、データの0と1、2と3・・を演算します。
次のステージでは、データの0と2、1と3・・を演算します。
・・
だんだんバラバラになってきます。
1Mポイントとかとなると、
・アドレス0とアドレス524288を計算
・アドレス1とアドレス524289を計算
・アドレス2とアドレス524290を計算
という風に、読み出す場所がかなり離れてしまいます。
プログラムで書くと、
int b = 2; for (stage = 0; stage < N; stage++) { for (i = 0; i < DataLength / b; i++) { int offset = b * i; for (j = 0; j < b / 2; j++) { Complex A = mem[offset + j]; Complex B = mem[offset + j + b / 2] * W[j * DataLength / b]; mem[offset + j] = A + B; mem[offset + j + b / 2] = A - B; } } b = b * 2; }
このようになります。アドレスが飛ぶところをbという変数にしていますが、ややこしいですね。シーケンシャルではなく、ランダムアクセスになってしまいます。
FPGA内のBRAMに収まるサイズのFFTなら無理やりできますが、1Mポイントだと内蔵BlockRAMに納まらないのでDDR3などの外部メモリを使うことになります。
DDR3メモリはランダムアクセスが苦手です。つまり、通常のFFTのアルゴリズムでは大きなサイズのFFTがやりにくくなります。
そこで、私が提案するのは、以下のようなアルゴリズムです。VFFTと呼びます。
VFFTは、普通のCooley-Tukeyのアルゴリズムとやっていること同じなのですが、計算のフローをねじった形になっています。
このFFTでは、データの読み書きするアドレスが独特です。
と、連続した番地へメモリアクセスができます。
計算結果は2本のFIFOを用意すれば、256バイト程度に分けて、連続したアドレスに書き込みができます。
それに嬉しいことにステージが変わっても、読み書きするアドレスは変わらないので、メモリの読み書きアドレスを計算するためのロジックが軽くてすみます。
プログラムで書くと、
Complex *work = new Complex[DataLength]; int mask = ~((2 << (N-2))-1); for (stage = 0; stage < N; stage++) { int offset = DataLength/2; for (j = 0; j < DataLength / 2; j++) { Complex A = mem[j*2]; Complex B = mem[j*2+1] * W[j & mask]; work[j] = A + B; work[j + DataLength/2] = A - B; } mask = mask >> 1; for (j = 0; j < DataLength; j++) { mem[j] = work[j]; } } delete[] work;
と、元のFFTは3重のループだったのが、2重のループになっていることがわかります。
メリットは、
ということで、FPGA向きだと思います。
欠点は、メモリの読み書きアドレスが異なるので、ワークメモリ用に2倍のメモリを使うことです。
メモリの必要量が2倍になっても気にならない場合には、ぜひ、検討してみてください。
Cosmo-Zの32ch版を作って、タカチのアルミの箱に納めました。
裏面は、このように凹んだパネルの中にコネクタ類があります。
なぜ凹んだリアパネルになっているかというと、タカチの既製品の箱を使っているため、Cosmo-Zの基板のサイズが短いからです。
中身はこうなっています。
このアルミの加工は板金屋さんにお願いしましたが、凹んだリアパネルの設計はアルバイトのスタッフがやってくれました。構造が難解なケースであるにもかかわらず、一発で成功させてくれました。さすが東工大。
なかなかいい感じのケースに仕上がったと思います。
・・と思っていたら、このお客様の要求仕様は、全部のコネクタがLEMOコネクタでした!!! SMAじゃなかった! 作り直し!
Cosmo-ZでハードウェアFFT回路を作ろうとしています。
FFTする元データと変換後のデータはDDR3メモリにあるので、PLからDDR3メモリにアクセスするにはHPポートというのを使わなければなりません。
AXI HPポート越しにDDR3にアクセスすると、どのくらいの読み書き速度がでるのでしょうか。実験してみました。
作ろうとしている回路は次のようなものです。バタフライ演算器が2個あって、2chのFFTを同時に実行します。
演算前のデータと演算後のデータはDDR3メモリにあって、ZYNQのPLとPSの間は、250MHz 64bitのAXI HPポートでつないでいます。
FPGAの中にロジアナのIPコアを埋め込んで、MITOUJTAGを使ってFIFOやAXI HPの信号を見てみました。
まずは、DDR3からの読み出しのみを行ったときの波形です。
上の図で見えているのは、アドレスと長さ(0xff=256QWORD)を与え、arvalidを'1'にして、16回分の転送を開始したところです。
AXIバスがarreadyを'1'にしたときに、自分の回路がarvalidを'1'にすると転送コマンドがセットされます。そして、AXIバスがrvalidを'1'にしたときにDDR3から読み出したデータが送られてきます。
AXIのデータバスは64bitで、1回の転送サイズは256QWORD=2048バイトで、それが16回行われるのですから、全体で32768バイトの転送が行われています。それに要した時間は約20usなので、1638MB/secの速度でメモリから読み出せていることがわかります。
Cosmo-ZのDDR3メモリは32bit幅で533MHzでインタフェースしているので、4264MB/secのバス速度があります。
AXI HPを1chで読み出した場合、実に38%しか活用できていないことになります。
次に、メモリのReadと並行して、Writeを行ってみました。
先ほどの波形とは違い、AWVALIDなどの書き込み系信号も使っています。
32768バイトの読み出しと、32768バイトの書き込みが並行して行われているのですが、全体で23.6usしかかかっていません。したがって、速度は2777MB/sec出ていることになります。
なんと、メモリのバス速度の65%を活用できていることになります。
DDR3メモリの読み出しだけだと、あまり帯域は活用できません。
その原因となるのは、
だからです。
DDR3の読み出し速度が遅いのではなく、AXI HPポートが遅いのです。
メモリから見ればスカスカなRead要求しかしてこないので、読み書きを同時に行うとバスの使用効率が飛躍的に上がるのでしょう。
今回は試していませんが、より高速に読み出すためには、
といった手が考えられます。
台形型波形整形回路を調整しました。
その波形整形の様子をアニメーションGIFにしました。
(クリックで拡大)
このフィルタは、HPFとLPFを組み合わせたようなものなのですが、積分回路のパラメータで時定数を調整できるようになっていて、うまく合わせると台形の頂上の部分が平らになるようになります。
下の図は、バックグラウンドのスペクトルです。
4本のグラフがありますが、オレンジと青の線がプラスチックシンチレータからの信号のパルスハイトを分析したものです。茶色と黄色の線が台形フィルタを通したものです。2つの線はほとんど同じで有意な差はありません。
プラスチックシンチレータの横に塩化カリウムの試薬を置いた状態のスペクトルが下の図です。
青・黄色の線の、横軸50のあたりにピークが見えます。塩化カリウムを置くことでこれらのピークが出たので、40Kからのガンマ線によるものと思われます。
波形整形回路を通してもエネルギーの分解能は向上することも、悪化することもありませんでした。これは、おそらく元の波形のパルスが十分に大きく、非常に綺麗であるため、波形整形回路を通す必要がなかったのだと思います。
ノイズにまみれていたり、ひずみが多いようなセンサの場合に威力を発揮するかもしれません。
逆に言えば、特電のプラスチックシンチレータ+フォトマルでは、これまで、計測が容易なエネルギーの高い波形しか取ってこなかったということです。もっと小さな(エネルギーの低い 10~100KeV領域)の波形取得にも挑戦するべきかもしれません。
FPGAに波形整形回路の台形フィルタを入れて、プラスチックシンチレータからの信号を整形してからMCAに入れてみました。
波形整形回路を入れるとエネルギー分解能が上がるとのことです。
まずは、フィルタを通す前と後の信号。
これは、たまたま2つのシンチレータが同時に発光したときの波形です。CH1とCH4の波形が生の波形、CH1+filterとCH4+filterと書かれた波形がフィルタ後のものです。
何もないときのバックグラウンドのスペクトラムを見てみます。
下の図は、塩化カリウムをプラスチックシンチレータの横に置いたときのスペクトルです。
プラスチックシンチレータなのでスペクトルはいい加減ですが、増えた部分がカリウム40によるものと思われます。
CH1は18くらい、CH4は50くらいのところにピークが出ています。
しかし、フィルタを通すことによって、ピークが鋭くなるどころか、なだらかになって分解能が下がってしまいました。
調整をしなければならないのかもしれません。
昨年のブログで、作った基板の内層がショートしていたりオープンになっていたという話を書きました。
という謎の現象でしたが、ようやくこの原因がわかりました。
私はProtel99SEを未だに愛用しているのですが、内層がつながっていないのはこのCADでの面付けのやりかたに問題がありました。
複数の基板を面付けしたときに、内層はメインとなる基板でのネット名でつながるので、つまり、メインとなる基板がAGNDという名前のネットをGNDプレーンに割り当てていて、サブ基板がGNDという名前のネットをGNDプレーンに割り付けていても、コピー&(スペシャル)ペーストしたときに内層への接続が解除されてしまうためです。
つまり、Protel99SEでのコピー&(スペシャル)ペーストは、コピーされた対象のデザインルールが適用されてしまうということでした。
電源がショートしているという件は、
このようにショートしているのですが、これは長穴の作り方に問題がありました。
L1層とL2(GND)層のガーバを見てみると
電源ジャックのVCCの部分はGNDの穴の周りに●の絶縁部分があるので、これだけならショートはしていないはずなのですが、●のサイズを越えて長穴をあけているため、長穴の淵の部分にスルーホールメッキがされて、L2、L3層とショートしてしまったようです。
では、今までの基板では大丈夫だったのかという問題になります。
下の図は別の基板のDCジャックの長穴の部分のGND内層です。3つのドリル穴があるのですが、真ん中のところしか内層がマスクされていません。
これだとショートしてしまうはずですが、過去に作った基板ではショートしていませんでした。
なぜかというと、P板.comの工場の人がデザイン・ルール・チェックで問題を見つけてくれて、修正をしてくれたからだそうです。ガーバ通りに作るとショートしてしまっていたそうです。
この基板は長穴の端の部分と真ん中の3か所に穴をあけたので、製造の人が気付いてくれたのかもしれません。失敗した基板のほうは真ん中だけにしか穴をあけていなかかったので、その微妙な差が明暗を分けたのでしょう。
さらに言えば、Protel99SEでは穴のあるPADを作る場合には、MultiLayerにしないといろいろな問題が生じます。これらの問題の起きた原因は、穴をあけるためのPADの存在するレイヤーがTopLayerになっていたからです。
様々な理由で基板に穴をあけたい場合、下の図のようなMultiLayerのPADにしておけば、内層には自動的にマスクが付くので問題はありません。
しかし、下の図のようなTopLayerの穴ありPADを作ると、内層のマスクが作られないのでショートします。
つまりまとめると、
ということです。
この記事が、私と同じくProtel99SEを一生使い続けるつもりの人の何かの役に立てば幸いです。
マーシーさんのツイッターによれば、Artix-7のXC7A15TとXC7A35Tは実は同一のダイだという可能性があるようです。
根拠としては、JTAGのIDCODEが一緒だという説。
コンフィギュレーションガイド(UG470)を見てみると、
確かに、両方ともX362D093で一緒です。
同じダイを使っているというのは、半導体メーカー的には十分にありえることです。小さい(安い)デバイスのために、わざわざマスクを作るのは経済的ではありません。同一のダイであっても、不揮発ビットで切り替えるか、パッケージングの際のボンディングで切り替えられるようにしておくのが合理的です。
同じダイで異なる品番にできれば、ラインナップを増やしたように見せられるというメリットがあります。歩留り向上のためではないと思います。(XC7A15でNGになるならXC7A200なんて全滅するはず)
さて、慣れないVivadoを使って、XC7A15TとXC7A35TのBitStreamを作ってみたところ、2つのBitStreamのサイズは2,192,112 バイトで一致していました。
しかしながら、XC7A35Tに対してXC7A15TのBitStreamを書き込もうとすると、エラーになってしまいました。
JTAG IDCODEが一緒のはずなのに、何らかの方法で識別しているのでしょうか。
ちなみに、BitStreamの中身を比較してみると、
先頭のテキストで書かれたデバイス名や論理合成時間の部分に差がある程度です。
その後ろにある
の部分が異なるのがわかります。先のUG470によればXC7A15TのJTAG IDCODEはX362D093なので、異なります。
ちなみに、30018001というのは、BitStreamのコマンド(BitStreamは命令とデータの組でできたパケットの列でできている)です。意味は、Write IDCODE Register 1Wordで、「次に続く32bitがデバイスのIDCODEと一致しない場合にはエラーとする」です。
結論を言うと、UG470のユーザガイドが間違っていたようで、XC7A15TとXC7A35TのJTAG IDCODEは異なります。
BSDLファイルを見てみると、XC7A35TのIDCODEはx362D093です。
attribute IDCODE_REGISTER of XC7A35T_CSG324 : entity is "XXXX" & -- version "0011011" & -- family "000101101" & -- array size "00001001001" & -- manufacturer "1"; -- required by 1149.1
です。
XC7A15TのIDCODEはx362E093です。
attribute IDCODE_REGISTER of XC7A15T_CSG324 : entity is "XXXX" & -- version "0011011" & -- family "000101110" & -- array size "00001001001" & -- manufacturer "1"; -- required by 1149.1
で、XC7A15TとXC7A35TのBitStreamは同じかというと、IDCODEと最後のCRCチェックの値を除いて完璧に同じでした。
BitStreamが同じなので、XC7A15TはXC7A35Tと同一のダイを特定のブロックを使わないようにツールで制限しているだけである可能性は高いと言えます。
しかし、XC7A35T用に作ったBitStreamのIDCODEとCRCを書き換えて、無理やりXC7A15Tにダウンロードすれば動くかというと、その可能性は低いでしょう。ボンディングによってXC7A35TをXC7A15Tに見せているのであれば、使用されないブロックの電源ごと落としてしまっている可能性があるからです。
推測ばかりの記事になりましたが、確かめることができないのでこのくらいにしたいと思います。
特殊電子回路㈱では大学生・大学院生の長期有給インターンシップを募集します。
場所は、本郷三丁目駅徒歩3分。東大赤門の前 です。
時給1200円~1500円以上ですが、高い能力をお持ちの方でたくさん来れる方はもっと高い給与をお支払します。月給や「プロジェクト単位」での報酬も可能です。
全力で特電を支えてくれる方には、学振以上の給与を保障します。
仕事内容は3つの職種で募集しています。どれか1つ当てはまればOK。
平日10時~23時までの中で週3以上・4H以上来れること。
詳しい条件や仕事内容については以下のページをご覧ください。
あけましておめでとうございます。
今年は、素粒子検出器を応用した計測器を作って、建設業界とかの一般顧客向けに販売することです。ただ、この計画が実現するにはあと2~3年はかかると思うので、今年はその第一歩が踏み出せたらよいなと思います。具体的には助成金とか取りたいですね。
製品としては、
などの開発を目指します。
事業の方向性としては、物理学実験向けの計測用電子回路の受託を伸ばしていきたいと思います。
最近のコメント