2017/06/28

[zybo]CLOCK_DEDICATED_ROUTE ?

以前、ボタンを押すとLEDが点灯するサンプルを真似して動かしたが、自力で書いてみたい。

module blink_led(
    output ld0,
    input btn
    );
    
    reg led = 0;
    assign ld0 = led;

    always @(btn) begin
        if (btn == 1) begin
            led = 1;
        end
        else begin
            led = 0;
        end
    end
endmodule

ld0にLEDを割り振っているのだが、直接代入させるとエラーが出た。
regみたいなやつじゃ無いとだめ、ということらしいが、reg変数をwire変数には突っ込めないということか。

image

btnを一度INPUTして、そのままOUTPUTしてld0に入っていくだけだ。
無駄無駄なのだが、if文を書いてみたかったのだ。

最初、if文をalways()の外に書いていたけどエラーになってね。。。
たぶん、always()の中に書いた文は順次処理文、外に書いた文は同時処理文と呼ばれているようなので、ifのように順番に処理するものはalways()の中に書かないといかんのだろう。


1回押したものが出ていくだけでは面白くないので、8回押したら点灯するようにしようとした。
always()の引数に書いた端子に変化があれば呼ばれるのだろうから、両エッジ割込みみたいなものか?

module blink_led(
    output ld0,
    input btn
    );
    
    reg [2:0] cnt = 0;
    reg led = 0;
    assign ld0 = led;

    always @(btn) begin
        if (btn) begin
            cnt <= cnt + 1;
        end
        if (cnt == 0) begin
            led = 1;
        end
        else begin
            led = 0;
        end
    end
endmodule

cntという3bitのreg変数を追加し、btnがHIGHだったらカウントし、ビットがあふれて0になったらLEDを点灯させようという考えだ。


そう悪くないと思うのだが、、エラーになってBitstream生成までのどこかでエラーになった。

[Place 30-574] Poor placement for routing between an IO pin and BUFG. If this sub optimal condition is acceptable for this design, you may use the CLOCK_DEDICATED_ROUTE constraint in the .xdc file to demote this message to a WARNING. However, the use of this override is highly discouraged. These examples can be used directly in the .xdc file to override this clock rule.
     < set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets btn_IBUF] >

    btn_IBUF_inst (IBUF.O) is locked to IOB_X0Y36
      and btn_IBUF_BUFG_inst (BUFG.I) is provisionally placed by clockplacer on BUFGCTRL_X0Y0

IOピンとBUFG間のルーティングが足りてないという意味か?
ルーティングというのは、配線のことだと思う。
btn_IBUFなどと書かれているが、btnはY16ピンに当てていて、前回から変えていない。


CLOCK_DEDICATED_ROUTEがどうのこうのと書かれているが。。。
検索すると、XilinxのPDFが出てきた。

CLOCK_DEDICATED_ROUTE を使用すると、 クロックソースがそのロードクロックバッファーに比べて不適切な箇所に配置されている場合に、 クロック配置の DRC をエラーから警告に変更できます。

注意:CLOCK_DEDICATED_ROUTE を False にすると、 クロック遅延に問題が出て、潜在的なタイ ミングおよびその他の問題が発生することがあります。

なにやら、制約を外すオプションらしい。
XDCファイルに、こんな感じで行を追加すればよいそうだ。

set_property CLOCK_DEDICATED_ROUTE value [get_nets net_name]

net_nameは他の設定を真似して書いた。

set_property CLOCK_DEDICATED_ROUTE false [get_nets btn]

が、これは途中でエラーになった・・・。
エラーメッセージに書かれている内容にすると通ったけど、warningが出てくるのよねぇ。
気にしなくてよいものか。

set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets btn_IBUF]


そして、動作はもっと気に入らない。
LoadさせるとLEDが点灯状態で始まり、ボタンを押すと消えたのだが、ボタンを押した回数とLEDが点灯するタイミングが不定だ。
なんだ、私のどこが間違っているというのだ。。。

CLOCK_DEDICATED_ROUTEで回避するという方法ではダメだったのだろうか?


I/OピンとBUFGを最適に接続できないから出てくるエラーらしい。

Vivadoで[Place 30-574]エラーが発生した時の対処法 | 彩の国・さきたま研究所
PC-9801Vm Style CLOCK_DEDICATED_ROUTE てナニ?


