プログラムdeタマゴ

nodamushiの著作物は、文章、画像、プログラムにかかわらず全てUnlicenseです

Vivadoにいつまでも入門できないの~VivadoでGUIなしで合成~

 おじさん分かった。ブログ書かねぇからいつまで経ってもVivadoがよく分からないんだ。

 世の中はインプットに読む人/聞く人、アウトプットに書く人/話す人がいるというけど、私はインプットに書く人、アウトプットはしない人というゴミ屑みたいなタイプなのだ。書かねばならぬのだ。

 というわけで、 Vivado をポチポチしたいけどプロジェクトの作り方の時点から躓いたから頑張った

目的

 以下の様なプロジェクトを作りたい。

  1. Vivado をGit管理する
  2. Vivado のGUIがなくても合成できるようにする

 

作ったレポジトリ

GitHubに置いてあります。この記事の時点でのコミットは以下。

https://github.com/nodamushi/vivado_init_project/tree/19e58c23419515d0829968369757c7973e2d1b1a

環境

  • Cora Z7
  • Windows
  • Vivado 2021.1
  • VSCode

 

事前準備

 VSCodeでコマンドプロンプトを開く。生DOS窓はツライ。

 Vivadoを通常通りインストールしているなら、以下のコマンドを実行して、Vivadoをコマンドプロンプトで実行できるようにする。

call C:\Xilinx\Vivado\2021.1\settings64.bat

 

まずはボードの名前を調べる

 Cora Z7 のボード名(ID?)を調べる為に先ずは Vivado の GUI で塵プロジェクトを作ります。

 Create Project を押しましてー

f:id:nodamushi:20220228134342p:plain:w320

 ゴミ箱作りましてー

f:id:nodamushi:20220228134455p:plain:w320

 Cora Z7 を選択しましてー

f:id:nodamushi:20220228134531p:plain:w320

 TCL Consoleに表示された digilentinc.com:cora-z7-07s:part0:1.0 の文字列をコピーして、Vivadoを閉じる。

 もうdustboxプロジェクトは要らないのでエクスプローラーから完全削除する。

f:id:nodamushi:20220228134641p:plain

 

プロジェクトを初期化する

適当なプロジェクトディレクトリを作成し、以下のコマンドを実行。環境はMSYS2のbash

git init
touch .gitignore
touch .editorconfig
mkdir -p src/rtl
touch src/rtl/myrtl.v
mkdir -p src/constraint
wget https://raw.githubusercontent.com/Digilent/digilent-xdc/master/Cora-Z7-07S-Master.xdc  -O src/constraint/constraint.xdc
mkdir vivado
touch vivado/Makefile
touch vivado/create_project.tcl

 

  • gitの初期化
  • .gitignoreと.editorconfigの作成
  • ソースコードディレクトリの作成と、適当にRTLファイルを作成
  • Cora z7 7Sの制約ファイル例がGitHubにあるので、src/constraint/constraint.xdcに保存
  • vivadoのプロジェクトディレクトリを作成
  • Makefileとプロジェクト作成用のTCLファイルを作成

f:id:nodamushi:20220228143834p:plain

 

Git Ignoreの設定

取りあえず以下

.Xil/
*.prj/
vivado_*
*.jou
*.log

Editor Config

取りあえず以下

root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space

[Makefile]
indent_style = tab
indent_size = 2

create_project.tcl

 プロジェクトの復元を行うスクリプトとして、create_project.tclを作成する。

 vivadoのバッチモードでこのスクリプトを実行すると、プロジェクトを復元できる。

 なお、先にコピった digilentinc.com:cora-z7-07s:part0:1.0は以下のboard_name で使う。

 最初に定義してるプロジェクト名とディレクトリは Makefile から渡す。

# Project name and directory are set from Makefile
set project_name      [lindex $argv 0]
set project_directory [lindex $argv 1]

set board_name           "digilentinc.com:cora-z7-07s:part0:1.0"
set rtl_directory        "../src/rtl"
set constraint_directory "../src/constraint"

# Create/Init Project
create_project $project_name $project_directory
set_property board $board_name [current_project]
update_ip_catalog

# Add sources
add_files $rtl_directory
add_files -fileset constrs_1 $constraint_directory/constraint.xdc

close_project

Makefile

先ほど作ったcreate_project.tclを実行するコマンドなどを定義する。

PROJECT_NAME := vivado_study
PROJECT_DIR := $(PROJECT_NAME).prj


$(PROJECT_DIR):
    @vivado -mode batch -source create_project.tcl -tclargs $(PROJECT_NAME) $(PROJECT_DIR)

create_project: $(PROJECT_DIR)

clean:
    @rm -rf $(PROJECT_DIR) .Xil vivado_* *.log *.jou


.PHONY: all create_project clean

 なお、cleanコマンドを rf で定義しているが、これはVivado環境下では Windows でも許される。  

 

myrtl.v

単に3色LEDを順にチカらせるだけのLチカです。

module myrtl#(
  parameter integer T = 1000 * 1000
) (
  input wire clk,
  input wire resetn,
  output wire [2:0] led
);

  reg [31:0] counter;
  reg [2:0] out;
  wire [2:0] out_next_led;
  assign led = out;

  always @(posedge clk) begin
    if (!resetn)
      counter <= 0;
    else
      counter <= counter == T? 0 : counter + 1;
  end

  assign out_next_led = {out[1:0], out[2]};
  always @(posedge clk) begin
    if (!resetn)
      out <= 3'b001;
    else
      out <= counter == T? out_next_led: out;
  end

endmodule

 

プロジェクトの作成

 この作業は、事前準備で Vivado を呼び出せるようにしたコマンドプロンプトで行う。事前準備は以下(再掲)

call C:\Xilinx\Vivado\2021.1\settings64.bat

 makeを呼び出す。

