« 2018年9月 | トップページ | 2018年11月 »

2018.10.31

MITOUJTAG BASIC 3.4をリリースしました

本日、MITOUJTAG BASIC 3.4をリリースしました。

また、MITOUJTAGの使い方を簡単に説明するスライドを作成しました。

Mjslide_2

http://www.tokudenkairo.co.jp/jtag/mjbas_usage.pdf

MITOUJTAGを使うと、オシロやロジアナでは見れないBGAの裏側の信号を見たり操作したりすることができます。

Mjbas34_2

あるのとないのとでは、FPGAの開発の効率が全然変わってきます。

MITOUJTAG BASIC 3.4では、

  • UltraScale+への書き込み、バウンダリスキャン対応
  • XILINX 7シリーズの温度・電圧測定

などに対応しました。

Mj_uscale

詳しい更新点はこちらのページをご覧ください。

http://www.tokudenkairo.co.jp/jtag/3xto34.html

| | コメント (0)

2018.10.30

UltraScale+でJTAGを挿しているとLinux起動中にハングアップする問題

UltraScale+でJTAGを挿しているとLinux起動中にハングアップする問題があると聞いて、実験してみました。

まず、@ikwzmさんのZynqMP-FPGA-Linux (https://github.com/ikwzm/ZynqMP-FPGA-Linux) で試してみました。

Vivado HLSのコマンドプロンプトで、xsdbと入力すると、デバッガ「XSDK」が起動します。

Xsdb3

ここでconnectと打つと、

Xsdb4

という画面になります。

xsdb% cInfo: Cortex-A53 #1 (target 10) Stopped at 0x0 (Cannot resume. APB AP transaction error, DAP status 30000021)
Info: Cortex-A53 #1 (target 10) Running
xsdb% Info: Cortex-A53 #2 (target 11) Stopped at 0x0 (Cannot resume. APB AP transaction error, DAP status 30000021)
Info: Cortex-A53 #2 (target 11) Running
xsdb% tInfo: Cortex-A53 #1 (target 10) Stopped at 0x0 (Cannot resume. APB AP transaction error, DAP status 30000021)
xsdb% Info: Cortex-A53 #1 (target 10) Running

上のようなメッセージが延々と表示されます。

targetコマンドで見てみると、たまに、

Xsdb5

いくつかのプロセッサが停止しているようなメッセージを出しています。

このとき、LinuxのUARTに出てくるコンソールには、SDカードのトラブルやBlueToothが初期化失敗だの、いろいろなエラーメッセージが出て不安定になっています。

Xsdb6

おそらくLinuxの起動が最後まで行かずに途中でハングすることと思われます。

解決策は、@ikwzmさんや、@marsee101のおっしゃるようにuEnv.txtのbootargsのところにcpuidle.off  =1を付ければいい https://twitter.com/nahitafu/status/1057237499980918784 ようです。

これは、Linuxのカーネルコンパイル時に

CONFIG_CPU_IDLE=y

という設定になっていると、CPUがアイドル状態になることがあり、アイドル状態のときにJTAGアクセスするからおかしくなるようです。

@hidemi_ishihara さんによるとAnswer Recordの69143にあるとのこと。

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

を見てみると、確かに、そのようなことが書いてあります。

XSDBはコアのパワーダウンをチェックしているけれども、チェック後に不意にIDLEになるからDAPがエラーを起こすようです。

これなら、CPU_IDLEをOFFにする以外に解決策はなさそうです。

cpuidle.off=1を設定すれば、xsdbのtargetコマンドでも4つのCPUが落ち着いて常にRunning状態で見えます。

Xsdb7

| | コメント (0)

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回目で目的のレジスタの値が読み出されます。

温度を測る場合は、

rdvalue / 65536. * 509.3140064 - 280.23087870;

で[℃]に変換します。

電圧を測る場合は、

rdvalue / 65536. * 3;

で[V]に変換します。

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

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

なお、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

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

  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にあるすべてのレジスタはリセットされてしまうので、画面を使うならもう一度再起動しなければならなくなるでしょう。

書き込んで→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を設計したのは同じグループなのかもしれない。偶数シリーズと奇数誤で設計担当グループが交互に変わるとか、そういう事情があるのかもしれない。

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

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

Zubscan_1

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

Zubscan_2

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

これまでにわかっている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は使えるので、セキュリティゲートを気にする必要はありません。

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)を発行すると読めます。

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)

