« 2017年6月 | トップページ

2017.07.21

ArtyのイーサネットをFPGAのロジックでコントロール

インターンで来ている学生さんが、DigilentのArtyボードでイーサネットのパケットを送信するデザインを作ってくれました。

Arty

Artyは、Artix-7のXC7A35Tが搭載された評価ボードです。Artyには100Mbpsのイーサネットコントローラが付いていて、FPGAでイーサのフレームを作ればパケットを送ることができます。

そうして作ったのがこのデザインです。

Ethercore_1

Vivadoのブロックデザインなのですが、「RTL」だらけで、一瞬、ぎょっとします。

それぞれのコアは、ARPリクエストに応答するモジュールや、UDPのチェックサムを計算するモジュール、PINGに応答するモジュールなどなどです。

このデザインは以下のことができます。

  • 100Mbpsでパケットを送れます
  • 任意のUDPパケットを送れます
  • ARPに応答したり、ARPを送信することができます
  • PINGに応答したり、PINGを送ることができます

Artyではちょっと無理ですがCosmo-Kに実装すればGigabitEtherや10GbitEtherが使えるようになります。

実際に試してみました。

まず、パソコン(192.168.1.2)からArty(192.168.1.190)にPINGを送ってみました。

Ethercore_2

ちゃんと帰ってきます。

このときのパケットをWireSharkで見てみると、

Ethercore_3

200~300usで返しています。

また、Artyの押ボタンスイッチを押すとUDPが送信されるようにしてみました。

ボタンを押すと・・

Ethercore_4

だーっとUDPが送信されます。中身はインクリメントしていく数字です。

別の押ボタンをPING送信に割り当てて、ボタンを押しますと、

Ethercore_5 .

これまたダーッと、192.168.0.0~192.168.255.255までPINGを送信しまくります。

WireSharkの画面を見ると1us以内に次のパケットが来ているようにも見えますが、受信側(PC側)でバッファされているのでしょうから、実際にどのくらいの速度になっているのかはわかりません。

とにかく、FPGAから生のパケットを送信することができるようになりました。

| | コメント (1)

2017.07.20

FPGAによるHDMI入力

アルバイトさんが、Cosmo-K DVIというFPGAボードでHDMI入力を可能にするデザインを作ってくれました。

(Cosmo-K DVIはKintex-7ボードで、詳細はまだ書いていません)

Cosmok_dvi

このボードにはHDMIの入力が2個、HDMIの出力が2個付いています。

今日できたのはHDMIの入力の片側です。

下の写真は、ノートパソコンのHDMI出力を本機に入れて、本機の出力をHDMIのモニタに表示したものです。

Cosmok_dvi2

Cosmo-Kには1GBのDDR3メモリが搭載されていて、フレームバッファとして使用しています。最初はDDR3の内容はランダムなので砂嵐が表示されます。

ノートパソコンに接続するとDDR3メモリにノートパソコンのデスクトップ画像が格納されて、それが表示されるようになります。

画面の解像度変更にもちゃんと付いてきているようです。

一見、完璧に動いているように見えるのですが、デジカメのHDMI出力や、RaspberryPiのHDMI出力につなぐと映らないので、何か必要なことが欠けているのかもしれません。

| | コメント (1)

2017.07.17

祝日なのに・・・

今日は祝日、海の日なのに、アルバイトさんが来て仕事をしてくれていたようです。

休日に来てMPPCという超高感度の光センサ基板と、電源基板、アンプ基板の設計を完成させてくれました。

Mppc1

それから、それらを納める筐体の蓋の設計も。

Mppc2

感謝感謝。

これが何をするものかというと、この装置のアップグレードです。

1479719723_mppc16

この赤い箱の中にはプラスチックシンチレータとMPPCという検出器があって宇宙線を検出します。

だけど、上の写真の去年作ったものは

  • 長時間動かしていると電源がだめになる
  • OPアンプは3段もいらない。2段で十分。
  • MPPCのバイアス電圧が個別に調整できない(全て感度が異なる)
  • MPPCの温度が測れない
  • どのコネクタがどのMPPCに対応しているのかわかりづらい

