« 2016年8月 | トップページ | 2016年10月 »

2016.09.29

ピンヘッダに1GHzを通す(続き)

昨日のブログでは、SSTLとTMDSの使い方を間違っていたので、測りなおしました。

Pinheader


まず、TMDS_33は50Ωで3.3Vにプルアップするのが正しい使い方のようなのですが、昨日は間違って100Ωでプルアップしていました。そのため、↓の図のような波形になっていました。

左から順に、250MHz、500MHz、1GHzのクロック(矩形波)です。

Tmds33_250Tmds33_500Tmds33_1000

(TMDS_33 プルアップ抵抗値間違え クリックで拡大) 

50Ωでプルアップしたところ、

Tmds33_25050ohmTmds33_50050ohmTmds33_100050ohm

(TMDS_33 プルアップ抵抗値正しい クリックで拡大) 

となって、低速度(250MHz)のときの波形の凸凹がなくなりました。

sun

次にSSTLですが、SSTLは50ΩでVTT(終端電圧。普通はVCCの1/2)につながなければいけないのですが、昨日はおもいっきり間違えていました。

Diffsstl18_0250Difftl_500mhzDiffsstl_ghz

(DIFF_SSTL_18  終端抵抗間違い クリックで拡大)

DIFF_SSTL_15で、50ΩでVTTに終端した、正しい波形は以下のとおりです。

Diff_sstl15_250Diff_sstl15_500Diff_sstl15_1000_1

振幅は徐々に小さくなっていきますが、1GHzのクロックもちゃんと出ています。

sun

では、実際にデータっぽいものを流してみましょう。まずは、8b/10bでエンコードしたLVDS_25の波形をご覧ください。K28.5 D10.2 D10.2 D27.3という、SATAのALIGNプリミティブのつもりです。

Lvds25_random5Lvds25_random4

綺麗でしょ。アイがはっきりと開いています。

DIFF_SSTL_15の場合は、LVDS_25よりは汚いですが、信号自体には問題なさそうです。LVDSのほうがサグが発生しにくいです。

Diff_sstl15_random1Diff_sstl15_random2
(DIFF_SSTL_15 クリックで拡大)

TMDS_33の場合は、さらに汚いですが、信号自体には問題なさそうです。

Tmds33_random2_2Tmds33_random1_2

(TMSS_33 クリックで拡大)

LVDSもTMDSもSSTLも、信号が同じ値が2回続いたときに電圧が高くなる現象がネックになっています。MGTではプリエンファシス(デエンファシス)でこれを回避できるのですが、汎用I/Oではどうしても回避できません。

結論を言うと、

  • 波形の綺麗さは、LVDS_25 > DIFF_SSTL15 > TMDS_33 >> LVCMOS33
  • ピンヘッダでも、1GHzは通る
  • ピンヘッダだからどうこうというよりも、むしろ、汎用I/Oだからプリエンファシスが効かなくて、速度の制限が出る可能性の方が高い。

| | コメント (0)

2016.09.28

2.54mmピッチのピンヘッダに1GHzの信号は通るか?

今設計している新しいFPGAボード「Cosmo-K」は、拡張コネクタとして2.54mmピッチのピンヘッダを使う予定です。

ピンヘッダは万能基板で簡単に拡張できたり、フラットケーブルをつないだりするのにとても便利です。メザニンでは、拡張するためにわざわざ基板を起こさなければならないので、とても面倒です。

ですが、2.54mmピッチのピンヘッダはどこまで信号品質が保てるのでしょうか?
はたして1GHzの信号は通るのでしょうか?

そういったことを実験してみました。

まず、ピンヘッダが出ているボードとして特電Artix-7ボードを使います。この基板のピンヘッダの多くは、差動ペアが隣り合うように配置されています。

今、下の写真のようなHDMI入出力拡張ボードを作っているので、このボードを使って実験しました。

A7_hdmi_2A7_hdmi2

このボードと、測定のスキームは次の図のようになります。

Board_config

Artix-7のMMCMで500MHzと1GHzと100MHzのクロックを作り、それらのクロックをODDRとOBUFDSで差動信号として出力します。計6本の信号は平行して基板上を走ってピンヘッダから出します。

それらを2.5GHz帯域の差動プローブで受けて、40Gサンプル/秒のオシロで測った結果を示します。

sun

まず、IOSTANDARDをLVDS_25にしたときの波形です。左から順に250MHz,500MHz,1GHzです。VCCIOは2.5Vにしています。なお、UCFファイルでLVDS_25を指定して、実際のVCCIOを3.3VにするとArtix-7では信号は出ない。1.8Vなら出る。裏ワザなので製品では使わないようにしよう。

