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

2018.08.25

ZynqberryにRasPiカメラをつなでJupyterで表示

世の中にはたくさんの種類のZYNQボードがあります。

どんなZYNQボードでも、Jupyterや機械学習やSDSoCは動きます。

私は言いたい。

「PYNQにできることは他のZYNQボードにだってできる。」

PYNQ一辺倒の世の中に一石を投じ、脱PYNQ化を進めるため、ZynqberryにRaspberryカメラを接続し、画像をJupyter上で表示させてみることにしました。

Zynqberry(ジンクベリー)というのは、ドイツTrenzElectronic社が開発したZYNQボードで、その名のとおりRaspberry Pi形状のZYNQボードです。

Te072603m_0

ZynqberryはRaspiカメラ(V1.3)とHDMI出力をつなげることができます。

Zbcam

まず、公式サイト https://shop.trenz-electronic.de/en/TE0726-03M-ZynqBerry-Zynq-7010-in-Raspberry-Pi-form-factor のページにあるDownloadタブからReference Design→2017.1→zynqberrydemo1をダウンロードし、書き込んで動かします。

zynqberrydemo1のサンプルプログラムを動かすと、SDカード上にあるinit.shが起動され、その中で

rpicam /dev/i2c-5
devmem 0x43c10040 32 $rc

という2つのプログラムが動作します。

rpicamはTrenz社が作成したプログラムで、ソースはzynqberrydemo1\os\petalinux\project-spec\meta-user\recipes-apps\rpicam\files にあります。

Rpicam

中を見てみると、V1.3用のコードとV2.1用のコードがあり、解像度もいくつか用意されているようです。基本的にはI2Cのレジスタを操作してカメラの設定を行っています。

devmemは単体のプログラムではなく、busyboxの中の機能です。このコマンドは0x431c0040番地に1または3を書き込んで、VDMAの転送を開始します。

フレームバッファとビデオタイミングコントローラはFSBLで初期化され、RasPiカメラから取り込んだ画像が0x1FC00000に格納されます。

サンプルのzynqberrydemo1では0x1FC00000は画面に出力するバッファにもなっているので、カメラで撮った画像がそのままHDMIから出力されます。

zynqberrydemo1と3はRAMDISKで動くシンプルなLinuxなので、GUIのデスクトップは動きません。zynqberrydemo3は、カメラバッファと表示バッファが別々のアドレスなので、そのまま出力はされませんが、

dd if=/dev/fb1 of=/dev/fb0 bs=5120 count=720

で表示することができます。(ddすごい!)

使用したカメラは、秋月で購入しました。

Akizuki_cam

Zynqberryにはスタータキットというのがあり、Ubuntu Linux 14.04とJupyterが動くように作りこまれています。Trenz社のサンプルとはLinuxのディストリビューションが全く異なるのですが、zynqberrydemo1で使用されていたrpicamはUbuntu 14.04に持っていっても動きました。

devmemはbusyboxのコマンドなので、同等のものを/dev/memを叩いて動かすようにします。こうすることで、リッチなUbuntu LinuxでもRasPiカメラを動かすことができます。

int fd = open("/dev/mem", O_RDWR | O_SYNC);
uint32_t *vaddr = (uint32_t *)mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x43c10000);
*(vaddr + 0x10) = 0x1; // 0x43c10040
munmap((void*)vaddr, 4096);
close(fd);

Linuxが起動したら、ddを使って/dev/fb1から生画像を得ることができます。

また、fbgrabというツールを使うことで、フレームバッファの中身をPNG画像として保存することもできます。

Fbgrab

fbgrabで画像を取得する時間は10秒くらいかかりました。結構遅いので、その間に手ブレすると歪んでしまいます。

Test

ddまたはfbgrabで画像が読み出せることがわかったので、Jupyter上で画像を表示させてみることにします。

ZynqberryでJupyterを動かす方法は「ZynqberryでJupyter notebookを動かそう!」 にあります。

