2018.10.22

HyperFADCを出荷

特電の製品でHyperFADCというものがあります。

1Gsps 16bit 2chの高速ADCチップを搭載し、QSFP光ファイバで送信するというものです。

Hdadc_1

右下にある放熱BOXがHyperFADCで、フロントパネルは

Hfadc_front

リアパネルは

Hdadc_rear

こうなっています。

発熱がとにかくすごい。扇風機をあてていないと触れないほど熱くなります。

Agilentの波形発生器と高速オシロをつないで、

.Hfadc_wavegen

まずは、測りたい信号がちゃんと出ているかどうかを確認。

Hfadc_osc

そして、HyperFADCでサンプリングしてみます。

Hfadc_wave

ちゃんと動いていそうですね。

周波数特性を測ってみたら、20MHzと300MHz付近にリンギングがあるのですが、ケーブルの問題かもしれません。

Hfadc_freq

納期が遅れてしまい、お客様には申し訳ございませんでしたが、無事に出荷できました。

| | コメント (0)

2018.10.18

UltraScale+におけるチップの温度をJTAGで拾ってみた

MITOUJTAGでUltraScale+の温度や電圧が表示されるようにしました。

Zubscan_5

毎秒2回更新します。

JTAGで温度を見る方法はユーザガイドUG580 (v1.9)に書かれているDRPという仕組みを利用します。

簡単に言うと、SYSMON_DRPという命令を使って、読み出したいステータスレジスタのアドレスをセットし、読み出します。

どのようなステータスレジスタがあるかというと、

Zubscan_6

このような感じになっています。

まず、IRにSYSMON_DRPという命令を発行し、次にDRに32bitの値をセットします。

シフトイン値は26bit目を1にし、[25:16]に読み出したいアドレスをセットします。

val = (1 << 26) | (addr << 16) | data;

DRPレジスタに書き込むのでなければdataは0でよいでしょう。

こうして、2回スキャンすると、2回目で目的のレジスタの値が読み出されます。

one 温度を測る場合は、

rdvalue / 65536. * 509.3140064 - 280.23087870;

で[℃]に変換します。

two 電圧を測る場合は、

rdvalue / 65536. * 3;

で[V]に変換します。

同じ要領でレジスタ0x10~0x1Fを読み出せば、XADCの値が読み出せると思います。

電源ピン電圧の監視では、HR I/Oでは上記の*3が*6になる場合もあるそうです。

sun

なお、JTAG DRPは、バウンダリスキャンとは排他的です。JTAGのデータレジスタにDRPが接続されているときは、バウンダリスキャンレジスタは切り離されています。

Zubscan_7_2

そのため、MITOUJTAGでは、I/Oの状態を表示している時には温度は出ないようにしました。

Zubscan_8_2

| | コメント (0)

2018.10.17

UltraScale+におけるJTAGの扱いが完璧になった

UltraScale+のJTAGの扱いが完璧にできるようになりました。

Zubscan_3

まず、リセット後にDummy TAP/DAPが接続される問題は自動で状況を認識して回復するようにしました。

EXTEST時にPSのバウンダリスキャンセルが入れ替わる問題も、ピン名からPSのピンなのかPLのピンなのかを自動的に判別して解決するようにしました。

こういった様々なバグに対してJTAGライブラリの根幹部分を、UltraScale+のためのパッチを書くことで対応したのですが、一つのFPGAファミリのバグ対策のためにここまでMITOUJTAGの深部に手を加えることになるとは思いませんでした。

Zubscan_4

これで、UltraScale+の自動認識とバウンダリスキャンの問題にはすべて対応できたと思います。

| | コメント (0)

2018.10.16

MITOUJTAGがネイティブでUltraScale+の書き込みに対応

MITOUJTAGからネイティブでUltraScale+のPLに書き込めるようになりました。

Zujwr_7

sun

書き込みのシーケンスは驚くほど簡単です。

  1. TAPをTEST_LOGIC_RESETに移動
  2. TAPをRUNTEST_IDLEに移動
  3. JPROGRAM命令を発行
  4. NOOP命令を発行
  5. RUNTEST_IDLEでしばらく待つ
  6. NOOP命令を発行。書き込みモードに変わったことを確認する
  7. CFG_IN命令を発行
  8. BitStreamをDRに流し込む
  9. RUNTEST_IDLEでトグルして、しばらく待つ
    -----------------------
  10. BYPASS命令を2回発行
  11. JSTART命令を発行
  12. RUNTEST_IDLEでトグルし、しばらく待つ

