FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

Vivado でZynqのブロックデザインをTCLで生成する方法の調査(2. ADIのモジュールを利用してブロック部品を作成する)

ZynqのCPU Interconnectに接続するためには、AXI経由でブロックモジュールを作成する必要がある。これらの部品は自分で作っても良いのだが、どうにもエラーが取り切れないところもあるし、きちんと作れているのかいまいち自信が無かったので、ADIのデザインを再利用して作ることにした。

github.com

例えば上記のリポジトリ内にある、 library/axi_clkgen/などを見てみよう。 axi_clkgen.v を開くと、まずはAXI信号を受け取り、up_axiというADIのモジュールを使ってアドレスとデータを同期させていることが分かる。

github.com

f:id:msyksphinz:20170802003836p:plain

これらはAXIを変換したもので、アドレスとデータが同期しているので扱いやすい。信号線も、

  wire            up_wreq_s;
  wire    [13:0]  up_waddr_s;
  wire    [31:0]  up_wdata_s;
  wire            up_wack_s;
  wire            up_rreq_s;
  wire    [13:0]  up_raddr_s;
  wire    [31:0]  up_rdata_s;
  wire            up_rack_s;

と数が少ないので、何のための信号かすぐに分かる。

これらを使ってブロックを構成する。例えば、axi_blockramを作ってみよう。

github.com

こんな感じにしてみた。合っているかはよく分からん。

    .up_wreq  (up_wreq_s),
    .up_waddr (up_waddr_s),
    .up_wdata (up_wdata_s),
    .up_wack  (up_wack_s),
    .up_rreq  (up_rreq_s),
    .up_raddr (up_raddr_s),
    .up_rdata (up_rdata_s),
    .up_rack  (up_rack_s));

  reg [31: 0]     reg_mem [1023: 0];

  assign up_wack_s = 1'b1;

  always @ (posedge clk) begin
    if (up_wreq_s) begin
      reg_mem[up_waddr_s[9:0]] <= up_wdata_s[31: 0];
    end
  end

  always @ (posedge clk) begin
    up_rack_s  <= up_rreq_s;
    up_rdata_s <= reg_mem[up_raddr_s[9:0]];
  end

endmodule

とりあえず、これで一通り論理合成を流して、Vivadoでbitファイルが作れるところまでは確認できた。

f:id:msyksphinz:20170802005258p:plain

Vivado でZynqのブロックデザインをTCLで生成する方法の調査

これまだVivadoのプロジェクトの生成方法や、SDKの処理などについてtcl化する方法について調査してきた。

いろいろ試して、結局以下のQiitaの方法に則るのが一番いいという結論に至った。

qiita.com

この中で、VivadoのブロックデザインはGUIで操作したものをtclに書き出し、それをCUIスクリプト化するときはインポートするという手法を取っている。

ブロックデザインというのはこういうのだ。Zynqとその周辺の接続関係を設計できるツールで、新しいIPを追加するとこのGUIを使用してモジュール間を接続する。

f:id:msyksphinz:20170723195744p:plain

この例では、変数 design_bd_tcl_file にファイル名が設定されていた場合、ファイルセット sources_1 に Block Design を追加して、さらにラッパーファイルも生成します。

一応、ADIのプロジェクトを見るとここもスクリプト化できるようだ。ADIのスクリプトをインポートしても良いので、これもtcl化しておきたい。

ADI Reference Designs HDL User Guide [Analog Devices Wiki]

ADIのブロックデザイン生成スクリプト

まずは、ADIのzed_system_bd.tclを見てみよう。これがZedBoard向けにブロックデザインを生成するスクリプトだ。

github.com

tclを読み解くには、Vivadoの “Vivado Design Suite Tcl Command Reference Guide” を参照しよう。

  • Vivado Design Suite Tcl Command Reference Guide

https://www.xilinx.com/support/documentation/sw_manuals/xilinx2013_3/ug835-vivado-tcl-commands.pdf

create_bd_port

ブロックデザインに対してポートを作成する。外部ポートなど、ZedBoardの外に出すポートを作成する。