make create_project

 すると、プロジェクトが復元されるので、 vivado/vivado_study.prj/vivado_study.xrpをダブルクリックするなりしてVivadoを起動する。

 起動したら以下の様な感じ。

f:id:nodamushi:20220228143222p:plain:w320

 Create Block Designを押してブロックデザインを作成する。名前は取りあえずそのまま。

f:id:nodamushi:20220228161725p:plain:w320

 先ほど適当に作ったLチカRTLをブロックデザインに突っ込む。右クリックからAdd Module

f:id:nodamushi:20220228181725p:plain:w320

 先ずは led を選択した状態で「Ctrl + K 」でポートを作成する。

f:id:nodamushi:20220228181947p:plain:w320

 で、Run Connection Automaticallyでクロックポートを繋ぐ

f:id:nodamushi:20220228182052p:plain:w320

f:id:nodamushi:20220228182154p:plain:w320

 そうすると何かこうなった。

f:id:nodamushi:20220228182233p:plain

 とりあえず、クロックに関しては、H16ピンから125MHzのクロックが入力されてるので、ピンとして外に出せばいいと思うんだけど、リセット………ってどうするんだ………

 なんか、こう、PLLとかから出てこないの………?わからん………

 というので、散々悩んだんですけど、取りあえず適当なピンにリセットを割り当てておけば良いらしいので、外にピンとして出しておく。

f:id:nodamushi:20220228182609p:plain:w320

 ※Autoconnectを使うとクロックは勝手に繋がった。

 後は、Validate Designを実行して、デザインにエラーがないか確認する。

f:id:nodamushi:20220228182739p:plain:w320

 そして、「File→Export→Export Block Design」を選択して、IP Integratorで構成したデザインを再構築するためのTCLファイルを出力する。

f:id:nodamushi:20220228202819p:plain:w320

 保存場所は、「vivado」ディレクトリの直下。プロジェクト直下がデフォルトでは選択されてるので間違えないこと。

 Automatically create top design にはチェックを入れておく。

f:id:nodamushi:20220228203033p:plain

 保存したらVivadoは終了し、 make clean でプロジェクトを削除。

 

create_projectにdesign_1.tclを読み込む処理を追加

 makeコマンドでIP Integratorを復元するために、 create_project.tclのclose_project の前に以下を追加。

source "design_1.tcl"
regenerate_bd_layout
save_bd_design
set design_bd_name [get_bd_designs]
set bd_files [get_files $design_bd_name.bd]
puts $bd_files
generate_target all $bd_files
make_wrapper -files $bd_files -top -import

close_project

 

  1. 先ほど出力した design_1.tcl を読み込む
  2. レイアウトを綺麗にする
  3. 保存
  4. ボードファイルの一覧を取得して、ターゲットを生成する。ターゲットがなんなのかはよく知らない。
  5. ボードのHDLラッパー作成し、プロジェクトにインポートする

 make create_project を実行して、再々生成したプロジェクトで IP Integrator が復元されていることを確認する。

 ついでに、SettingsのTop Moduleが design_1_wrapper になっていることも確認。

f:id:nodamushi:20220228204212p:plain

   確認したらプロジェクトはもう要らないのでVivadoを閉じて make clean で削除。

 

制約ファイルの修正

 作成したボードのポート定義に合うように、ledreset の設定を変更。

  とりあえず、リセットはボタン0に割り当てた。

  sys_clk はボード定義ファイルにあるので不要らしい。

set_property -dict { PACKAGE_PIN L15   IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_L22N_T3_AD7N_35 Sch=led0_b
set_property -dict { PACKAGE_PIN G17   IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L16P_T2_35 Sch=led0_g
set_property -dict { PACKAGE_PIN N15   IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L21P_T3_DQS_AD14P_35 Sch=led0_r
set_property -dict { PACKAGE_PIN D20   IOSTANDARD LVCMOS33 } [get_ports { reset }]; #IO_L4N_T0_35 Sch=btn[0]

 

Makefileから合成する

 合成からビットストリーム作成までをMakefileから行えるようにする。

 これも vivado をバッチモードで起動して、合成用のTCLファイルを実行するだけである。

 以下の implement.tcl を vivado ディレクトリに保存

set project_name      [lindex $argv 0]
set project_directory [lindex $argv 1]

open_project ${project_directory}/${project_name}.xpr

set project_status [get_property STATUS [get_runs impl_1]]
if {$project_status != "write_bitstream Complete!"} {
    launch_runs impl_1 -jobs 8 -to_step write_bitstream
    wait_on_run impl_1
}

close_project

 

  1. プロジェクト(xprファイル)を開く
  2. プロジェクトステータスを見ると「write_bitstream Complete!」だと、合成が完了してるので無視することが出来る
  3. write_bitstreamまでを実行
  4. 完了するまで待機
  5. プロジェクトを閉じて終了

 

 そして、 Makefileに implement ターゲットを追加。 all の対象も implement に変更

all: implement

implement: $(PROJECT_DIR)
    @vivado -mode batch -source implement.tcl -tclargs $(PROJECT_NAME) $(PROJECT_DIR)

 

 で、再々再度 プロジェクトを開くと、合成できてた。

f:id:nodamushi:20220228205703p:plain

 

BitStream をCora Z7 07S に書き込む

 Cora Z7 をUSB経由でPCに接続する。

 Open Hardware Managerから Hardware Manager の画面を開き、Open Targetから Auto Connect を選択して接続。

 自動で接続できない場合は Open New Targetから選択。

f:id:nodamushi:20220228205813p:plain

 で、Program deviceをするとLチカしました。

f:id:nodamushi:20220228210440p:plain

 

まとめ

 とりあえず、VivadoのGUIがなくても合成とかできるようになりました。