2018.10.09

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

Ultra96ボードを使ってZYNQ UltraScale+ MPSoC(以下、ZUと略)のJTAGの仕組みを解明しています。

まず、ZUは本体のPLのJTAGのほか、ARMのDAPや、ダミーのDAPが付いたりして、JTAGチェーンの構成が変わります。JTAGチェーンの構成はおそらくFSBLの中からCSUレジスタを操作することで行われますが、デフォルトのFSBLでは以下のようになります。

Zujtag_1_2

ここで厄介なことが3つあります。JTAGチェーンの構成が変わるたびに、JTAGのTMSを1にして何回かのTCKを与えてTAPをRESETしないといけないことと、JTAGチェーンの構成はソフトで変わることです。そのため、ハードウェアリセットが行われて、PMU→CSU→FSBLと起動のステップが進んだあたりでJTAGをリセットしなければなりません。

また、ZUのARM TAPはJTAGの規格に反してTAP RESET後にDRにIDCODEが現れません。そのため、自動で認識することができないことです。

JTAGを使う汎用的なツールに「MITOUJTAG(みとうジェイタグ)」というのがあります。MITOUJTAGを使うとバウンダリスキャンで端子の状態が見えます。

Ultra96ボードでは以下のように見えます。

Zujtag_2

Ultra96ボードでチカチカ光っているLEDのあたりのピンを見てみます。

Zujtag_3

AB4、AA4、Y5、AA3、AB5番ピンにこれらの端子があります。

ZUでは、普通にバウンダリスキャンでSAMPLEしても、これらの端子の状態は正しく見ることができません。

前の記事で書いたとおり、SAMPLEするときには入力セルから値を読むのが普通なのですが、

Bscan1_2

ZUではなぜか出力セルから入力値が読み込まれるからです。

Bscan2

これは、はっきり言って、ZUのバグだと思います。

しかも、この入力ピンの値が出力セルから読み出される現象は、SAMPLE時のみ発生し、EXTEST時には発生しません。したがって、BSDLファイルの変更では対処できません。

そこで、MITOUJTAGでは、「ZYNQUltraScale+ MPSoCならば、SAMPLE状態のときに、入力セルと出力セルの読み出した値を入れ替える」という方法でこの問題に対処することにしました。

このようにすることで、端子から出力している値と、端子から入力している値を正しく読み出すことに成功しました。

以上の問題を解決し、Ultra96ボードでLinuxが起動する時の波形を見ることに成功しました。

まずは下の波形をご覧ください。

UART0_TXに間欠的に動く波形が出ています。これはコンソールへの文字出力です。

Zujtag_4

起動してから5秒と8秒付近で、それぞれLinuxの起動と、BlueToothとWLANの起動が起こります。このときにMIOのピンの出力状態が変わるのが見てとれます。

Zujtag_5

起動後8秒後くらいというのは、コンソールにこのような文字列が出力されているあたりです。

Zujtag_9

LED0(緑のLED)がチカチカを開始するのが見えています。

Zujtag_6

あと、見て面白いのは起動後8秒付近でUSB1が起動することと、SD1に一瞬だけアクセスすることかなと思います。

Zujtag_7Zujtag_8

UltraScale+のJTAGの仕組みがだいたい解明できました。

ポイントは、

  • CSUやFSBLによってソフト的にJTAGチェーンの構成が変わるので、それに合わせてTAP RESETをしなければならない
  • SAMPLE時の入力セルと出力セルが逆になっている
  • DDR4メモリの端子は見えない(これもチップのバグかもしれない)

MITOUJTAGでは、このような問題に対処するためのUltraScale+用のパッチを提供する用意があります。

| | コメント (0)

2018.10.08

Ultra96ボードのBOOT.BINを作って起動させてみた

自分でUltra96ボードをブートさせようと思った場合、まずUltra96ボードのVivadoのプロジェクトを探してくる必要があります。

Vivadoプロジェクトは、

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

にあるようです。

この中のTutorial 01-04 Solutionsをダウンロードします。

Ultra96_tutorial

この中にあるUltra96_Basic_SystemというフォルダがVivadoのプロジェクトで、Ultra96_Basic_System\Ultra96_Basic_System.sdk\design_1_wrapper.hdfがHDFファイル(ハードウェア定義ファイル)です。

このファイルはVivado 2018.2用なので、私のVivado 2018.1では開けませんでしたが、HDFがあれば、XILINX SDKでプロジェクトが作成できます。