書いたPythonのコードは

#for Zynqberry Stater kit (https://www.trenz.jp/product/TE0726-STARTER-KIT)
from PIL import Image
 
import matplotlib.pyplot as plt
import numpy as np
import subprocess

subprocess.call(["/usr/bin/fbgrab","-d","/dev/fb1","/tmp/grab.png"])
im = np.array(Image.open("/tmp/grab.png"))
plt.figure(dpi=100)
plt.imshow(im)

です。

このとおり、Jupyter上で、カメラ画像を表示することができました。

Zb_jupyter_camera

| | コメント (0)

2018.08.24

Spartan-7ボードを設計しています2

Spartan-7ボードですが、FPGAを45度回転させることで配線がすっきりし、ここまでできました。

Sp7brd2

USBのコネクタは最近流行りのMicro-Bにして、EZ-USB FX2を使って480Mbpsの速度を出します。UARTではないので画像も流せるほど高速です。

9月中に試作が完了し、発売開始できるのではないかと思います。

| | コメント (0)

2018.08.23

Spartan-7ボードを設計しています

特電のアルバイトさんが、Spartan-7ボードを設計してくれています。

Sp7brd

名刺サイズで、XC7S50を中心にDDR3メモリとUSB2.0が乗っていて、40ピンx2のコネクタから64本のI/Oを取り出せます。

2.54ピッチなので、万能基板に乗せてケーブルを引き出すことができる、試作用途に使いやすいボードになります。

メザニンコネクタではないので、ユーザが拡張するのにわざわざ基板を起こす必要がありません。それに、PMODでもないのでたくさんのI/Oが使えます。

USB2.0は、遅いUARTではなく、40MByte/secが出る生のHighspeed(デバドラあり)なので、画像の転送にも使えます。

さて、Spartan-7は、コア電源1.0VとAUX電源1.8Vを必要とし、DDR3メモリを使うには1.5Vが必要になります。また、入出力にLVDSを使う場合はこれに加えて2.5Vが必要になります。

そういうわけでこの基板は5種類の電源が使われることになりますが、VCCAUXの1.8Vって何に使うのでしょう。

FPGAが空のときは20mA程度ですが、PowerEstimaterを使って調べてみるとDDR3を動かしたデザインでは250mA程度消費します。

たぶん、コアの1.0Vロジックと外部のVCCIOのバッファの間に入って信号を中継するバッファに使われているのではないかと思うのですが、いまいちわかりません。

| | コメント (0)

2018.08.22

ZYNQ UltraScale+のJTAGに異常を発見

Ultra96ボードを入手して、さっそくやってみたことはJTAGのテストです。

Uscale1

ボードから12Vの電源と、JTAGの配線を引き出してテスト開始です。

MITOUJTAGで認識させてみると、XCZU3しか見つかりません。実際にはXCZU3のほかにARMのDAPというのがつながっているので2個のデバイスが見つかるはずなのですが・・

そこで、SVFプレイヤーを用いて

STATE RESET;
STATE IDLE;
SDR 128 TDI (00000000000000000000000000000000) TDO (00000000000000000000000000000000);

というコマンドを実行して、JTAGの低レベルなデバッグをしてみると、XCZU3のIDCODEが1bitずれたものが読み出されました。

ARM DAPのDRが1bitになっていて(ZYNQ7000では32bitあった)、JTAG IDCODEが存在していないことがわかります。これは、ちょっと問題です。ARM DAPのIRは4bit長なので規格どおりですが。

この点は、ARM DAPのBSDLを作成して手動で追加すれば何とかなりました。

MITOUJTAGのバウンダリスキャンで、端子のI/Oが見えているように見えます。

Uscale2

また、端子のAA3、AA4あたりをEXTESTで動かすとLEDがチカチカするので、MITOUJTAGから操作もできていることがわかりました。

Uscale3

しかし、問題はここからです。基板上のSW4を押してもそれに相当する端子の状態が変化しないのです。