BUFGなんて使ってないよ!と思ったが、最初の方に載せた図を見るとbtn_IBUFというやつがいるな。
この図は最初のverilogから生成しているのだが、それにもかかわらず最初はそんなエラーは出ていない。
ということは、ソースを追加したことで、この図に変化が生じたのだろうか?

生じていた・・・。

image


コンパイルした結果みたいなものだから、これを読み解けば何が起こったか分かるだろう。

まず、左上のbtnが入力となる端子で、右側のld0が出力となる端子だ。
btnはRTL_LATCHのGに入り、Dの方は丸っこいのの出力になっている。

丸っこいのは、プラスマークが入っているから、加算器だろう。
今回で言えば、cnt <= cnt + 1、の部分だ。
上側のI1というやつが、上から吊られているからHIGHの1bit分ということか(Input1、なのかな?)。
そして、下側はI0(Input0 ?)で、これが右辺のcntに当たるやつだ。

その出力がRTL_LATCHに入って、Qから出ていく。
これが3bit分のメモリのようなものか。
マウスオーバーで説明が出てくるのだが、Typeが"RTL Register"になっていた。

その出力は、RTL_ROMの入力になっていて、そのままld0につながっている。
RTL_ROMのTypeは"RTL Memory"だ。


えー、btn_IBUFがないやん!


CLOCK_DEDICATED_ROUTEをfalseにしたことで、クロックが仕事に専念(dedicate)しなくなったため、スイッチをクロック代わりに使おうとしても、スイッチのINPUTを定期的に読む人がおらず、不定期に反応してしまったとか、そういう現象だろうか?

だったら、何とかしてクロックを入れてやればよいのかもしれない。


ZYBOのPDFを見ると、PL部にはCLK125からL16へクロックが入っているように見える。
が、なんでEthernetのPHYからなんだ?
50MHzということはRMIIだろうか。

image

あるいは、PS_CLKへのINPUTからPLLが動かないとPL部にはクロックが入っていないことになるのだろうか?

ソフトにとってはクロックってINPUTというよりは別次元で餌が与え続けられているようなイメージなので気にしなかったのだが、明示的に何かしないといかんのかもしれん。
CLOCK_DEDICATED_ROUTEの説明も「クロックソースがそのロードクロックバッファーに比べて不適切な箇所に配置されている場合に」だったので、適切な位置に配置すればよいだけなのか。


と推測したけど、何をしてよいかわからん。
検索だ!

PiTs laboratory: ZYBOのPLだけを使う場合のクロックソース
PSが動いていないとFCLK_CLKは動かないようだが、L16の方はクロックとして使えるらしい。


らしいが・・・だからなんなのだ?
btn_IBUFとかいうInput用のバッファを使うためにclkがどうのこうのという話だと思うので、btn_IBUFとかいう部品にクロックを突っ込んでやればよいとかじゃないのか???


そういえば、最初に参照したサイトは、自分でXDCファイルを変更していたな。。。
【Zynq】ZyboでPLのみ使用してLチカしてみた

よくわからんが、btnをやめて、clkをコメントアウトし、btnの代わりにclkを使うようにしてみた。
カウント数は8では足りないだろうから、どこかのサイトを見て増やした。
(ブラウザを閉じてしまって、どのサイトかわからなくなってしまった。。。)


そうすると、動くのだよ、動いたのだよ!
btnもclkも割込みで動くようなイメージで考えていたのだけど、そこは考え方が間違っているようだ。
うーむ、奥が深い。

2017/06/27

[zybo]ZYBO向けのLinux (1)

ZYBOのような組込み開発用のボードでOSが載る場合、ほぼメーカーがボード用のOSをリリースしていると思っている。
昔は「自分でがんばってね」という感じだったのだけど、提供するところが増えてきた今、使ってもらうためには「今すぐ使えます」を売りにしないといかんのだろう。

ZYBOはCortex-Aが載っているし、SDカード無しでもLinuxが動いているから、OSを動かしたいならLinuxがよいだろう。
ARMのCortex-Aだから、アドレスさえうまくやっておけばどのLinuxでもいいとは思うのだが、初っぱなから失敗したくないので、動くOSがあるならそれをまずは使いたい。


Zybo [Reference.Digilentinc]

これがZYBOを販売している会社のページで、右側のDesign Resourcesにいろいろファイルがある。

image

ここにPetalinux BSPというのがある。
XilinxはPeta Linuxというディストリビューションを使っているらしい。

