RocketChipを改造しようにも、どこがどうなっているのか全く分からなかったので、頑張ってエディタで配線を追いかけながら接続構成図を作った。
だいたい3本のバスがRocketChipにつながっている。メインのバスと、L2に接続するためのバス、コヒーレント用のバスだ。
RocketChipを改造しようにも、どこがどうなっているのか全く分からなかったので、頑張ってエディタで配線を追いかけながら接続構成図を作った。
だいたい3本のバスがRocketChipにつながっている。メインのバスと、L2に接続するためのバス、コヒーレント用のバスだ。
前回の続き。bitファイルが完成したので、boot.binをSDカードコピーして動作させてみた。
本当に動作しているかどうかを確認するために、BlockRAMのデザインに少しだけギミックを入れた。
always @ (posedge s_axi_aclk) begin up_rack_s <= up_rreq_s; blockram_rdata <= reg_mem[up_raddr_s[9:0]]; end always @ (posedge s_axi_aclk) begin up_raddr_s2 <= up_raddr_s; end assign up_rdata_s = (up_raddr_s2 == 14'h0) ? 32'hdeadbeef : blockram_rdata;
つまり、当該ブロックの先頭アドレスにリードアクセスをすると、0xdeadbeefが返されるはずだ。
当該ブロックのアドレスは、design_1_bd.tcl
で定義している。
ad_cpu_interconnect 0x43c00000 axi_blockram
さて、さっそく実行してみた。
まず、当該ブロックの先頭へのリードを実行する。
devmem2 0x43c00000 word
0xdeadbeefが返ってきた。成功だ。
次に、次のワードに対して書き込みを実行する。書き込む値は0x12345678だ。
devmem2 0x43c00004 word 0x12345678
次に同じアドレスに対してリードをする。ちゃんと0x12345678が返ってきた。成功だ。
devmem2 0x43c00000 word
ZynqのCPU Interconnectに接続するためには、AXI経由でブロックモジュールを作成する必要がある。これらの部品は自分で作っても良いのだが、どうにもエラーが取り切れないところもあるし、きちんと作れているのかいまいち自信が無かったので、ADIのデザインを再利用して作ることにした。
例えば上記のリポジトリ内にある、 library/axi_clkgen/
などを見てみよう。 axi_clkgen.v
を開くと、まずはAXI信号を受け取り、up_axiというADIのモジュールを使ってアドレスとデータを同期させていることが分かる。
これらは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を作ってみよう。
こんな感じにしてみた。合っているかはよく分からん。
.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ファイルが作れるところまでは確認できた。
これまだVivadoのプロジェクトの生成方法や、SDKの処理などについてtcl化する方法について調査してきた。
いろいろ試して、結局以下のQiitaの方法に則るのが一番いいという結論に至った。
この中で、VivadoのブロックデザインはGUIで操作したものをtclに書き出し、それをCUIでスクリプト化するときはインポートするという手法を取っている。
ブロックデザインというのはこういうのだ。Zynqとその周辺の接続関係を設計できるツールで、新しいIPを追加するとこのGUIを使用してモジュール間を接続する。
この例では、変数 design_bd_tcl_file にファイル名が設定されていた場合、ファイルセット sources_1 に Block Design を追加して、さらにラッパーファイルも生成します。
一応、ADIのプロジェクトを見るとここもスクリプト化できるようだ。ADIのスクリプトをインポートしても良いので、これもtcl化しておきたい。
ADI Reference Designs HDL User Guide [Analog Devices Wiki]
まずは、ADIのzed_system_bd.tcl
を見てみよう。これがZedBoard向けにブロックデザインを生成するスクリプトだ。
tclを読み解くには、Vivadoの “Vivado Design Suite Tcl Command Reference Guide” を参照しよう。
https://www.xilinx.com/support/documentation/sw_manuals/xilinx2013_3/ug835-vivado-tcl-commands.pdf
ブロックデザインに対してポートを作成する。外部ポートなど、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 ...
ブロックデザインに対して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] ...
これは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_clk
で sys_ps7/FCLK_CLK0
から axi_hdmi_core/vdma_clk
への接続が完成している。
ブロックデザインでその様子を見ると以下のようになっている。
これらをスクリプトを組み込み、まずはZynqのブロックデザインを構成した。
$ 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
合成結果は、無事にブロックデザインが生成されている。
FPGAマガジンNo.18はRISC-V特集「RISC-Vづくり」ということで、早速入手した。ちなみに、私は本文は何も寄稿してません。
雑誌の上においてあるHiFive1ボード2枚、うち1枚は私のだが壊してしまった。
最初は中森章さんのRISC-Vそのものについての解説。仕様の特徴からRISC-Vがなぜ注目を浴びているのかについての背景まで開設されている。
というところは同意。もう一つ、RISC-Vが脚光を浴びた、という一つの要因に、ARMがソフトバンクに買われたという事実があげられる。ARMがソフトバンクに買われた際に、私のブログのアクセス数も急上昇した。
つまり、
で、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自作プロセッサの開発実績についてまで、幅広くご紹介する予定です。
あー恥ずかし。まだ内容ほとんど出来てないんだけど、何しゃべるのかしら。
わずか10~20年前、パーソナルコンピュータといえば日本の大手家電メーカがこぞって手を出していた分野であり、また国内家電量販店に並べてあるPCはほとんどが国産だった。 名立たる国内家電メーカは独自のPCを短いスパンでリリースし、国内のシェアも相当高かったものと思う。
そんな中、ThinkPadユーザといえば非常にコアな人間か、PCに熱い思いを持っている人たちの集まりであるという印象だった。 しかし、それは昔の話、国内PCは衰退し、今や格安海外メーカのPCか、ビジネス用にはThinkPad、くらいの選択肢くらいしかなくなってしまったと思う。 (私はLenovoがIBMからThinkPadを買ってからのユーザなのでそういう意味ではニワカである。が、それ以降メーカPCは全部ThinkPad。)
というわけなので、別に今の時代ThinkPadを使っていてもPCヘビーユーザとは限らず、キーボードの真ん中に何か赤いの付いてる、ナニコレ指に当たって邪魔なんだけど、くらいの人がいても不思議はない、っていうかそんな人ばかりである。
しかしThinkPadヘビーユーザにとって、赤ポチ(トラックポインタ)の摩耗は死活問題だ。トラックポインタが削れてくると指が滑るようになり、作業効率が落ちる。 従って、定期的にトラックポインタを交換するのは大事な作業だ。
しかし、長らくThinkPadを使っているユーザでも、トラックポインタのキャップが交換できることを知っている人が少なくて驚いた(サンプル数は数人だけど…)。
下記のような感じである。
ThinkPad X250のトラックポイントキャップを底上げして交換 | ThinkPad X240sを使い倒す シンクパッドのレビュー・カスタマイズ
ちなみに、私はトラックポインタの種類は2種類(古いタイプのものとロープロファイルのもの)しか知らなかったのだが、どうやら2016年モデルからさらにロープロファイルになったようだ。
私の持ってるやつ。左が古いもの、右がロープロファイル。さらに2016年モデルからはさらにロープロファイルになってるっぽい。もうどんどん互換性がなくなっていく!
というわけでロープロファイルのものが無くなったので秋葉原に買いに行った。秋葉原にある唯一のThinkPad専門店、ThinkFactoryで取り扱っている。
ThinkFactory IBM Lenovo秋葉原 持込修理 販売 保守パーツ
ただし、
って感じのため、ThinkPadユーザはもうちょっと足繁く通ってあげよう。
AXIインタフェースに対して、RAMを実装していく。
// 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
まあ簡単な実装なので、すぐにできると思うのだが、少し改造するとビルドスクリプトが動かなくなってしまった。。。調査中。。。