XSDKで新規プロジェクト作成、とやって、Newを押します。

New_proj_1

次のダイアログでHDFファイルを指定すれば新しいハードウェアプラットフォームとして登録されます。

New_proj_2

これで、プロセッサのタイプをPMUにしてPMUファームウェアを作り、FSBL、Periferal Testなどのアプリを作ります。

注意しなければならないことは、デフォルトではUART0に標準出力が出力されてしまうことです。Ultra96ボードのUART0はBluetoothなので、普通にFSBLやPMUを作ってもコンソールに何も出てきません。

Ultra96ボードのUARTを3ピンのピンヘッダ(J15)につないでいる場合、UART1に出してやらなければなりませんが、その変更はPMU_BSPや、FSBL_BSP、TEST_BSPなど、_BSPと付いたプロジェクトの中のxparameters.hにあります。xparameters.hのSTDIN_BASEADDRESSとSTDOUT_BASEADDRESSがデフォルトでは0xFF000000になっているので、これを0xFF010000に変更します。

#define STDIN_BASEADDRESS 0xFF010000
#define STDOUT_BASEADDRESS 0xFF010000

ビルドが走ってしまうと数十分かかってしまうようですね・・

XSDKが作ったデフォルトのFSBLやPMUはデバッグメッセージを出さないので、デバッグメッセージを出すように修正します。

まず、PMUのプロジェクトではxpfw_config.hを開いて

#define XPFW_DEBUG_ERROR_VAL (1U)
#define XPFW_DEBUG_DETAILED_VAL (1U)

を有効にします。

FSBLのプロジェクトではxfsbl_config.hを開いて、

#define FSBL_PRINT_VAL              (1U)
#define FSBL_DEBUG_VAL              (1U)
#define FSBL_DEBUG_INFO_VAL         (1U)
#define FSBL_DEBUG_DETAILED_VAL     (1U)

を有効にします。

bootimage.bifは以下のようにします。

//arch = zynqmp; split = false; format = BIN
the_ROM_image:
{
	[fsbl_config]a53_x64
	[pmufw_image]D:\ultrascale\PMU\Debug\PMU.elf
	[bootloader, destination_cpu=a53-0]D:\ultrascale\FSBL\Debug\FSBL.elf
	[destination_device = pl]design_1_wrapper.bit
	[destination_cpu = a53-0]D:\ultrascale\TEST\Debug\TEST.elf
}

bootimage.bifの書き方でいろいろ実験してみてわかったことは、

  • [fsbl_config]の行は無くても影響なさそう
  • 実は、PMU.elfはなくてもFSBLとアプリは起動する
  • FPGAのBitファイルがなくても、CPUは起動する(ただしPLがコンフィグされないので、DONEのLEDは点灯しない)
  • アプリ(test.elf)はなくても、FSBLまでなら起動する

ということでした。

なお、bootimage.bifからboot.binを作るのは

D:\Xilinx\SDK\2018.1\bin\bootgen -image bootimage.bif -arch zynqmp -o D:\ultrascale\mkboot\BOOT.bin -w on 

とコマンドを打ちます。

ためしにどこまで削っていってブートするかを試してみたら、最小限のbootimage.bifとして

the_ROM_image:
{
	[bootloader, destination_cpu=a53-0]D:\ultrascale\FSBL\Debug\FSBL.elf
}

だけで起動できました。

Minimum_zu

Xilinx Zynq MP First Stage Boot Loader
Release 2018.1   Oct  9 2018  -  01:03:55
Reset Mode      :       System Reset
Platform: Silicon (4.0), Cluster ID 0x80000000
Running on A53-0 (64-bit) Processor, Device Name: XCZU3EG
Processor Initialization Done
================= In Stage 2 ============
SD0 Boot Mode
SD: rc= 0
File name is BOOT.BIN
Multiboot Reg : 0x0
Image Header Table Offset 0x8C0
XFSBL_ERROR_NO_OF_PARTITIONS
Image Header Table Validation failed
Boot Device Initialization failed 0xD
================= In Stage Err ============
Fsbl Error Status: 0x0

PMUも複数のプロセッサも出てこない。これならZYNQ 7000と同じですね。

さて、本筋に戻りましょう。

FSBL、PMU、BitStream、テストアプリ(Periferal Test)を結合させてBoot.binを作り、ブートさせてみた結果が次の画面です。