Lvds25_250Lvds25_500Lvds25_1000

(クリックで拡大)

シングルエンドの信号であったり、差動信号でも終端しなければバリバリにクロストークしますが、差動信号にして終端すればクロストークは観測できないほどに激減します。250MHz(一番左)の信号を見ると、平行して走っている1GHzの成分は漏れてきていません。また、反射もほとんど見られません。反射してヒゲが出たとしても、その成分が周波数が高すぎてオシロで見られないだけかもしれませんが。

sun

次に、TMDS_33というIOSTANDARDを使った場合です。

Tmds33_250Tmds33_500Tmds33_1000

(クリックで拡大) 終端抵抗が間違っているので信用しないこと

250MHzのときの波形がちょっと乱れています。隣を走る1GHzや500MHzからクロストークして漏れてきているのかもしれません。後からわかったのですが、終端抵抗の値を間違えていました。実際に使うときにはもっときれいな波形のはずです。

sun

次は、シングルエンドのLVCMOS33を使って、疑似的な差動信号を作った場合。

Lvcmos33_250Lvcmos33_500Lvcmos33_1000

(クリックで拡大)

これは酷い波形ですね。終端抵抗の有無に関わらず、汚いです。

250MHzの時は振幅がオーバー気味で、500MHzだと凸凹していて、1GHzは何も見えません。これではきっと通信はできません。でも、ピンヘッダが悪いのではなく、FPGAからLVCMOS33で出すことができないだけです。

sun

最後はDIFF_SSTL18の場合です。

Diffsstl18_0250Difftl_500mhzDiffsstl_ghz

(クリックで拡大) 終端抵抗が間違っているので信用しないこと

LVCMOS33よりはマシですが、1GHzも厳しいかもしれません。周波数が高くなると振幅が小さくなるのも嫌な感じです。あとから分かったのですが、これも終端抵抗の値を間違えていました。

sun

次の図は、LVDS_25規格にして、乱数パターンを出してみたときの図です。ビットレートは1Gbpsです。

Lvds25_randomLvds25_random3Lvds25_random2

(クリックで拡大)

左から順に、波形の全体、拡大、そのさらに拡大となっています。

見た感じでは、波形が全体的に上下に揺らいでいます。ただし、1つ1つのビットは綺麗なので、十分にデコードできそうです。また、拡大してみるとアイはちゃんと開いていそうなのですが、綺麗とも言い難い波形です。

その原因は、本当の乱数を送っているため、0が多かったり1が多かったりする箇所で、信号のベースラインが上に下に移動してしまうためだと思われます。

また、ただのI/Oを使っているので、プリエンファシスが効かないという理由もあります。

sun

というわけで、ピンヘッダでも1GHzが通ることがわかりました。ピンヘッダだから信号が減衰して通らなくなるとか、反射がひどくて通信できないということはなさそうです。

まぁ、ピンヘッダの部分でインピーダンスは不整合しているのでしょうけれども、反射っていうのは反射している距離が問題なのですから、こんなもんでしょう。

まとめると、

  • FPGAのIO STANDARDをLVDS25やTMDSなど差動規格にすること
  • シングルエンドだとクロストークが激しいから、ダメ。
  • 差動信号で終端すれば1GHzでもいける。
  • LVCMOS33は、振幅の抑制が効かず、高速信号には向かない
  • Artix-7のHRポートからLVDSを出すにはVCCIO=2.5Vでないといけない
  • TMDS_33やDIFF_SSTL18は終端抵抗の値が間違えているためか、今回の実験ではあまり綺麗ではない
  • 乱数パターンの送信で波形が乱れがちなのは、おそらくFPGAの出力バッファの問題。8b/10b変換してディスパリティに気を付ければ改善するはず。
  • 汎用のI/Oを使っているので、プリエンファシスが効かない。1~2GHzあたりが限界なのではないだろうか。

私はピンヘッダ万歳派で反メザニン主義なのですが、気になる人はメザニンを使ってください。

Cosmo-Kの拡張ピンには汎用のピンヘッダを使いますが、さすがにCosmo-Zの拡張基板にはメザニンを使います。

| | コメント (0)

2016.09.26

Cosmo-KのPCI Expressの配線を引いた

PCI Expressまわりの配線を行いました。

Pcie_gen2x4

FPGAとPCI Expressを接続するうえでの問題点は以下のとおりです。

  • 長距離を走って劣化した高速シリアル信号をFPGAで受信するのは難しい
  • FPGAの動作停止やバウンダリスキャンによって、PCI Expressの各信号の電位が変わり、本体PCの動作に影響を与えることがある(特にリセットまわり)