こういった問題がありました。そこで、一気に作り直そうというものです。

| | コメント (1)

2017.07.11

MITOUJTAGでDDR3メモリ基板の不具合を発見

あるお客様からの依頼で、DDR3を搭載した基板のデバッグをすることになりました。

いわゆるコンサルティングのご依頼です。

DDR3メモリを搭載した基板のキャリブレーションが終了しない(init_doneが立ち上がらない)とのことなのですが、確かに動きません。MIGの設定で数か所間違いはあったものの、直しても動きません。

クロック速度を下げても、データバス幅を狭くしても動かきません。オシロで見た感じでは波形の反射とかでもなさそうです。

普通ならここであきらめるしかないのですが、特電は違います。

MITOUJTAGがあります。

MITOUJTAGを使うと、FPGAの動作状態にかかわらず、JTAGを使って端子だけを操作するという強力なデバッグができるからです。

しかも、MITOUJTAG Proには、C言語のスクリプトを使って波形を作り出す機能があり、DDR3メモリの波形パターンを作るライブラリも用意されています。

Mjpro

FPGAを論理合成して動かす普通のやり方だと、規定された標準的な信号パターン以外は出せません。たとえば、DQSの配置が間違っていたり、配置できないピンにつないでいたりすると、どうしようもありません。

ところが、C言語でソフトウェア的にI/Oの端子を動かすのであれば、どのようなパターンでもFPGAから出力できます。

sun

そこで、まずはツール自体の動作をテストするために、確実に動作する特電のKintex-7ボードを使ってMITOUJTAGのスクリプトを試してみました。

1478579840_cosmok

DDR3メモリのテストのやり方は、

  1. データバスを1本1本Hにした書き込みを行ってデータバスのオープン/ショートを発見する
  2. その後、アドレスバスを1本ずつHにした書き込みを行って、アドレスバスのオープンショートを発見する

というものです。

実際には下の図のようなパターンを作り出します。波形の赤いところは出力している信号、緑は入力している信号です。

Ddr3_ok

このとき、コンソールには

Dq_path

と表示されます。

sun

次に、お客様の基板でやってみると、データバスのうち何本かで読みだしたデータが常にLになっていて、断線してることがわかりました。

Dq7_err

DQ7が切れていたので8bitに縮退させても動かなったのです。

そこで、中間のDQ[39:8]だけを使って32bitに縮退させたデザインをMIGで作って動かしてみると、問題なくDDR3 SDRAMが起動することが確かめられました。

FPGAを普通に動作させて、動作中の状態をバウンダリスキャンで見てみると、ちゃんとinit_doneの信号が上がるのがわかります。ちゃんと1600MT/sで動作しています。

Calib_done_2

どうやら基板のパターンの不具合のようでした。

エンドユーザさんに聞いたところによると、この問題でもう数か月止まってしまっているとのことでした。MITOUJTAG ProのJTAGスクリプト機能とDDR3ライブラリを使うことで、長い間かかっていた問題が、わずか1日で解決できました。

MITOUJTAGについて、詳しくはこちら↓をご覧ください。

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

| | コメント (0)

2017.07.10

XVCサーバを作る(1)

XILINXのVirtual Cable(XVC)サーバを作ろうとしています。

XVCは、基本的には

TMS:1111101100000000・・・
TDI:00000000001111100・・・

みたいなビット列を送ってきます。これを何も考えずにFTDIのBitBangのようにして送りだせばよいのですが、特電のJTAG製品はなまじっかインテリジェントになっているので、このような単純なビット列を送ることができません。

否、送ることはできてもGPIO扱いとなって、1ビット送るたびにUSBのパケットを1個使うので効率が悪いのです。

それでも何とか認識されることができました。

Xvc

これでUSBを挿すだけでXILINXツールから認識されることができます。

Vjtag4

下の図はKintex-7が認識されたところです。

Vjtag5

これでようやくNextを押すことができるようになりました。

Vjtag7

テストプログラムのコンソールの画面には、送受信されているビット列が表示されています。

Vjtag6

XADCで温度を見るくらいならばできますが、

