« 2019年3月 | トップページ | 2019年5月 »

2019.04.30

Vivadoが生成するプロジェクト生成Tclを読んでみた

VivadoでFile→Project→Write Tclという操作をすると、プロジェクトをTclで保存できるようです。

Vivado_tcl_2

この機能は一体何なのか、出力されるTclファイルは何ができるのかを調べてみました。

上記の操作を行うと、このようなTclファイルが吐き出されます。

Vivado_tcl_1

この構造を見てみると、以下のような構造になっています。

Tcl_struct

 

このtclスクリプトはスタートメニューの中にあるVivado Shell

Vivado_shell

から実行するのが本来のやり方なのかもしれませんが、複数のVivadoを入れていると探すのが大変なので、MS-DOSプロンプトから(あるいはバッチファイルを作って)実行するようにします。こうすればVivado Shellを起動しなくても動かせます。

D:\Xilinx\Vivado\2018.3\bin\vivado.bat -mode tcl -nolog -nojournal -source creat_project.tcl -tclargs [<option>] [<option2>] [<option3>] ...

Tclスクリプトを実行すると、実行したディレクトリの下にプロジェクトのフォルダを掘ってプロジェクトを作成するので、Vivadoのプロジェクトディレクトリを生成したい一つ上のディレクトリで実行するようにします。

Tclのオプションについて

この引数ですが、-mode tclを付けることでVivadoをコマンドラインモードで起動します。

-sourceで、読み込むtclファイルを指定します。

-nolog -nojournalはログファイルを作らせないものなので、無くても構いません。

-tclargsは、Tclのスクリプトに対してオプションを与えるものです。このTclスクリプトでは以下のようなオプションが用意されています。

  • --origin_dir <path> ソースコードを読み込む基点となるディレクトリを変更する
  • --project_name <name> プロジェクトの名前を変える
  • --help 使い方を表示する

順番に見ていきます。

--project_nameオプションは、その名のとおりで、例えばproject_1という名前のプロジェクトを再生成する際にhogehogeという名前に変更したいような場合に使います。例えば、テスト用のビルドをしたいとかでしょうか。

--origin_dirオプションはわかりにくいのですが、ソースコードが格納されたディレクトリを指定します。通常は.です。つまり、現在のディレクトリの下にソースがあると仮定されます。

VivadoのGUIモードで、何も考えずにプロジェクトを生成すると下のような構造のディレクトリ構成が作られます。

root_directory
+ vivado_project + vivado_project.src
| + vivado_project.ip_user_files
| + vivado_project.sim
| + vivado_project.cashe
| ...
...

Tclではこの、vivado_projectの下のvivado_project.srcの・・・のnewの中にあるmain.vhdのようにソースファイルのパスを指定しているのですが、その基点となるディレクトリを指定するのが --origin_dir です。

create_project.tclはroot_directoryにあるので、"."のままでよく、通常は変更する必要はありません。

Tclのスクリプトは何をやっているのか?

●プロジェクトの作成

このスクリプトの最も重要なのは、

create_project ${_xil_proj_name_} ./${_xil_proj_name_} -part xc7a100tcsg324-2

です。

第一引数の_xil_proj_name_はプロジェクト名で、第二引数はプロジェクトを作るディレクトリを指定するものです。$で表現されているものはTclの変数で、デフォルト値やオプションの引数の解析などで設定されます。

ぶっちゃけ、このcreate_projectの一行があればプロジェクトは生成されます。この後ろを全部削除してしまってもプロジェクトは生成されます。

●ソースファイルの指定

次にソースファイルの指定が続きます。

# Create 'sources_1' fileset (if not found)
if {[string equal [get_filesets -quiet sources_1] ""]} {
create_fileset -srcset sources_1
}
# Set IP repository paths
set obj [get_filesets sources_1]
set_property "ip_repo_paths" "[file normalize "$origin_dir/ip_repo"]" $obj
# Rebuild user ip_repo's index before adding any source files
update_ip_catalog -rebuild
# Set 'sources_1' fileset object
set obj [get_filesets sources_1]
set files [list \
[file normalize "${origin_dir}/src/bd/design_2/design_2.bd"] \
[file normalize "${origin_dir}/src/bd/design_2/hdl/design_2_wrapper.vhd"] \
]
add_files -norecurse -fileset $obj $files
# Set 'sources_1' fileset file properties for remote files
set file "$origin_dir/src/bd/design_2/design_2.bd"
set file [file normalize $file]
set file_obj [get_files -of_objects [get_filesets sources_1] [list "*$file"]]
set_property -name "registered_with_manager" -value "1" -objects $file_obj

このスクリプトに出てくるsources_1のfilesetというのはVivadoでいう↓のことです。

Fileset

このようなfilesetを、create_filesetコマンドを使って、srcset、constrset、simsetを作ります。Utility Sourcesは何かよくわかりません。

●Runの指定

その次にcreate_runコマンドを使ってrunを作ります。

# Create 'synth_1' run (if not found)
if {[string equal [get_runs -quiet synth_1] ""]} {
create_run -name synth_1 -part xc7a100tcsg324-1 -flow {Vivado Synthesis 2018} -strategy "Vivado Synthesis Defaults" -report_strategy {No Reports} -constrset constrs_1
} else {
set_property strategy "Vivado Synthesis Defaults" [get_runs synth_1]
set_property flow "Vivado Synthesis 2018" [get_runs synth_1]
}
set obj [get_runs synth_1]
set_property set_report_strategy_name 1 $obj
set_property report_strategy {Vivado Synthesis Default Reports} $obj
set_property set_report_strategy_name 0 $obj
# Create 'synth_1_synth_report_utilization_0' report (if not found)
・・・