Ultra96_boot

起動時の全メッセージを載せます。FSBLがデバッグメッセージをUART1に出力するので、中で何をやっているかがわかると思います。

Xilinx Zynq MP First Stage Boot Loader
Release 2018.1   Oct  9 2018  -  01:03:55
Reset Mode      :       System Reset
Platform: Silicon (4.0), Cluster ID 0x80000000
Running on A53-0 (64-bit) Processor, Device Name: XCZU3EG
Processor Initialization Done
================= In Stage 2 ============
SD0 Boot Mode
SD: rc= 0
File name is BOOT.BIN
Multiboot Reg : 0x0
Image Header Table Offset 0x8C0
*****Image Header Table Details********
Boot Gen Ver: 0x1020000
No of Partitions: 0x3
Partition Header Address: 0x440
Partition Present Device: 0x0
Initialization Success
======= In Stage 3, Partition No:1 =======
UnEncrypted data Length: 0x153E27
Data word offset: 0x153E27
Total Data word length: 0x153E27
Destination Load Address: 0xFFFFFFFF
Execution Address: 0x0
Data word offset: 0xED80
Partition Attributes: 0x26
Destination Device is PL, changing LoadAddress
XPFW: Calling ROM PWRUP Handler..Done
XPFW: Calling ROM Isolation Handler..Done
Non authenticated Bitstream download to start now
DMA transfer done
PL Configuration done successfully
PPFW: Calling ROM PWRUP Handler..Done
 artition 1 Load Success
======= In Stage 3, Partition No:2 =======
UnEncrypted data Length: 0x6412
Data word offset: 0x6412
Total Data word length: 0x6412
Destination Load Address: 0x0
Execution Address: 0x0
Data word offset: 0x162BB0
Partition Attributes: 0x116
Partition 2 Load Success
All Partitions Loaded
================= In Stage 4 ============
PM Init Success
Protection configuration applied
Running Cpu Handoff address: 0x0, Exec State: 0
Exit from FSBL
---Entering main---

 Running ScuGicSelfTestExample() for psu_acpu_gic...
ScuGicSelfTestExample PASSED
ScuGic Interrupt Setup PASSED

 Running XZDma_SelfTestExample() for psu_adma_1...
XZDma_SelfTestExample PASSED

 Running Interrupt Test  for psu_adma_1...
ZDMA Simple Example PASSED

 Running XZDma_SelfTestExample() for psu_adma_2...
XZDma_SelfTestExample PASSED

 Running Interrupt Test  for psu_adma_2...
ZDMA Simple Example PASSED

 Running XZDma_SelfTestExample() for psu_adma_3...
XZDma_SelfTestExample PASSED

 Running Interrupt Test  for psu_adma_3...
ZDMA Simple Example PASSED

 Running XZDma_SelfTestExample() for psu_adma_4...
XZDma_SelfTestExample PASSED

 Running Interrupt Test  for psu_adma_4...
ZDMA Simple Example PASSED

 Running XZDma_SelfTestExample() for psu_adma_5...
XZDma_SelfTestExample PASSED

 Running Interrupt Test  for psu_adma_5...
ZDMA Simple Example PASSED

 Running XZDma_SelfTestExample() for psu_adma_6...
XZDma_SelfTestExample PASSED

 Running Interrupt Test  for psu_adma_6...
ZDMA Simple Example PASSED

 Running XZDma_SelfTestExample() for psu_adma_7...
XZDma_SelfTestExample PASSED

 Running Interrupt Test  for psu_adma_7...
ZDMA Simple Example PASSED

 Running SysMonPsuPolledPrintfExample() for psu_ams...

Entering the SysMon Polled Example.

The Current Temperature is 46.561 Centigrades.
The Maximum Temperature is 47.082 Centigrades.
The Minimum Temperature is 46.102 Centigrades.

The Current VCCINT is 0.853 Volts.
The Maximum VCCINT is 0.855 Volts.
The Minimum VCCINT is 0.852 Volts.

The Current VCCAUX is 1.817 Volts.
The Maximum VCCAUX is 1.818 Volts.
The Minimum VCCAUX is 1.815 Volts.

Exiting the SysMon Polled Example.
SysMonPsuPolledPrintfExample PASSED

 Running SysMonPsuIntrExample()  for psu_ams...

Entering the SysMonPsu Interrupt Example.