これで、PLが書き変わります。

PLが書き変わってもLinux自体は動作し続けられますが、PLにあるすべてのレジスタはリセットされてしまうので、画面を使うならもう一度再起動しなければならなくなるでしょう。

sun

書き込んで→I/Oを確認→書き込んで→I/Oを確認・・という開発&デバッグのプロセスが楽にできるようになりました。

Zujwr_8

Ultra96ボードへの書き込みだと約10秒でできます。

PLの書き換えだけならば再起動を伴わないので、楽ですよ。

| | コメント (0)

2018.10.13

UltraScale+のバウンダリスキャンがおかしい件

UltraScale+のバウンダリスキャンにおいて、コントロールセルがおかしい問題は、Answerに書かれていました。

https://japan.xilinx.com/support/answers/62985.html

実はSpartan-6のときにも同様の問題があったのです。

6シリーズのときは出力ピンとして誤認識されてしまうのに対して、UltraScaleでは入力ピンとして誤認識されます。

7シリーズでは全く問題なかったので、6シリーズとUltraScaleを設計したのは同じグループなのかもしれない。偶数シリーズと奇数誤で設計担当グループが交互に変わるとか、そういう事情があるのかもしれない。

sun

さて、上記のAnswerによると、バウンダリスキャンで方向セルを正しく読めるようにするには、OBUFの代わりにT=0にしたOBUFTを使えとのことでした。

出力ピンにOBUFTを使うようにしたら、PLの入出力セルの方向が正しく読めるようになりました。

Zubscan_1

この波形を作るために書いたコードはこんな感じです。

Zubscan_2

カウンタがある一定値以上になると入力になり、一定値未満ならばバイナリでカウントアップする値を出力するというものです。

sun

これまでにわかっているUltraScale+のJTAGの仕様(バグ?)をまとめると、

  • PLはコントロールセルから正しくない値が読み出される。PSは問題ない。
  • PSはSAMPLE時に入出力セルが逆になる。PLは逆にならなない。
  • EXTEST時はPSでも入出力セルは逆にならない。
  • DDR4 SDRAMとのやりとりは見えない。

ということなのですが、PSとPLとDDR4でバウンダリスキャンの作りが違って、みんなどこかしら問題を抱えているわけなのです。

どうなっているんでしょう!?

| | コメント (0)

2018.10.12

UltraScale+のPLにJTAGで書き込み成功

Ultra96ボードで実験していて、ついにPLへJTAGで直接書き込むことに成功しました。

まず、PLのデザインのBitファイルを作らなければならないので、

http://zedboard.org/support/design/24166/156

からリファレンスデザインをダウンロードしてきます。

この中のUltra96_Basic_SystemをVivado 2018.2で開きます。

Zujwr_1

Ultra96のサンプルは、PLは使わずに、PSのみで動いているようです。

これだと書き込んでも何も起きないので、簡単なカウンタ回路を作ります

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity counter is
	Port (	clk  : in  std_logic;
			test_o : out std_logic_vector(7 downto 0)
	);
end counter;

architecture Behavioral of counter is
	signal counter : std_logic_vector(24 downto 0); 