Runというのは↓のことです。

Run

生成手順は複雑でプロパティの設定もあり、レポートの出し方の設定などもあるのですが、全て削除してしまってもデフォルトのRunが生成されるようです。

まとめ

  • VivadoでWrite Tclを行うと、そのプロジェクトを作成するためのソースファイルの指定やオプション設定が書かれたTclファイルが生成される。
  • Tclにはソースファイルや制約ファイルは含まれておらず、ソースファイルの場所が書かれている。
  • このTclファイルから元のxprを復元できる。
  • Tclファイルの実行は、vivado.bat -mode tcl <ファイル名>.tclで行う。

このTclファイルは、VivadoのTclスクリプトの使い方サンプルの宝庫です。Vivadoのプロジェクトを生成するようなプログラムを作りたいという方はぜひ読んでみてください。

 

 

| | コメント (0)

2019.04.29

VivadoのLock by userとLOCK_UPGRADEプロパティ

子IPプロジェクトを更新した場合や、Vivadoのバージョンを変更した場合、IPにロックがかかります。

Lock_ip

ロックされると上の図のように赤い鍵マークが出て、Editしたり論理合成に進むことができなくなります。

通常はReport IP StatusからのUpgrade Selectedで解除できるのですが、それだけでは解除できない場合もあります。

具体的にはIP Statusの所にLock by userと出ている場合で、このときにはBlock Designの各セルをクリックしてプロパティを見ると、
LOCK_UPGRADEというチェックボックスがONになっています。

Lock_ip2

このチェックボックスを一つ一つ外していけばよいのですが、Tclで書くこともできます。

foreach cell [get_bd_cells] {
    set_property LOCK_UPGRADE 0 [get_bd_cells $cell]
}

もしくは

set_property LOCK_UPGRADE 0 [get_bd_cells [get_bd_cells]]

でもよさそうです。

これでユーザロックが外れて、IPの更新と論理合成に進むことができるようになります。

| | コメント (0)

2019.04.26

ゴールデンウイーク中の営業について

特殊電子回路は、以下の商品はゴールデンウィーク中も休まずに商品を出荷します。

  • MITOUJTAG BASIC
  • MITOUJTAG Pro
  • Artix-7ボード
  • Spartan-6ボード
  • Cosmo-K
  • Cosmo-Z
  • Cosmo-Z Mini
  • Zynqberryスタータキット

Amazonの倉庫に在庫保管と発送を委託しており、Amazonの倉庫より出荷されるので、連休中であっても当日から1日程度で商品をお届けできます。ただし、部品の調達が難しくなっていますので、在庫がなくなった場合にはしばらく納期がかかってしまいます。お早目にご注文ください。「銀行振込先払い」では決済できないため、クレジットカードか代金引換、または後払いでご注文ください。

また、私はこの10連休を利用してMITOUJTAG Proの改良やCosmo-Zのドキュメント整備、Spartan-7ボードの開発など、普段なかなか取り組めなかったことに挑戦し、有意義な連休にしたいと思っています。

 

| | コメント (2)

2019.04.22

MITOUJTAG ProでDDR3メモリテストを追加し、テストスイートを作成

インターコネクトテスト、NORフラッシュテストに続き、DDR3メモリテストもパッケージ化しました。

DDR3メモリテストはこのブログでも何度か出てきているのであえて説明しませんが、バウンダリスキャンでFPGAの端子を操作して、DDR3メモリに読み書きするというものです。

ユーザ側のソースはとてもシンプルです。

printf("★FPGA1_DDR3のテストを行います\n");
int error_num = 0;
unsigned long dbus_error = 0;
unsigned long abus_error = 0;
DDR3Signals dsigs;
dsigs.ras = &U1_DDR3_RAS;
dsigs.cas = &U1_DDR3_CAS;
dsigs.wen = &U1_DDR3_WEN;
dsigs.cs = &U1_DDR3_CS;
dsigs.cke = &U1_DDR3_CKE;
dsigs.a = &U1_DDR3_ADDR;
dsigs.ba = &U1_DDR3_BA;
dsigs.d = &U1_DDR3_DQ;
dsigs.odt = &U1_DDR3_ODT;
dsigs.dm = &U1_DDR3_DM;
dsigs.ckp = &U1_DDR3_CLKP;
dsigs.ckn = &U1_DDR3_CLKN;
dsigs.dqsp = &U1_DDR3_DQSP;
dsigs.dqsn = &U1_DDR3_DQSN;
dsigs.reset = &U1_DDR3_RESET;
if(test_sdram(dsigs,abus_error,dbus_error))
{
printf("FPGA1_DDR3は正常です\n");
}
else
{
printf("FPGA1_DDR3に異常があります\n");
}
printf("\n");
j_bypass();

もちろん、呼び出した先の関数でMRSの設定やらRAS/CASの制御やDQSのタイミングなどはC++でぐちゃぐちゃと書かれていますが、ユーザが気にすることはありません。

ユーザがやることは、dsigsという構造体のメンバにRASやCAS、アドレス等を登録してtest_sdram関数を呼び出すだけです。

Ddr3

バス幅や構成は抽象化されているので、様々なボードに対して同じソースが使えます。

今回、3回に分けてJTAGスクリプトの機能を紹介してきました。

JTAGスクリプトを使うと、デスクトップで手軽にFPGAやCPUの端子をバウンダリスキャンで操作することができ、基板の検査を楽に行えます。

インターコネクトテスト、NORフラッシュテスト、DDR3メモリテストを行うための全ソースコードを下記のURLにアップロードしました。