Xvc2

書き込みは遅すぎて、Vivadoの進捗バーが1%のままから動きません。

さすがに使い物になりません。

| | コメント (0)

2017.07.08

「AWS EC2 F1について、みんなでワイワイ調べる会」に参加した

「AWS EC2 F1について、みんなでワイワイ調べる会」に参加してワイワイ調べてきました。

EC2 F1というのは、Amazonが、FPGAボードがついた仮想サーバを貸し出すというサービスです。

私はデバッグの仕組みであるVirtual JTAGについて調べてきました。Virtual JTAGを使うとVivadoでOpen Hardwareをすれば、ボード上のJTAGを介してChipScopeが使えたりメモリが見れたりといったデバッグができるはずなのですが、どういった仕組みで動いているかを解析するのが班の役割です。

簡単に言うと、XILINXにはネットワーク経由でターゲットボードをデバッグする抽象度の高い「hw_server」というプロトコルと、抽象度の低い「Xilinx Virtual Cable(XVC)」というプロトコルがあります。

hw_serverは「書き込め」とか「ChipScopeで波形をとれ」みたいな抽象度のことを高いことをやっていて、ネットワークの先にあるマシンがhw_serverのコマンドを解読して、JTAGの1001010101みたいなビット列を作ります。そのビット列をTCP/IP経由でJTAG端子をもったマシンのGPIOに出力するのがXVCというわけです。

Vjtag1

XVCはshift:、getingo:、settck:というコマンドくらいしか用意されていない単純なものです。shift:コマンドでTMSとTDIにデータを送ったら、TDOから受け取ったデータをテキストにして返すだけです。

XVCのサーバは仕様も公開されているので、誰でも作れますし、もちろんAmazonのサーバで動かすこともできますし、Zynqで動かすことだってできます。debug bridgeという標準IPも用意されていて、AXI-JTAGまで作れるのでZYNQにすぐに実装できます。

Vjtag3

AmazonのF1サーバの場合は、PCIe to JTAGというIP(おそらくPCI-AXIとAXI-JTAG)が使われていて、PCIeのどこかのBARにpeek/pokeして書き込むとJTAGの信号がテケテケ動くというものになっています。

だいたいの仕組みは以下の図のようになります。

Vjtag2_2

さて、JTAGでは何かのコマンドを送って、帰ってきたデータを見て次のコマンドを送る(例えば書き込み完了フラグを見る)ことがよくあります。書いて読んでをするとTCPのパケットが往復するのですが、XVCプロトコルでは読み書きのたびにTCPを送りあうので、遅延があるとスループットが遅くなることが容易に予見されます。

したがって、高位のコマンドを解析するhw_serverマシンと、低レベルなXVCを実行するターゲットマシンはネットワーク的に近いところにあったほうが良いでしょう。

実際にやってみようとしたのですが、AmazonのF1サーバを借りるには手続きに1日程度かかります。勉強会の時間内には借りられなかったので、すでにF1サーバを借りている人のを使わせてもらって試しました。ですが、その方のサーバにはhw_serverが入っていなかったので、XVCで接続しました。

そのさいの結果をパワーポイントにまとめて、発表しました。

下においておきます。

Vjtag_top

よくよく考えてみれば、PCI ExpressのGPIOからFPGA内部のBSCANにつなぐわけなので、JTAGが出てこなくてもいいですよね。PCI ExpressからChipScopeのDebugインタフェースにつなげばいいわけだから、仮想的にJTAGを経由しなくてもいいんじゃないだろうか・・いずれそうなるかもしれません。

はまったこと

・リージョンを北米バージニアにしないとF1のインスタンスは借りられない

・FPGAの論理合成だけなら東京のサーバでもできる。AMIとかいうのをXilinxにすれば、Vivadoの2017.1のフル版が入っているサーバが借りられて、UltraScale+の論理合成もできる。これは便利かも。

・デフォルトでは借りられるF1インスタンスの上限がlimit=0になっているので、AWSのサービス窓口にコンタクト(Webフォームからlimitを上げる要求)して、limit=1にしてもらわないといけない。これには1日程度かかるから、試したいと思ってもすぐにはできない

