« 2018年10月 | トップページ | 2018年12月 »

2018.11.29

粗大ごみの回収に向けて

明日、粗大ごみの回収が来るので、オフィス家具などをまとめていました。

机などもたくさん出して、オープンスペースが広くなってきました。

1129_3

写真のダンボールはレンタル倉庫に送ります。

1129_1

椅子さん、さようなら。

1129_2

なお、移転先はまだ決まっていません。

| | コメント (0)

2018.11.26

XILINXのJTAG to AXI masterのプロトコル

JTAG to AXI masterは便利そうなのですが、Vivadoを起動しないと使えず、またtclで操作するとか、操作するシーケンスをcreateしたりdestroyしたりと、使い勝手の面ではよいとは言えません。

そこで、どのようなプロトコルで通信しているかを探りました。

実験に使ったボードは特電Artix-7ボード

Artixboardt_4

USB3.0に対応していて、オンボードでUSB-JTAGも乗っていて、2.54mmピッチのピンヘッダがあるのが便利です。

Artix-7用に、Vivadoで下の図のようなデザインを作ります。

Jaxi1

そして、VivadoとMITOUJTAGを接続し、Vivadoが出力するJTAGシーケンスをキャプチャします。

Vivadoは以下のようなシーケンスを大量に吐き出します。

SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00400) TDO (00000);
SDR 37 TDI (00060008A9) TDO (0160008000);

最初のSIR 6 TDI (02)は、USER1という命令です。

USER1命令の後は、SDR 32 (データレジスタへの32bitシフト)か、SDR 17 (データレジスタへの17bitシフト)かのどちらかです。

SDR32の中身は04900180か04800100、00000000であることが多く、SDR17の中身は00000 00400 00500 00600 0F000など様々です。

XILINXのILA、VIO、JTAG2AXIはいずれも共通のJTAGコンポーネントを使っているようで、(※ALTERAに例えればJTAG HUB)、何かのHUB的なものの下に複数のJTAGサブコンポーネントをぶら下げているようです。

そのため、JTAG HUB的な何かをコントロールするのが04900180などのコマンドではないかと想像できます。

そして、各コンポーネントのレジスタに具体的な値を与えているのが、

SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00400) TDO (00000);
SDR 37 TDI (00060008A9) TDO (0160008000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00500) TDO (00000);
SDR 27 TDI (1FFF0A9) TDO (7F00000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00600) TDO (00000);
SDR 139 TDI (000000000000000000000000000000000A9) TDO (0000000003F000818081000380008038800);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);

というSDR17のシーケンス。この00400,00500,00600という順番で3個セットで繰り返し出てきます。また、たまに0F000と00000も出てきます。

00400の後はSDR37で、00500の後はSDR27、00600の後はSDRの長さは可変です。そして、データレジスタの末尾は必ずA9になっています。

出てくるパターンをまとめると、

  • SDR32 04900180 -> SDR17 0F000 -> 75bit
  • SDR32 04900180 -> SDR17 00000 -> 1243bit
  • SDR32 04900180 -> SDR17 00400 -> 37bit
  • SDR32 04900180 -> SDR17 00500 -> 27bit
  • SDR32 04900180 -> SDR17 00600 -> 可変

となります。

そんな感じの心の目で見ていくと、VivadoのTclを通じてJTAG2AXIに

create_hw_axi_txn wr [get_hw_axis hw_axi_1] -len 1 -address 40001234 -data 55555555 -type write
run_hw_axi wr
delete_hw_axi_txn wr

で書き込んだ値を出力したと思われる箇所が見つかりました。

SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00400) TDO (00000);
SDR 37 TDI (00000001A9) TDO (0160008000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00500) TDO (00000);
SDR 27 TDI (00006A9) TDO (7FF0000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00600) TDO (00000);
SDR 27 TDI (00000A9) TDO (1001000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00400) TDO (00000);
SDR 37 TDI (00020002A9) TDO (0000001800);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00500) TDO (00000);
SDR 27 TDI (20011A9) TDO (0006000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00600) TDO (00000);
SDR 42 TDI (055555555A9) TDO (2AAA8000000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00400) TDO (00000);
SDR 37 TDI (00020004A9) TDO (0020002000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00500) TDO (00000);
SDR 27 TDI (20010A9) TDO (0011800);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00600) TDO (00000);
SDR 74 TDI (04000123400498400A9) TDO (091A0024C2000000000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00400) TDO (00000);
SDR 37 TDI (00000001A9) TDO (0020004000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00500) TDO (00000);
SDR 27 TDI (00003A9) TDO (0010000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00600) TDO (00000);
SDR 27 TDI (00000A9) TDO (0000000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00400) TDO (00000);
SDR 37 TDI (00000001A9) TDO (0000001800);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00500) TDO (00000);
SDR 27 TDI (00004A9) TDO (0003800);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00600) TDO (00000);
SDR 27 TDI (00000A9) TDO (0000800);
STATE RESET;

どうやら、データを先に与えてからコマンドを与えるようです。

ただ、この部分シーケンスをSVFプレイヤーで流し込んでも、LEDは変化しませんでした。もっと前後の長い部分を流さなければならないようですが、ちょっと間違えるとVivadoのRefreshの操作をしないと戻らなくなります。

結論としては、JTAG to AXI masterのプロトコルは非常に長く、1ワードのAXIトランザクション発行のために数十行のJTAGコマンドを発行しなければならず、効率が良くありません。

プロトコルも難解でリバースエンジニアリングするのは容易ではなさそうです。

