* AMT-VME [#qff10614] Atlas Muon TDC として開発されたチップを VMEのボードとして実装したものが、AMT-VMEです。 - 制作者、KEKの[[新井氏のページ>http://research.kek.jp/people/araiy/indexj.html]] -- [[AMT chip のページ>http://research.kek.jp/group/atlas/tdc/amt3/index.html]] --- [[AMT-3 chip のマニュアル>http://research.kek.jp/group/atlas/tdc/amt3/AMT3manual_034.pdf]] -- [[AMT-VMEのページ>http://research.kek.jp/group/atlas/tdc/AMT-VME/]] * High rate 環境下で使用する場合の問題 [#f81ce552] AMT-VME ボードは、チャンネル単価が約5000円とこの手のモジュールとしては安価なものです。 そのため、うちの研究室でも多数購入して使用しています。 通常の使用ではあまり顕著ではありませんが、common stop モードの測定で高レート環境で使用すると、TDC が想定されない値になるという現象があります。 AMT chip の制作者である新井氏相談後、ボードの制作会社である株式会社アムスクの協力により AMT-VME ボードを制御している DSP 及びCPLD のプログラムを入手できました。 また、DSPプログラムの開発環境およびフラッシュメモリにプログラムを書き込むソフト・ハードを一式借り受けることが出来ました。 実験データでのTDC分布及び、プログラムの解析の結果分かった事とDSPプログラムの書き換えによる対策を以下に記します。 ** 内容 [#n058280d] - 現象 -- [[NKS2実験での測定条件>#y1871935]] -- [[TDC 分布>#v9c3467f]] - 対策 -- [[ボード制御プログラムの改造>#v0421b4b]] -- [[パラメータの設定方法>#ha6a8c16]] -- [[ビームテストの結果>#m5ee566a]] ** 現象 [#zcb3b835] *** NKS2実験での測定条件 [#y1871935] 我々は、NKS2実験でドリフトチェンバーの時間測定のために AMT-VME ボードを使用しています。 NKS2 実験は標識化実光子ビームを用いたハドロン物理の研究を行っており、ビームレートは標識化された光子(0.8-1.1 GeV の領域)に対するのカウンターのレートで 1~3 MHz になります。 実際は、標識化されていないものが約2, 3十倍 あり、標識化ビーム 1MHzでドリフトチェンバーでの 1 チャンネル辺りのシングル・レートが平均約10kHz、最大50kHz です。 この環境下で、一台のPC辺り12枚あるいは14枚のAMT-VME ボードを読み出しています。 *** TDC 分布 [#v9c3467f] 測定するTDCのレンジは、Module Control parameter の Time range count という変数を VME 側から指定することで変更可能です。 Time range count は、12 bit の整数で、1カウント 25 ns の時間幅を持っています。 これは、AMT chip 内でのカウンターの時間幅がクロックでそろえてあるからで、40MHz クロックを使用していることによります。 NKS2 実験のシステムでは、チェンバーのシグナルが AMT-VME に入ってから、common stopが来るまで約 1 μs の遅れがありますので、Time range count は、 0x25 (= 37, 925 ns) のレンジに設定しています。 TDC の時間幅は、クロックを PLL で 1/32 にしたものを使用しています。 つまり、TDC 1 ch = 25/32 = 0.78125 ns の時間幅を持っていますので、TDC のレンジは 1200 ch 以下に収まると予想されます。 #ref(AMT-VME/AMT-VME_TDC_distribution_s.png,right,around) 測定されたデータを見てみると、0x1000辺りから 0x1FFFF までと、0xF0000辺りから 0xFFFFFまでの間にもヒットがあります。 結論からいうと、これは common stop が入った後も AMT chip が測定を続けておりそのために出てくるマイナスの値です。 AMT-VME ボードでは、入力 64 ch を 三つのAMT chip で請け負っていて(0-23, 24-47, 48-63 ch に対応、AMT0, AMT1, AMT2 と呼ばれている)、そのほかに common start/stop の時刻測定の為だけに 一つの AMT chip (AMT3 と呼ばれている)が使用されています。 ボード上の DSP プログラムは、四つの AMT chip のステータスを監視していて、AMT3 がレディーになればその時間情報を取り出し、AMT0, AMT1, AMT2 の時間情報を読んだ後に、時間差を計算しデータとして整形したあとメモリに書き込みます。 AMT chip 内での時間のカウンターは 12bit の coarse counter と 5 bit の fine counter、併せて17bit のカウンターを持っています。 一方、DSPの内部では、32bit の整数で処理をした後 20 bit の整数に整形しています。 カウンターのウインドウの位置により、17 bit のマイナスの値に成る場合と、20 bit のマイナスの値に成る場合があり、その結果として 0x1FFFF 以下と 0xFFFFF 以下の 領域二ヶ所に変な値が分布することになります。 common stop のシグナルは、AMT3 に入ります。 同時に CPLD に入り内部でクロックと同期した後、各 AMT chip の trigger に入力されています。 AMT chip は、trigger にシグナルが入力されると、それまで 内部の Level 1 buffer に貯められていた hit 情報と、trigger matching を行い、条件に合った物だけが Read-out FIFO に送られます。 Matching に関するパラメータは、mask_window, search_window, matching_window の三種類があります。 この三つの変数は AMT chip の CSR レジスタで変更可能ですが、現在アムスクから出荷されているAMT-VMEボードに実装されている DSP プログラムではVME側から変更することが出来ません。 値はそれぞれ、 CSR1: mask_window = 0 (AMT0-3) CSR2: search_window =2038(AMT0-2), 2056(AMT3) CSR3: matching_window = 2030(AMT0-2), 2048(AMT3) に固定されています。 この matching_window は、trigger timing から後に開いている windows ですが、trigger timing のカウンターは、coarse counter に対して、 bounch_count_offset で指定される値分だけ遅らせられます。 AMT-VME ボードでは、bounch_count_offset は、Time range count 分だけマイナス方向にずらしてあります。 NKS2実験では、Time range count は約 1 μs ですので、そこから matching_window の時間だけ AMT chip は ヒット情報を Read-out FIFO に送ります。 つまり、common stop から約 49 μs も後の方にタイム・ウインドウが開いており、common stop 後のヒット時刻を記録し続けることになります。 これが原因となり、非常に高レートの環境下では、マイナス時刻のヒットがTDCとして出てき、イベントサイズの増加とそれ伴う DAQ 効率の低下が問題となりました。 ** 対策 [#tbbd0316] *** ボード制御プログラムの改造 [#v0421b4b] AMT-VME ボード上では、DSPとCPLDの二種類のプログラム可能なチップがあります。DSPは入力とCommon Start/Stop との時間差の計算及びデータの整形と、AMT chip の制御パラメータ(CSRレジスタ等)の値の設定を行っています。 CPLDの方は、DSPからのシグナルをクロックに同期させたあとにAMT chip に送るものと、VME bus とデータをやりとりする為のものとの二つのチップがあります。 マイナスのTDCの値が出ないようにするために、以下の三つのことを考えました。 最終的に採用したのは三番目のものです。 + DSP プログラムの改造(1) -- マイナスのTDCに値に相当するデータが出たら捨てるように if 分を足す。 -- 値は出なくなったが、AMT から出てくるデータ量は変わらないので読み出し時間の短縮にならない。 -- この方法は得にならないのでボツ。 + Common stop が入ったあと AMT chip を止め、測定を行わないようにする -- AMT chip の Measurement Start/Stop は、DSPプログラムが Module Control Parameter の Run Status (DSP address: 0x8F82) の Bit1 を見てコントロールしている。DSPは、DSP IO の CNTRという名前のポート(0xFE00)に対して値を設定し、CPLDがその値を見て Start/Stop のシグナルを AMT chip に送るようになっている。 -- しかし、CPLDのプログラムを見てみると CNTR に Stop が設定された場合に AMT chip に Stop が送るコマンドがコメント・アウトされており、現在の実装では AMT chip の測定を止めることが出来ない。 -- 今回は、DSP プログラムの書き換えツールのみを借りており CPLD のプログラムを変更して試すことが出来なく、この案は断念。 + DSP プログラムの改造(2) -- DSP プログラムは、パラメータ設定モードと測定モードを交互に繰り返すが、最初一回だけパラメータ設定モード中で AMT chip の CSRレジスタの値を設定し chip に送っている。 -- time window に関連するパラメータをVME 側から設定できるように DSP プログラムを変更。 -- AMT chip 内で要らないデータを捨てることが出来るので、DSPでの処理時間が短縮される。 DSP用のプログラムは複数のファイルから構成されていますが、改造したのは &ref(main.c); というファイルのみです。 追加部分は 429: unsigned int *mask_win, *search_win, *match_win; 439: mask_win = (unsigned int*)0x8f91; // mask_window (12 bit) 440: search_win = (unsigned int*)0x8f93; // search_window (12 bit) 441: match_win = (unsigned int*)0x8f95; // match_window (12 bit) 501: // Tohoku Univ. version, added by M.Kaneta 502: if ( (uiRunStatus&0x0200)==0x0200 ) { 503: for (u=0;u<3;u++) { 504: amtcsr_init[u][1] = 0x0fff&(*mask_win); // mask_window 505: amtcsr_init[u][2] = 0x0fff&(*search_win); // search_window 506: amtcsr_init[u][3] = 0x0fff&(*match_win); // match_window 507: } 508: } になります。 なお、各行の最初の数字と:は行番号を示していて、実際のコード(&ref(main.c);)には書かれていません。 プログラム中の uiRunStatus という変数は、アムスク制作の User's Manual (user,s m.pdf) の22ページに記述のある RunStatus に対応します。 マニュアルの記述では、Bit0 - Bit7, Bit28 - Bit30 だけが使われています。 (''注意! マニュアルには記述がありませんが、Bit8 にフラグが立つと、「連続測定モード」がテストできる用に実装されています。'') オリジナルのプログラムでは使われていない Bit9 が 1 の場合のみ、三つの time window 変数に値が与えられるように実装しました。 504から506行目で、配列変数 amtcsr_init に値を代入しています。 この変数は、AMT chip の CSRレジスタの値を設定するために使われます。 一つ目の配列の添え字は AMT chip の番号、二つ目のものは CSRレジスタの番号に対応しています。 (CSRレジスタについては、"[[AMT2&3 User's Manual (V0.34, Dec. 11, 2009)>http://research.kek.jp/group/atlas/tdc/amt3/AMT3manual_034.pdf]]の p.30から"を参考にして下さい。) Module Control Parameters 等の AMT-VMEボードに関連する変数とVMEアドレスの関係は、[[別のページ>https://spreadsheets.google.com/pub?key=0AqCNir5ySiBLdEIxUUZKZkl0X0JnTzItV2tBN3gxLXc&hl=ja&output=html]]にまとめてあります。 *** パラメータの設定方法 [#ha6a8c16] NKS2実験では、SBS Technologies (Bit3) 社製 PCI-VME アダプタ (Model 618)を用いてVMEからPCでデータを読み出しています。 デバイスドライバ及びVMEデバイスへアクセスするためのライブラリは、東北大学ニュートリノ科学研究センターの榎本三四郎氏の開発したvmedrvとvmeslibを使用しています。 ドライバとライブラリの関数の詳しい使用方法は以下のリンクを参考にして下さい。 - [[榎本三四郎氏のページ>http://www.awa.tohoku.ac.jp/~sanshiro/]] -- [[vmedrvのページ>http://www.awa.tohoku.ac.jp/~sanshiro/kinoko/vmedrv/index.html]] -- [[vmeslibのページ>http://www.awa.tohoku.ac.jp/~sanshiro/kinoko/vmedrv/vmeslib.html]] AMT-VMEボードへのパラメータの設定方法は、ソフトにより異なりますので、上記以外のドライバ・ライブラリを使用している場合適宜そのドライバに応じて変更する必要があります。 以下に、NKS2実験で用いているDAQプログラムの一部を抜粋・省略したものを載せます。 AMT-VMEボードは5枚使用する場合の例で、それぞれのVMEメモリマップの先頭のアドレスは define で定義されている変数 AMT1, AMT2, ... AMT5 で指定されています。 // 変数定義等 #include <vmeslib.h> #define AMT_ACCESS_MODE VME_A24D32 // アドレス幅 24bit, データ幅 32bit #define AMT_TRANFER_MODE VME_NORMAL // 標準モード (Programmed I/O) #define AMT_CTR_ADDRESS 0x071f00 // VME_BASE (0x060000) + 0x011F00 #define AMT_DAT_ADDRESS 0x072000 // VME_BASE (0x060000) + 0x011F00 + 0x0100 #define AMT1 0x100000 // VMEメモリマップの先頭のアドレス #define AMT2 0x200000 // ボード上のディップスイッチ(SW3, SW4)で設定 #define AMT3 0x300000 // #define AMT4 0x400000 // #define AMT5 0x500000 // #define AMT1ID 1 #define AMT2ID 2 #define AMT3ID 3 #define AMT4ID 4 #define AMT5ID 5 static int AMTList[] = { AMT1, AMT2, AMT3, AMT4, AMT5 }; static int AMTIDList[] = { AMT1ID, AMT2ID, AMT3ID, AMT4ID, AMT5ID }; static const int nAMT = sizeof(AMTList)/sizeof(int); const int* dat_base[30]; int* ctr_base[30]; #define SIZE 0x100 // マッピングする領域のサイズ(バイト) #define DAT_SIZE 0xc000 // バッファ一つ分のサイズ(バイト) // 0x3000 / NUM_PART の値を指定 #define NUM_PART 0x4 // number of patition in a buffer #define TIME_RANGE 0x25 // 37 = 925 ns (TDC chでは 1184に相当) VMEMAP* amt_ctr_map[30]; // VMEMAP は vmeslib で定義されている構造体 VMEMAP* amt_dat_map[30]; // // Module Control Parameters の ctr_base[]に対する相対アドレス const long ePcount = 0x00; const long eRunStatus = 0x01; // Run Status const long eTimeRange = 0x02; // TDCの最大値の設定 const long eModuleID = 0x03; // モジュールID const long eCHenable1 = 0x04; // チャンネルマスク const long eCHenable2 = 0x05; // チャンネルマスク const long eNumPartition = 0x06; // 複数バッファで使用する時の分割数 const long eIcount = 0x07; // const long eMaskWindow = 0x08; // 新たに設定, mask_window の設定 const long eSearchWindow = 0x09; // 新たに設定, search_window の設定 const long eMatchWindow = 0x0a; // 新たに設定, match_window の設定 const long eEchoPoint = 0x38; // const long eAMTStatus = 0x39; // const long eScount = 0x3a; // // VMEメモリのマッピング for(i=0; i<nAMT; i++){ // コントロール・アドレスのマッピング // マッピングに失敗した場合は、エラー出力にメッセージを出して終了する if((amt_ctr_map[i] = vme_mapopen(AMT_ACCESS_MODE,AMTList[i]+AMT_CTR_ADDRESS, SIZE))==NULL ){ perror("ERROR : AMT-TDC ctr mapopen()"); exit(EXIT_FAILURE); } // データ・アドレスのマッピング // マッピングに失敗した場合は、エラー出力にメッセージを出して終了する if((amt_dat_map[i] = vme_mapopen(AMT_ACCESS_MODE,AMTList[i]+AMT_DAT_ADDRESS, DAT_SIZE))==NULL ){ perror("ERROR : AMT-TDC dat mapopen()"); exit(EXIT_FAILURE); } // マッピングされた領域の先頭を指すポインタ ctr_base[i]=vme_mapbase(amt_ctr_map[i]); dat_base[i]=vme_mapbase(amt_dat_map[i]); } 上記のプログラムにより、Module Control Parameters の設定が、このプログラムのローカル変数 ctr_base[i] に対して行えるようになります。 各ボードに対して以下の様に設定を行います。 for(i=0; i<nAMT; i++){ *( ctr_base[i] + eRunStatus ) = 0x0000; *( ctr_base[i] + ePcount ) = 0x0000; *( ctr_base[i] + eIcount ) = 0x0000; *( ctr_base[i] + eScount ) = 0x0000; *( ctr_base[i] + eEchoPoint ) = 0x0000; *( ctr_base[i] + eAMTStatus ) = 0x0000; *( ctr_base[i] + eTimeRange ) = TIME_RANGE; // Time range count: 0x25 = 37 *( ctr_base[i] + eModuleID ) = AMTIDList[i]; *( ctr_base[i] + eCHenable1 ) = 0xffffffff; // ch. 0-31, 全てのチャンネルを読む *( ctr_base[i] + eCHenable2 ) = 0xffffffff; // ch.32-63, 全てのチャンネルを読む *( ctr_base[i] + eNumPartition ) = NUM_PART; // Time windows are default values //long run_status = 0x0006; // 0000 0000 0000 0110 rising //long run_status = 0x000e; // 0000 0000 0000 1110 rising and falling // Time windows will be changed long run_status = 0x0206; // 0000 0010 0000 0110 rising //long run_status = 0x020e; // 0000 0010 0000 1110 rising and falling *( ctr_base[i] + eRunStatus ) = run_status; *( ctr_base[i] + ePcount ) = 0x01; *( ctr_base[i] + eMaskWindow ) = 0; // mask_window = 0 *( ctr_base[i] + eSearchWindow ) = TIME_RANGE + 8; // search_window = 45 *( ctr_base[i] + eMatchWindow ) = TIME_RANGE; // match_window = 37 } // Run Status bit information (original) // 31 |30-28|27-8| 7 | 6-5 | 4-3 | 2 | 1 | 0 //-----+-----+----+--------+--------+----------------+-----------|-----|------ // not |width|not |0:Trig |subtract|edge detection |0:com start|start|not // used| |used|1:Normal|offset |0:rising |1: stop |meas.|used // | | | | |1:rising&falling| | | // | | | | |2:falling | | | // | | | | |3:rising&width | | | この中で、Common Stop モードでの 測定領域に関するパラメータを設定しているのは、 *( ctr_base[i] + eTimeRange ) = TIME_RANGE; // 0x25 = 37 *( ctr_base[i] + eMaskWindow ) = 0; // mask_window = 0 *( ctr_base[i] + eSearchWindow ) = TIME_RANGE + 8; // search_window = 45 *( ctr_base[i] + eMatchWindow ) = TIME_RANGE; // match_window = 37 の四行です。 なお、Time Window に関するパラメータの元々の値は、DSPプログラム内部で mask_window = 0 search_window = 2038 match_window = 2030 に設定されています。 TIME_RANGE は、1 count = 25 ns の幅を持つ(クロックの幅と同じ)パラメータです。 このパラメータは、AMT chip のCSR4(reject_count_offset)と CSR6 (bunch_count_offset)に対して CSR4 (reject_count_offset) = 0xFFF - (0x08 + TIME_RANGE) CSR6 (bunch_count_offset) = 0xFFF - (0x04 + TIME_RANGE) の値になるようにDSPプログラム内で設定されています。 AMT chip のマニュアルにある例では、この二つのオフセットはポジティブの値に設定されています。 これは、トリガー・タイミングが AMT chip へのヒット入力よりも先に入ることが想定されているから(コライダーのバンチ・クロッシング・タイムなど)です。 AMT-VME ボードのコモン・ストップ・モードの場合は、コモン・ストップのシグナルがCPLD上でクロックに同期されたあと、AMT chip にトリガー・シグナルとして入力されます。 イベント・マッチングを行うトリガー・タイミングがヒットより後に来ますので、マイナスの方向にオフセットを指定する必要があります。 そのため、12bit のマイナスになるように 0xFFF から TIME_RANGE の値を引いてあります。 また、それぞれ 0x08, 0x04 の さらなるオフセットがあります。 安全のため少しずらしてあるのではと想像しますが、元々の開発者がすでにアムスクを退社しているので本当の理由は分かりません。 AMT-VME ボード上での動作としては、TIME_RANGE よりも過去の時間のヒットについては、イベント・マッチングをする際(トリガー・シグナルが入った後)に AMT chip 内の Level 1 (L1) buffer から 捨てられます。 つまり、この値より過去のヒットはデータとして出てきません。 mask_window は、time window に関係するパラメータなので、変更可能にしています。 元々の初期値はゼロなので、私が使用する際はゼロに設定しています。 トリガー・シグナルがAMTに入った時点から、search_window に入っているヒットに対し、match_window 以内あるヒットだけが、L1 buffer から Read-out FIFO に送られます。 この条件に充たさないヒットは捨てられることになり、コモン・ストップより後に入力に入ったヒットが L1 buffer に入っていても、Read-out FIFO に送られません。 *** ビームテストの結果 [#m5ee566a] 2010年4月26-28日に、東北大学電子光理学研究センター(旧核理研)で実際のNKS2セットアップで標識化実光子ビーム(ESUB{γ}; = 0.8 - 1.2 GeV)を使用してテストを行いました。 本実験のセットアップで time window のパラメータを変えた場合、どのくらい読み出し時間のロスが減りDAQ効率が上がるかを確かめることが目的です。 パラメータは、TIME_RANGE = 0x25 = 37 に固定し - オリジナル -- mask_window = 0 -- search_window = 2038 -- match_window = 2030 - Plan A -- mask_window = 0 -- search_window = 2038 -- match_window = TIME_RANGE - Plan B -- mask_window = 0 -- search_window = TIME_RANGE + 8 -- match_window = TIME_RANGE の三種類の組み合わせをテストしました。 各パラメータの組み合わせに対して、加速器の(電子の)ビームカレントを変えたものを三つデータを取っています。 加速のビームカレントが完全に安定しているわけではないので、各データ内でも光子ビームレートに変動があります。 下に、結果の図を示しました。 #ref(daq_efficiency.png,center) 最初の四つの図は、Trigger Accepted(1行目), DAQ efficiency(2行目) を、光子ビームレート(左側)とTrigger Requested(右側)のレートでプロットしたものです。 (なお、光子ビームレートは、標識化出来ている光子についてのものです。) 左下の図はビームレートに対する Trigger Requested のレートで、これは AMT-VMEのパラメータとは関係なく同じ曲線状に乗るものです。 図中オープン・シンボル(黒)で書かれたものが、time window のパラメータを何も変えなかった場合。 赤と青がtime windowを変えたものです。 DAQ効率が向上していることが、見て取れます。 (後ほど、event size と TDC 分布がどのように変わったかについての画像を載せる予定です。)