Uscale4

これはUltraScale+の持つJTAGのバグではないかと思います。

本来、JTAGバウンダリスキャンでは、I/Oパッドから入力した値は入力セルから読み出されます。

Bscan1_2

しかし、コンフィギュレーションされたUltraScale+では、なぜか出力セルから読み出されます。

Bscan2

これが仕様なのか設計ミスなのかわかりませんが、JTAGの動作としては間違っているように思われます。

なお、バウンダリスキャンセルを手動で書き換えて、出力セルの値を見るようにすると、一見正しい動作をするのですが、FPGAが出力する値を読めなくなってしまうので、これも正しくありません。

Bscan3

BSDLファイルが間違っているというわけではなく、チップレベルで間違っているようです。

それから、DDR4メモリの端子が全く動いていないことも気になります。Ultra96ボードのデフォルトのSDカードでは、DDRメモリは使用していないのでしょうか。

| | コメント (0)

2018.08.21

UltraScale+用のJTAG書き込みアルゴリズム

AVNETのUltra96ボードを買いました。

Ultra96

私がやるべきことは、UltraScale+のJTAGコンフィギュレーションの仕組みを解析することだと思います。

参考にしたのは、Vivado Design Suiteユーザガイド(ug908)と、UltraScale アーキテクチャ コンフィギュレーション ユーザー ガイド (UG570)です。UG570にはJTAGコンフィギュレーションの仕組みは書いてありますが、実際にどういうシーケンスで動作させるかの実例がないと、不安要素はぬぐえません。

そこで、VivadoにSVFファイルを生成させてみることにします。SVFファイルの生成方法は、UG908の77ページあたりに書かれています。

とりあえずVivadoでZU2CGの適当なデザインを作り、Tclコンソールから下記のように入力します。

open_hw
create_hw_target my_svf_target
open_hw_target

このコマンドを打つと、Hardware Managerがファイル生成モードで開き、VivadoにSVF Operationsという欄が出来ます。

このcreate_hw_targetというのが、SVF生成プログラムを起動するTclコマンドのようです。

Svf1

次に、

set device0 [create_hw_device -part xczu2cg]

とコマンドを打つと、JTAGチェーンにxczu2とarm_dapの2つのデバイスが追加されます。

(紫の部分は実際に使用するデバイスに合わせて変えます)

Svf2_2

以下のコマンドで書き込みたいビットストリームファイルを指定して、書き込み操作を指示します。

set_property PROGRAM.FILE {D:/naitou/uscale/uscale.runs/impl_1/main.bit} [get_hw_devices xczu2_0]
program_hw_devices -disable_eos_check [get_hw_devices xczu2_0]
write_hw_svf -force D:/naitou/uscale/uscale.runs/impl_1/my_svf_target.svf

ただし、SVFモードなので、実際にはデバイスに書き込まれず、SVFファイルが生成されます。

最後に

close_hw_target
close_hw

とやって、Hardware Managerを閉じます。

出来上がったSVFファイルは10Mバイト以上あるのですが、