その上、エラーが起きたときの復帰が難しいので、無理に解読して自分のソフトウェアで使えるようにするのは得策ではないと考えられます。

| | コメント (0)

2018.11.25

Cosmo-Z Miniのファームウェアアップデート・スクリプトを作った

ZYNQ搭載の小型高速ADCシステム「Cosmo-Z Mini」のシステムは、boot.binや、メインのelfファイル、Webブラウザで動くアプリケーションなど様々なファイルで成り立っています。

こういったファイルを一括で更新するためのスクリプトを作成しました。

1527731222_1525757428_cszmini_sma_f

アップデート方法の詳細は

http://www.cosmoz.jp/update.html

のページに記載しましたが、wgetに-q -Nオプションを付けて、サーバから最新の更新スクリプトをダウンロードしてきます。

-qは進捗を画面に表示させないオプション、-Nは、サーバとローカルで日付を比較して、サーバのほうが新しければダウンロードするというオプションです。

そして、ダウンロードしたスクリプトを実行するのですが、ダウンロードしたスクリプトの中もwget -q -Nの羅列となっています。

また、

echo "  Enter [y|yes|YES] to execute."
read input

でユーザ入力を促して、

if [ -z $input ] ; then
	echo "  コンフィグは行われませんでした。"
elif [ $input = 'yes' ] || [ $input = 'YES' ] || [ $input = 'y' ] ; then
	chmod 600 /home/share/cszmain.elf
	echo "Stopping 'cszmain.elf' process."
	killall cszmain.elf
	echo "Check and download firmware '$BITFILE'"
	wget $WGETOPTION http://www.cosmoz.jp/files/$BITFILE -O /tmp/tmp.bit
	if [ $? -ne 0 ] ; then
		echo "file not found."
		exit 1
	fi
	echo "Wait more 2sec"
	sleep 2s
	echo "Execute configuration via /dev/xdevcfg. Sorry if hang-up"
	sleep 1s
	if [ -s /tmp/tmp.bit ]; then
		cat /tmp/tmp.bit > /dev/xdevcfg
		rm /tmp/tmp.bit
	fi
	chmod 777 /home/share/cszmain.elf
	echo "....."
	echo "Run setup script"
	echo "----------------"
	/home/share/setup
	echo "----------------"
	echo "done"
	exit 0
fi

でyesが押されれば、bitファイルをサーバからダウンロードしてきて、/dev/xdevcfgに流し込むようになっています。

アプリからPLのAXIにアクセスしている最中に/dev/xdevcfgを使ってコンフィグするとハングアップするので、まずアプリを止めてから実行権限を消して、他人が実行できないようにして、それから初めてxdevcfgを使ってコンフィグし、その後にアプリを再び実行可能なようにしています。

更新した結果、Cosmo-Z Miniでちゃんとイベントキャプチャができるようになりました。

Filewave

NaI + PMTで4時間取ったスペクトラムもそれなりに出るようになりました。

Spec

次は、このような自動更新スクリプトをさらに一歩進めて、「更新があります」というのをユーザに通知するような仕組みを作っていきたいと思います。

| | コメント (0)

2018.11.24

XILINXのJTAG to AXI masterの使い方

本日、RTLを語る会に参加して、JTAG to AXI masterというものを紹介していただきました。

JTAGからAXIのトランザクションを発行するというもののようですが、気になったので、早速試してみました。

テストに使ったボードは、Ultra96ボードです。

まず、下の図のようなブロックデザインを作ります。

Axi_jtag_sample

jtag_axi_0というのがそのコンポーネントで、M_AXIの出力をBlockRAMにつなぐと同時にsystem_ilaに入れて波形を見ることができるようにしました。

つまり、JTAGから操作したAXIの波形を、ILAで見ようというわけです。

これを論理合成して、Bitstreamをダウンロードしたら、HardwareManagerを開きます。

Axi_jtag_setting

そして、AWREADY==1でトリガがかかるように設定します。

JTAGコマンドの発行はTclのコンソールで行います。

上の図では画面下の細長いところです。

create_hw_axi_txn wr [get_hw_axis hw_axi_1] -len 4 -address c0000003 -data 0000000F_00000001_0200000F_0005000F -type write
run_hw_axi wr
delete_hw_axi_txn wr

このように、createでコマンドを作って、runで実行して、deleteで消すという、大変面倒くさいコマンド体系になっています。コマンドの詳細はUG908の205ページあたりを見ると書いてあります。

バーストライトも発行できるのはありがたいですね。

実際にキャプチャされた波形を示します。

Axi_jtag_waveform

ご覧のとおり、ちゃんと長さ4のバーストライトの波形が出て、それをILAでキャプチャできました。

このコマンドの面倒臭さが解消できれば使えるようになると思います。

では、プロトコルを解析してみましょう!(続く)

| | コメント (0)

2018.11.23

Amazonフルフィルメントに委託

日々の発送業務の負担を減らすため、特電の製品のうち汎用的な製品をAmazonに委託することにしました。

Amazonには、フルフィルメント・マルチチャネルというサービスがあります。Amazonの倉庫に商品を預けておいて、自社のショッピングカートで受注したものをAmazonが代行して発送してくれるようです。

自分のブログを読み返してみると、2012年にも実験していたようです。

以前はAmazon箱で発送されてしまっていたため顧客を驚かせていたのですが、最近では無地の箱で発送してくれるようになったそうです。