そこで、FPGAとカードスロットの間に、PCI Express用のリドライバというICを入れることにしました。そのため、配線が複雑になっています。

なお、PCI Expressのカードスロットは、左側がレーン0なのに、FPGAのMGTの番号は右側がレーン0となっています。そのため配線がねじれてしまいます。

PCI Expressにはレーン・リバーサルといって、どのレーンにどんな順番でつないでもいいはずなのですが、「必須」の仕様ではないため、マザーボードやカードが対応していないこともあります。

レーン・リバーサルはトラブルの元です。この基板では、レーン・リバーサルは使わずに、1対1でつないでいます。

| | コメント (0)

2016.09.25

Cosmo-KのDDR3まわりの配線が引けた

開発中のCosmo-Kですが、DDR3まわりの配線を引いています。

Cosmokddr3

だいたいできた、といいたいところですが、DDRとFPGAとの間をもう少し縮めたいと思います。

Cosmokddr3_2

こうなりました。

最高密度で引いてこそ、基板は美しさを最高に引き出せると思います。

| | コメント (0)

2016.09.24

新ADCボード「Cosmo-K」について

特電では、Kintexを使った、高速ADCデータ計測用ボードとして、新ブランド「Cosmo-K」(コスモ・ケイ)を企画しています。

Cosmo-Kでは、ボード上にADCを乗せるのではなく、ADCとキャプチャボードは分離し、その間を光ファイバでつなぐことにします。

イメージとしてはこんな感じです。

Adcprobe_2

高速ADCから出てくるデータはJESD204Bという規格です。JESD204Bというのは8b/10bを使った近代的なプロトコルです。Cosmo-Kでは、このJESD204B形式の信号を光ファイバでキャプチャボードへ伝送します。

実験の種類によって計測に必要なADCのスペックは様々です。例えば、1Gサンプリング 2ch 16bitが必要という人もいれば、250MHzで16chという人もいるし、10MHzでいいけど64chが欲しいという人もいます。

そのため、ADCプローブボードを実験に合わせて作り変えられるよう、分離することにしました。

1GHz,2ch,16bitならば40Gbpsになるので、QSFPのファイバが丸々1本必要な計算になります。

Cosmok

また、JESD204Bに対応していない汎用のADCを並べておいて、それらのADCから受け取ったデータをJESD204Bに変換して(エンコードして)送るようなボードも考えられます。

Adcprobe2

このことは、ノイズに敏感なADCのフロントエンドの部分と、データ処理を行うメインボードを分離し、ADCの部分をより小型にすることができるという効果もあります。

なお、Cosmo-KのKはKintexのKです。Cosmo-Kのキャプチャボードには、Cosmo-K0とCosmo-K-とCosmo-K+3種類のバリエーションを考えています。

one Cosmo-K0(コスモ・ケイ・ゼロ)

Cosmok0_2

Cosmo-K0は、SFPを2chと、ECL/NIM/オープンドレインの汎用入出力ポートを4ch搭載したボードです。

two Cosmo-K-(コスモ・ケイ・マイナス)

Cosmo-K-は、SFPを2ch搭載したロープロファイル型のボードです。ロープロファイルなので、小型のPCにも搭載できます。

2.54mmのピンヘッダも搭載しているので、拡張が容易です。EXPARTAN-6Tの後継機種としての位置づけです。

Cosmok