begin
	process(clk) begin
		if(clk'event and clk='1') then
			counter <= counter + 1;
		end if;
		if(counter(23) = '1') then
			test_o <= (others => 'Z');
		else
			test_o <= counter(23 downto 16);
		end if;
	end process;

end Behavioral;

カウントアップしながら、一定期間test_oを

そして、VivadoにRTLモジュールとして登録します。

Zujwr_2

これでGenerate Bitstreamすると、Bitstreamができるわけですが、これをSVF形式に変換します。

SVFに変換するには、VivadoのTclコンソールで次のように入力します。

open_hw
create_hw_target my_svf_target
open_hw_target
set device0 [create_hw_device -part xczu3eg]
set_property PROGRAM.FILE {D:/Ultra96_Basic_System/Ultra96_Basic_System.runs/impl_1/design_1_wrapper.bit} [get_hw_devices xczu3_0]
program_hw_devices -disable_eos_check [get_hw_devices xczu3_0]
write_hw_svf -force D:/Ultra96_Basic_System/counter.svf
close_hw_target
close_hw

SVFを生成すると、Hardware Managerが開いて、以下のような画面になります。

Zujwr_3_2

そうしたら、MITOUJTAGで以下のSVFファイルを実行し、PL TAPとARM DAPを有効化します。

STATE RESET;
TDR 0;
HDR 1 TDO (1); // ARMのDAPを無視するため
SIR 16  TDI (83FF) ; // JTAG_CTRL
SDR 32 TDI (00000003) PRINT; // ARM DAPとPL TAPを有効化
RUNTEST RESET 16 TCK;

そして、Vivadoで生成したSVFファイルをMITOUJTAGのSVFプレイヤーで再生します。

Zujwr_4

書き込みには結構な時間がかかります。

書き込んだ後、JTAGロジックアナライザで見てみると、

Zujwr_5

ちゃんとカウントアップして、休む波形が見えました。

ただ、様子がおかしいですね。バウンダリスキャンセルの方向ピンが正しく読み取れていないようです。

Zujwr_6_3

本来は、このDIRと書かれた方向制御ピンは出力時には0になり、入力時には1になるはずです。

しかし、常に1のままで、入力として判断されてしまいます。

| | コメント (0)

2018.10.11

ZYNQ UltraScale+ MPSoCのJTAGのしくみ

ZYNQ UltraScale+ MPSoC(以下、ZU)の仕組みを完全に理解しました

ZUの中にあるJTAGの構造をかみ砕いて描くと、こうなります。

Zujtag_3_2

ZUの内部には、PS TAP、PL TAP、ARM DAPという3つのJTAGコンポーネントが入っています。

  • PS TAPはPSの制御に使われるもので、JTAGステータスを見たりPMU(実体はMicroblaze)のデバッグポート(MDM)に接続されています。
  • PL TAPはPLのバウンダリスキャンやFPGA部分のコンフィグに使われます。
  • ARM DAPはCortex CPUのデバッグに使われます。

PL TAPとARM DAPは、デフォルトではDummyのほうを選択されていて、本体は無効になっています。また、PMU MDMとPL TAPとARM DAPにはセキュリティゲートというのがあって、勝手にデバッグをさせないようになっています。

セキュリティゲートは電源ON時やセキュアブートの時、eFUSEが切られているときには有効になっていて、JTAGが突破できません。

しかし、非セキュアブート(つまり普通のブート)するときには、CSUのROMのコードにってセキュリティゲートは無効になり、JTAGアクセスできるようになります。したがって、普通に起動した場合にはJTAGは使えるので、セキュリティゲートを気にする必要はありません。

sun

ZYNQ UltraScale+ MPSoCのJTAG命令レジスタの構造は次の図のようになっています。

Zujtag_6

ただし、PSとPLのIRは合わせて12bitという扱いなので、個別にコマンドを与えることはありません。PLのDRの長さは0bitになることもあります。

あまりPSとPL TAPを分離して考える必要はありませんが、ZUのJTAGのコマンドを解読していくときに、6bitごとに切って考えると理解しやすいところがあります。

ただし、PL TAPも一人前にIDCODEを持っていて、XCZU3EGのPSのIDCODEが0x14710093なのに対して、PLのIDCODEは0x14A42093でした。

このPL IDCODEは特別な命令IDCODE_PL(0x925)やIDCODE_PSPL(0x265)を発行すると読めます。

sun

JTAGのTDIから入ってきた信号はPS TAPを通った後、PL TAPかDummy TAPを通ります。その後、ARM DAPかDummy DAPを通ります。どちらを通るかというのは、PS TAPに対して発行するJTAG_CTRLコマンドで指定します。

具体的には、JTAG_CTRLコマンド(0x83F)をPS-PLに発行して、そのあと、0x00000003をDRに書き込みます。

SVF形式で書くなら、

STATE RESET;
TDR 0;
HDR 1 TDO (1); // ARMのDAPを無視するため
SIR 16  TDI (83FF) ; // JTAG_CTRL
SDR 32 TDI (00000003) ; // ARM DAPとPL TAPを有効化
RUNTEST RESET 16 TCK; // 切り替えた後は、Test-Logic-Resetステートで5回以上 TCKをトグルする

となります。

こうすることで、PL TAPとARM DAPが有効になって、MITOUJTAGの自動認識でも2個のデバイスが見つかるようになりました。

Zujtag_4

そして、ARMのDAPも認識されるようになり、正常にバウンダリスキャンができるようになります。

Zujtag_5

まとめると

  • ZYNQ UltraScale+ MPSoCのIRの長さは常に16bit
  • 非セキュアブートではセキュリティゲートは無効になっていて、突破できる
  • リセット後は、PL TAPとARM DAPはDummyが選択されているので、バウンダリスキャンやコンフィギュレーションをするなら、JTAG_CTRLコマンドで有効にしなければならない
  • PMUがJTAGでデバッグできそうだ

となります。

| | コメント (0)

2018.10.10

トランジスタ技術2018年11月号に掲載されました

発売日になるまで黙っていましたが、トランジスタ技術11月号の特集「私の人工知能チップ製作」の第1章から第3章に、記事が掲載されました。

Trg

今回の特集記事では、トラ技の本来の趣旨である「プロのビギナーのための記事」に徹し、人工知能(AI)の基礎とFPGA化のやり方を中心に執筆いたしました。

最初に考えた記事のプランでは、NNとCNNを両方作って比較したり、リアルタイム性にこだわってカメラ画像→DDRメモリ転送→即座にAIで推論、とかいうのをやろうと考えていたのですが、それだと初心者を置き去りにしてしまうのではないかと思われました。

現在のFPGAによるAI実装の最先端は、すでにビギナーの方には追い付けないほど先に進んでしまっています。

「FPGAが如何にすごいか」「こんなすごいものを作ったぞ」というスタイルで記事を書くと、すでにわかっている方にしか理解できない記事となってしまいます。トラ技の目指すところを念頭において初心者向けに何度か書き直しました。

はじめてFPGAやAIに接する人でもわかりやすくなるよう、自分がAIの勉強を始めたときの気持ちを思い出しながら、用語解説やAIの基本的な部分を中心に執筆いたしました。バリバリのプロの方には物足りないかもしれませんが、ご容赦くださいませ。

Trg2

幸いなことに第4章にマーシーさんが書いてくれたCNNの記事があるので、全体として見れば第一線のプロの方でも満足いただけるような構成になっているかと思います。

●記事で使用したFPGAボードについて

本特集3章の内容は、CMOSカメラで撮った猫画像をFPGAで認識させるというものです。

使用したFPGAボードはRasppberry Pi型のFPGAボード「Zynqberry(ジンクベリー)」です。ZynqberryにUbuntu LinuxとSDSoCをいれて猫画像を認識させています。

Trg5

写真1 Raspberry Pi型のFPGAボード「Zynqberry(ジンクベリー)」

世の中にはPYNQやZYBO、ArtyといったDigilent系のボード以外にも、いろいろなZYNQボードがあります。なのに、どうしてみんな、ZYBOやArtyばかり使うのでしょう。

Zynqberryのようなユニークなボードにも焦点が当たればよいなと感じています。

 

●記事で使用したCMOSイメージセンサについて

本記事では、Raspberry Piカメラを使用して画像をキャプチャしています。Raspberry Piカメラの入手は大変容易です。

Trg4

写真2 どこでも手に入るRaspberry Piカメラ

Raspiカメラは、Amazonや秋月、千石などで互換品も含めて簡単に入手できます。なお、本記事で試したのはRaspiカメラのV1.3です。2.1では試していません。

下の写真は、猫画像を認識させているときのようすです。

カメラで撮った画像を1280×720→32×32に縮小しているわけですが、画面いっぱいの画像を32×32に縮小してからNNに入れるので、なかなか距離感が難しいです。

Trg3

写真3 「Zynqberry」にCIFAR-10を入れて猫画像認識

現時点では全く実用的なAIではありませんが、SDSoCのソースは公開しているし、超絶技巧は使っていないので、わかりやすいと思います。

ぜひいろいろ試してみてください。

この記事が、これからFPGA×AIをしようという人の一助になれば幸いです。

| | コメント (0)

«Ultra96ボードのJTAGバウンダリスキャンができた