https://github.com/Digilent/petalinux-bsps
ここからOSがダウンロードできるのかと思ったけど、Linuxが動きそうなサイズでもないし、かといってスクリプトしか載っていないようなサイズでもない。
そして、READMEにも何も書かれていない。。。


PetaLinux ツール
Xilinxのページで、右の「クイックリンク」にPetaLinuxがダウンロードできそうな項目があるのだけど、クリックしても行き当たらない。
英語ページだったら行くかと思ったが、そうでもなさそうだ。


では、ZYBOのリンクにあるPetalinux BSPが使えるのだろうと思ったけど・・・と、考えがぐるぐる回ってしまったのだ。


ここに、Xilinxが認識している動作OSが載っていた。
https://japan.xilinx.com/products/design-tools/software-zone/embedded-computing.html#os

いろいろある。

Xilinxのgithubにはkernelが置いてあった。
今の最新は、4.9.0のようだ。
https://github.com/Xilinx/linux-xlnx/blob/master/Makefile

kernelだけあっても困るので、ディストリビューションになっているものがよい。
PetaLinuxがよいのか、FPGAマガジン No.12ではYocto ProjectのLinuxを動かしているので、それがよいのか。。。


まあ、試すのは無料だから、Yocto Projectをまずは試すことにする。

2017/06/25

[xilinx]Vivadoの種類

Xilinxの開発環境は「Vivado(ヴィヴァドゥ?)」というようだ。
インストールしたものの、選択肢としてどれがよいのかさっぱりわからん。

いくつかインストールしたついでにAbout画面のスクリーンショットを撮ったので、載せておこう。


Vivado HLS 2017.2

image


Vivado 2017.2

image


xsdk 2017.2

image



image

Design EditionとSystem Editionがあるのだけど、どっちがどうなのだろう?
Systemの方が上っぽい感じはするが。

Vivado Design Suite
Design EditionとSystem Editionの両方とも「パーシャルリコンフィギュレーション」というやつが追加費用無しでできるが(保証期間内だけ?)、WebPACK Editionは追加費用がかかるらしい。
が、これではわからんなぁ。。。


Vivado Design Suite 評価版および WebPACK
一覧表があった。
違いは、"System Generator for DSP"の有無のようだ。
画面の選択肢に書いてあるとおりだな。


いや、そもそも私はDesign Editionを選択したのだけど、実はよくある30日間の無料試用版なのだろうか。
Installing Vivado [Reference.Digilentinc]
ZYBOの販売先にあるインストール説明でも、WebPACKと書いてあるし。


今回、ZYBOはSDSoCのライセンス(購入したボードのみという制限はあるが)もセットにしたので、SDx開発環境というものもインストールした。
というよりも、先にこちらをインストールして使っていたのだが、後述する問題点があったので2017版をインストールしたのだ。



Xilinx_SDSoC_2016.4_sdx_0310_1_Win64.exe

image

インストール画面。
ZYBOにはZynq-7010が載っているから、それだけ選べばよいよね?
これは何回目かのインストールしなおしをした画面なのでCable Driverのチェックは外している。

インストールすると、Vivadoとxsdkも一緒にインストールされた。



Vivado 2016.4

image


image


で、SDx開発環境の何が問題だったかというと、SDx IDE 2016.4だ。

Windows10のバージョンによるのかもしれないが、うまく起動できなかったのだ。
ZYBOのチュートリアルに書かれてある起動方法では、スプラッシュ画面が出てしばらくすると落ちる(%APPDATA%\Xilinx\Vivadoにhs_err_pid***.logというファイルを見ると、Java自体が落ちている)し、単体だと起動できるのだけどもFPGAに関する機能が使えないのだ。

image

たぶん、ツールバーの空白になっているところにFPGA関連のボタンが出るはずなのだが、無い。
Xilinxメニューにも、何も出てこない。
プラグインが起動できなかったとか、そういう理由だろうか。

image

こちらが、2017.2のXSDK。
違いは明らかじゃろう。


ただ、「SDSoC」という名前が入っているのはSDx IDEだけなので、C/C++でFPGAのコード?が書けるというSDSoCという機能を使いたかったらこれしかないのかもしれん。


SDx IDEはeclipseで、パースペクティブは「SDx」というものになっていたのでcustomize画面を開いた。

image