create_bd_port -dir O spi0_csn_2_o
create_bd_port -dir O spi0_csn_1_o
create_bd_port -dir O spi0_csn_0_o
create_bd_port -dir I spi0_csn_i
create_bd_port -dir I spi0_clk_i
...

create_bd_cell

ブロックデザインに対してIPをインスタンスする。必要なIPをインスタンスしていく。

set axi_iic_main [create_bd_cell -type ip -vlnv xilinx.com:ip:axi_iic:2.0 axi_iic_main]
...
set axi_hdmi_core [create_bd_cell -type ip -vlnv analog.com:user:axi_hdmi_tx:1.0 axi_hdmi_core]
...

ad_connect

これはADIが用意しているサポート関数のようだ。定義を見てみると、いくつかの指定タイプによって、Vivadoの関数connect_bd_xxxを使うかを決定している。さらにどうもポートのDirectionは関係ないようだ。

ad_connect  sys_cpu_clk sys_ps7/FCLK_CLK0
ad_connect  sys_200m_clk sys_ps7/FCLK_CLK1
ad_connect  sys_cpu_reset sys_rstgen/peripheral_reset
ad_connect  sys_cpu_resetn sys_rstgen/peripheral_aresetn
...
ad_connect  sys_cpu_clk axi_hdmi_core/vdma_clk
...

例えば、ad_connect sys_cpu_clk sys_ps7/FCLK_CLK0 でまずは sys_ps7/FCLK_CLK0 から sys_cpu_clkという仮想のクロック配線へと接続し、次に ad_connect sys_cpu_clk axi_hdmi_core/vdma_clksys_ps7/FCLK_CLK0 から axi_hdmi_core/vdma_clk への接続が完成している。 ブロックデザインでその様子を見ると以下のようになっている。

f:id:msyksphinz:20170731013713p:plain

これらをスクリプトを組み込み、まずはZynqのブロックデザインを構成した。

github.com

$ make impl
vivado -mode batch -source create_project.tcl > adv7511_create_zed_hdf.log 2>&1
vivado -mode batch -source implementation.tcl > adv7511_impl_zed_hdf.log 2>&1

合成結果は、無事にブロックデザインが生成されている。

f:id:msyksphinz:20170731014243p:plain

関連記事

msyksphinz.hatenablog.com

msyksphinz.hatenablog.com

msyksphinz.hatenablog.com

msyksphinz.hatenablog.com

FPGAマガジン No.18「RISC-Vづくり」を入手

FPGAマガジンNo.18はRISC-V特集「RISC-Vづくり」ということで、早速入手した。ちなみに、私は本文は何も寄稿してません。

f:id:msyksphinz:20170722001900p:plain

雑誌の上においてあるHiFive1ボード2枚、うち1枚は私のだが壊してしまった。

最初は中森章さんのRISC-Vそのものについての解説。仕様の特徴からRISC-Vがなぜ注目を浴びているのかについての背景まで開設されている。

というところは同意。もう一つ、RISC-Vが脚光を浴びた、という一つの要因に、ARMがソフトバンクに買われたという事実があげられる。ARMがソフトバンクに買われた際に、私のブログのアクセス数も急上昇した。

つまり、

  • 別にARMが安泰ならARMで良いのである(ASIC作っている人は少ないし、ASIC作っている人はARMも買えるお金持ち)。
  • でも、ARMがダメならなるべく楽なやつが良いよね。MIPSとか誰が使ってんのか分かんないし、OpenRISCに戻りたくないし。

で、FPGAマガジン特別設計のRISC-VのVerilog実装は、5段パイプラインと言いつつシーケンシャル実行。これは時間が足らなかったのかな。 CSRレジスタも実装してあるし、割り込みも実装してある。RISC-Vの仕様を身をもって理解したい人はいいんじゃないかしら。

ただし、これ、誰向けに書かれた内容かというとなんだか良く分からない。CPUを作る人向け、っていうのはニッチだし、使う側の人にとってはVerilogの実装とかどうでも良い。

CPUインプリする人だったらRocketChipとか使った方が機能多いし、性能良い。使う人にとって参考になるのはRISC-Vの仕様の解説くらいかしら。