The Current Temperature is 46.514 Centigrade.

The Current VCCINT is 0.854 Volts.

The Current VCCAUX is 1.816 Volts.

Temperature Alarm(0) HIGH Threshold is 36.512 Centigrade.
Temperature Alarm(0) LOW Threshold is 26.510 Centigrade.
VCCINT Alarm(1) HIGH Threshold is 0.654 Volts.
VCCINT Alarm(1) LOW Threshold is 1.054 Volts.
VCCAUX Alarm(3) HIGH Threshold is 1.615 Volts.
VCCAUX Alarm(3) LOW Threshold is 2.016 Volts.

Alarm 0 - Temperature alarm has occured

The Current Temperature is 46.607 Centigrade.
The Maximum Temperature is 47.346 Centigrade.
The Minimum Temperature is 45.955 Centigrade.

The Current VCCINT is 0.853 Volts.
The Maximum VCCINT is 0.855 Volts.
The Minimum VCCINT is 0.851 Volts.

The Current VCCAUX is 1.817 Volts.
The Maximum VCCAUX is 1.818 Volts.
The Minimum VCCAUX is 1.815 Volts.

Exiting the SysMon Interrupt Example.
SysMonPsu IntrExample PASSED

 Running XCsuDma_SelfTestExample() for psu_csudma...
XCsuDma_SelfTestExample PASSED

 Running Interrupt Test  for psu_csudma...
CSUDMA Interrupt Example PASSED

 Running XZDma_SelfTestExample() for psu_gdma_0...
XZDma_SelfTestExample PASSED

 Running Interrupt Test  for psu_gdma_0...
ZDMA Simple Example PASSED

 Running XZDma_SelfTestExample() for psu_gdma_1...
XZDma_SelfTestExample PASSED

 Running Interrupt Test  for psu_gdma_1...
ZDMA Simple Example PASSED

 Running XZDma_SelfTestExample() for psu_gdma_2...
XZDma_SelfTestExample PASSED

 Running Interrupt Test  for psu_gdma_2...
ZDMA Simple Example PASSED

 Running XZDma_SelfTestExample() for psu_gdma_3...
XZDma_SelfTestExample PASSED

 Running Interrupt Test  for psu_gdma_3...
ZDMA Simple Example PASSED

 Running XZDma_SelfTestExample() for psu_gdma_4...
XZDma_SelfTestExample PASSED

 Running Interrupt Test  for psu_gdma_4...
ZDMA Simple Example PASSED

 Running XZDma_SelfTestExample() for psu_gdma_5...
XZDma_SelfTestExample PASSED

 Running Interrupt Test  for psu_gdma_5...
ZDMA Simple Example PASSED

 Running XZDma_SelfTestExample() for psu_gdma_6...
XZDma_SelfTestExample PASSED

 Running Interrupt Test  for psu_gdma_6...
ZDMA Simple Example PASSED

 Running XZDma_SelfTestExample() for psu_gdma_7...
XZDma_SelfTestExample PASSED

 Running Interrupt Test  for psu_gdma_7...
ZDMA Simple Example PASSED

 Running IicPsSelfTestExample() for psu_i2c_1...
IicPsSelfTestExample PASSED

 Running XZDma_SelfTestExample() for psu_adma_0...
XZDma_SelfTestExample PASSED

 Running Interrupt Test  for psu_adma_0...
ZDMA Simple Example PASSED

 Running SpiPsSelfTestExample() for psu_spi_0...
SpiPsSelfTestExample PASSED

 Running SpiPsSelfTestExample() for psu_spi_1...
SpiPsSelfTestExample PASSED

 Running Interrupt Test  for psu_ttc_0...
TtcIntrExample PASSED

 Running Interrupt Test  for psu_ttc_1...
TtcIntrExample PASSED

 Running Interrupt Test  for psu_ttc_2...
TtcIntrExample PASSED

 Running Interrupt Test  for psu_ttc_3...
TtcIntrExUartPsPoUartPsIntrExample PASSED

 Running WdtPsSelfTestExample() for psu_wdt_0...
WdtPsSelfTestExample PASSED

 Running WdtPsSelfTestExample() for psu_wdt_1...
WdtPsSelfTestExample PASSED
---Exiting main---

そして豪華なペリフェラルテストを行っています。

あれ?PMUが出てこない。

どうしてでしょう。

| | コメント (0)

2018.10.07