すごく久しぶりに使うのでやり方が間違っていないといいのですが、AmazonのセラーセントラルでFBAマルチチャネルに納品という手続きを経ると、バーコードが出てくるので、それを商品に貼り付けます。

Fba1

商品をまとめる外箱にもAmazonのバーコードを印刷して貼り付けます。

Amazonはこの黒い箱をピッキングして発送するので、カタログや案内などは製品箱の中に入れることにしました。

中に入れるものを間違えたり忘れたりすると取り返しがつかないので、いつもにも増して集中して、一つ一つまごころを込めて詰めていきます。

Fba2

コツとしては、入れ忘れがないかどうかは、全体の重さで見るとよいということがわかりました。

A4の紙1枚でも5グラムあるので、案内の紙を入れ忘れただけでも重さで判断できます。

あとは注文が入ったらFBAの管理画面から住所を入力してぽちっとするだけです。

Fba3

自分のところから佐川急便やクロネコヤマトで発送するよりも、Amazonのほうが早く(お急ぎ便)、手数料を入れても運送料も安くなるのが、やはり数のパワーというやつを感じます。

これで、日々の事務作業のうち、商品発送という作業を外注することができるようになりました。

事務の省力化と自動化を目指す、勤労感謝の日でした。

| | コメント (0)

2018.11.22

MAX10のJTAG書き込みシーケンス

MITOUJTAGからMAX10に書き込みをができるようにするため、MAX10の書き込みシーケンスを解析しています。

まず、Qualtus Primeで適当なデザインを作り、pofファイルを作ります。

Qualtus

POFファイルの中身はこんな感じです。

Pof

じっと眺めていると、最初の12バイトを読み飛ばした後、キー(2バイト)+長さ(4バイト)+データの順にレコードが並んでいるのがわかります。0x00a8からはじまるFFFFFFFF・・・の部分が本体のデータです。

これをQualtus PrimeのProgrammerを使ってSVFに変換します。

Qualtus_programmer

SVFというのは、Serial Vector Formatの略で、JTAGのシーケンスを記述する汎用的な言語です。

Svf

これをじーっと眺めながらPOFファイルと見比べます。

SIR 10 TDI

の行を探します。SIRはJTAGの命令レジスタへのシフト命令で、続く10bitの値がコマンドです。ただし、このコマンドはIDCODEくらいしか公開されていないので、残りはリバースエンジニアリングしながら推定するしかありません。

その解析結果は、

  • (006)はIDCODE命令
  • (2CC)はCFGモードへの切り替え
  • (203)はメモリアレイへのアドレス指定
  • (2F4)は書き込み
  • (205)はベリファイ
  • (3F2)はDSMの消去
  • (307)はDSMのベリファイ
  • (201)はCFGモードからの復帰
であることが推定できます。

基本的にはPOFファイルの内容をどんどん書き込んでいるだけなのですが、たまに

Svf_skip_2

というふうにアドレスを与えなおしています。それは元のFFFFFFFFが出てきたところでそうなるようで、消去後にはROMの内容はFFFFFFFFになっているから、書く必要のない部分はスキップするという方針のようです。

これでMAX10へのCFMへの書き込みシーケンスの作り方は80%くらい理解できました。

| | コメント (0)

2018.11.20

XILINXのUSER_ACCESSをJTAGで見る

XILINXの比較的新しい(Virtex-5,6やArtix-7、Kintex-7など以降)にはUSER_ACCESSというプリミティブがあります。

User_access

USER_ACCESSとは、XILINX FPGAに元から備わっているプリミティブで、32bitの値を格納しておくものです。

32bitの値は、

  • コンフィギュレーションの時にBitStreamに含まれるコマンドで書き込まれる
  • この値はユーザが任意の値に指定することもできるし、タイムスタンプにすることもできる
  • この値はJTAGを通じて読み出すことができると同時に、FPGAのロジックからも読み出せる

という特徴があります。

応用としては、

  • 設定値をタイムスタンプにしていつごろ作られたデザインかを知ったり、固有の値を書き込んで、バージョン管理に役立てる
  • ユーザ一人ひとりに異なる値を設定し、IPコアのライセンスの鍵にする

でしょうか。

JTAGのUSERCODEと似たようなものなのですが、FPGAのロジックとJTAGで同じ値が読み出せるというところがポイントです。USERCODEはFPGAのロジックからは読み出せません。

VivadoでUSER_ACCESSの値を埋め込むにはBitGenのオプションで指定する(つまり論理合成や配置配線を使わない)のですが、普通は、BitStreamを作るところのXDCファイルで、以下のように記述します。

① まずは、固定の値にする方法

set_property BITSTREAM.CONFIG.USR_ACCESS 0x12345678 [current_design]

② 次はタイムスタンプにして自動設定する方法です。

set_property BITSTREAM.CONFIG.USR_ACCESS TIMESTAMP [current_design]

いずれもXDCファイルに書いてGenerate BitStreamを行うというのがポイントです。

では、早速実験してみました。

実験に用いたのは、特殊電子回路株式会社製のArtix-7ボード

Artixboardt

USBからJTAGでコンフィギュレーションできるので便利です。

 

USER_ACCESSの値をロジックから読み出すには、USER_ACCESS2というコンポーネントをインスタンシエートします。

使い方はとても簡単です。

   USR_ACCESSE2_inst : USR_ACCESSE2
   port map (
      CFGCLK => CFG_CLK,       -- 1-bit output: Configuration Clock output
      DATA => CFG_DATA,           -- 32-bit output: Configuration Data output
      DATAVALID => DATA_VALID  -- 1-bit output: Active high data valid output
   );