といってもなかなか珍しいRISC-Vの実装なので、「CPUに興味があるけどどうやって作ればよいのか分からない」という方は是非読んでみることをお勧めする。

ついでに宣伝だけど、Vengeneerさんのご厚意で、今年10月のDesign Solution ForumにてRISC-Vトラックの一つとして発表することになり、その宣伝文を掲載させて頂いた。

“オープンアーキテクチャの時代がやってきた!RISC-Vを取り囲む世界のご紹介”

これまで、ソフトウェアの世界だけの話であったオープンソースという概念は、ついにハードウェアの世界にまで広がろうとしています。RISC-Vはこれまでこれまでに限られた会社によって開発されていたマイクロプロセッサアーキテ> クチャを、誰でも触れる、仕様や実装について議論できる、広くオープンなものにしました。 この新しいオープンアーキテクチャのプロセッサについて、「FPGA開発日記(http://msyksphinz.hatenablog.com) 」というブログにまとめる活動をしています。 この新しいアーキテクチャについて、その特徴やこれを取り囲むエコシステム、またRISC-V自作プロセッサの開発実績についてまで、幅広くご紹介する予定です。

あー恥ずかし。まだ内容ほとんど出来てないんだけど、何しゃべるのかしら。

ThinkPadのトラックポインタが交換できることは意外と知られていなかった

わずか10~20年前、パーソナルコンピュータといえば日本の大手家電メーカがこぞって手を出していた分野であり、また国内家電量販店に並べてあるPCはほとんどが国産だった。 名立たる国内家電メーカは独自のPCを短いスパンでリリースし、国内のシェアも相当高かったものと思う。

そんな中、ThinkPadユーザといえば非常にコアな人間か、PCに熱い思いを持っている人たちの集まりであるという印象だった。 しかし、それは昔の話、国内PCは衰退し、今や格安海外メーカのPCか、ビジネス用にはThinkPad、くらいの選択肢くらいしかなくなってしまったと思う。 (私はLenovoIBMからThinkPadを買ってからのユーザなのでそういう意味ではニワカである。が、それ以降メーカPCは全部ThinkPad。)

というわけなので、別に今の時代ThinkPadを使っていてもPCヘビーユーザとは限らず、キーボードの真ん中に何か赤いの付いてる、ナニコレ指に当たって邪魔なんだけど、くらいの人がいても不思議はない、っていうかそんな人ばかりである。

しかしThinkPadヘビーユーザにとって、赤ポチ(トラックポインタ)の摩耗は死活問題だ。トラックポインタが削れてくると指が滑るようになり、作業効率が落ちる。 従って、定期的にトラックポインタを交換するのは大事な作業だ。

しかし、長らくThinkPadを使っているユーザでも、トラックポインタのキャップが交換できることを知っている人が少なくて驚いた(サンプル数は数人だけど…)。

下記のような感じである。

ThinkPad X250のトラックポイントキャップを底上げして交換 | ThinkPad X240sを使い倒す シンクパッドのレビュー・カスタマイズ

ちなみに、私はトラックポインタの種類は2種類(古いタイプのものとロープロファイルのもの)しか知らなかったのだが、どうやら2016年モデルからさらにロープロファイルになったようだ。

f:id:msyksphinz:20170721235658p:plain

私の持ってるやつ。左が古いもの、右がロープロファイル。さらに2016年モデルからはさらにロープロファイルになってるっぽい。もうどんどん互換性がなくなっていく!

というわけでロープロファイルのものが無くなったので秋葉原に買いに行った。秋葉原にある唯一のThinkPad専門店、ThinkFactoryで取り扱っている。

ThinkFactory IBM Lenovo秋葉原 持込修理 販売 保守パーツ

ただし、

f:id:msyksphinz:20170722000603p:plain

って感じのため、ThinkPadユーザはもうちょっと足繁く通ってあげよう。

VivadoでIPを生成する方法の調査(VivadoのIPインテグレーションの仕組み調査3. RAMの実装)

f:id:msyksphinz:20170723195744p:plain

AXIインタフェースに対して、RAMを実装していく。

github.com

  • blockram_test_v1_0_S00_AXI.v
  // Add user logic here
  reg [C_S_AXI_DATA_WIDTH-1:0]               mem_ram[1024-1: 0];
  wire                                       mem_wren, mem_rdenn;
  assign mem_wren = axi_wready && S_AXI_WVALID ;
  assign mem_rden = axi_arv_arr_flag ; //& ~axi_rvalid
  always @ (posedge S_AXI_ACLK) begin
    mem_ram [axi_awaddr[11: 2]] <= S_AXI_WDATA[31: 0];
  end

  always @ (posedge S_AXI_ACLK) begin
    if (!S_AXI_RESETN) begin
      axi_rdata <= 32'h0;

      axi_rvalid <= 0;
      axi_rresp  <= 0;
    end else begin
      if (axi_arv_arr_flag && ~axi_rvalid) begin
        axi_rvalid <= 1'b1;
        axi_rresp  <= 2'b0;
        // 'OKAY' response

        axi_rdata <= mem_ram [axi_araddr[11: 2]];
      end else if (axi_rvalid && S_AXI_RREADY) begin
        axi_rvalid <= 1'b0;
      end
    end // else: !if(!S_AXI_RESETN)
  end // always @ (posedge S_AXI_ACLK)

   // User logic ends

まあ簡単な実装なので、すぐにできると思うのだが、少し改造するとビルドスクリプトが動かなくなってしまった。。。調査中。。。

github.com

RISC-V Foundationのメンバーのインタビュー記事から考える、半導体で生き残る道

RISC-VのFoundation Memberの一人、"Krste Asanovic"のインタビュー記事が掲載されている。

普段このような細かいニュース記事をブログにすることはないのだけれども、この記事を読めばRISC-Vが何を狙っているのか良く分かるので、興味のある人は読んでほしい。

circuitcellar.com

ここで彼が答えていることはRISC-Vの概要、そして狙っているターゲット、RISC-Vの将来について。 これらについては、ほぼ私の考えている事と一致しているというのは正直安心した。

つまり、

  • ISAをオープンソースにすることによって誰が利益を享受するのか?

    • ARMのような高価なコアを購入することのできない中小ベンダ。
  • 既にARM、x86が占拠しているマイクロプロセッサ業界において、何処をターゲットにするのか?

    • IoT、自動車分野など、まだ上記のプロセッサが占拠できていない場所
    • (私の意見だが)、IoTはまだしも、自動車は難しいと思うんだな。。。制御マイコンは工場などの品質を含めた協力が必要、上位はより高性能なアクセラレータが必要。。。

プロセスが進むにつれてGoogleNVIDIAなど、一部の巨大企業のみがチップを作れるようになっている。 一方で古いプロセスにて、無料でIPを使うことができ、プロセッサを含めデザインを構築することができるというのは、現在の産業界の摩擦(技術はあってもチップを作るお金がない)などの問題を解決することができるとしている。 つまり直接RISC-Vの利益を享受できるのは、協賛に入っているGoogleMicrosoftNVIDIA、も含めだが、より重要なのはあまりお金を持っていない中小企業だ。

また、これまでの少品種大量生産から、大量のバリエーションを少量ずつ生産するというモデルに代わる際、現在のIPビジネスは成り立たなくなり、自由に利用できカスタマイズできるOpenISAに利点が集まるとしている。

これを読んでわかることは、もう日本の古い半導体企業を含め、プロセッサなんて差異の出ない分野に取り組んではいけないということだ。

プロセッサは汎用品で十分。むしろ最も時間をかけずに実装できるものを選ぶべき。そして、その傍に何を搭載するか、アクセラレータだったり、ペリフェラルだったり、ソフトウェアだったり、そちらに焦点を当てないと乗り遅れるぞ、と言っているんじゃないのかい?

とまあ偏った考え方をしてみたが、RISC-Vが狙っているのはこのような世界ではないかと思えてきた。

RISC-Vがプロセッサの世界で標準として確立されるならば、そのメリットに大いに享受して、ほかの人はそれ以外のことを考えるべき、じゃないだろうか?

VivadoでIPを生成する方法の調査(VivadoのIPインテグレーションの仕組み調査3. tclを用いた自動化の調査)

f:id:msyksphinz:20170723164014p:plain

Vivadoで生成したIPを接続してVivadoプロジェクトをビルドし、SDカードに書き込むことでブートできるようになった。

f:id:msyksphinz:20170726005913p:plain

物理デバイスにアクセスしてBlockRAMとして制御できているか確認する。 書き込んだ値が読めている。またアドレス毎に別々に値が読み書きできていることから、BlockRAMとしてきちんと動作できていることが分かる。

f:id:msyksphinz:20170726010447p:plain

  • devmem2 について

armadillo.atmark-techno.com

さて、ここまでは良いとして、いちいちGUIを立ち上げるのは面倒なので、どうにかしてtcl化したい。

いろいろ参考にしているが、主にQiitaの記事を参考にしている。

qiita.com

qiita.com

Vivadoプロジェクトのビルド後に、ハードウェアをエクスポートするのもスクリプト化しておく。まさしく上記の記事がドンピシャだ。

以下のようなプロジェクトを作成した。

github.com

  • create_hdf.tcl
set project_directory   [file dirname [info script]]
set hw_name             "system_top_hw_platform_0"
set project_name adv7511_zed

open_project [file join $project_directory $project_name]

set project_directory [file dirname [info script]]
set sdk_workspace  [file join $project_directory $project_name.sdk]

if { [file exists [file join $sdk_workspace $hw_name]] == 0 } {
    file mkdir [file join $sdk_workspace $hw_name]
}
set design_top_name [get_property "top" [current_fileset]]
file copy -force [file join $project_directory $project_name.runs "impl_1" $design_top_name.sysdef] [file join $sdk_workspace $hw_name $design_top_name.hdf]

close_project

次に、SDKを走らせてfsbl.elfを作成する。こちらもスクリプト化してある。

  • ceate_fsbl.tcl
#!/usr/bin/tclsh

set app_name            "fsbl"
set app_type            {Zynq FSBL}
set bsp_name            "fsbl_bsp"
set hw_name             "system_top_hw_platform_0"
set hwspec_file         "system_top.hdf"
set proc_name           "ps7_cortexa9_0"
set project_directory   [file dirname [info script]]
set sdk_workspace       [file join $project_directory "adv7511_zed.sdk"]

if {[info commands sdk::setws] ne ""} {
    sdk setws         $sdk_workspace
} else {
    sdk set_workspace $sdk_workspace
}

if {[info commands sdk::createhw] ne ""} {
    sdk createhw          -name $hw_name -hwspec [file join $sdk_workspace $hwspec_file]
} else {
    sdk create_hw_project -name $hw_name -hwspec [file join $sdk_workspace $hwspec_file]
}

hsi::open_hw_design  [file join $sdk_workspace $hw_name $hwspec_file]
hsi::create_sw_design $bsp_name -proc $proc_name -os standalone
hsi::add_library xilffs
hsi::generate_bsp -sw $bsp_name -dir [file join $sdk_workspace $bsp_name] -compile
hsi::close_sw_design  $bsp_name

if {[info commands sdk::createapp] ne ""} {
    sdk createapp          -name $app_name -hwproject $hw_name -proc $proc_name -os standalone -lang C -app $app_type -bsp $bsp_name
} else {
    sdk create_app_project -name $app_name -hwproject $hw_name -proc $proc_name -os standalone -lang C -app $app_type -bsp $bsp_name
}

if {[info commands sdk::projects] ne ""} {
    sdk projects -build
} else {
    sdk build_project $app_name
}

exit

boot.binの作成も上記のQiitaの要領だ。とても役に立つ!

bootgen:
        bootgen -image ./boot.bif -o i boot.bin

boot.bifは以下のように記述した。

image : {
        [bootloader]./adv7511_zed.sdk/fsbl/Debug/fsbl.elf
        ./adv7511_zed.sdk/system_top_hw_platform_0/system_top.bit
        ../../../../u-boot-xlnx/u-boot.elf
}