感想

  • 巨大なFPGAだから、hellow worldの論理合成に60分以上かかった。
  • UltraScale+じゃなくていいから、Kintex-7の小さなものを借りられるようにして練習できればいいのに。
  • これまでにもXILINXは組み込みマイコンでJTAGを動かすXSVFや、TCP/IP経由でJTAGを動かすCSE_SERVERなどの仕組みを用意してきたが、今回のXVCは本物かもしれない!?

時間内にVirtual JTAGの全貌が解明できてよかったです。

この成果を使って、特電のAritx-7ボードやKintex-7ボードもVivado対応にしようと思います。

| | コメント (2)

2017.07.04

Vivadoでソースファイルを秘密にしたIPを作る方法

Vivadoで配布するプロジェクトでソースコードを秘密にしたいと思ったことはありませんか?

例えば、

  • 商用のコアを作りたい人
  • 商用じゃなくても、秘密にしたコアを持っている人
  • 学生に実習用に渡すライブラリの中身を見せたくないTAさん
  • 学生実験のソースが汚すぎてTAに見られたくない学生さん
  • ・・

ソースを秘密にするには、いろいろな理由があると思います。

こういう場合、本来のVivadoの使い方は公開鍵を使って暗号化したものを配布するらしいのですが、NDAとかあって、すぐにできるものではありません。

そこで、誰もが簡単に、秘密IPを配布できる方法として、ネットリストを使った配布方法を紹介します。ネットリストというのは、HDLのソースを論理合成して、XILINXのプリミティブを当てはめたもので、要するにC言語に対するOBJファイルみたいなものです。

1.プロジェクトのディレクトリを作る

まずはプロジェクトのディレクトリを作ります。プロジェクトの本体とレポジトリを分けますが、そのほかにコアを生成するためのmycoreというディレクトリも作ります。全体の構造は下の図のようになります。

Vivsec1

そして、Vivadoでプロジェクトの本体を作ります。Vivadoでのプロジェクトの作り方については詳しい説明は割愛します。

Vivsec2 Vivsec3 Vivsec4

2.ISEでコアを作る

次に、XILINXのISE14.7を使って、コアのプロジェクトを作ります。コア名はledchikaとしました。Working Directoryがrepoのledchikaになっているところがポイントです。こうすると後で少し楽になります。

Vivsec5

そしてプロジェクトを作ったら、VHDLのソースを書きます。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library UNISIM;
use UNISIM.VComponents.all;
entity ledchika_core is
    Port ( clk_ip : in  STD_LOGIC;
           pushsw_ip : in  STD_LOGIC;
           led_op : out  STD_LOGIC_VECTOR (7 downto 0));
end ledchika_core;
architecture Behavioral of ledchika_core is
	signal clk     : std_logic;
	signal pushsw  : std_logic;
	signal timer   : std_logic_vector(21 downto 0);
	signal counter : std_logic_vector(7 downto 0);
	signal led     : std_logic_vector(7 downto 0);