MITOUJTAG ProのJTAGスクリプトのサンプル

MITOUJTAG Proをお使いのお客様はダウンロードしていただくことができます。どうぞ様々な基板の検査に応用し、設計、製造、検査の手間を効率化してみてください。

 

| | コメント (0)

2019.04.21

MITOUJTAG ProでNOR型フラッシュを扱うためのクラス

MITOUJTAG ProにはJTAGスクリプトとしてユーザプログラムを作り、組み込んで使う機能があります。

このJTAGスクリプト機能を使ってNOR型フラッシュのテストを行うプログラムを用意しました。

C++のクラス化です。

	printf("Flashメモリを読み出します\n");
BPIFlash *bpi = new BPIFlash(U1_FLASH_ADDR,
U1_FLASH_DATA,
U1_FLASH_CE,
U1_FLASH_WE,
U1_FLASH_OE);
// bpi->NarrowMode(); // NarrowModeにしない→16/8bitの選択は16bitを選ぶ
bpi->RegistOptionalByteSignal(U1_FLASH_BYTE); // オプション信号
bpi->RegistOptionalBusySignal(U1_FLASH_BUSY); // オプション信号
bpi->RegistOptionalResetSignal(U1_FLASH_RESET); // オプション信号
bpi->Dump(0,256); // メモリダンプの実行
delete bpi;
printf("\n");

BPIFlashクラスのコンストラクタを、アドレスやデータの信号線を引数として呼び出すと、検査用のオブジェクトを作ってくれます。

そして、RESETやBUSYなどのオプションの信号を登録した後で、Dump(アドレス,長さ)を呼び出すと、FlashROMの信号を操作してメモリの内容を読み出してダンプしてくれます。

下の図は、MAX10のBSDLファイルを書き込んだFlashROMを読み出したところです。

Bpi1

アクセスしているときの波形を示します。

OEとCEをLにしてアドレスをカウントアップさせるだけなので、単純ですね。

Norflash

このクラスは、データバスの幅は自動的に認識してくれますが、NarrowMode関数を呼び出すと、BYTE信号をLにしてA-1を操作するモードでアクセスするようになります。これは16bitのFlashROMを8bit幅でアクセスするというモードで、アドレスバスにA-1(マイナス1)というA0以下を意味する珍奇な信号がでてきます。

A-1は、通常はデータバスの最上位ビットに出てくるので、D15がトグルします。

Norflash2

読み出した結果はこのように同じ内容をバイト単位でアクセスしたものになります。

Bpi2

このほか、ビッグエンディアンにする機能もあります。

このソースのダウンロード方法は、次回の記事で公開します。

| | コメント (0)

2019.04.20

MITOUJTAG Proでインターコネクトテスト

MITOUJTAG Pro でインターコネクトテストを行えるようにしました。

インターコネクトテストというのは、複数のICの間の配線にオープン・ショートがないかを1本1本チェックするテストです。

ターゲットボードは、下の写真の「JTAGチャレンジ基板」。

Jcha

JTAGチャレンジ基板は、バウンダリスキャンの実習を目的としたボードで、データバスの一部をジャンパピンで切ったりショートしたりして、バウンダリスキャンの挙動を調べることができます。

このボードでは、Spartan-7とMAX10が16本のデータバスと2本のクロックでつながっています。

書いたスクリプトは以下のようなものです。

bool U1_to_U2_interconnect_test()
{
JSSignal u1_bus;
u1_bus << U1_FPGA_DBUS(15 downto 0);
u1_bus << U1_FPGA_CLK_p;
u1_bus << U1_FPGA_CLK_n;
JSSignal u2_bus;
u2_bus << U2_FPGA_DBUS(15 downto 0);
u2_bus << U2_FPGA_CLK_p;
u2_bus << U2_FPGA_CLK_n;
printf("U1とU2間の配線を検査します (U1出力)\n");
if(!interconnect_test(&u1_bus,&u2_bus))
{
printf("ERROR:U1とU2間の配線に異常があります\n\n");
return false;
}
printf("SUCCESS:U1とU2間の配線は正常です\n\n");
return true;
}

この、U1_FPGA_DBUSやU2_FPGA_CLK_pという名前のオブジェクトは、信号線に対応したもので、JTAG信号クラス(JSSignal)型のオブジェクトです。

JSSignal型の新しいオブジェクトを作り、<<で放り込んでいって、最後にinterconnect_testという関数に入れると、1本ずつ信号をHにするWalking 1や、一本ずつ信号をLにするWalking 0テストをしてくれるようになっています。

実際にやってみました。

MAX10とSpartan-7の間の信号を一本ずつ検査します。

下の波形がその実行中の波形で、緑の線が入力、赤の線が出力を表しています。

Interconnect_1

このように、通常は何事もなければ出力したものと同じ波形が入力デバイスで得られるはずです。

しかし、信号にショートやオープンがあった場合、下の波形のように異常な個所が出てきます。

Interconnect_3

これによって、D0とD4に異常が生じているということが判断できるというわけです。

このようなインターコネクトテストを行うためのC++のクラスと関数を用意したので、MITOUJTAG Proにユーザ機能として手軽に追加して実行できるという仕組みです。また、どのような順序であっても、どのような回数であっても、C++のプログラムを書き換えればよいので、自由にカスタマイズできます。

最後に、Spartan-7の場合、FPGAの設計時に入力としてコンフィギュレーションされてしまっている端子は、バウンダリスキャンを使っても出力にすることができません。

下の波形の左半分は、Spartan-7が起動しているときに、Spartan-7から出力した信号をMAX10で受け取ろうとしたものです。

Interconnect_4

