• 3. Zynq LEDのIPコアを作り接続する

    Vivadoでやらなければいけないのは

    1. LEDのIPを作る
    2. それをAXIバスと、外部端子に接続する
    3. ハードウェアデザインとbitstreamを作る

    です。まずは今あるLEDのIPを消しちゃいましょう。
    Diagramの中央右辺りにLEDs_4BitsというIPがあると思います。これを右クリックして「Delete」

    lb8

    消すと、配線が消えてLEDの外部端子だけが取り残されます。

    lb11

    また、ProjectSettingからIPのベンダー名を変更するようです。
    IPのPackagerのVendorをDigilentにしてOKを押します

    lb16

    新しいIPを作る

    ここで、新しいIPを作りましょう。Linuxからアドレスでアクセスできて、4つのLEDを操作するIPです。「Tools」->「Create and Package IP」を押します

    lb12

    Nextを押し、「Create a new AXI4 peripheral」を選びます。

    lb17

    名前などはチュートリアルに従ってmyLedとmyLed_v1.0にします。 次へ

    lb18

    AXIインターフェイスの設定画面になります。やることはNameをS_AXIにすることです。

    lb19

    これで完了です。Edit IPを選んでFinishしましょう。

    lb20

    すると、プロジェクトが開かれます。

    lb21

    この新品のプロジェクトはAXIバスに繋がるようになってはいますが、出力するようにはなっていません。なので、4bitの出力端子を作成します。
    Verilogのファイルが2つあります。両方編集します。
    myLed_v1_0_S_AXIの2箇所に以下のように
    output wire [3:0] led,

    assign led = slv_reg0[3:0];
    を追加します

    lb79

    lb80

    また、myLed_V1.0の方は
    output [3:0]led,

    .led(led),
    を以下のように追加します。

    lb22

    lb25

    編集はこれだけです。
    これはつまり出力端子を4bit幅で用意してslv_reg0がそのまま出るようにしています。
    あとはIPの作成です。
    Package IPを押します。

    lb26

    そうするとIPのパッケージ画面が出てきます。
    lb27

    「Customization Parameter」の「Merge Changes From,,,」を押します

    lb28

    そうすると「Ports and Interfaces」でledが見えてきます

    lb29

    「Customization GUI」でも問題なさそうです。変更しちゃダメですよ。

    lb30

    ここまできたら「Review and Package」 の下にある「Package」ボタンを押します。lb31

    2回目以降は「Re-Package IP」になりますけどね。
    正常に終了したら「前のプロジェクトに戻りますか?」と聞かれるのでOKを押して戻りましょう。
    lb32

     追加する

    作成したIPを追加してつなぎます。AddIPからmyLedを追加します。

    lb33

    きれいな場所に出ることもあれば変な場所に出ることもあります。今回はちょっと変。

    lb34

    正しい場所へ移動します。

    lb35

    そしたらS_AXI端子を右クリックしてMakeConnectionをおしましょう。するとAXIを自動的に配線してくれます。

    lb36

    どのAXIか聞かれます。まぁ1つなのでこれを選んでOK

    lb37

    s_axi_aclkとs_axi_aresetnは自分でマウスの左クリックで配線します。

    lb39

    今度はLEDです。今あるのは邪魔なので右クリックで削除

    lb40

    IPの出力端子を右クリックして「Create Port」から外部出力端子を作ります。

    lb41

    名前はledにします。あとはデフォルトのままで大丈夫です。

    lb42

    これでIPの出力がledという外部端子になりました。ただ、番号をまだ決めてないので(あとでやります)何番ピンかは不明です

    lb43

    ここで、http://marsee101.blog19.fc2.com/blog-entry-2915.htmlによるとAXIのslaveとしてアドレスが割り当てられていないとのこと(ほんとにこういうの助かります)
    上の「Address Editor」を押します。
    lb44

    Unmapped SlavesにいるmyLed_0を右クリックし、「Auto Assign Address」を押します。

    lb45

    これでmyLed_0に0x43C30000からのアドレスが割り当てられました。
    これはLinuxからアクセスするときのアドレスになります。

    lb46

    ピンアサイン

    ledのピンをアサインします。base.xdcを開きましょう。
    ここではダイアグラム上のピンが何番ピンなのかとか、ピンの制約は何かとかを設定します。
    7~11にさっき消した古いledのアサイン情報が残ってます。名前だけ変えちゃいましょう

    lb47

    これが古いもので、これのleds_4bits_tri_oを

    lb48

    ledに変更します。
    leds_4bits_tri_oを選択して右クリックから「Replace」を選びReplace: led とすると一気に変更してくれます。

    lb55

    この時にxdcファイルだけでなく他のファイルにも文字が見つかった場合はそれも変更します。
    変更が終わったらGenerateBlockDiagramを押して再度確認してみましょう。
    「Toolf」->「Find」からleds_4bits_tri_oで検索して本当に亡くなったか確認できれば完了です。

    BitStream作成

    Bitstreamを作成しましょう。

    lb50

    カスタムIPのプロジェクトを保存するか聞かれると思うので、保存します。

    lb51

    また、論理合成や実装もやるよねって聞いてくるのでYESで実行しましょう。

    lb52

    幾つかWarningが出てくると思いますが、大丈夫です。lb53

    出力する

    Bitsreamの作成が完了したら、出力しちゃいましょう。
    「File」->「Export」->「Export Hardware」を押します

    lb56

    Include Bitstreamにチェックを入れてOKを押して出力します。

    lb57

    これでVivadoでやることは終了です。大変でしたね。

    次はUbuntuにてU-Bootを作成します。
    VivadoなしのUbuntuでGCCだけでU-Bootを作る


     

    メモ カスタムIPを再編集する

    今回LEDのIP作りましたが、後からでも再編集してIPを再度作ることが出来ます。
    「Verilog間違えた!」ってときとかですね。
    編集したいIPを右クリックして「Edit in IP Packager」を押すと、またIPの編集画面を開いてVerilogの変更などが出来ます。

    lb78

    変更したらRe-Packageを押してプロジェクトを閉じると新しいIPで自動的にリロードしてくれるので元のプロジェクトで変更がすぐに反映されます。

  • 2. Zynq Digilentからプロジェクトをもらってくる

    では、早速始めましょう。基本的にはDigilentのpdfの通りでOKです。

    何をするのか

    最終的に作成したいものはなにか知っていると理解に役立つと思います。
    作成したものは全てSDカードに入れます。最後にはSDカードはこうなっています

    Screen Shot 2015-01-11 at 14.35.18

    • BOOT.bin ・・・FSBLとbitstream(FPGAの設定ファイル)が入っている。これが起動してLinuxを動かし始める
    • devicetree.dtb・・・デバイスツリー。どのアドレスに何があるかなどLinuxにデバイスについて教えるためのもの
    • myled.ko ・・・・今回作るLEDのLinuxにおけるデバイスドライバ
    • uImage・・・Linuxカーネル。今回はこれも0からビルドしてみる
    • uramdisk.image.gz・・・HDDはZYBOにないので、ディスクイメージをRAMに展開する。その時の最初のディスクイメージがこれ。

    これらを作成します。手順としては

    1. BOOT.binを作る
      Vivadoでプロジェクトと新しいLED用のIPを作成してつなぐ。U-Bootをコンパイルしてそれと一緒にSDKでBOOT.binを作成する
    2. uImageを作る
      Linuxをコンパイルする
    3. ramdiskを作る
      これはただ公開されているものから作成するだけです
    4. devicetree.dtbを作る
      新しいLEDがある事を追加してデバイスツリーを作成
    5. デバイスドライバを作る
      あるアドレスを読み書きするデバイスドライバを作ります

    WIndowsとVivadoが登場してくるのは1だけで、あとはUbuntuを使います。
    Ubuntuの入れ方が分からない方は
    http://zakkiweb.net/a/20/
    とかを参考にして下さい。
    vagrantがオススメです。vagrantの場合はboxは
    http://files.vagrantup.com/precise64.box
    を使いました。

    プロジェクトを入手

    まず。ZYBOのページ
    http://digilentinc.com/Products/Detail.cfm?Prod=ZYBO
    から「ZYBO Base System Design」をダウンロードします。
    lb2

    適当な場所(出来ればパスが短くなる方が良い C:¥Projectsとかね)lb4

    Zipファイルを展開して zybo_base_sstem>source>vivado>hw>zybo_bsdのなかにvivadoのプロジェクトファイルがあるので開きましょう。
    すると、プロジェクトのバージョンが古い影響でUpdateを聞かれます。
    lb5

    このままOKを押してUpdateしてしまいましょう。
    あとはちょっとしたDialogが出てきますが問題ありません。
    lb6

    開かれるとこんなふうに既にDiagramができているプロジェクトが開かれます。
    これはZYBOボードに合わせた設定がされています。既にHDMIのIPがありますし、ボタンもあれば、実はLEDもすでに作成されてつながっています。

    lb7

    「じゃあ作らなくていいじゃん」って思いますが、これは作る勉強なので次回からLEDのIPを作成・追加していきましょう。

    ちなみにUpdateの時にもエラーが出ましたが、VerifyBlockDiagramや、Generate Block Diagramを押した時にもCritical Warningが出ます。

    lb82

     

    [shell]

    [BD 41-1348] Reset pin /axi_dispctrl_0/s_axi_aresetn (associated clock /axi_dispctrl_0/s_axi_aclk) is connected to asynchronous reset source /processing_system7_0/FCLK_RESET1_N.
    This may prevent design from meeting timing. Please add Processor System Reset module to create a reset that is synchronous to the associated clock source /processing_system7_0/FCLK_CLK0.

    [/shell]

    全部、こういった内容のものです。これは何かというと「非同期リセットになってる」ってことです。通常リセットはクロックのタイミングで行われるのが良いのですが、そういう風になってないというものです。Processor System Reset というIPを追加して配線すれば良いのですが、大変ですし今回はこれでも動くのでここまま進みます。

    次へ

  • 1. Zynq LinuxからFPGAを利用するって?

    ZynqはARMコアが載っていて、FPGAとつながってるわけです。
    当然やりたいのは「ARMで動かしてるLinuxからFPGAを使う」ことです。
    これができたらFPGAにちょっとした難しい処理をするハードウェアを作っておいて、
    使い慣れているC言語やNode.jsのソフトからその回路を使うことで簡単に高速化などが出来ちゃいます。

    つなぐってどうやって

    Zynqの中はPL部(ARM)とPS部(FPGA)で、できていますね。
    PL部に自分で回路を作って、ピンにアサインして外の電子部品を制御することも可能です。
    もちろん外部に出さないで、高速な画像処理回路を組んでどことも繋がないということもできます。
    Screen Shot 2015-01-11 at 19.19.44

    この回路にPS側から(つまりLinux)からアクセスするにはどうしたらよいでしょうか。
    PSとPLは接続可能で、PL部をメモリにマッピングすることが出来ます。

    Screen Shot 2015-01-11 at 19.21.42

     

    マイコンをよく使う人には分かりやすいでしょう。メモリというのは全部RAMってわけじゃなくて、ある番地はUARTの受信、ある番地はI2Cの制御レジスタなど、連番だけど、いろんな機能が割り振られています。
    同じようにPLに作成した回路もメモリにマッピングできます。RAMに書き込むつもりでメモリに書き込むと実はPLのその番地に接続されているある回路にデータがおくられて、RAMからデータを読むつもりで読み取っても実はPLからデータを受け取っているということが出来ます。こんなイメージね。

    Screen Shot 2015-01-11 at 19.23.03

    これができるとLinux側はただメモリにアクセスして読み書きすればいいことになります。
    ただ、実際は決められたアドレスにアクセスするのは危険ですし、権限の問題もあるので、デバイスドライバを作成して、メモリへの読み書きをファイルへの読み書きでできるようにします。
    fopenで開いてfreadで読み取ってというどっかでやったことあるやりかたでFPGAからPLに接続できます。

    チュートリアルがあります

    DigilentからZYBOのボード用に「LED4個をPLに追加してLinuxもコンパイルしてLinuxから使ってみる」というチュートリアルがありますのでそれをやります。
    http://www.digilentinc.com/Data/Products/ZYBO/ZYBO-Embedded_Linux_Hands-on_Tutorial.pdf

    また、以下の2つの日本語サイトもすごく参考になると思います。
    http://nerdengineer.com/jp/blog/files/09c7e46c28ab96e4ecce1800b9b11575-3.html
    http://marsee101.blog19.fc2.com

    それぞれ、Ubuntu上で全てやったり、WindowsとUbuntuを使ったりしていますが、
    僕はWindowsとUbuntuで、ただし、UbuntuではVivado無しでGCCのみで作業をします。

    では、早速やってみましょう。

    Digilentからプロジェクトをもらってくる

  • 6. Zynq Verilog-HDLをZynqに書き込みFPGAを使う

    前回はFPGA部分(ZynqではPL部と呼ばれています)は無視していました。
    とりあえず回路構成をSDKに教えて、SDK側でARMのデバッグ実行を指定ました。
    実はSDKはARMの操作やデバッグに使うためのもので、PL部のプログラムだけならVivadoから行えます。今回は簡単なVerilog-HDLで回路を構成してZynqに書き込んでみましょう。

    Verilog-HDLを書く

    Vivadoを開いて前回利用したプロジェクトをそのまま利用します。
    新しいVerilogを追加するには「Add Sources」を押します。

    bitstream0

    「Add or create design sources」を押します。

    bitstream1

    ここで既存のファイルを入れるのか、新しくファイルを作るのか決められます。
    新しく作りたいので「Create File…」を押しFile typeで「Verilog」を選びます。File nameは適当にledなどと入れて。「OK」を押します。

    bitstream2

    Finishを押して完了させるとVerilogが出てきますが、 同時にポートの設定Dialogも出てくると思います。これはあとでも出来ますので「Cancel」で閉じておきましょう。

    bitstream3

    Sourcesウインドウにled.vというファイルが追加されていると思います。
    恐らくSimulation SourcesとDesignSourcesのそれぞれのNon-module Filesっていう場所に入っていると思います。
    ファイルはダブルクリックで開けますが、どちらも同じファイルを指しているのでどちらから開いても同じファイルになります。

    bitstream4

    開いたら今回のVerilogを書いてみましょう。
    今回は入力をそのまま出力に出すというものです。

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

    これをled.vに書き込みます。
    ファイルの保存は右クリックから「Save File」で保存できます。

    bitstream9

    ちなみに保存した瞬間にVerilogとして正しいかが検証されます。
    もし文字を間違えたりして文法エラーを起こしていたら「Syntax Error Files」に入ります。
    bitstream7

    また、エラーの詳細は右下の「Log」というところに出てきて、細かく何が違ったのか、どのファイルの何行目なのかを教えてくれます。

    bitstream8

    問題がなければ保存すると同時にNon-module Filesから出てきて、前回勝手に作成されたwrapperファイルと同じレベルにled.vが上がってきます。

    bitstream10

    led.vを論理合成させるためにled.vをTopに持ってきます。
    今はledでなくwrapperが太文字になっていると思いますが、それはwrapperがTopになっている証拠です。ledの方をTopにするにはledを右クリックし「Set as Top」を押します。

    bitstream16

    ledが太文字になるはずです。
    ここまででVerilogの準備は出来ました。

    RTL Analysis

    Verilogである入力がある出力にそのまま繋がるというのは決めました。じゃあそれってどのピンなのよというのはまだ設定していません。RTLAnalysisのI/O Plannningから設定します。
    FlowNavigatorのRTL AnalysisにあるElaborated Designを押します。
    初めて押す場合は押すだけで前処理が始まり、一度押した場合は既に作成されているので右クリックから「Reload Design」を押します。

    bitstream6

    終わったら下にある「Schematic」を押してみましょう。Verilogで書いた通りの回路が出てくると思います。

    bitstream14

    ここでVerilogで設定した入出力がどのピンなのか、CLockどうするのかTimingどうするのかを設定できます。今回はとりあえずピンだけ設定しましょう。上に「Default Layout」となっている部分をI/O Plannningにします。

    bitstream17

    すると下に「IO Ports」ってのが出てくると思います。これこそがVerilog上のピンと実際のZynqのピンをつなぐためのものです。

    bitstream13

     

    今回どこへつなぎましょうか。ZYBOの説明書によるとスイッチやLEDはこうなっています。

    bitstream12

    PLから利用できるLEDは4つD18, G14, M15, M14です。
    スイッチはスライドスイッチとボタンがそれぞれ4個あります。
    今回はY16のボタンとD18のLEDをつかってみましょうか。
    さっきのIOPortsの「Site」っていうのがZynqの物理ピンを選択する部分です。
    buttonの方をY16に、ledの方をD18に設定します。
    「I/O std」にdefaultの赤文字がついていますが、defaultだと後で失敗します。
    LVCMOS25などに切り替えましょう。
    これでピンアサインは終わりです。

    Synthesis-Implementation-GenerateBitstream

    あとはZynqに書き込むためのbitstreamを作成するだけです。
    「Run Synthesis」「Run Implementation」「Generate Bitstream」の3つをそれぞれ実行します。
    ちなみにそれぞれ終わるときに「次これやります?」と親切に聞いてくれるのでそのまま従ってみましょう。

    ボードを開く

    VivadoからJATG経由でbitstreamを書き込みましょう。
    OpenHardwareManagerからOpen Targetを押しOpen New Targetを押します

    bitstream18

     

    後はDialogに従って行くだけです

    bitstream19

     

    Connect toではLocal serverを選びます。
    Local serverって何かというと、JTAGでZynqにはつなぐわけですがVivadoとSDK両方でJTAGを使うこともありそうですよね。なので、JTAGを使いローカルサバーとして立ち上がっているプロセスがあってそこにつなぐことでそれ経由でボードにbitstreamを書き込んだり出来るのです。

     

    bitstream20

     

    問題なくボードが見つかればこんな風になると思います。下の写真だと2つ出てきてますが、xc7cの方がZYBOボードですのでそれを選んでNextで進みます

     

    bitstream21

     

    以上で完了です。

     

    bitstream22

     

    デバイスが追加されると、HardwareManagerが開かれます。

    bitstream23

     

    これでbitstreamを書き込める状態になりましたので、早速書き込みましょう。
    Hardware Managerの「Program Device」を押して、先ほど追加したチップを選択します。

    bitstream24

    ここで、bitstreamを選択してくれと出てきます。
    多分前回のプロジェクトのbitstreamファイルが選ばれたままになっています。なので、右側のファイル選択を押して今回作成したbitstreamを選びましょう。
    Debug probes fileはそのままで大丈夫です。
    これでもうProgramを押すだけで、ボードに書き込まれます。

    bitstream25

     

    書き込みが完了するとPL部ConfigrationDoneLEDが点灯すると思います。

    2014-12-31 17.17.01

     

    このLEDがついたということは問題なくbitstreamが書き込まれたということで、もう動作しています。

    2014-12-31 17.17.16

     

    Y16に繋がれているボタンを押してみましょう。(ボードにも印字されています。一番左のボタンですね)そうするとD18につながれているLEDが点灯すると思います。
    回路図ではボタンを押すと電圧が加わるようになっていて、LEDは先がGNDにつながっているので、ボタンを押すとLEDが点灯するというので合っていますね。

    試しに

    
    assign led = !button;
    
    

    と反転させるとちゃんとボタンを押していない時だけLEDが点灯すると思います。

  • 5. Zynq VivadoのbitstreamからSDKでHello worldを出す

    前回頑張ってVivadoでbitstreamまで出力出来ました。
    今回でHelloWorldを出すところまで行きましょう。

    SDK

    今回はVivadoでなくSDKを開きます。Vivadoと同じようにインストールされたアプリでデスクトップにあると思います。

    SDKを初めて起動するとプロジェクトフォルダをどこにするか聞かれます。

    vivado43

    どこでも良いので設定しちゃいましょう。
    ここでやることは3つです。

    1. さっきのBitstreamからプロジェクトを作る
    2. FSBLプロジェクトを用意されているものから作る
    3. HelloWorldプロジェクトを用意されているものから作る

    1から行きましょう。「File」->「New」->「Other」を選びます。

    vivado44

     

    「Hardware Platofmr Specification」を選びます。

    vivado45

     

    ここで、Vivadoでさっきまで使っていたプロジェクトフォルダの中に .sdkっていう名前のフォルダがあるのでそれを開いてください。すると中に.hdfというファイルが出てきます。それを選択してください。

    vivado46

    project nameを聞かれますが適当で大丈夫です。
    そして、そのままFinishで作成しちゃいましょう。

    vivado47

    するとプロジェクトページが開けるようになります。
    もしWelcomeという画面が出ているだけで、プロジェクトが出てこない方はWelcomeを閉じてもらえれば登場するはずです。

    vivado48

    sdkの最初の画面がまだ出ている人はそれ閉じられるので何とか閉じてください。

    次にFSBLのプロジェクトをテンプレートから作成します。
    FSBLは最初のほうでやったブートローダーのことです。
    「File」->「New」->「Application Project」を押します。

    vivado49

    Project nameはfsblなどにして他はそのままに Finishを押さずにNextを押してください。

    vivado50

    するとテンプレートという元々用意されているものを選ぶ画面になります。「Zynq FSBL」というのがありますのでそれを選択し「FInish」します。

    最後にHelloworldです。同じく「File」->「New」->「Application Project」でproject nameをhelloworldなどにします。

    vivado51

     

    Nextを押してテンプレートから「Hello World」を選択します。vivado52

    ここまででプロジェクトが3個と_bspってのが2個出来ていると思います。

    vivado53

     

    これで完了です。

    ボードを繋ぐ

    ボードをPCにつなぎます。
    ただし、FSBLのロード先をQSPIからJTAGに切り替えます。

    2014-12-30 16.17.11

    後は前の設定のままUSBをPCにつなぎます。
    ドライバーはVivadoをインストールした時に入っているのでつないですぐに認識されると思います。
    ただ、ボードの電源を入れないと認識されないので電源は入れておいてください。

    TeraTermを開く

    今回のHelloWorldはシリアルポートから出てきます。HDMIではないです。
    このボードのUSBはJTAGになっていてプログラム書き込んだりデバッグしたりでもできますが、USB-シリアルにもなっていますので繋いだ時にCOMポートがPCに追加されています。

    TeraTermなどいつも使っているシリアル通信ソフトを起動してください。
    COMポートが追加されていると思います。それを開きましょうvivado58

    テンプレートのHelloWorldは通信速度が115kなので、通信速度を切り替えます。
    設定のシリアルポートから変えられます。OKを押すだけで再起動しなくても設定の速度になります。

    vivado59

     

    デバッグ開始

    では、SDKに戻りましょう。
    今繋がっているJTAG経由でデバッグします。

    helloworldプロジェクトの中にDebugフォルダというのがあってその中にhelloworld.elfってのがあると思います。これを実行するのでこれを選んだ状態で「Run」->「Debug Configurations…」を押してください。

    vivado_100

    そしてXilinx C/C++ application(System Debugger)を選んだ状態で「New Launch Configuration」を選びます。New Launch Configurationは下にあるスクショにもありますが、Xilinx C/C++ application(System Debugger)などが出ている場所の上にある新規ファイルのようなボタンがそれです。
    それを押すと自動的に下のスクショのようなものが出てくると思います。

    vivado54

    ここで重要なのはHardwarePlatformに別プロジェクトとしてHardware Platform Specificationで作ったやつが選ばれていてInitialization fileがps7_init.tclになっていることです。また、bitstreamもVivadoで頑張って作ったbitstreamが選択されています。それぞれ、おそらくNewで作った最初からそうなっていると思います。このために新しいDebugConfigrationを作ったのです。あとはこのまま右下のDebugを押せば始まります。TeraTermが動いていることと、ボードがJTAG側になっていて、USBで電源が入った状態で繋がっていることを確認して下さい。

    デバッグ画面を開いてないのでこういうことを聞かれると思いますがYESを押します。

    vivado55

    また、「FPGAのコンフィグレーションないけどいいの?」と聞かれますが、これもOKを押します。

    書き込みが終わりデバッグ状態になるとこんな感じの画面になるはずです。
    これは今main関数のところでブレークポイントで止まっています。
    動かしちゃいましょう。
    動かすには

    vivado56

    再開ボタンを押せばOKです。緑のPlayボタンの右にある黄色と緑の三角のボタンです。

    vivado56

    ちなみにその左にある青丸に線のボタンはbreakpointを無効にするボタンです。今回はとにかく動かしたいので外しちゃいましょう。
    で、再開ボタンを押すと、起動していたTeraTermに文字が出てくるはず。

    vivado57

    やったね!

    ただUARTするだけですんごい大変でしたね(笑)
    今回はテンプレートから作っただけで、何もしていません。
    次回は実際にFPGAを使って見るところをやってみます。