three Cosmo-K+(コスモ・ケイ・プラス

Cosmo-K+は、40GbpsのQSFPと、低速のSFPを1ch搭載しています。SFPはMGT(GTX)ではなく、汎用のI/Oポートにつながっているので、クロック・データ・リカバリなどの高度なことはできません。8b/10b変換も自前で行う必要があります。

Cosmok_2

QSFPは、JESD204B規格でADCからのデータを受信するためのポートとして使い、SFPはADCボードへコマンドを送ったりするために使います。

  • Cosmo-K0…SFP 10G×2ch。トリガ等の汎用入出力あり
  • Cosmo-K-…SFP 10G×2ch。
  • Cosmo-K+…QSFP 40G + 低速SFP 1G

もちろん、40Gbpsで受け取ったデータのすべてをパソコンに取り込むことはできないので、波形をFPGAの中でフィルタして、有意なイベントだけを取り込むという使い方になると思います。

開発ソフトウェアについては、Cosmo-Zのライブラリを改良したものが使われますが、APIを用意してユーザが自由にプログラムを作れるようにします。

sun

このCosmo-Kは、今年の展示会ET2016に出展しようと思います。

ご意見やご要望などがあれば、当ブログのコメント欄や、メール、会場で直接、どうぞお寄せください。

| | コメント (0)

2016.09.23

Kintex-7のPCI Expressボードを作ります

特電では、Kintex-7のPCI Expressボードを作ることにしました。

Kintex-7のは昨年の7月ごろ設計していたのですが、その後、モチベーションが続かずに開発を中断してしました。

  • Kintex-7 XC7K160T-2FBG656C
  • DDR3メモリ 1GB
  • SFP+(光ファイバ)2本
  • SATA
  • PCI Express
  • 2.54mmピッチのピンヘッダ
  • USB3.0

という仕様でした。

昨年の最後の段階が↓の図です。

Kintexboard

特電では、お客様からの要望で12~16bit、2ch、1Gサンプル/秒のデータ取得装置を作ろうとしていますが、このクラスになるとADCからのデータがJESD204Bという高速シリアル通信で送られてくるのですが、10Gbpsを4レーンで受けられるボードが必要になります。

このボードをのSFPを4chに増やしてパソコンで受け取れるようにしたほうが良いかなと思い、開発を再開することにしました。

目的がはっきりしてきたので、俄然やる気が出てきました。

MGTとSDRAMの部分の配線ができました。MGTのコンデンサと、配線の引き出しが終わっています。

Mgtsdram_2

SDRAMの配線は、Cosmo-Zの配線をだいたいそのまま持ってきた感じになっています。

Sdram

ボード全体はこんな感じ。

Np1078

| | コメント (0)

2016.09.21

日本物理学会に行ってきました

今日の1日だけ、日帰りで日本物理学会に行ってきました。

宮崎空港を降り立つと、南国の雰囲気。

Miyazakikuukou

電車はほとんど走っていない

Miyazaki_train_2


のでタクシーで会場の宮崎大学に向かいます。

私が興味あるのは、素粒子・核物理・宇宙の、通称「素核宇」という分野ですが、FPGAを計測に使っている話や、自分で計測器を作っている人の発表を何件か聴いてきました。

物理界隈でFPGAというと、Open-ITというがあって、みんなSiTCPを使っているという印象でした。

今の仕事で知り合った人にも何人か合いました。

| | コメント (0)

2016.09.20

Cosmo-Zの新しいソフトウェア開発

現状のCosmo-Zのソフトウェアは、Web経由での操作や、Linuxのコンソールからの操作、WindowsやLabViewの専用アプリからの操作など、いくつかのアプリが用意されています。

CosmozwebappCosmozlinCosmozwin

これらのアプリの構造は、下の図のようになっています。

Cosmoz_hier

基本的にはZYNQ Linux上で動くコンソールのアプリがベースとして動いていて、WindowsアプリはTCP/IP経由でコマンドを送って動いているにすぎません。

また、この構造だと、コマンドの解釈ルーチンと、ハードウェアを操作する部分が一体となっているので、ユーザがプログラム全体を把握して、独自の機能を追加するのが極めて困難になってきています。

Cosmozapp

そこで、アプリからハードウェアを操作している部分、コマンドを解釈している部分、レジスタやメモリ操作の手順を実行している部分を分けて、APIの形で整理することにしました。

新しいアプリの構造は次の図のようになります。

Cosmoz_hier2_2

まず、Cosmo-ZのアプリからFPGA内のレジスタやメモリを操作する部分をHAL層として分離します。

具体的には

  • 物理メモリへのRead/Write
  • FPGA内蔵レジスタへのRead/Write
  • 割り込みのハンドリング

のような低レベルの処理です。

そして、ユーザAPIからはHAL層を隠ぺいし、「サンプリング周波数の変更」「波形キャプチャの実行」などの高レベルな処理をユーザに解放することにします。

こうすることで、Cosmo-ZのプログラムはZynq Linuxの上で動くだけではなく、Windowsのアプリとして、VisualStudioやBorland C++で作ることができるようになります。

例えば、Windows PC上で動作するCosmo-Z APIが、「波形キャプチャ」という関数を呼び出されたら、

  • FPGAのレジスタの○番に○○を書く
  • FPGAのレジスタの○番が○になるまで待つ
  • メモリの○番地から読み出し

という処理を行っているのですが、このレジスタの読み書きはWindows PC上で実行されるわけではなく、TCP/IPを通じてターゲットボードのZYNQ Linuxへ送られ、ZYNQ Linux上のCosmo-Zのアプリがそのレジスタ/メモリ操作を行い、生のデータをWindows PCに送り、Windows PC上でデータを解釈して結果を組み立てるという仕組みです。

| | コメント (0)

MPPCアレイの設計

青函トンネルでの実験により、プラスチックシンチレータとMPPCで宇宙線(おそらくミューオン)を観測することができることがわかったので、今度は2次元にならべたものを作ろうと思います。

MPPCは遮光と温度が大事なので、プラスチックではなくアルミで箱をちゃんと作ります。

今回は、6cm×6cm×1cmのプラスチックシンチレータを、縦横に4個×4個並べて、16個入りのユニットを作ります。

Asm1

1つ1つのシンチレータの部屋はアルミの壁で分離されていて、互いに光が漏れないようになっています。

Asm2

金属加工屋さんに見積もりを依頼したら、だいたい10万円くらいでできそうです。16個のシンチレータとMPPCとアンプ基板を合わせても、100万円はかからないでしょう。

これが完成すれば、宇宙線(おそらくミューオン)がどこを通ったかがわかるはずです。この箱を最低2レイヤー並べれば、宇宙線が飛来した方向がわかるでしょう。

そんなに簡単にはできないとも言われましたが、やってみないとどうして簡単にできないのかもわからないので、チャレンジしてみる価値はあると思っています。

| | コメント (0)

2016.09.19

VivadoでGenericのパラメータを垂直伝搬させる方法

VHDLで書いたコードなら、Genericで指定したパラメータを、

INST_XXX : XXXX generic map (
  PARAM1 := PARAM1
);

とやれば上から下のモジュールへ伝えられるのですが、Vivado IPインテグレータではどうやるのでしょう?

Vivadoでは、VHDLのGenericの部分が自動的にGUI化されて、ユーザがカスタマイズできるようになるのですが、それを垂直伝搬させる方法がわかりません。

例えば、ADCのビット数や、ADCの数などです。

Vivado_param

ブロックデザインを階層化したときに、上のモジュールで指定したのが下のモジュールに自動的に設定されれば便利なのに。


| | コメント (0)

2016.09.16

Vivado版Cosmo-ZでMCA動作

Vivado版の新デザインのCosmo-Zで、MCAを長時間走らせてみた。

2台の「プラスチックシンチレータ&MPPC検出器」をつないでバックグラウンドを8時間測定。

Mcanewcosmoz

MPPCは温度にすごく敏感なので、設置場所に注意しないと(他の機器の排熱や空調で)結果に差がでてしまうが、今回はうまくいった。

2つのスペクトラムはぴったり重なる。

中央の少し盛り上がっている部分が40Kによるもの。それ以上はだいたい宇宙線と思われる。

| | コメント (0)

2016.09.15

Cosmo-ZのVivado化が完成

ようやく、Cosmo-Zの(ほぼ)全機能をVivadoへ移植できました。

Cszv1

ちゃんと波形のキャプチャも、

Cszv3

マルチチャネルアナライザも動きます。

Cszv2








| | コメント (0)

2016.09.13

VivadoでのZYNQの割り込み

Cosmo-ZのVivado版デザインで、波形のキャプチャができるようになったわけなのですが、どうも1回キャプチャすると止まってしまいます。

なんと、割り込みが発生していない疑い。

そもそもZYNQの割り込みはかなりの謎仕様で、IRQ0が割り込みの何番につながっているか、よくわかりません。

ISEのときは、例の画面で割り込み0と1を使うようにしておくと、

Irq_1

ZYNQのPL→PS割り込みは、割り込み番号91~84と、68~61にあるようなのですが、IRQ(0)の割り込み番号は90番に割り当てられます。(91番ではない)

おそらく、IRQ0→#90、IRQ1→#91になっているのでしょう。

VivadoでのZYNQ場合はさらに複雑で、何番に割り当てられるかは全くわかりません。

Zynq_irq

少なくとも、IRQ_F2P(0)は#91でも#90でもないようです。しかし、デバイスドライバはIRQ #90をハンドルするように作ってしまっているので、何としても90番の割り込みを発生させたいところです。

そこで、IRQ_F2P(0)からIRQ_F2P(15)の16bitを全部一緒にドライブすることを考えました。そうすれば、#61~#68と#84~#91の全部が発生するから、#90の割り込みも発生するだろうというわけです。

ところが、ZYNQのIRQ_F2Pは[0:0]で定義されてしまっていて、

Zynq_irq2

このバス幅を変える設定箇所はGUI上にはありません。

では、どうやって変えるかというと、割り込み信号を出力している側のモジュールで16ビットの幅にしてやればよいようです。簡単にやるには、xlcontatを使います。

Zynq_irq4

接続したらValidate Designを行うと、ZYNQの入力ポートが自動的に16bitに変わります。割り込みの信号をドライブするバスが16bitだと、割り込み信号も16bitになるようです。パラメータの伝搬というそうです。

これで無事に90番の割り込みが(も)発生するようになりました。

| | コメント (0)

2016.09.11

Cosmo-Z Vivado版で波形キャプチャができた!

ZYNQ搭載ADCボード、Cosmo-Z(コスモゼット)のVivado版デザインで波形キャプチャができた。

まだ、CPUモジュールと、ADCブロックとキャプチャモジュールを組み合わせただけだけど、

Csz_capture_2

このとおり、波形がキャプチャできました。

Csz_capture2


| | コメント (0)

2016.09.10

Vivadoで3ステートバッファ!?

Vivadoでトライステートバッファ作ろうとしているのですが、HDLで作ったIPモジュールの中で、

pad_bp <= o when (dir = '1') else 'Z';
i <= pad_bp;

というような記述してもCriticalWarningが出てしまいます。

Tricell

メッセージは、「Converted tricell instance 'U0_i1447' to logic」でした。

このU0_i1447というのは、デザインによって変わります。

つまり、tricellのロジック(おそらく3ステートのロジック)を普通のロジックに変更したよ、というCritical Warningのようです。

実機で動作させてみると、出力はちゃんとできているようですが、入力はできていないようです。

もちろん、ISEでは普通に動いていたのに、なぜでしょうね。

sun

プリミティブのIOBUFを使ったら双方向ができました。

adc_sclk_op   : out std_logic;
adc_sdio_ip   : in  std_logic;                    -- ADCチップへ
adc_sdio_op   : out std_logic;                    -- ADCチップへ
adc_sddir_o   : out std_logic                     -- 1ならsdio出力
・・・
adc_sdio_inst : IOBUF port map (
	IO => adc_sdio_bp,
	O => adc_sdio_i,
	I => adc_sdio_o,
	T => not adc_sddir
);

sun

何はともあれ、今手掛けているCosmo-ZのデザインのVivado再設計プロジェクトが、CPUとADC周辺までは完璧にできました。

Csz_adc1

全体はこんな感じ。

Csz_adc2

| | コメント (0)

2016.09.08

Number of Nodes with overlapsについて

ADCから受け取った信号をAXIで読み出せるような回路を書いていたら、VivadoのRoutingが急に遅くなった。ログを見ると

Number of Nodes with overlaps = ??

というメッセージが出ている。

調べてみると、フォーラムにそれらしき記事がある。

https://forums.xilinx.com/t5/General-Technical-Discussion/What-is-quot-Number-of-Nodes-with-overlaps-quot-parameter-in/m-p/526817#M20549

よくわからないけど、複数のクロックが使われている信号があると遅くなるようだ。

Cosmo-ZではADCのクロックや、AXI GPのクロック、AXI HPのクロックと3つのクロックが使われている。

これらのクロック間でのタイミング解析をしないようにするには、XDCファイルにフォルスパスというのを設定すればいいようだ。

基本的な書き方は、

set_false_path -from [get_clocks クロック1] -to [get_clocks クロック2]
set_false_path -from [get_clocks クロック2] -to [get_clocks クロック1]

でいいのだけど、そのクロックがMMCMの出力であるような場合は、名前を探すのが大変になる。

set_false_path -from [get_clocks [get_clocks -of_objects [get_pins cosmoz_top_i/adcblock_0/U0/inst_adcclkgen/inst_clkmult/inst/mmcm_adv_inst/CLKOUT0]]] -to [get_clocks clk_fpga_1]
set_false_path -from [get_clocks clk_fpga_1] -to [get_clocks [get_clocks -of_objects [get_pins cosmoz_top_i/adcblock_0/U0/inst_adcclkgen/inst_clkmult/inst/mmcm_adv_inst/CLKOUT0]]]
set_false_path -from [get_clocks [get_clocks -of_objects [get_pins cosmoz_top_i/adcblock_0/U0/inst_adcclkgen/inst_clkmult/inst/mmcm_adv_inst/CLKOUT0]]] -to [get_clocks clk_fpga_0]
set_false_path -from [get_clocks clk_fpga_0] -to [get_clocks [get_clocks -of_objects [get_pins cosmoz_top_i/adcblock_0/U0/inst_adcclkgen/inst_clkmult/inst/mmcm_adv_inst/CLKOUT0]]]
set_false_path -from [get_clocks clk_fpga_0] -to [get_clocks clk_fpga_1]
set_false_path -from [get_clocks clk_fpga_1] -to [get_clocks clk_fpga_0]

| | コメント (0)

2016.09.06

VivadoとISEの違い

ZYNQのAXIポートへセレクタを通じて複数の信号から選択して入れる場合(ステータスレジスタReadなど)

  • ISEは未接続のポートがあってもWarningで済む
  • VivadoはLUT3とかがエラーを出す

これは面倒すぎる。

| | コメント (0)

2016.09.05

VivadoでのSynthesizeを速くしたい

Vivadoでの論理合成時間を速くすることはできないかどうか、試してみました。

検証に使用したのは、特電Artix-7ボードのサンプルデザイン。

Vivado_bench

EZ-USB FX3のコアと、DDR3のコアと、パターンジェネレータ等がAXIインタコネクトで相互につながっているというものです。

これを普通にSynthesizeすると、

Vivado_bench_1

となって、様々なOut of contextのモジュールが合成されてから本体が合成されます。

Synthesizeの時間を見てみると、xlconstantやLEDチカチカなどのシンプルなものは18~30秒くらいですが、MIGやBRAM、FX3のコアは分単位の時間がかかっているのがわかります。

この時間をどのようにしたら短縮できるでしょうか?

思いつく方法は、Vivadoのスレッド数を変える方法と、Job数を変える方法。Job数は標準では2ですが、私のPCでは8まで上げることができました。

Vivado_bench_2

ためしにJobを8にして実行してみると・・

Vivado_bench_3

おおっ! 緑のクルクルが8個同時に回るではないですか!!

これは期待できそう。

ちなみに、タスクマネージャで見てみると、このときXEONのCPU 8個がフル稼働しています。PCのファンがグオーンと音を立てて、頑張っているんだな~と感じさせます。余っているコアに、たまには仕事をさせなければなりませんね。

Vivado_bench_4

無事に合成できたのですが、

MIGの合成にかかった時間を見てみると、ジョブ2個のときは2分38秒だったのが、ジョブ8個では3分14秒かかっています。

同時にたくさんのジョブを実行させると、個々のジョブの実行時間は増えますが、並行して動作しているので、トータルでの時間は短くなりなります。

sun

スレッド数とJob数を様々に変化させて、実験してみたくなりますね。

パソコンの前に貼りついてストップウォッチで測るのも大変なので、Tclのスクリプトを書いて実行しました。

open_project C:/share/fx3-axi-ddr/fx3-axi-ddr.xpr;
reset_project;
reset_target all [get_files  C:/share/fx3-axi-ddr/fx3-axi-ddr.srcs/sources_1/bd/main/main.bd]
export_ip_user_files -of_objects  [get_files  C:/share/fx3-axi-ddr/fx3-axi-ddr.srcs/sources_1/bd/main/main.bd] -sync -no_script -force -quiet
delete_ip_run [get_files -of_objects [get_fileset sources_1] C:/share/fx3-axi-ddr/fx3-axi-ddr.srcs/sources_1/bd/main/main.bd]
set_param general.maxThreads 8;
puts "Num of threads has been changed to [get_param general.maxThreads]";
set start_sec [clock seconds];
launch_runs -jobs 2 synth_1;
wait_on_run synth_1;
set end_sec [clock seconds];
set sec [expr $end_sec-$start_sec];
puts "thr2_Synth_time = $sec";

と、いう感じです。

実行すると、このようにTclのコンソールに経過時間が表示されます。

Vivado_bench_5

※このTclは昔いたアルバイトの学生さんが書いてくれたものをベースにしています。彼はいい仕事を残していってくれました。

こうして測ってみた結果は、こうなりました。

Vivado_bench_6

同時に実行するジョブ数を増やしたほうが良いようです。スレッド数はあまり関係がないようです。

結論は、「Vivadoを速くしたければジョブを増やせばよい」、ということのようです。

| | コメント (0)

2016.09.01

ZYNQでQSPI ROMを使う方法

ZYNQ搭載のADCボード「Cosmo-Z」には、128MbitのQSPI ROM(N25Q128A11)が乗っています。

N25q128


これまでのCosmo-Zでは、QSPI ROMはLinuxから認識されないため、活用してこれなかったのですが、ようやくその原因と使いかたがわかりました。

sun

ZYNQのLinuxをビルドすると、QSPI ROMのデバイスドライバ(MTD: Memory Technology Driver)は標準で入っています。なので、カーネルから認識されない原因はデバイスツリーにありました。

Cosmo-Zのデバイスツリーを、dtcを使って逆コンパイルしてみてみると、

ps7-qspi@e000d000 {
    clock-names = "ref_clk", "pclk";
    clocks = <0x2 0xa 0x2 0x2b>;
    compatible = "xlnx,zynq-qspi-1.0";
    interrupt-parent = <0x3>;
    interrupts = <0x0 0x13 0x4>;
    is-dual = <0x0>;
    num-cs = <0x1>;
    reg = <0xe000d000 0x1000>;
    xlnx,fb-clk = <0x1>;
    xlnx,qspi-mode = <0x0>;
    #address-cells = <0x1>;
    #size-cells = <0x0>;
    flash@0 {
        compatible = "n25q128";
        reg = <0x0>;
        spi-tx-bus-width = <0x1>;
        spi-rx-bus-width = <0x4>;
        spi-max-frequency = <0x2faf080>;
        #address-cells = <0x1>;
        #size-cells = <0x1>;
        partition@qspi-fsbl-uboot {
            label = "qspi-fsbl-uboot";
            reg = <0x0 0x100000>;
        };
        partition@qspi-linux {
            label = "qspi-linux";
            reg = <0x100000 0x500000>;
        };
        partition@qspi-device-tree {
            label = "qspi-device-tree";
            reg = <0x600000 0x20000>;
        };
        partition@qspi-rootfs {
            label = "qspi-rootfs";
            reg = <0x620000 0x5e0000>;
        };
        partition@qspi-bitstream {
            label = "qspi-bitstream";
            reg = <0xc00000 0x400000>;
        };
    };
};
ps7-qspi-linear@fc000000 {
    clock-names = "ref_clk", "aper_clk";
    clocks = <0x2 0xa 0x2 0x2b>;
    compatible = "xlnx,ps7-qspi-linear-1.00.a";
    reg = <0xfc000000 0x1000000>;
};

となっています。

問題だったのは、上のn25q128と書かれた部分です。ここをn25q128a11に変えればMTDドライバは問題なく認識され、

m25p80 spi0.0: n25q128a11 (16384 Kbytes)
1 ofpart partitions found on MTD device spi0.0
Creating 1 MTD partitions on "spi0.0":

と、表示されます。MTDドライバは、n25q128でも、n25q128aと書いてもでもだめで、n25q128a11の型番の末尾の11までちゃんと区別しているようです。

さて、QSPIドライバの使い方は、XILINXのWikiにあるのですが、

http://www.wiki.xilinx.com/Zynq+QSPI+Driver

これを試してみましょう。ただ、このWikiの内容はQSPI ROMを5つのパーティションに分けているのですが、Cosmo-ZではQSPIからのブートはしないので、このQSPIを16MBのフラットな領域として扱おうと思います。

したがって、デバイスツリーのflash@0とかいうところで、

partition@qspi-all {
    label = "qspi-all";
    reg = <0x0 0x1000000>;
};

と書いておきます。こうすると、0番地から16MBの領域がqspi-allというパーティションになり、起動時には

Creating 1 MTD partitions on "spi0.0":
0x000000000000-0x000001000000 : "qspi-all"

と表示されます。

cat /proc/mtd

で見てみると、

zynq> cat /proc/mtd
dev:    size   erasesize  name
mtd0: 01000000 00010000 "qspi-all"

と表示されます。

QSPIのFlashROMは、そのまま生で使うか、ファイルシステムを作るかが選べるようです。ファイルシステムを作る場合はまず、

flash_eraseall -j /dev/mtd0

でフラッシュを一度消去します。

そして、

mkdir /qspi

でマウント用のディレクトリを作り、

mount -t jffs2 /dev/mtdblock0 /qspi

でマウントします。jffs2というのは、ウェアレベリングしながら扱ってくれるフラッシュROM用のファイルシステムだそうです。

これでマウントできるので、あとは、普通にファイルを何でも放り込むだけです。ただし、結構遅いです。

私はQSPI ROMに、ボードのシリアル番号や、ADCのキャリブレーションデータ、回路のカスタマイズの有無など、ボード1枚1枚ごとに固有の情報を入れておこうとおもいます。

zynq> ls -al
total 1
drwxr-xr-x    2 root     root             0 Jan  1  1970 .
drwxr-xr-x    4 root     root             0 Jan  1  1970 ..
-r--r--r--    1 root     root           180 Jan  1  1970 adcconf
-rw-r--r--    1 root     root             4 Jan  1  1970 serialnum

| | コメント (0)

« 2016年8月 | トップページ | 2016年10月 »