このようにすると、CFG_DATAに32bitの値が出てくるので、これをユーザロジックで使えばよいのです。

さて、JTAGで読むにはどうすればよいでしょうか。

XILINXのドキュメントをさんざん探しましたが、JTAGではUSER_ACCESSを読むための命令はありませんでした。プライベート命令にあるのかと思い、ドキュメントに書かれていない命令も探しましたが、USER_ACCESSを読むための見つかりませんでした。

しかし、VivadoのHardware ManagerでFPGAを選択してProperties→REGISTERを開くと、確かにUSER_ACCESSが読み出されています。

User_accesse2_3

そこで、VivadoからMITOUJTAGを通じてJTAGにアクセスするようにして、その通過するJTAGのシーケンスを解析してみました。

その結果の核心部分がこちらです。

STATE RESET;
SIR 6 TDI (05) TDO (35);
SDR 160 TDI (0000000400000004800580140000000466AA9955) TDO (00000004800580140000000466AA995500000000);
SIR 6 TDI (04) TDO (35);
SDR 32 TDI (00000000) TDO (1E6A2C48);

SIR 6 TDI (05)はCFG_IN命令、(04)はCFG_OUT命令です。

解析してSVFに落とし込んだシーケンスをMITOUJTAGで再生してみると、

User_accesse2

ばっちり見えました。

つまり、JTAGの命令で読み書きするのではなく、BitStreamのコマンドをJTAGポートから与えて、読み書きするのです。なお、BitStreamコマンドの 0000000400000004800580140000000466AA9955 というのは、

  • SYNC
  • NOP
  • READ (0x0d)
  • NOP
  • NOP

で、コンフィギュレーションレジスタの0x0d、つまりAXSSレジスタを読むものです。

このように、JTAGのコマンドにない機能は、JTAGからBitStreamコマンドを送り込むことで間接的にアクセスし、知ることができるようです。

JTAGの応用が広がりますね!

| | コメント (0)

2018.11.14

Gitがファイルの日付を管理しない問題を何とかしたい(1)

gitで様々なプロジェクトを管理したいと思っているのですが、gitに上げて戻すと、ファイルの日付がcloneした日付に変わってしまいます。

これでは困ることがあります。

  • 目的のファイルがいつ頃作られたものなのかわからない
  • ファイルの更新日時でソートできなくなる
  • 長い間更新されていないファイルを探せなくなる
  • ファイルが更新されたかどうかをWindowsの機能だけで見つけられなくなる

Git2

確かに、ソースコードマネージメントの考え方から言えば、日付で管理したり比較するというのは邪道なのでしょう。

ブランチを切ったり、commitの際にコメントを付けろと言われそうですが、本当にそれで十分でしょうか?

ソースコードの更新履歴やコメントで辿るというのは素晴らしいことだとは思いますが、本当にそれだけで十分でしょうか。

コメントなんて最初は真面目に書いていても、そのうちtempとかtmptmpとか、hogeとかそんなものになっていくでしょう?ファイル名に"-最新"とか、"-20181113"とか付けるのと大して変わらない。

ファイルの更新日時は、プロジェクトの中で目的のファイルがいつ頃に作業していたかとか、ファイルの作成された順序を教えてくれます。これは貴重な情報です。

それに、Windowsのエクスプローラに備わった一覧表示を見て、ファイルの更新の有無や、日付でソートできることの便利さは手放せません。わざわざgitというツールに頼らなければ何もわからないのは不便ではありませんか?

Git1

ちょっと探したいときに、毎度毎度GIT CMDでコマンドを打ちますか?

フォルダだけで見えるのは、最高。

だからgitの「日付は管理しない」というポリシーには頷けません。

gitでcloneしたときに、日付が変わってしまって不便しているという人はほかにもいるようです。

1番目の方はcommitするときに日付を格納したファイルを別途作る方法で、2番目と3番目の方は、cloneしたファイルをスクリプトを使ってコミット時刻にまで戻す方法です。

gitはファイルの更新日時を保存していないのですが、コミット日時は保存しています。したがってせめて、コミットした日まで戻そうというわけです。

ただ、これにも問題はあります。

新しいプロジェクトを作ってgitで管理するのならばそれでいいのですが、既に10年以上前からあるプロジェクトを今からgitで管理すると、すべてのファイルがfirst commitの時点(つまり、現在)のタイムスタンプになってしまうのです。

これではやはり困ることになります。

そこで考えたのが、「commitする時だけ、システムの時刻を過去に戻そう」というやり方です。

実際にツールを作ってみました。

Win32APIのFindFirstFileでディレクトリを再帰的に調べて、すべてのファイルを1つずつgit addして、時間を戻してからgit commitします。

ファイルの数だけcommitするので、commit回数がすごいことになります。

サンプルとして、RXマイコンにUSBで書き込むという2012年ごろのプロジェクトフォルダ一式をgit化してみました。

https://github.com/tokuden/rxprog

Git3

過去に作ったプロジェクトではありますが、ちゃんとcommit日時が過去を指すようになりました。

作ったプロジェクトをgithubに上げておきます。

https://github.com/tokuden/ttgac/

原理的には動作することが確かめられたので、

  • cloneやfetchしたファイルの日付をcommit日時に戻す機能
  • 前回のcommitから変更のあったファイルをaddしてcommitする機能
  • システムの日付全体を変更するのではなく、起動するgitだけ異なる日付で動くsandbox的な環境を作ること

などの機能を拡充していこうと思います。