begin
	clk    <= clk_ip;
	pushsw <= pushsw_ip;
	process(clk) begin
		if(clk'event and clk='1') then
			timer <= timer + 1;
			if(timer = 0) then
				counter <= counter + 1;
				if(pushsw = '0') then -- pushed!
					if(counter(4) = '0') then
						led <= x"ff";
					else
						led <= x"00";
					end if;
				else
					led <= not counter;
				end if;
			end if;
		end if;
	end process;
	led_op <= led;
end Behavioral;

Vivsec6

このとき、entityの名前は〇〇_coreのようにしておくと良いでしょう。

そうしたら、Synthesisのところで右クリックし、オプションを出します。そして、Xilinx Specific Optionsのタブを開き、Add I/O Buffersのチェックを外します。

Vivsec7

そして、Synthesisを実行します。

Working Directoryで指定したrepo/ledchikaの中にledchika_core.ngcというファイルができています。

Vivsec8_2

これがネットリストです。

3.ラッパ用のVHDLファイルを作る

そうしたら、コア用のラッパを作ります。ラッパは何もせずに下位のモジュールを呼び出すだけのものを作ります。component文では、ISEで作ったコアのエンティティ名を指定します。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity ledchika is
    Port ( clk_ip : in  STD_LOGIC;
           pushsw_ip : in  STD_LOGIC;
           led_op : out  STD_LOGIC_VECTOR (7 downto 0));
end ledchika;

architecture Behavioral of ledchika is

	component ledchika_core is
	    Port ( clk_ip : in  STD_LOGIC;
	           pushsw_ip : in  STD_LOGIC;
	           led_op : out  STD_LOGIC_VECTOR (7 downto 0));
	end component;

begin

	inst_ledchika : ledchika_core port map (
		clk_ip     => clk_ip,
		pushsw_ip  => pushsw_ip,
		led_op     => led_op
	);

end Behavioral;

4.VivadoでIPのプロジェクトを作る

そして、Vivadoへ戻ってメインのプロジェクトからTools->Create and Package New IPを行います。

Vivsec9

Package a specified directoryを行い、

Vivsec10

先ほど作ったngcとラッパVHDのあるディレクトリを指定します。

Vivsec11

出来上がったプロジェクトには、ラッパのledchika.vhdとNGCがデフォルトで登録されてますが、ツリーの中に入っていないので気持ちがわるいので、いったんngcを削除します。

Vivsec12

そして、Add Sourceで改めてngcを登録します。

Vivsec13

Copy sourcesのチェックは外しておきます。

Vivsec14

これで、ラッパの下にngcが入っている構造が認識されました。

Vivsec15

最後にPackagingして完成です。

Vivsec16

5.メインのプロジェクトから呼び出す

そうしたら、作ったIPコアをブロックデザインで呼び出せるようにします。プロジェクトのsettingsのIPの中からRepositoryを選び、今つくったrepoフォルダを指定します。

Vivsec17

サブディレクトリにあるIPコアが認識され、IPカタログから呼び出せるようになります。

Vivsec18_2

こうして、足をつけて、

Vivsec19

論理合成実行!

何事も問題なくBitstreamが作れました。

Vivsec20

ちゃんと動きます。

6.IPコアのソースを書き換える

IPコアのソースを書き換えたときは、再びISEでSynthesisを行います。ngcが生成されるので、Vivadoはngcの更新を検知してIP Statusが起動します。

Vivsec21

あとはいつも通りにRefresh IP Catalogを行って、Upgrade Selectedを行えばコアがアップデートされます。

Vivsec22

IPコアをRefreshするためにサブVivadoを開く必要はない(メインのプロジェクトでボタンを押すだけな)ので、普通にIPコアを作るよりも楽かもしれません。

なお、ISEのプロジェクトとソースファイルはなくても、NGCとラッパVHDLがあれば論理合成はできるので、ソースを秘密にしたまま配布できるというわけです。

7.まとめと注意点

要点をまとめると、

  • ISEに含まれるXSTを使ってVHDLからNGCを作る(そのとき、Add I/Oバッファは外しておく)
  • component宣言と、つなぐだけのラッパVHDLを作る。componentの名前はXSTで作ったコアの名前に合わせておく。
  • ラッパVHDLをIPコア化する。
  • 全体の論理合成には、ラッパVHDLとNGCがあればよく、ソースのVHDLは不要。

ということです。

注意点/問題点としては、

  • Kintexでやる場合は、UltrascaleがどうのというCritical Warningが出るのでNGCではなくEDIFでやったほうが良いかもしれない(Warningが少し減る)
  • ISEを使うため、Coregenの新しいコアが使えない
  • Genericでパラメータ化ができない

NGCではなくて、DCPを使えば上の問題は解決できると思うのですが、Vivadoの非プロジェクトモードでDCPを作る方法がわからないので、それは後日また試してみることにします。

NGCでのIPコアは配布はISEではよくやられていたのですが、最近ではあまり見なくなりました。この方法は古い方法なのですがVivadoでも使えることがわかりました。

ソースが秘密のIPを配布できると思うので、みなさんぜひ試してみてください。

| | コメント (0)

« 2017年6月 | トップページ