Spartan-7(赤い線)は出力しているつもりなのに、MAX10(緑の線)からは何も受け取れていません。

バウンダリスキャンでインターコネクトテストを行う場合には、FPGAは未コンフィギュレーションの状態でやらないと、正しい結果が得られない場合があります。

このソースのダウンロード方法は、次々回の記事で公開します。

 

| | コメント (0)

2019.04.19

MITOUJTAGで長いチェーンを扱うとエラーが出る件と対策パッチ

あるお客様からのご指摘で、MITOUJTAGで長いJTAGチェーンを扱う場合に不具合が発見されたため、パッチを作成しました。

具体的には、MITOUJTAGはIR(命令レジスタ)の長さが100bit以上になるJTAGチェーンで、SAMPLEやEXTESTなどのバウンダリスキャンコマンドを発行した際に、不正な処理(多くはメモリ保護違反)が生じることがわかりました。

Mimic2

これは、ALTERA(INTEL)のFPGAではおよそ10個、XILINXではおよそ17個のFPGAを1つのJTAGにチェーン接続した場合に起こります。
この問題はJTAGデバイスが1~5個程度の通常の基板では起こりません。

パッチは下記のリンクからダウンロードできます。
長いJTAGチェーンでの不具合を対策するパッチ

※このパッチはMITOUJTAG BASIC 3.41用です。他のバージョンに適用した場合の動作は保証できません。次回の更新時にMITOUJTAG Pro,BASIC,Lightの各バージョンに取り込まれます。

 

さて、この問題を発見するために、JTAGMIMICという特別なデザインを作成して検証しました。JTAGMIMICはVivadoのデザインdえす。

Jtagmimic

MIMIC(ミミック)とは、真似する、擬態するという意味の言葉です。ドラクエでは宝箱に扮したモンスターでおなじみですね。

JTAGMIMIC(ジェイタグミミック)は、任意のJTAGデバイスをエミュレートするデザインをFPGAの中に作りこむ仕組みで、当社のSpartan-6ボードやArtix-7ボードで動作します。

今回は18個のFPGAを持つ仮想的なJTAGチェーンを、FPGAの中に作ることで検証しました。

 

Spartan-6ボード/Artix-7ボードとMITOUJTAGをご利用のお客様に無償で提供させていただきます。

詳しくは下記のURLをご覧ください。

http://www.tokudenkairo.co.jp/jtag/mimic.html

| | コメント (0)

2019.04.17

長いJTAGチェーンを仮想的に作る

ALTERA(INTEL)のArria10を10個つないだJTAGチェーンをMITOUJTAGでバウンダリスキャンして、12fpsくらいのレートで画面が更新できました。もうちょっといいPCだと22fpsくらい出ます。

Arria10

続きはこちら↓

続きを読む "長いJTAGチェーンを仮想的に作る"

| | コメント (0)

2019.04.11

LAN9514のEEPROMをLinuxから設定する方法

Micrichip社のLAN9514というICがあります。

USBのハブとホストに加え100BASEのUSB-LANを搭載しているICで、コネクタをつなぐだけで4ポートのUSBホストと100BASEのLANが実現できます。

Lan9514

RaspberryPiやZynqberryにも搭載されています。(RaspberryPiではEEPROMにMACアドレスを書いていないという話もあるので、この方法で変わるかどうかは試していない。ZynqberryはOK)

このICが作るLANのMACアドレスはEEPROMに設定されていなければ電源を投入するたび(リセットするたび)ランダムで決まります。

ランダムになってしまうと、例えばDHCPサーバが割り当てるIPアドレスがリブートのたびに変わるので、困る場合があります。例えば、Windowsでホスト名でファイル共有をするのに時間がかかるとか。

そこで、このICのMACアドレスをLinuxから設定することを試してみました。

LAN9514のEEPROMを設定するには、まずデバイスドライバを読んでみたところethtoolsという構造体があったので、ethtoolsとは何ぞやということで調べてみると、PHYの管理などができるそういうツールがあるようです。

これはZYNQのLinuxからサクッとapt-getでインストールできました。

zynqberry@zynqberry:~$ sudo apt-get install ethtool
[sudo] password for zynqberry:
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下のパッケージが自動でインストールされましたが、もう必要とされていません:
bind9-host geoip-database libavahi-core7 libbind9-90 libdaemon0 libdns100
libgeoip1 libisc95 libisccc90 libisccfg90 liblwres90
これを削除するには 'apt-get autoremove' を利用してください。
以下のパッケージが新たにインストールされます:
ethtool
アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 0 個。
84.5 kB のアーカイブを取得する必要があります。
この操作後に追加で 284 kB のディスク容量が消費されます。
取得:1 http://ports.ubuntu.com/ubuntu-ports/ trusty/main ethtool armhf 1:3.13-1 [84.5 kB]
84.5 kB を 1秒 で取得しました (74.3 kB/s)
以前に未選択のパッケージ ethtool を選択しています。
(データベースを読み込んでいます ... 現在 50239 個のファイルとディレクトリがイン ストールされています。)
Preparing to unpack .../ethtool_1%3a3.13-1_armhf.deb ...
Unpacking ethtool (1:3.13-1) ...
ethtool (1:3.13-1) を設定しています ...

起動してみます。一般ユーザでやる場合はsudoを付けてください。

zynqerry@zynqberry:~$ sudo ethtool -e eth0
Offset Values
------ ------
0x0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x00a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x00b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x00c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x00f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0110: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0120: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0130: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0140: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0150: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0160: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0170: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0180: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0190: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x01a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x01b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x01c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x01d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x01e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x01f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

初期状態では、中身は全部FFのようです。