TRST OFF;
ENDIR IDLE;
ENDDR IDLE;
STATE RESET;
STATE IDLE;
FREQUENCY 1.00E+07 HZ;
HIR 4 TDI (0f) SMASK (0f) ;
TIR 0 ;
HDR 1 TDI (00) SMASK (01) ;
TDR 0 ;
// config/idcode
SIR 12 TDI (0249) ;
SDR 32 TDI (00000000) TDO (04711093) MASK (0fffffff) ;
// config/jprog
STATE RESET;
STATE IDLE;
SIR 12 TDI (090b) ;
SIR 12 TDI (0914) ;
// Modify the below delay for config_init operation (0.100000 sec typical, 0.100000 sec maximum)
RUNTEST 0.100000 SEC;
// config/jprog/poll
RUNTEST 10000 TCK;
SIR 12 TDI (0914) TDO (0011) MASK (0031) ;
// config/slr
SIR 12 TDI (0905) ;
SDR 44549344 TDI (00000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000
・・・
・・・
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ;
// config/start
SIR 12 TDI (0249) TDO (0031) MASK (0011) ;
// config/status
STATE RESET;
RUNTEST 5 TCK;
SIR 12 TDI (0905) ;
SDR 160 TDI (0000000400000004800700140000000466aa9955) ;
SIR 12 TDI (0904) ;
SDR 32 TDI (00000000) TDO (3f5e0d40) MASK (08000000) ;
STATE RESET;
RUNTEST 5 TCK;

となっています。

この動作を解説すると、まずHIRとHDRでARM_DAPをBYPASSする設定を与え、次にIDCODEをチェックしています。

090bはJPROGRAMコマンドで、PROG_Bピンと同等の働きをします。その後、0914のISC_NOOP命令(動作なし)に切り替えて、0.1秒待ちます。

再びISC_NOOP命令(914)を行い、IRの下位6bitが01XXX1であることをチェックしています。このbit5はDONEピンの状態を表していて、bit4は内部INITピンの状態を表しています。

つまり、DONE=0で現在のコンフィギュレーションが消えていること、INITで初期化状態であることを確認しています。

次の0905はCFG_INコマンドで、このコマンドを与えた後でJTAGのTDIからBitStreamを流し込めば、コンフィギュレーションが行われます。

次に0249(IDCODE)命令を行っていますが、特にIDCODE命令である必要はないようです。そのときのIRの状態を見て、DONE=0、INIT=1であることを確認しています。

そのあとで、CFG_INとCFG_OUTを実行して、0000000400000004800700140000000466aa9955を送って、3f5e0d40であるかどうかを確認しています。

それでは、0000000400000004800700140000000466aa9955という呪文のようなワードは何かというと、以下のように読みます。

  • 66aa9955・・同期ワード
  • 00000004・・NOOP
  • 80070014・・レジスタ7(ステータスレジスタ)を1ワード読む
  • 00000004・・NOOP
  • 00000004・・NOOP

つまり、FPGAのコンフィギュレーションレジスタのステータスレジスタを読んでいるようです。ステータスレジスタの値としてチェックしている3f5e0d40というのは逆から読むので、0x02b07afcとなりますが、DONEピンや、GHIGH、GWEなどのビットを確認しているようです。

Statreg

ただし、08000000でマスクしているので、実際にチェックするのはEND_OF_STARTUP_(EOS)_STATUSだけのようです。

ところで、-disable_eos_checkを付けても付けなくても結果は変わらないので、このオプションは効いていないようです。

ただ、これではJSTARTが実行されていないので、FPGAは起動しないような気がするのですが、良いのでしょうか?

おそらく、Vivadoのバグではないかと思います。本来は、

// config/start
SIR 12 TDI (0249) TDO (0031) MASK (0011) ;

ではなく、

// config/start
SIR 12 TDI (090C) ;

ではないかと思います。

disable_eos_checkのオプションが効かない点と、JSTARTが含まれていないので、Vivadoも完璧ではないのかもしれません。

明日にでもVivadoの出力したSVFでコンフィギュレーションできるかどうか、検証してみたいと思います。

| | コメント (0)

2018.08.18

高位合成のお勉強

私もZynqberryでSDSoCで高位合成の勉強を始めることにしました。

ADCやDACを扱いたいので、AXI Streamを入力して、AXI Streamを出力したりAD変換データを処理するようなコアをC言語で作りたいと思います。

まずは、入力を出力にそのまま出すだけのコア「pass_through」を作ります。

SDSoCでAXI Streamを扱うには、AXI-4 Stream Data FIFOを置くようです。

入力側(SDSoCのにとってのデータソース)をaxis_data_fifo_0とし、出力側をaxis_data_fifo_1としました。そして、そのポートに

set_property PFM.AXIS_PORT { M_AXIS {type "M_AXIS"} } [get_bd_cells /axis_data_fifo_0]
set_property PFM.AXIS_PORT { S_AXIS {type "S_AXIS"} } [get_bd_cells /axis_data_fifo_1]

でアトリビュートを設定し、DSAファイルを作成します。

SDSoCのプログラムでは、

#pragma SDS data sys_port (A:axis_data_fifo_0_M_AXIS)
#pragma SDS data sys_port (B:axis_data_fifo_1_S_AXIS)
//#pragma SDS data copy(A[0:32], B[0:32])
#pragma SDS data zero_copy(A[0:32], B[0:32])
void pass_through(unsigned long *A, unsigned long *B)
{
#pragma HLS INLINE
#pragma HLS interface axis port=A
#pragma HLS interface axis port=B
	unsigned long A_in;
	A_in = *A;
	*B = A_in;
}

Sdsoc_axis_1

とします。

#pragma SDS data sys_port の引数の部分にモジュール名_ポート名を書くと、そのポートにつながるようです。

こんなものでいいのかと思ったのですが、作られた回路を見ると、

Sdsoc_axis_2

pass_through_1_ifというモジュールが作られていて、pass_through関数の入力と出力をラップしているように見えます。

SDSoCが作ったと思われるコードを見てみると、

Sdsoc_axis_3

・・・

作りたかったものは、こうじゃない。

シンプルなデータパスルーでさえ、簡単には作れません。(;ω;)

覚書として、プラットフォームを作成するときに使用したプロパティの設定などを書いておきます。

set_property PFM.AXIS_PORT { M_AXIS {type "M_AXIS"} } [get_bd_cells /axis_data_fifo_0]
set_property PFM.AXIS_PORT { S_AXIS {type "S_AXIS"} } [get_bd_cells /axis_data_fifo_1]

set_property PFM_NAME "tokudenkairo.co.jp:zbstd:zbstd:1.1"\
[get_files [get_property FILE_NAME [get_bd_designs]]]

set_property PFM.CLOCK { \
 clk_out1 {id "2" is_default "true" proc_sys_reset "proc_sys_reset_0" } \
 clk_out2 {id "1" is_default "false" proc_sys_reset "proc_sys_reset_1" } \
 } [get_bd_cells /clk_wiz_0]
 
set_property PFM.AXI_PORT { \
M_AXI_GP1 {memport "M_AXI_GP"} \
S_AXI_ACP {memport "S_AXI_ACP" sptag "ACP" memory "processing_system7_0 ACP_DDR_LOWOCM"} \
S_AXI_HP2 {memport "S_AXI_HP" sptag "HP2" memory "processing_system7_0 HP2_DDR_LOWOCM"} \
S_AXI_HP3 {memport "S_AXI_HP" sptag "HP3" memory "processing_system7_0 HP3_DDR_LOWOCM"} \
} [get_bd_cells /processing_system7_0]

set intVar []
for {set i 2} {$i < 16} {incr i} {
lappend intVar In$i {}
}
set_property PFM.IRQ $intVar [get_bd_cells /xlconcat_0]

write_dsa -force d:/zbstd/zbstd.dsa

| | コメント (0)

2018.08.16

セキュリティキャンプ2018の講師を努めました

セキュリティ・キャンプ全国大会2018で講師を務めてまいりました。(写真は公式Twitterや掲示板の画像から引用)

Seccamp1

今年はフィジカルレイヤーという物理層レベルのセキュリティのトラックが新設され、その講師に任命されたので、私の専門であるJTAG(ジェイタグ)について講義と実習を行ってきました。

Seccamp2

添付の写真のような基板を受講者に渡して、JTAGのビット列を解読したり、解読したビット列をもとにEXTESTを使ったLEDをチカチカさせたりといった演習となりました。

Seccamp3

Seccamp4

Seccamp5

当日朝まで徹夜でパワポをまとめたり、ソフトをデバッグしたりで大変でしたが、4時間の講義が終わったときのやり遂げたという解放感はひとしおでした。

Seccamp6

| | コメント (0)

2018.08.13

特電のオフィスに会議室兼セミナールームを設置しました

アルバイトさんに手伝ってもらって、特電のオフィスに会議室を設置しました。

特電のオフィスはワンフロアになっています。

まず、この雑然とした一角を片付けて・・

Before_2

本棚を動かして小部屋を作りました。

After1

本棚に隠れていた窓にもアクセスできるようになりました。(夜なので閉まっていますが)

After1_2

圧倒的、予備校の自習室感

いや、進路相談室かもしれない


大きなテーブルを出せば10人くらいまでなら一度に入れそうです。お昼ごはんを食べたり、軽作業をしたりする小部屋としても使えそうです。

小さなセミナーは自社で開催できるようになりました。Cosmo-Zセミナーなど機材の多いセミナーや、はんだごてが必要になるセミナーは、自社オフィスでやっていきたいと思います。

| | コメント (0)

2018.08.11

MITOUJTAGからMAX10に書き込む方法

XILINXとALTERAのデバイスが同一のJTAGチェーンにつながっている場合に、MITOUJTAGから書き込む方法を紹介します。

まず、Qualtus PrimeでMAX10のデザインを作ります。

Qp_1

QualtusのToolsからProgrammerを起動します。

Qp_2_2

QualtusのProgrammerが起動したら、いちど、まっさらな状態にします。

Qp_20

Add Fileを押して、MAX10の出力したファイルを選択します。

MAX10の内蔵ROMに書き込みたいならPOFを選び、揮発性のコンフィギュレーションをしたいならSOFを選びます。

Qp_8

下の図はPOFを選んだ場合の状態です。

Qp_6

次に、同一チェーン上にあるXILINXデバイスを追加したいのですが、当然ながらALTERAのツールはXILINXデバイスを認識しません。

そこで、Add Deviceボタンを押します。

どのデバイスを追加するかを聞かれるので、Importボタンを押します。

Qp_3

ファイル名を入力するダイアログが出るので...ボタンを押します。

Qp_4

D:\Xilinx\Vivado\2018.1\data\parts\xilinx\spartan7\public\bsdlディレクトリを指定し、中にあるxc7s25_csga225.bsdを指定します。

Qp_5

XC7S25が使用できるようになりました。

Qp_7

下の図のように、XILINXとALTERAがJTAGチェーンでつながります。

もし、順番が逆になっている場合にはUpボタンを押します。

Qp_9

次にMITOUJTAGから書き込むために、SVFというファイルを作ります。SVFを作るにはProgrammerのFileからCreate JAM JBC、SVF or ISC Fileを行います。

Qp_12_2

デフォルトでは、下の図のようにjamファイルになっているので、

Qp_14_2

これを選択して、

Qp_11_2

SVFファイルに変更します。また、TCKを1MHzに変更します。(これを行わないと遅くなる)

Qp_13

OKを押します。

Qp_16

これでSVFファイルができました。SVFファイルというのはこのような感じのテキストファイルです。

Qp_10

この中に、Spartan-6とMAX10がチェーンになった場合のMAX10書き込みシーケンスが入っていて、そのまま実行すれば書き込まれるようになっています。

そうしたら、MITOUJTAGを起動して、[ツール]→[SVFプレイヤー]を起動します。

Qp_17

先ほど生成したSVFファイルの中身を貼り付けます。

Qp_18

ここで開始ボタンを押すと、SVFが実行されて、MAX10に書き込まれます。

Qp_19

無事に書き込みが行われ、MAX10が起動しました。

Max10_write_success

下の図は、MAX10につないだシリアルADCを操作して、半固定抵抗の値やマイクで拾った音声を、JTAGロジアナで波形として表示しているようすです。

Max10_adc

Max10_adc2

特にWindowsのソフトウェアを組むことなく、FPGAのピンからバイナリの値を出せば、MITOUJTAGのロジアナでそれを拾って、アナログ波形として表示できます。

このやり方は、FPGAやWindowsのソフトを作らなくてもよいので楽ですよ。

| | コメント (0)

2018.08.10

JTAGチャレンジ基板の実装が上がってきた

わざと間違いを作りこんでおいて、JTAGバウンダリスキャンでそれを発見するという「JTAGチャレンジ基板」の初期ロット12台が上がってきました。

Jtag_challenge_12

Jtag_challenge

Jtag_challenge_sm

Jtag_challenge_rx

とりあえずは、JTAGケーブルを接続してSpartan-7とMAX10が認識されました。

Jtag_challenge_bscan

この画面が出れば電源とJTAGは正常であることが保証されるので安心できますね。

よく見るとエラーになっていますが、MAX10は書き込み前だとINSTRUCTION_CAPTUREレジスタの値が変わるという変な仕様のためです。

最初は動かなくてかなり焦りました。まさか、こんな罠があるとは・・

これから動かないことを確認します!

| | コメント (0)

2018.08.09

Digilentのボードを片っ端からスキャンしてみた

MITOUJTAGのDigilentプラグインができたので、手元にあるDigilent製ボードを、MITOUJTAGで片っ端からバウンダリスキャンしてみました。

まずは、Artyです。ArtyはXC7A35TのCSG324が乗っているFPGAボードです。

Arty_a7

自動認識すると同じIDCODEのデバイスの候補が見つかるので、この中で324ピンのものを選びます。

Arty_detect

Artyが動作しているときの、Artix-7の端子の状態です。

ピンクはHレベル、水色はLレベル、塗りつぶしは出力、網掛けは入力の状態を表しています。

Arty_bscan

ArtyにはSPI ROMが乗っているようで、MITOUJTAGからSPI ROMを認識することもできました。

Artyspirom

Artyが起動するときのSPI ROMの端子の動きや、起動後のLEDチカチカの信号も見えました。

Arty_logana

次はSpartan-7が乗ったArty-S7です。Artyとの大きな違いは、Etherのコネクタが無いことです。

Arty_s7

こちらも自動認識すると、同じIDCODEのデバイスが見つかります。この中で324ピンのものを選びます。

S7_detect

端子の状態もばっちり見えました。

S7_bscan

Arty-S7のデフォルトのLEDチカチカはPWMがかかって、じわりじわりと点滅します。そのようすがJTAGロジアナでも見えています。

S7_logana

最後はZYBO-Z7です。

ZYBOは初期のころの評価ボードなので画面出力がVGA端子だったりしますが、その後HDMI出力やCSIカメラが付いたZYBO Z7というのが出ました。

Zybo_z7

FPGAもXC7Z020にアップグレードされています。

Z7_detect

自動認識すると、ARMコアとFPGAコアの2つのデバイスが見えます。

Z7_bscan

LEDチカチカのPWMもよくできています。

Z7_pwm

様々な端子の信号を見るとこのような感じになっています。

Z7_logana

MITOUJTAGは、他社製ボードであっても使えます。デフォルトのサンプルデザインが動いている状況でも使えます。つまり、FPGAに何もIPを書き込む必要がありません。

FPGAの起動前であっても信号が見えるので便利ですよ。

組み込みの世界にバウンダリスキャンを普及させたMITOUJTAGについて詳しく知りたい方は、こちらをクリックしてください↓

MITOUJTAGについて詳しく

| | コメント (0)

2018.08.08

MITOUJTAGのDigilentプラグインを作成

Digilent製ボードでMITOUJTAGが使えるようにするため、プラグインを作っています。

ようやくDigilent USB-JTAGの使い方を理解して、MITOUJTAGから使えるようにできました!

まずは、ZYBOとパソコンをつなぎます。ZYBO上のUSB-JTAGで通信するので、USBケーブル1本だけです。

Zybo_3

これでDigilent製のボードはUSBをつなぐだけでI/Oピンや波形が見れるようになったわけなのですが、ZYBOが起動するときの波形をバウンダリスキャンのロジアナで見てみたら、毎秒4000サンプリングほど出ていました。つまり250usくらいのサンプリング周期のようです。

Zybo_bscan

JTAGロジアナで見てみると、DDR3メモリの動きなどが見えます。

Zybo_logana

実は今までのMITOUJTAGにもDigilent USB-JTAGを接続する機能はあったのですが、XILINX ISEがサポートするDigilent Cable Pluginを間接的に使っていたので、ISE(Labtool)が入っていないと使えませんでした。

LabToolはISEのでなければだめで、Vivadoには対応していませんでした。

その意味でも、今回の改良でISEに依存せずにDigilentケーブルが使えるようになったのは大きいといえます。

Dflow

| | コメント (0)

2018.08.04

DigilentのJTAGを自分のプログラムで使う方法

DigilentのボードにはUSB-JTAGが付いています。

このUSB-JTAGを自分のプログラム方法を調べました。

簡単に言うと、Digilent Adeptというライブラリがあって、djtgとdmgrというライブラリを使います。AdeptはJTAG以外にもDigilentが用意するシリアルI/OやパラレルI/Oを統括した、総合的なターゲットボード用ライブラリのようです。

様々なボードがあるので、JTAGの機能にもいろいろなオプションがあるようです。

また、PCに何台のターゲットボードがつながるかもわからないので、最初にEnumerateして、ボードのシリアル番号を調べて、そのシリアル番号を使ってデバイスをオープンするという手順になります。

開いたボードはたいていはFT2232が乗っていて、FT2232のファームウェアでAdeptのターゲットを実装していると思うのですが、そうでないボードもある可能性があるので、ボードが備えているabilityを調べます。

Zyboのボードは、スピード調整や、ピンの設定、WAIT機能、バッチ機能などを備えているようです。

Jtag_program

DigilentのUSB-JTAGを叩いて、ZYBO上のUSB-JTAGのプロパティと、ARMとZYNQコアをスキャンすることに成功。

AUX Resetというポートは存在していて、GPIOは付属していないようですね。

AUX Resetを0にするとARMのJTAGがしばらく認識できなくなるので、何かの機能はあるようです。GPIOは、おそらくCPUのデバッグに用いる補助的なI/Oに使われるものと思われます。最近のARMでは使いませんが、MIPSのころはGPIOが必要でした。

次に、Digilentのボードに乗っているUSB-JTAGを使う実験をしてみました。

最初の感想は、かなり遅い。

それもそのはず。USB 2.0 HighSpeedは、1つの操作をするたびに125us待たなければなりません。FT2232はさらに遅いはずです。

実際に試してみると数百usかかったり、かなり不安定です。

そこで、Adeptにはバッチモードというのが用意されていて、複数のJTAG操作をスクリプト化してまとめて投げるのです。

このバッチモードを使うと、任意の波形をそこそこの速度で出せるようになりました。USBの遅さカバーする方法が私のライブラリと同じ設計思想なのですぐに使い方がわかりました。FTDIのICの動きもだいたい想像できます。

Djtag

ZYBOのJTAGでIDCODEを読み出すシーケンスを実行してみました。

Djtag_idcode

ARMとZYNQコアのIDCODEが読み出せているのがわかります。

TCKは最高で30MHzほど出ていて、これが最高速度のようです。

| | コメント (0)

2018.08.03

JTAGチャレンジ基板の生板ができてきた

バウンダリスキャンを使って回路設計やエレクトロニクス実装の間違いを見つける「JTAGチャレンジ基板」の生板が出来上がりました。

Np1114_raw

来週中には実装が完了する予定です。セキュリティ・キャンプ全国大会2018の講義で使う予定だったので、間に合ってよかった!

そして、9月には誰でも参加できる「JTAGバウンダリスキャン・セミナー」を開催していく予定です。

セミナーの予定はcompassなどで告知していきたいと思いますので、お楽しみに。

| | コメント (0)

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