toolbar1というやつが表示されていないだけか・・・?
3つともチェックして再起動すると、アイコンが出てきたし、押すとチュートリアルにある画面も出てきた。

image


VivadoからのLaunchはできないけど、これでSDSoCの機能も使えるのであれば問題ないと思う。
問題があるとすれば、私がSDSoCが何なのかわかっていないことと、そもそもFPGAがよくわかっていないということだろう。
FPGAマガジンNo.16にはSDSoCのことも書いてありそうだから、買ってみるか。

2017/06/24

[zybo]ZYBOを動かしてみよう

いきなりだが、XilinxのFPGAであるZYNQ7010が搭載されたZYBOというDIGILENT社のボードを動かしてみた。
むかしから、FPGAというものを動かしてみたかったのだけど、仕事でしか見たことがなかったので、個人で使えるような時代になっていると思っていなかったのだ。

しかも、Linuxが動くARMのCortex-Aが載ったボードまであると言うことで、そろそろやってみてもよい時期だろうと判断したのだ。
判断したというか、やってみたい熱が高まっただけだがね。


ZYBOは、秋月通商さんで購入。

image

比較のためPaSoRiと一緒に撮影したが、小さいねぇ。
Cortex-Mに比べると大きいけど、そこと比べるものでもないだろう。


勢いで購入したものの、そもそもFPGAを自分で構成したことなどないので、まずは一連の流れをやっているところを探しました。

6. Zynq Verilog-HDLをZynqに書き込みFPGAを使う – yuki-sato.com
【Zynq】ZyboでPLのみ使用してLチカしてみた

この2箇所を見て、動かすことができた。
私はVerilogの方を使ったが、ハードウェア記述言語(HDL)としてはVerilogかVHDLが使えるようだ。
Wikipediaによると、厳密には"Verilog"はエミュレータのことらしい。
VHDLはVerilog HDLの略ではなく、別の言語。
誰がこんな紛らわしい名前にしたんだ・・・と思ったが、VHDLの"V"はveryらしいし、Verilogは名前の由来が分からないので、どっちがどうのという話でもなさそうだ。


なお、Windows10にインストールする際はここを参考にした。
VC++のランタイムって、該当するバージョンが入っているだけではダメなのか?
謎は残ったが、今回は困らないので削除した(Vivadoの2017版は関係なく動いたが、SDxは2016版が自動的にインストールされるので、そういう制約になってしまうようだ)。
FPGAの部屋 Vivado や Vivado HLS が Visual Studio 2012 Visual C++ Runtimeのインストールダイアログが出て起動できない


やっていることを、整理してみよう。


まず、プロジェクトを作成する。
「RTL Project」を選ぶそうだが、RTLとはなんだ?

Register Transfer Levelの略
レジスタ転送レベル - Wikipedia

CPUのレジスタとは違うもので、ごくごく小さな回路を「これはレジスタね」と決めて、そういうレジスタからレジスタへのINPUTとOUTPUTを書いていくもののようだ。

Lはlanguageじゃなくて、levelなのが気になる。
Wikipediaのはそこまで書かれていないが、「ゲートレベルよりも抽象的な記述レベル」と書いてあるので、何かのものを指す用語ではなく、切り口というか考え方というか、そういうもののようだ。
ゲートレベルがアセンブラだったら、レジスタ転送レベルはC言語、みたいな感じかもしれん。


プロジェクトを作ったら、HDLで内容を書く。
こちらを参考にVerilogで書いた。
引数?が昔のC言語っぽいので気になったが、今のC言語っぽく引数内に型?を一緒に書いてもよいようだ。

module led(output led, input button);
    assign led = button;
endmodule

C言語っぽく、{}で囲みたいところだが、それは我慢だ。

なお、ZYBOに転送すると Vivadoの画面がHardware Managerになって、Verilogのファイルが載っていたナビゲーションが消えてしまう。
元に戻したい場合は、左側の"Flow Navigator"からProject Managerをクリックするとソースファイルが入ったツリーが出てくる。


次は、Verilogのoutputやinputで付けた名前と、実際のポートを割り付ける作業だ。
"RTL Analysis"内の"Elaborated Design"を選択して、レイアウトを"I/O Planning"にして行っているのが、それだ。