ethtoolsを使ってEEPROMを書き込むには、ethtools -E eth0 の後ろにmagicやoffset、lengthを指定する必要があります。LAN9514のmagicは0x9500です。offsetはEEPROMの何番地から書き込むかで、これは0。lengthは140にします。

書き込むべきデータはLAN9514のデータシートに載っているので、それをコピペするなどしてテキスト化し、それをもとにバイナリファイルを作ります。Linuxで16進のテキストからバイナリ列を作るには、echoの後ろに-enを付けて、エスケープシーケンスを含んだ文字列を書けばよいようです。

echo -en "\xA5\x12\x34\x56\x78\x9A\xBC\x01\x04\x05\x09\x04\x0A\x1D\x00\x00\x00\x00\x00\x00\x00\x00\x12\x22\x12\x2B\x12\x34\x12\x3D\x00\x00\x24\x04\x14\x95\x00\x01\x9B\x18\x00\x02\x00\x00\x01\x00\x01\x00\x32\x00\x00\x00\x00\x00\x21\x43\x05\x01\x0A\x03\x53\x00\x4D\x00\x53\x00\x43\x00\x12\x01\x00\x02\xFF\x00\x01\x40\x24\x04\x00\xEC\x00\x01\x01\x00\x00\x01\x09\x02\x27\x00\x01\x01\x00\xE0\x01\x09\x04\x00\x00\x03\xFF\x00\xFF\x00\x12\x01\x00\x02\xFF\x00\xFF\x40\x24\x04\x00\xEC\x00\x01\x01\x00\x00\x01\x09\x02\x27\x00\x01\x01\x00\xE0\x01\x09\x04\x00\x00\x03\xFF\x00\xFF\x00" > eeprom.bin

これで140バイトの設定データが出来ました。

上の赤い部分がMACアドレスなので、必要に応じて書き換えてください。なお、最初の1バイトのbit1が'1'になっている(つまり0x02)MACアドレスはプライベートアドレスなので、自分の責任で自由に使うことができます。

ethtool -E eth0 magic 0x9500 offset 0 length 140 < eeprom.bin

これで書き込まれました。
確認してみましょう

zynqberry@zynqberry:~$ sudo ethtool -e eth0
Offset Values
------ ------
0x0000: a5 12 34 56 78 9a bc 01 04 05 09 04 0a 1d 00 00
0x0010: 00 00 00 00 00 00 12 22 12 2b 12 34 12 3d 00 00
0x0020: 24 04 14 95 00 01 9b 18 00 02 00 00 01 00 01 00
0x0030: 32 00 00 00 00 00 21 43 05 01 0a 03 53 00 4d 00
0x0040: 53 00 43 00 12 01 00 02 ff 00 01 40 24 04 00 ec
0x0050: 00 01 01 00 00 01 09 02 27 00 01 01 00 e0 01 09
0x0060: 04 00 00 03 ff 00 ff 00 12 01 00 02 ff 00 ff 40
0x0070: 24 04 00 ec 00 01 01 00 00 01 09 02 27 00 01 01
0x0080: 00 e0 01 09 04 00 00 03 ff 00 ff 00 ff ff ff ff
0x0090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x00a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x00b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x00c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x00f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x0100: a5 12 34 56 78 9a bc 01 04 05 09 04 0a 1d 00 00
0x0110: 00 00 00 00 00 00 12 22 12 2b 12 34 12 3d 00 00
0x0120: 24 04 14 95 00 01 9b 18 00 02 00 00 01 00 01 00
0x0130: 32 00 00 00 00 00 21 43 05 01 0a 03 53 00 4d 00
0x0140: 53 00 43 00 12 01 00 02 ff 00 01 40 24 04 00 ec
0x0150: 00 01 01 00 00 01 09 02 27 00 01 01 00 e0 01 09
0x0160: 04 00 00 03 ff 00 ff 00 12 01 00 02 ff 00 ff 40
0x0170: 24 04 00 ec 00 01 01 00 00 01 09 02 27 00 01 01
0x0180: 00 e0 01 09 04 00 00 03 ff 00 ff 00 ff ff ff ff
0x0190: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x01a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x01b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x01c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x01d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x01e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0x01f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

ちゃんと書き込まれているのがわかります。

起動時のメッセージを見ると、今まではランダムになっていたのが、

[    2.669168] usb 1-1.1: New USB device found, idVendor=0424, idProduct=ec00
[ 2.675982] usb 1-1.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[ 2.686405] smsc95xx v1.0.5
[ 2.784367] smsc95xx 1-1.1:1.0 eth0: register 'smsc95xx' at usb-ci_hdrc.0-1.1, smsc95xx USB 2.0 Ethernet, fe:c0:42:d9:23:f9
[ 7.477999] EXT4-fs (mmcblk0p2): recovery complete
[ 7.485256] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
[ 7.493315] VFS: Mounted root (ext4 filesystem) on device 179:2.

下のように設定したが使われているのがわかります。

[    2.663831] init: ureadahead main process (1120) terminated with status 5
[ 2.688673] usb 1-1.1: New USB device found, idVendor=0424, idProduct=ec00
[ 2.695469] usb 1-1.1: New USB device strings: Mfr=1, Product=0, SerialNumber=0
[ 2.705719] usb 1-1.1: Manufacturer: SMSC
[ 2.718420] smsc95xx v1.0.5
[ 2.823765] smsc95xx 1-1.1:1.0 eth0: register 'smsc95xx' at usb-ci_hdrc.0-1.1, smsc95xx USB 2.0 Ethernet, 12:34:56:78:9a:bc

ifconfigで見てみると、