特に3番目の機能は重要です。Windowsは裏で様々なバックグラウンドタスクが動いているので、システムの日付を変えるのは大変危険です。このツールを安全に利用するには、APIのフックを利用して、呼び出される子プロセス(git)からだけ過去の日付として見えるようにする方法が必須と思っています。

このツールはTrueTime Git Add and Commitなのでttgacという名前ですが、語呂が悪いのでgitttにしようかと思います。

この考え方がgitユーザの皆様の逆鱗に触れれば幸いです。

| | コメント (0)

2018.11.12

VivadoのJTAG書き込みではPAUSE DRステートを使う

一週間ほど悩んできた、「VivadoからMITOUJTAGを経由してXILINX FPGAに書き込む」というテーマがようやく完成に近づいてきました。

MITOUJTAG(みとうジェイタグ)を使ってターゲットボードとJTAGでつなぎながら、Vivadoから遠隔操作できるようにしようとする計画です。

今日、ついにVivadoからUltraScale+のJTAG書き込みに成功しました。

Vivadomjuscale

いままでうまくいかなかった原因は、Vivadoの書き込みシーケンスがJTAGのPAUSE DRステートというマイナーなステートを使っていたところにありました。

Ultra96ボードへの書き込みは

SDR 44549344 TDI (00000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000000400

というふうに44.5Mバイトのビット列をシフトして送り込むのですが、Vivadoでは1Mbitくらいの単位に区切って複数のSHIFT操作で送り込んでいるのです。

そのときに使われるのがPAUSE_DRというステートです。

Pausedr

PAUSE_DRステートを通ることで長いSHIFT動作を複数のSHIFTに分割したり、SHIFTの途中でダミーのクロックを与えたりすることができるのですが、VivadoがこのPAUSE_DRを使っている理由はわかりません。

DigilentのHSケーブルを使ってVivadoから操作したときにもPAUSE_DRは通っているので、ケーブルの種類によらずPAUSE_DRは使っているようです。

ただ、SVFを出力させたときにはPAUSE_DRを使わないような手順ができるので、PAUSE_DRを使うことはFPGA書き込みの本質ではないものと思われます。

実際の波形を示します。青い線がTMS、黄色がTCKです。TMSが1に上がっているところがPAUSE_DRになっているところです。

最初の波形は、SHIFT_DRを抜けてEXIT1_DRに入るところです。

Exit1dr

最後のパルスでTDOがハイインピーダンスに開放されるのが見えています。

次は、EXIT1_DR、PAUSE_DR、EXIT2_DRを経由してSHIFT_DRへと戻るところです。

Pause

最初の3つのパルスでステートが遷移して、その後の詰まっているクロックの部分がデータのシフトです。

Artix-7でも同様に書き込みができるようになったので、シーケンス的にはこれで問題ないのでしょう。

MITOUJTAG経由でVivadoが使えるメリットは、

  • バウンダリスキャンで端子の状態が見える
  • MITOUJTAGのバウンダリスキャンロジアナで、全端子の状態が波形にできる
  • コンフィギュレーション失敗したときの原因が究明できる
  • Vivadoのロジアナを使って高速信号が見える

など、いいとこどりになるのです。

| | コメント (0)

2018.11.06

UltraScale+のJTAG RESETは余分なTCKを必要とする

VivadoからMITOUJTAGを介してUltraScale+を認識しようとしたとき、リセット後のデバイスを検出できないという問題がありました。

Usjtag1

Digilentケーブルを使っていればこの画面にUltraScale+本体とARM DAPが出てくるのですが、MITOUJTAG経由だと出てきません。

この問題を徹底的に調査しました。

VivadoがUltraScake+を検出するときのJTAGのシーケンスは次のようになっています。
STATE RESET;
SDR 32 TDI (000000FF) TDO (28E20126);
STATE RESET;
SDR 1056 TDI (000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF) TDO (000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE28E20126);
SIR 192 TDI (FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) TDO (FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0751);
STATE RESET;

ここで、28E20126というのは、UltraScale+のIDCODEを1bit左にシフトさせたもので、これはUltraScale+のDummy DAPが接続されていることに由来します。

まず、VivadoとDigilentのHSケーブルでUltraScale+を認識するところをオシロで見ましたが、MITOUJTAGでも同じシーケンスで出しているはずです。

Scope_6

問題は2回目のSTATE RESETにありました。

JTAGのTAPステートマシンはRESETステートに入るとリセットされるのですが、UltraScale+ではRESETステートで何発かの余分なTCKを与えないといけないのです。

実際にVivadoから送受信されたデータのログを見てみると、

最終送受信データの表示
tms: ff
11111111 01000000 00000000 00000000・・
tdi:
00000000 00001111 11110000 00000000・・
tdo:
11111111 11110110 01001000 00000100・・

と、TMSを1にしたまま、8回ものパルスを与えているのです。

この問題に対処して、RESETステートで複数回のパルスを与えてとどまれるようにしたら、

Usjtag2

ちゃんとリセット後にも2つのデバイスを認識してくれるようになりました。

普通のJTAGデバイスなら、RESETステートを通ってRUNTEST_IDLEに戻るにはTMS=1にしたままTCKに5回のパルスを与えるというのが「常識」ですが、UltraScale+の場合は6回以上のTCKを与えないとうまくいかないのです。

UltraScale+はPLやARM DAPにダミーのものが用意されていて、その切り替えに1クロックかかるからです。

これもまた、UltraScale+の仕様です。バグと言ってもいいと思います。

おそらく、MITOUJTAG以外のJTAGツールでは、SVFを実行してもUltrasScale+は思ったように動作しないでしょう。

また、UltraScale+の動作中にいきなりリセットしても、

Usjtag3_2

一瞬、Not programmedになりますが、Refresh Deviceの操作をすれば元に戻ります。

Usjtag4_2  

場合によっては、Refreshをしなくても勝手に戻ります。

Usjtag5

これで、VivadoからMITOUJTAG経由でJTAGアクセスするということが、ほぼ完璧にできるようになりました。

| | コメント (0)

2018.11.05

EXPARTAN-6Tの最終出荷

Spartan-6LXTを使ったPCI Expressボード「EXPARTAN-6T」の最後の1台を出荷しました。

Exp_2

発売開始してから約8年くらいで数百台売れました。

Exp_1

Kintex-7の登場で自社製のPCI ExpressコアよりもXILINXのIPを使ったほうが性能も品質も速度もよいので、だんだん需要が減っていったと思います。

PCI ExpressのDMAドライバもすべて自作して苦労した回路でした。CQ出版さんにはInterface誌にPCI Expressの連載記事を書かせていただき、書籍まで出させてもらった基板なのですが、最近は年に数台しか出ないうえにSATAやDDR2メモリ、USBなどがあり、検査にものすごく時間がかかってしまうので、思い切ってディスコンとしました。

Expartan_last

久しぶりに動かしたら、PCI Expressはもちろん、SATAも動きました。

Exp_sata_rdid

Exp_sata_dmard

何年も前の設計なのですが、ちゃんと動きました。

この基板をお買い上げいただいた皆様のプロジェクトが成功を収めることを心よりお祈り申し上げます。

| | コメント (0)

2018.11.04

VivadoとUltraScale+との間の通信を解析(2)

昨日の続きをやっております。

開発中の新しいバージョンのMITOUJTAGを使って、VivadoからUltraScale+へのJTAGアクセスを解析できたのはいいのですが、それを目で追っていると大変なので、SVFフォーマットで出力できるようにしました。

Svf_capture

それを見ると、かなりプライベート命令を使っているな・・という感想です。

アクセスの最初の部分を見ると、

SIR 16 TDI (902F) TDO (0411); // USER1
SDR 33 TDI (000000000) TDO (000000000);
STATE RESET;
SIR 16 TDI (7E4F) TDO (0411); // ???
SDR 33 TDI (000000000) TDO (060018202);
STATE RESET;
SIR 16 TDI (902F) TDO (0411); // USER1
SDR 18 TDI (1E000) TDO (38000);
SDR 77 TDI (00000000000000000152) TDO (00000000000000000548);
STATE RESET;
SIR 16 TDI (922F) TDO (0411); // USER3
SDR 18 TDI (1E000) TDO (38000);
SDR 77 TDI (00000000000000000152) TDO (00000000000000000548);
SIR 16 TDI (FFFF) TDO (0411);
SIR 16 TDI (903F) TDO (0411); // USER2
SDR 33 TDI (000000000) TDO (000000000);
SIR 16 TDI (FFFF) TDO (0411);
SIR 16 TDI (903F) TDO (0411); // USER2
SDR 43 TDI (000000000D2) TDO (00000000348);
SIR 16 TDI (FFFF) TDO (0411);
SIR 16 TDI (903F) TDO (0411); // USER2
SDR 7 TDI (18) TDO (60);
SDR 43 TDI (000000000D2) TDO (00000000348);
SIR 16 TDI (A32F) TDO (0411); // ????
SDR 97 TDI (0000000000000000000000000) TDO (0000000000000000000000000);
SIR 16 TDI (FFFF) TDO (0411);
SIR 16 TDI (0E4F) TDO (0411); // ????
SDR 33 TDI (000000000) TDO (000000000);
SIR 16 TDI (FFFF) TDO (0411);
・・・
SIR 16 TDI (824F) TDO (0751);
SDR 33 TDI (000000006) TDO (000000000);
・・・

となっています。USER1,2,3はILAなどの内蔵ロジアナを見るためのものだと思いますが、0x7E4F 0xA32F 0x0E4Fという秘密のプライベート命令なので何をやっているかわかりません。

ユーザガイドug1085にもug570にも記述はありません。また、BSDLファイルを解読しても、該当する命令はありません。自力で解析するしかなさそうです。

UltraScale+のJTAGコマンドは上位12bitがPS-PL系へのアクセスで、下位4bitがARM DAPへのコマンドなのですが、上記の解析結果からわかることは、

  • 0x7E4は何かの32bitのステータスレジスタ読み出しで、VivadoがJTAGでアクセスをするとそのステータスは変わる。
  • 0xA32は96bitのレジスタがつながる
  • 0x0E4は32bitのレジスタがつながる
  • 0x824は32bitのレジスタがつながる

ということです。

UltraScale+のリセット後にDummy DAPからARM DAPに切り替えるJTAG_CTRL命令は見つかりませんでしたが、PS TAPとPL TAPを分離して考えると、上記のプライベート命令というのは既知の命令の組み合わせの表現なのかもしれません。

そう考えると、0x7E4というのは011111 & 100100なので、JTAG_STATUSコマンドとPLに対する24というコマンドの組み合わせです。JTAG_STATUSコマンドでPS TAP Controllerのステータスレジスタが見えるはずです。下位6bit(PL)に対する0x24のコマンドは公開されていませんが、データレジスタ長を0にする命令かもしれません。

0x7E4の後で32bitのDRをスキャンして0x060018202という結果を得ていますが、

Pstap_status

と照らし合わせて、ビンゴじゃないかなと思います。

0xA32は101000 & 110010なのですが、これに該当する命令はありません。ですが、下位6bitの110010はFUSE_DNAコマンドの下位6bitと一致するので、FUSE_DNAを読み出しているのだろうと推測されます。一回しか試せなさそうですが、FUSE_DNAを書き込んで試してみたいところです。上位6bit(PS)に対する0x28もレジスタ長を0にするものかもしれません。

0x0E4は、000011 & 100100と読めるので、PSに対するPMU_MDM命令と解釈できそうです。

0x824は、100000 & 100100と読めるので、PSに対するJTAG_CTRLコマンドで、直後のSDRに6を与えているので、PS TAPとPL TAPとARM DAPを接続するようです。

まとめると

  • 0x7E4はPSのステータス読み出し
  • 0xA32はDNAの読み出し
  • 0x0E4はPMUのMicroblaze Debug Moduleへのアクセス
  • 0x824と続く0x00000006はJTAGチェーンの正常化

なのかと推測されます。

それ以外の902や903、922はUSER1,2,3コマンドで、ILAやVIOの有無を調べているのだと思われるので、重要ではなさそうです。

その他にもプライベート命令はFUSE関係でたくさん出てきましたが、すべて解読できました。

さて、Vivadoが起動した後は、ARMのDAPに対するコマンドが発行されるのが確認できました。

STATE RESET;
SIR 16 TDI (FFF8) TDO (0751);
SDR 36 TDI (000000008) TDO (000000000);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (08000019A) TDO (000000002);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (000000003) TDO (18000000A);
SDR 36 TDI (000000007) TDO (18000000A);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (000000784) TDO (000000002);
SIR 16 TDI (FFFB) TDO (0751);
SDR 36 TDI (000000007) TDO (000000782);
SDR 36 TDI (000000003) TDO (1A3B80022);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (008000784) TDO (000000012);
SIR 16 TDI (FFFB) TDO (0751);
SDR 36 TDI (000000007) TDO (008000782);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (010000784) TDO (223B80012);
SIR 16 TDI (FFFB) TDO (0751);
SDR 36 TDI (000000007) TDO (010000782);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (000000003) TDO (123B00082);
SDR 36 TDI (000000007) TDO (18000000A);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (008000004) TDO (000000002);
SIR 16 TDI (FFFB) TDO (0751);
SDR 36 TDI (400000010) TDO (008000002);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (000000004) TDO (123B00082);
SIR 16 TDI (FFFB) TDO (0751);
SDR 36 TDI (000000001) TDO (000000002);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (008000004) TDO (184030212);
SIR 16 TDI (FFFB) TDO (0751);
SDR 36 TDI (000000001) TDO (008000002);

というものですが、SIRの行にあるFFF8、FFFA、FFFBというのがコマンド、続く36bitのがデータです。

この解釈はARM Debug Interface Architecture Specification(https://static.docs.arm.com/ihi0031/c/IHI0031C_debug_interface_as.pdf)ににあります。

ARMのデバッグシステムは以下のような構造になっていて、

Arm_debug

FFF8が発行されるとABORT、FFFAはDPACC、FFFBはAPACCへの読み書きが行われます。

これが何を意味しているかの解読は別の機会にするとしましょう。

| | コメント (0)

2018.11.03

Ultra96(UltraZed)実践勉強会に参加しました

今日はUltra96実践勉強会に参加してきました。

DisplayPortをベアメタルで動かすというチームになりました。

考えるだけでも複雑そうなテーマなのですが、いろいろ触ってわかったことは、

  • ひでみさんやikwzmさんのLinux、デフォルトのLinuxでは、Linux起動時にDisplayPortは有効になっている
  • U-Bootの時点ではDisplayPortは有効ではない
  • PLにJTAGで書き込んでいる最中でもDisplayPortは表示され続けている

ということでした。

このことから、

  • DisplayPortは、Linuxのドライバによってレジスタが初期化され、設定されて、動作するようになっている
  • PLの力を借りず、PSだけで動ける

ということがわかります。

LinuxのドライバでDisplayPortっぽいものは、

  • /linux-xlnx/drivers/gpu/drm/xlnx/zynqmp_disp.c
  • /linux-xlnx/drivers/gpu/drm/xlnx/zynqmp_dp.c
  • /linux-xlnx/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
  • /linux-xlnx/drivers/gpu/drm/xilinx/xilinx_drm_drv.c
  • /linux-xlnx/drivers/gpu/drm/xilinx/xilinx_drm_dp.c
  • /linux-xlnx/drivers/gpu/drm/xilinx/xilinx_drm_dp_sub.c

があります。

xilinxと書かれたほうのフォルダは2014年ごろのファイルなので、Kintex-7とLogiCOREを使ってDisplayPortを実現していたもので、xlnxになっているほうがおそらくZYNQMPのものだと思われました。

ただ、それでも3000行くらいあるし、解析して、プログラムのエッセンシャルな部分を抜き出して短い時間内にデモプログラムを仕上げるのは無理そうです。

そんなとき、小林さんが教えてくれたのが、AR# 71416「2018.1/2 Zynq UltraScale+ MPSoC: ベアメタル DPDMAP のサンプルをシングル レーンの DisplayPort でコンフィギュレーションできるようにする方法」

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

というものです。

ここに載っている方法を使って、DisplayPortがあっさり動きました。(私のUltra96ではboot.binの作り方が悪くてうまくいきませんでしたが、いずれ再挑戦します)

ただ、画面が黒一色なので、AXI StreamかDPDMAを使って何かの画像を送り込んでやらねばならないのだと思います。

ZYNQMPはGPUを積んでいるはずですが、Linuxの文字の表示がZYNQ7000と大して変わらないのが気になっていました。

ZYNQMPのLinuxでも、フレームバッファを作っておいて、フレームバッファからDisplayPortコントローラへDMDMAして表示しているのではないかと思われます。

機会があれば、

  • /linux-xlnx/drivers/dma/xilinx/zynqmp_dma.c

あたりを読んでみようかと思います。

いろいろな人と話ながらFPGAが触れて、とても楽しかったです。

| | コメント (0)

VivadoとUltraScale+との間の通信を解析

前の記事で書いたとおり、VivadoからFPGAへのJTAG通信にMITOUJTAGを通すことができるようになったので、どのようなシーケンスが流れているのかを解析してみることにしました。

Xvcs_zu_2

VivadoからのJTAGシーケンスは、TMSやTDIをどのように動かすかという10の羅列なので、TAPコントローラをどのように動かすか、どんなデータがシフトされるかを解析できるようにしました。

Bscan_capture

最初に

tdi=000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF

というシーケンスを送って、IDCODEが返ってくるのを見ています。

次に、

tdi=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE

という長いシーケンスをIRに流して、FFFE0751が返ってきているのですが、IRの長さを測っているのかもしれません。最後のEはARMコアに送るIDCODEのコマンドなので安全です。

次にtdi=902FをIRに流し、その後、DRを33bitスキャンしてます。902はUSER1のコードなので、ILAなどが入っているかを見ているのかもしれません。DRの戻り値は00000000です。

その次は、7E4FをIRに流してから、DRを33bitスキャンしていますが、7E4に該当するコマンドは不明です。返ってきたデータは6001C67Aですが、右1ビットシフトさせて読むと、3000E33Dなります。

何でしょうね。

次に再びtdi=902FをIRに流し、その後、DRを18bitスキャンしてます。USER1のコードですが、DRに1E000を入れて戻り値は38000ですから1bitシフトしているだけでした。

| | コメント (0)

2018.11.02

オフィスのパソコンを処分

今の本郷オフィスを12月中旬に退去することにしました。

ありし日のオフィスを再現した写真です。

Office1

Office2_2

ここに最大で10人ほどいました。

引っ越しのためには家具やパソコンを処分しないといけないのですが、パソコンは業者さんに引き取ってもらうことになりました。

Office3_2Office4

1年以内に買ったパソコンはだいたい定価の30~40%、3年以内のは20~30%で買い取ってもらいました。モニタは500円~2000円くらい。二束三文ですが、結構な高く買い取ってもらえたなと思います。

ちなみに、まだ残っているアルバイトさんのパソコンと、Displayport対応のモニタはまだ残っています。

すっかり綺麗になったオフィスです。

Office5

これから机と本棚、パーティションなどの処分を始めます。

オフィス家具リサイクルの業者さんに問い合わせてみましたが、机などのオフィス家具は売っても値段が付かない、つまりこちらが業者に費用を出して処分となるので、欲しい方がいたら差し上げます。

  • スチール製オープン書架 幅88cm×高さ180cm×奥行40cm ・・5個
  • スチール製平机 幅120cm、高さ70cm、奥行き70cm ・・8台
  • 観葉植物 1mくらいの常緑樹。2個
  • 空気清浄機 1台
  • ミニ冷蔵庫 1個

ただし、本郷まで取りに来れる方限定です。軽トラとか台車でお越しください。

ご希望の方は nahitafu@nifty.com か、twitterの@nahitafu までご連絡ください。

| | コメント (0)

2018.11.01

VivadoからMITOUJTAGを介してUltraScale+にJTAGアクセス

Vivadoから開発中の新しいバージョンのMITOUJTAGを介してUltraScale+にJTAGアクセスできるようになりました。

Vivado_mitoujtag

温度と電圧くらいは見えていますが、まだかなり不安定なので、ちょっとしたことをすると切れてしまいます。

例えば、Vivado+Digilentケーブル、あるいはVivado+Platform Cable USBならばUltraScale+をリセットしても復帰できるはずですが、

WARNING: [Labtools 27-3361] The debug hub core was not detected.
Resolution: 
1. Make sure the clock connected to the debug hub (dbg_hub) core is a free running clock and is active.
2. Make sure the BSCAN_SWITCH_USER_MASK device property in Vivado Hardware Manager reflects the user scan chain setting in the design and refresh the device.  To determine the user scan chain setting in the design, open the implemented design and use 'get_property C_USER_SCAN_CHAIN [get_debug_cores dbg_hub]'.
For more details on setting the scan chain property, consult the Vivado Debug and Programming User Guide (UG908).
refresh_hw_device [lindex [get_hw_devices xczu3_0] 0]
CRITICAL WARNING: [Labtools 27-3421] xczu3_0 PL Power Status OFF, cannot connect PL TAP.  Check POR_B signal.
INFO: [Labtools 27-1435] Device xczu3 (JTAG device index = 0) is not programmed (DONE status = 0).

となって、復旧できません。

ただ、MITOUJTAGを通るということは、どのようなシーケンスが流れているのかを解析できるということです。

Xvcs_zu

このような感じで少しずつ解析を行っています。

| | コメント (0)

« 2018年10月 | トップページ | 2018年12月 »