画面には、FPGAのBGAっぽいものが表示されるが、そっちは見方がわからん。
画面のしたにI/O Portsという一覧が表示されていて、Verilogの引数にしたものが出てくるようだった。
「I/O StdをLVCMOS25などに切り替えましょう」と説明されていたが、「Low Voltage CMOS 2.5V」という意味なんじゃなかろうか。
ZYBOのドキュメントには、3.3Vで吊られている図が載っていたので、2.5Vくらいにしようぜ、ということかもしれん。


その後は、「Run Synthesis」「Run Implementation」「Generate Bitstream」を実行すると、FPGAのPLに転送するデータができるようだ。
ツールバーに3つ並んでいる。

image

しかし、用語のそれぞれがわからん。

まず、Synthesis。
単語としては、合成とか組み立てとか。
Xilinx Synthesis Technologyを略してXSTと呼んでいて、合成ツールという位置づけのようだ。

合成は、論理合成を指しているのだと思う。
だからXilinx専用の言葉ではなさそうだ。
Wikipediaの説明では、HDLで書かれたものをRTLまで変換するツールのようだ。
HDLがRTLかと思っていたけど、もう少し高級ということか。
HDLがC言語としたら、RTL相当なものがアセンブラで、それを論理ゲートレベルまで変換したら機械語、くらいなのかな。


次はImplementationだが、ソフトでいえば実装だが、FPGAではこのページの「デザインインプリメンテーション」に当たるのかな。
半導体技術解説:いまさら聞けない FPGA入門 (3/3) - MONOist(モノイスト)

詳しいことはわからんが、コンパイル後の最適化みたいなものか。
そういえばGCC4から中間言語に変換して最適化するようになったが、あれもRTLと呼ばれていたな。
GCCのRTLは、Register Transfer Languageのようだ。
GCC 4 について学ぶ


そしてBitstream。
Monoistのページではデザインインプリメンテーションの中に入っているが、FPGAに書込むことができるデータを作る工程のようだ。
拡張子はbitで、プロジェクト名がprojだった場合、proj/proj.runs/impl_1/proj.bit、というところにできているようだ。


そして、これを"Program and Debug"を使ってFPGAに転送すれば動くようになる。
どうも、FPGAに焼くというよりは、転送する、という感じがしている。
電源を入れ直すと動かなかったからだ。
PL部だけ電源OFFにすることもできるようなので、PS部から毎回転送するイメージなのかもしれん。

2017/06/22

[c/c++]引数が多いことに対する抵抗が薄れてきた

関数を作るとき、あまり引数が多いのはよろしくない、と教えられて育って(?)きた。

もちろんそれには理由があり、C/C++コンパイラはある程度の数までは引数をCPUのレジスタで引き渡し、それ以上になるとスタックメモリに入れて引き渡すからだ。
C言語の規格書を読んだことがないので決まりなのかどうかは知らないが、メーカー製のコンパイラ仕様なんかを読むとだいたいそうなっていた。


これはARM Cortex-AのARMv8-Aのようだが、Argument registersということで8つ確保してある。。。のだと思う。
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/ch09s01s01.html

別の環境で、Cだと4つまで、C++だと3つまではレジスタ渡しするというのも読んだことがある(thisで1つ取られるからね)。
CPUによってレジスタの数や使い方が違うだろうから、全部同じではないだろう。


以前はけっこう気にしていたのだが、そんなに効果があるのかも気になっていた。
引数をたくさん与えないといけない関数は、だいたい使用頻度が少ないものが多かったからだ。
使用頻度があまりにも多い場合は、マクロ関数なりinline関数にするとそこそこ対応できるし(ROM容量との兼ね合いにもなるが)、みんなが使うのでstaticなどでグローバル変数にしているから渡す必要がなかったり。

引数を渡すということは、モジュールと切り離したいという意思が強いだろうから、そういうのはstructにして渡せるようにし、グローバル変数みたいにして保持するときもstructのままで持っておくと渡しやすい。


いや、何の話をしているかというと、引数が多いのはよろしくない→じゃあstructを用意して代入してポインタで渡す、などということを自分でやっていたからだ。
それって、スタックにためて渡すのとあんまり内容として変わらないけど、実装の手間だけ増えてるよな、と漠然と思っていたのだ。

そんなことをするくらいだったら引数が多いままの関数を作ってもよいし、そもそもそういう関数を作らなくていいような構造にできるした方が効率いいんじゃないの、という「引数が多いのはよろしくない」という警告だったのかもしれない。


そんなことを自分で作った引数8個の関数を見ながら思った。