eth0      Link encap:イーサネット  ハードウェアアドレス 12:34:56:78:9a:bc
inetアドレス:192.168.1.215 ブロードキャスト:192.168.1.255 マスク:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 メトリック:1
RXパケット:99 エラー:0 損失:14 オーバラン:0 フレーム:0
TXパケット:75 エラー:0 損失:0 オーバラン:0 キャリア:0
衝突(Collisions):0 TXキュー長:1000
RXバイト:8532 (8.5 KB) TXバイト:9821 (9.8 KB)

lo Link encap:ローカルループバック
inetアドレス:127.0.0.1 マスク:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 メトリック:1
RXパケット:106 エラー:0 損失:0 オーバラン:0 フレーム:0
TXパケット:106 エラー:0 損失:0 オーバラン:0 キャリア:0
衝突(Collisions):0 TXキュー長:1
RXバイト:5300 (5.3 KB) TXバイト:5300 (5.3 KB)

ちゃんと書き変わりました。

なお、ethtoolsでは、140バイトのデータを正しく書かないとLAN9514が起動しなくなってしまいます。その場合はEEPROMを物理的に外すなどの処置が必要になるので多少の危険を伴います。最初の7バイトだけを書き込んだら動かなくなったので、復旧に苦労しました。

 

もっと簡単な方法としては、

ifconfig eth0 down
ifconfig eth0 hw ether 02:01:02:03:04:05
ifconfig eth0 up

で設定してしまうことです。これを/etc/rc.localに書いておけば起動時に設定されます。

ZYNQの内蔵のGigabitEtherは、Linuxのドライバの問題によりこの方法ではMACアドレスを変更できませんが、LAN9514経由のUSB-LANであればifconfigでMACアドレスを変更できるので、より安全で手軽です。

ユーザがSDカードをどんなふうに書き換えても動くようにハード的に固定値を書き込んでおきたいという場合にはethtooslでEEPROMに書き込むのがよいでしょう。

 

| | コメント (0)

2019.04.07

ZYNQのLinuxでMPC79411というRTCを使う方法

Microchip社のリアルタイムクロックMPC79411をZYNQのLinuxから使うには、DeviceTreeに以下のように書きます。

i2c@e0004000 {
compatible = "cdns,i2c-r1p10";
status = "okay";
clocks = <0x1 0x26>;
interrupt-parent = <0x4>;
interrupts = <0x0 0x19 0x4>;
reg = <0xe0004000 0x1000>;
#address-cells = <0x1>;
#size-cells = <0x0>;
clock-frequency = <0x61a80>;
rtc@6F {
compatible = "mcp7941x";
reg = <0x6f>;
};
};

この6FというのがI2Cのデバイスアドレスで、compatible="mpc7941x"と書くことで起動時に探されます。clock-frequency=<0x61a80>というのはI2Cのクロックを400kHzにするという意味です。ぴったり400kHzになります。

# dtc -I dts -O dtb devicetree.dts > /mnt/devicetree.dtb

でデバイスツリーを作り、rebootします。

MPC79411のドライバはDS1307用の汎用RTCドライバを用いているので、起動時にはDS1307のドライバで認識され、

[    1.304585] i2c /dev entries driver
[ 1.308235] cdns-i2c e0004000.i2c: 400 kHz mmio e0004000 irq 23
[ 1.315197] rtc-ds1307 0-006f: SET TIME!
[ 1.320404] rtc-ds1307 0-006f: rtc core: registered mcp7941x as rtc0
[ 1.326682] rtc-ds1307 0-006f: 64 bytes nvram
[ 1.331237] cdns-i2c e0005000.i2c: 400 kHz mmio e0005000 irq 24

と、起動時に認識されます。

MPC79411はアドレス0のbit7がSTARTビットといってカウントを開始するためのレジスタとなっていて、アドレス3のbit3がバッテリバックアップの有効化ビットなので、これらをONにしないと動きません。

そのため、必ずMPC7941Xを指定してDS1307ドライバを使う必要があります。

これで電源が落ちても時間を保持できます。

続きを読む "ZYNQのLinuxでMPC79411というRTCを使う方法"

| | コメント (0)

2019.04.05

ZYNQでEMIO経由でI2Cを動かす方法

ZYNQのI2CをEMIO経由で出すデザインを作ったのですが、全く信号が出てこないので困っていました。

I2CをEMIO経由で出すとIIC_0とIIC_1という2つのバスが出てきて、この中にはSDAとSCLの信号がI,O,Tで3本ずつ通っています。

I2cdesign5

このIIC_0の信号を外に出すために、次のようなコードを書いていたのですが、

	i2c_iobuf_inst : IOBUF port map (
IO => sda1_io,
O => sda1_o,
I => sda1_i,
T => sda1_t
);
scl1_io <= scl1_i;
sda2_io <= sda2_i;
scl2_io <= scl2_i;
scl1_o <= '0';
sda2_o <= '0';
scl2_o <= '0';

信号が何も出てこないという結果となっていました。

I2Cがそもそも動いていないのか、初期化などに失敗しているのかと考えられました。

しかし、PLはそのままにしてPSだけ修正し、I2CをEMIOに通すようにしたら、なんと、I2Cの信号が出てくるようになったのです!

I2cdesign4

U-BOOTでi2c probeを実行し、その時のPLの中の波形をMITOUJTAGを使ってみてみると、ぴったり100kHzのクロックで出てきています。

I2cdesign6

波形を目で読んでみると、0x03,0x05,0x07,0x09・・・と奇数番地にアクセスしています。

しかし、EMIOデザインにするとこの波形も出てきません。