ZYNQ UltraScale+ MPSoCの起動について調べたこと

ぼちぼちUltra96ボードを触り始めまています。

まず、1000ページ以上にもなるZYNQ UltraScale+ MPSoCのユーザガイド(特にUG1085)を印刷して、ひたすら読みました。A4の紙に4ページで縮小印刷し、両面印刷するので、1枚あたり8ページです。それでも数百枚の紙を使ったと思います。

Zu_manual

読んでわかったことは、

  • ZYNQ UltraScale+には、Cortex-A53が2個(あるいは4個)、Cortex-R5が2個、PMUプロセッサ、CSUプロセッサの4種類のプロセッサが入っている
  • Cortex-A53とR5はどちらを使ってもよいが、R5は低消費電力ドメインにつながっているので、電力やパフォーマンスの兼ね合いでR5を使うのも面白いかもしれない
  • PMUとCSUのプロセッサは、おそらくMicroblazeでできている。これは3重に冗長化されていて、高いセキュリティを持つ。
  • ZYNQとは違ってA53やR5のプロセッサは最初は起動していない。
  • 最初に起動するのはPMUであり、PMUがCSUを起動する(リセットを解除する)。
  • CSUは、A53かR5のどちらかにFSBLをロードする。
  • PMUやCSUがちゃんと動作していないと、PLはコンフィグできない。
  • セキュアブートというのは、おそらくeFUSEやBBRAMを使ってキーを格納しておいて、認証されたFSBLでしか起動しないようにする仕組み。認証と暗号化。
  • 普通に使うなら非セキュアブートでよさそうだ。

ということです。

つまり、起動するにはPMU、CSUを起動してFSBLをロードしてあげなければならないようです。

| | コメント (0)

2018.10.04

Cosmo-Zのアルミケース入りを出荷

お客様から注文をいただいていたCosmo-Zアルミケース入り(80MHz 12bit 8ch)を出荷しました。

FANが付いていて、温度が37度までしか上がらないというスグレモノです。

Csz_alm_2

フロントパネルに24個の使われていない穴が開いていますが、これはCosmo-Z 32chにした場合には全部埋まります。

Csz_alm_3

背面は凹んでいます。このアルミの設計は結構大変だった。

Csz_alm_4

Cosmo-Zは、もともと地中深くで宇宙線を検出するという目的のために作られたので、基板の幅が89mmで細長いというサイズになっています。

地上で使う一般的な用途では、そのようなサイズに合ったケースはありません。タカチのケースをカスタムで使うことになりますが、既存の基板を既存のケースに合わせるのはなかなか苦労しています。

Cosmo-Z アルミケース入りの中身はこんな感じ。

Csz_alm_5

床板や天板は鉄なのでかなり丈夫です。側面は3mmくらいある凸凹したアルミです。

Csz_alm_1

これで、お客様から注文をいただいていて、注文残になっていたCosmo-Zはすべて出荷できたと思います。

あと、Cosmo-Z Miniと、HyperFADCと、Spartan-6基板20個か。ふう。

| | コメント (0)

2018.10.03

Cosmo-Z 16ch版を出荷

Cosmo-Zの16ch版を出荷しました。

また予定以上に納期がかかってしました。

Csz16_1

Csz16_2

Cosmo-Zは1台1台、お客様ごとにカスタマイズしたり、仕様が異なるのが難しい理由なのかもしれません。

| | コメント (0)

2018.10.01

Cosmo-Zのロックインアンプを作成しました

お客様からご依頼を受けて、時間が経ってしまった案件であるCosmo-Zのロックインアンプがようやく作成しました。

Csz_lockin1

見てのとおりVivadoで作られていて、ADC Blockから出てきたデータをlockinというモジュールに入れることで、ロックイン計測ができるというものです。

動作させているときの画面の様子です。

Csz_lockin2

CH1の入力をリファレンスとして、周期を推定して、同期した正弦波をFPGAの中で作り出しています。

その作り出した正弦波と観測したい波形を乗算して何周期か積分することで、特定の周波数における振幅の大きさを測るというものです。

要するに1つの周波数だけのフーリエ変換のようなものです。

FPGAで動くフルディジタルなロックインアンプですが、1.5MHz程度なら余裕でロックできます。

Csz_lockin3

このような感じで、いまは積み残してきた案件を1つずつ解決していきたいと思います。

| | コメント (0)

« 2018年9月 | トップページ | 2018年11月 »