Vivadoのバグかと思ってVivado2018.3にアップデートしてみても変化なし。

もうわけがわからないので、徹底的にデバッグすることにしました。

まず、EMIOを通すデザインとMIO50,51から出すデザインの2つを作って、export hardwareを行い、ps7_init.tclの内容を比べてみると、

mask_write 0XF80007C8 0x00003FFF 0x00001300
mask_write 0XF80007CC 0x00003FFF 0x00001300

mask_write 0XF80007C8 0x00003FFF 0x00001340
mask_write 0XF80007CC 0x00003FFF 0x00001340

になっているという程度の違いでした。

この0xf80007c8と0xf80007ccのレジスタ以外の違いはありません。ug585を読むとMIO50/51をGPIOにするかI2Cにするかの選択だけで、それ以外の変化はありませんでした。

I2cdesign7

したがって、MIO50から出てくるのであればI2Cのモジュール自体は正しく設定されていて、動いているといえるでしょう。

すると、MIOから出すのとEMIOから出すの違いは一体何なのか。

実はMIO50とMIO51に入力される値の違いと、SDA_OやSCL_Oは'0'から動かないということでした。

まず、上にあるMITOUJTAGの波形を見てみるとわかりますが、動いているのはSDA_TとSCL_Tであって、scl1_iとsda1_i
は常に'0'となっています。

I2cdesign12

つまり、I2Cの信号を出力するときには、SCLとSDAはトライステートバッファを利用して、0かZかを出力しろというわけです。

したがって、

scl1_io <= scl1_i;

という書き方はダメで、SCLについてもIOBUFTを使うか、

scl1_io <= '0' when (scl1_t = '0') else '1';

と書かなければいけないようです。

もう一つはZYNQコアのSCL_Iに入れる値を'0'のままに固定してはいけないということです。具体的には、

scl1_o <= '0';

というのが間違っていて、

scl1_o <= '1';

にしなければならなかったのです。

入力値が'0'のままだとZYNQのI2C内蔵ペリフェラルは動作をしてくれないようです。

まとめると、

i2c_iobuf_inst : IOBUF port map (
IO => sda1_io,
O => sda1_o,
I => sda1_i,
T => sda1_t
);
scl1_io <= '0' when (scl1_t = '0') else '1';
scl1_o <= '1';

にするか、SCLに対しても

i2csda_iobuf_inst : IOBUF port map (
IO => sda1_io,
O => sda1_o,
I => sda1_i,
T => sda1_t
);
i2cscl_iobuf_inst : IOBUF port map (
IO => scl1_io,
O => scl1_o,
I => scl1_i,
T => scl1_t
);

と、3ステートバッファを使えばよいようです。

SDAだけではなくSCLについても、素直にIOBUFTを使えばよかったのですね。

I2CにつないだRTCのMPC79411も動くようになり、Linux起動時に下記のような波形が出てきました。

I2cdesign8

内蔵レジスタも読めた!

I2cdesign13

こんなことで1週間近くもハマっていました。

てゆーか、AR#56858によれば末尾に_t、_o、_iが付いている信号は自動的にIOBUFTが推論されるそうなので、そもそもIOBUFTをラッパするだけのIPなんていうのは作る必要さえなかったようでした。IP CatalogのUtility bufferにIOBUFTが無い理由はそこにあるのかもしれません。

結論を言うと、これでよいようです。

I2cdesign9

バスの信号をそのままMake Externalするのはとても心理的抵抗があるのですが、Vivadoは信号名の末尾に_i,_o,_tという信号を見つけると、自動的にIOBUFTを入れて、_ioという名前の信号に置き換えてしまうので、HDL Wrapperの出力は

I2cdesign10

となります。

XDCファイルには

I2cdesign11

と、_ioの名前でピン配置を指定すればよいというわけです。

やらなくていいことを自分でやろうとしてI2Cが動かないという結果になっていた典型的なパターンでした。もう少しVivadoを信頼してもいいのかもしれません。

 

| | コメント (0)

2019.04.04

TrenzElectronicの製品を続々入荷中

TrenzElectronic製品は納期が3か月から半年かかるものもざらです。

そんな製品たちを、半年前に注文していたものがぞくぞく入荷しています。

TE0720-03-2IFTE0720-03-1CFA

Te0720

ZYNQのXC7Z020を搭載した標準的なSoCモジュール。Trenz社の代表的なZYNQボードなのに、納期が3か月程度かかりますが、今なら在庫があります。

ちなみに、2IFの方が高性能です。1CFAというのはスピード・温度グレードが1Cのもので、AはSPI ROMの型番が変わったことを意味しています。

TE0808-04-09EG-2IE

Te0808 

Zynq UltraScale+ ZU9EGという大容量のFPGAと、4 GByte DDR4 SDRAMを搭載たウルトラ級のボード。自動運転やAIの研究・開発、そしてコンパクトなサイズを活かしてAIの組み込みに最適です。

納期が平均して半年くらいかかるので、いま入手しないと次に手に入るのは秋ごろになるかもしれません。

TEC0053-04-K1

SDSoCを使ってモータコントロール回路を作るというチュートリアル的なボードです。

Tec0053

かくいう私もこのボードで勉強してSDSoCの使い方が理解できました。

昨年の11月にオーダーしてようやく入荷という超長納期ボードです。

 

TE0715-04-30-1IA

4×5cmの小さい基板にXC7Z030を詰め込んだ高密度ボード。いったいどうやったらこのサイズに詰め込めるのか?その技術を探ってみたい。

2個売れたので、在庫は残り1個。即納可能。

Te0715

 

ここに挙げた以外にも、TrenzElectronic社のボードをいろいろ在庫していますし、取り寄せもいたします。

https://www.trenz.jp/ へ。

 

| | コメント (0)

2019.04.03

EMIOからI2Cの信号が出てこない

開発中のZYNQボードでI2Cの通信がしたいのですが、EMIOからI2Cの信号が出てきません。

なぜなんでしょう。

ZYNQから生えているI2Cの信号は、SCL_I、SCL_O、SCL_T、SCA_I、SDA_O、SDA_Tの6本で、これをOBUFTでバッファするためだけのIPを作って通しています。

I2cdesign1_1

I2C0を叩いても、I2C1を叩いても、うんともすんとも言いません。

でも、EMIOではなくMIO50、MIO51などを使うデザインにすると、信号が出てきます。

U-Bootにはi2cコマンドというのが、あって、i2c probeとやるとデバイスアドレスの00~FFまでをスキャンして何かいるかを探してくれます。

I2cdesign3

I2C probeを実行している間、MIOの端子は下の波形のようにパタパタと動いています。

I2cdesign2

さて、何が原因なのでしょう。

 

| | コメント (0)

2019.04.02

MITOUJTAGでDigilentのUSB-JTAGが使えるようになった

MITOUJTAGで、DigilentのUSB-JTAGを認識させようとすると、ケーブル自体は認識されるのですが、下の図のようにNo Response. Cable downと出てしまいます。

Mj_usbjtag

この原因もようやくわかりました。

ログを見ると、

2019/04/02 11:23:11 XILCABLE: Attempting to launch hw_server...|
2019/04/02 11:23:11 XILCABLE: |****** Xilinx hw_server v2013.3| **** Build date : Sep 24 2013-19:42:04| ** Copyright 1986-1999, 2001-2013 Xilinx, Inc. All Rights Reserved.||INFO: hw_server application started|INFO: Use Ctrl-C to exit hw_server application||INFO: Set the HW_SERVER_ALLOW_PL_ACCESS environment variable to 1 to access any PL address memory in the TCF debugger memory window.||
2019/04/02 11:23:11 XILCABLE: Connection established.|
2019/04/02 11:23:11 |***Error:Command CseJtag_target_getPin failed.|

となっていて、CseJtag_target_getPinというコマンドがエラーを起こしていることがわかります。

DigilentのHS-JTAG USB等ではこのコマンドは通るのですが、Embedded Platform Cable USBでは通らないようです。

MITOUJTAGでXILINXケーブルのオプションを開き、ケーブルタイプをxilinx_platformusbに変更すると、CseJtag_target_getPinも通るようになり、認識されるようになります。

Cse_setting_1

これで手近にあった基板につないで・・

Zynq_board

やった、認識した!動いたっ!

Usbjtagzynq

ちなみにログはこんな感じです。

2019/04/02 12:01:19 ローカルホストでCSE Serverを起動します
2019/04/02 12:01:19 Cse_Server : D:\xilinx\14.7\ISE_DS\ISE\bin\nt64\cse_server.exe found|
2019/04/02 12:01:21 XILCABLE: Connecting to cable (Usb Port - USB21).|
2019/04/02 12:01:21 XILCABLE: Checking cable driver.|
2019/04/02 12:01:21 XILCABLE: Driver file xusbdfwu.sys found.|
2019/04/02 12:01:21 XILCABLE: Driver version: src=1027, dest=1027.|
2019/04/02 12:01:21 XILCABLE: Driver windrvr6.sys version = 10.2.1.0.
2019/04/02 12:01:21 XILCABLE: WinDriver v10.21 Jungo (c) 1997 - 2010 Build Date: Aug 31 2010 x86_64 64bit SYS 14:14:44, version = 1021.|
2019/04/02 12:01:21 XILCABLE: Cable PID = 0008.|
2019/04/02 12:01:21 XILCABLE: Max current requested during enumeration is 74 mA.|
2019/04/02 12:01:21 XILCABLE: Type = 0x0004.|
2019/04/02 12:01:21 XILCABLE: Cable Type = 3, Revision = 0.|
2019/04/02 12:01:21 XILCABLE: Setting cable speed to 6 MHz.|
2019/04/02 12:01:21 XILCABLE: Cable connection established.|
2019/04/02 12:01:21 XILCABLE: Firmware version = 1303.|
2019/04/02 12:01:21 XILCABLE: File version of D:/xilinx/14.7/ISE_DS/ISE/data/xusb_xlp.hex = 1303.|
2019/04/02 12:01:21 XILCABLE: Firmware hex file version = 1303.|
2019/04/02 12:01:21 XILCABLE: PLD file version = 0012h.|
2019/04/02 12:01:21 XILCABLE: PLD version = 0012h.|
2019/04/02 12:01:21 XILCABLE: Type = 0x0004.|
2019/04/02 12:01:21 XILCABLE: ESN device is not available for this cable.|
2019/04/02 12:01:21 JTAGケーブル xilcable と接続しました
2019/04/02 12:01:21 このJTAGケーブルの詳細情報はありません

XILINXのケーブルにつなぐためにISE 14.7を介しているので、まだまだISEは手放せません。

 

| | コメント (0)

2019.04.01

令和ボードを作ります

新元号が令和に決まりましたね。

とても良い響きだと思います。

この国の一大イベントで、自分にも何かできることはないかと思い、「令和」と記された基板を作ることにしました。

昨年開発していたSpartan-7ボードに「奉祝🇯🇵令和元年」とシルクで刻印してみました。

Reiwa1

点描画で描かれています。

Reiwa2

令和元年5月1日の発売が目標です。

| | コメント (0)

« 2019年3月 | トップページ | 2019年5月 »