VivadoのIP Integratorをコマンドラインで実行する

FPGA

VivadoのGUIでプロジェクトを作成すると、色々なファイルが生成されます。そのプロジェクトのデータを配布する場合、ファイルに絶対パスなどが含まれていると、データの再現性に不安が残ります。また、配布は必要最低限の設定ファイルだけにして、RTLなどのデータは配布先の環境で生成できた方がいろいろと都合が良いです。
Vivadoの中で、GUIへの依存度が高いと思われるのが、IP Integratorです。IP Integratorでは、GUIを使ってIPを接続し、目的とするシステムを簡単に作成することができます。

IP IntegratorのGUI

IP IntegratorのGUI

GUIで作成したIP Integratorのデザインを、CUI(コマンドライン)で生成するにはどうすれば良いかといろいろ試したのですが、結局、GUIでデザインを作成した時にTcl Consoloeに表示されるコマンドをファイルに格納し、Tcl Shellで実行するのが一番簡単で間違いがないようです。
既に作成済みのIP Integratorのデザインを、もう一度同じ手順でトレースするのは面倒ですが、この方法が一番間違いがありません。

IP Integratorをコマンドラインで実行する手順

適当なプロジェクトを作成して、Block Designを作成する

適当なプロジェクトを作成して、既に作成済みのBlock Designを参考に、同じBlock Designを作成します。この時、ユーザーの操作に対応したコマンドがTcl Consoleに表示されます。例えば、GPIOを追加すると、それに対応するcreate_bd_cellコマンドがTcl  Consoleに表示されます。

GPIOの追加

GPIOの追加

startgroup
create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio:2.0 axi_gpio_0
endgroup

必要なIPの追加と接続を行って、目的とするシステムを構築します。今回のサンプルは、次のような構成のシステムです。

  • ZedBoard用のデザイン
  • ZYNQ Processing Systemを使用
  • 3種類のGPIOを使用
  • S_AXI_ACPをS_AXIという名前で外部ポートとして出力
  • M_AXI_GP0をM_AXIという名前で外部ポートとして出力
IP IntegratorのGUI

IP IntegratorのGUI

コマンドライン用のTclファイルでプロジェクトを作成する

次のようなファイルを作り、create_projectでプロジェクトを作成します。プロジェクト作成後、create_bd_designでIP Integratorのデザインを作成します。この例では、polyphonyという名前のプロジェクトを作成し、zed_baseという名前のIP Integratorのデザインを作成しています。ZedBoardの場合は、em.avnet.com:zed:part0:1.3というプロパティの設定が必要です。

# project generation
set PROJ_NAME polyphony
set BD_NAME zed_base
set BD_DIR ./${PROJ_NAME}.srcs/sources_1/bd/${BD_NAME}
create_project -verbose -force -part xc7z020clg484-1 ${PROJ_NAME}
set_property board_part em.avnet.com:zed:part0:1.3 [current_project]
create_bd_design -verbose ${BD_NAME}

GUIでTcl Consoleに表示されたコマンドをファイルに格納する

GUIのIP Integratorでシステムを構築した時に、Tcl Consoleに表示されたコマンドを、Tclファイルに追加します。プロジェクト名などに関連する部分は、一部変更を加えています。

# project geneartion
set PROJ_NAME polyphony
set BD_NAME zed_base
set BD_DIR ./${PROJ_NAME}.srcs/sources_1/bd/${BD_NAME}
create_project -verbose -force -part xc7z020clg484-1 ${PROJ_NAME}
set_property board_part em.avnet.com:zed:part0:1.3 [current_project]
create_bd_design -verbose ${BD_NAME}

# below commands are from Vivado GUI
startgroup
create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0
endgroup
startgroup
set_property -dict [list CONFIG.preset {ZedBoard}] [get_bd_cells processing_system7_0]
endgroup
startgroup
set_property -dict [list CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {50.000000}] [get_bd_cells processing_system7_0]
endgroup
startgroup
create_bd_intf_port -mode Master -vlnv xilinx.com:interface:ddrx_rtl:1.0 DDR
connect_bd_intf_net [get_bd_intf_pins processing_system7_0/DDR] [get_bd_intf_ports DDR]
endgroup
startgroup
create_bd_intf_port -mode Master -vlnv xilinx.com:display_processing_system7:fixedio_rtl:1.0 FIXED_IO
connect_bd_intf_net [get_bd_intf_pins processing_system7_0/FIXED_IO] [get_bd_intf_ports FIXED_IO]
endgroup
startgroup
set_property -dict [list CONFIG.PCW_USE_M_AXI_GP1 {1} CONFIG.PCW_USE_S_AXI_ACP {1} CONFIG.PCW_USE_FABRIC_INTERRUPT {1} CONFIG.PCW_IRQ_F2P_INTR {1}] [get_bd_cells processing_system7_0]
endgroup
startgroup
create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio:2.0 axi_gpio_0
endgroup
startgroup
apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config {Master "/processing_system7_0/M_AXI_GP1" Clk "Auto" }  [get_bd_intf_pins axi_gpio_0/S_AXI]
apply_bd_automation -rule xilinx.com:bd_rule:board -config {Board_Interface "btns_5bits ( Push buttons ) " }  [get_bd_intf_pins axi_gpio_0/GPIO]
endgroup
startgroup
create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio:2.0 axi_gpio_1
endgroup
startgroup
apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config {Master "/processing_system7_0/M_AXI_GP1" Clk "Auto" }  [get_bd_intf_pins axi_gpio_1/S_AXI]
apply_bd_automation -rule xilinx.com:bd_rule:board -config {Board_Interface "leds_8bits ( LED ) " }  [get_bd_intf_pins axi_gpio_1/GPIO]
endgroup
startgroup
create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio:2.0 axi_gpio_2
endgroup
startgroup
apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config {Master "/processing_system7_0/M_AXI_GP1" Clk "Auto" }  [get_bd_intf_pins axi_gpio_2/S_AXI]
apply_bd_automation -rule xilinx.com:bd_rule:board -config {Board_Interface "sws_8bits ( DIP switches ) " }  [get_bd_intf_pins axi_gpio_2/GPIO]
endgroup
startgroup
create_bd_intf_port -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_GP0
set_property -dict [list CONFIG.PROTOCOL [get_property CONFIG.PROTOCOL [get_bd_intf_pins processing_system7_0/M_AXI_GP0]] CONFIG.HAS_REGION [get_property CONFIG.HAS_REGION [get_bd_intf_pins processing_system7_0/M_AXI_GP0]] CONFIG.NUM_READ_OUTSTANDING [get_property CONFIG.NUM_READ_OUTSTANDING [get_bd_intf_pins processing_system7_0/M_AXI_GP0]] CONFIG.NUM_WRITE_OUTSTANDING [get_property CONFIG.NUM_WRITE_OUTSTANDING [get_bd_intf_pins processing_system7_0/M_AXI_GP0]]] [get_bd_intf_ports M_AXI_GP0]
connect_bd_intf_net [get_bd_intf_pins processing_system7_0/M_AXI_GP0] [get_bd_intf_ports M_AXI_GP0]
endgroup
set_property name M_AXI [get_bd_intf_ports M_AXI_GP0]
startgroup
create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_ACP
set_property -dict [list CONFIG.DATA_WIDTH [get_property CONFIG.DATA_WIDTH [get_bd_intf_pins processing_system7_0/S_AXI_ACP]] CONFIG.PROTOCOL [get_property CONFIG.PROTOCOL [get_bd_intf_pins processing_system7_0/S_AXI_ACP]] CONFIG.ID_WIDTH [get_property CONFIG.ID_WIDTH [get_bd_intf_pins processing_system7_0/S_AXI_ACP]] CONFIG.AWUSER_WIDTH [get_property CONFIG.AWUSER_WIDTH [get_bd_intf_pins processing_system7_0/S_AXI_ACP]] CONFIG.ARUSER_WIDTH [get_property CONFIG.ARUSER_WIDTH [get_bd_intf_pins processing_system7_0/S_AXI_ACP]] CONFIG.HAS_REGION [get_property CONFIG.HAS_REGION [get_bd_intf_pins processing_system7_0/S_AXI_ACP]] CONFIG.NUM_READ_OUTSTANDING [get_property CONFIG.NUM_READ_OUTSTANDING [get_bd_intf_pins processing_system7_0/S_AXI_ACP]] CONFIG.NUM_WRITE_OUTSTANDING [get_property CONFIG.NUM_WRITE_OUTSTANDING [get_bd_intf_pins processing_system7_0/S_AXI_ACP]] CONFIG.MAX_BURST_LENGTH [get_property CONFIG.MAX_BURST_LENGTH [get_bd_intf_pins processing_system7_0/S_AXI_ACP]]] [get_bd_intf_ports S_AXI_ACP]
connect_bd_intf_net [get_bd_intf_pins processing_system7_0/S_AXI_ACP] [get_bd_intf_ports S_AXI_ACP]
endgroup
set_property name S_AXI [get_bd_intf_ports S_AXI_ACP]
connect_bd_net [get_bd_pins processing_system7_0/M_AXI_GP0_ACLK] [get_bd_pins processing_system7_0/M_AXI_GP1_ACLK]
connect_bd_net [get_bd_pins processing_system7_0/S_AXI_ACP_ACLK] [get_bd_pins processing_system7_0/FCLK_CLK0]
startgroup
create_bd_port -dir O -type clk FCLK_CLK0
connect_bd_net [get_bd_pins /processing_system7_0/FCLK_CLK0] [get_bd_ports FCLK_CLK0]
endgroup
startgroup
create_bd_port -dir O -type rst FCLK_RESET0_N
connect_bd_net [get_bd_pins /processing_system7_0/FCLK_RESET0_N] [get_bd_ports FCLK_RESET0_N]
endgroup
set_property CONFIG.ASSOCIATED_BUSIF {M_AXI} [get_bd_ports /FCLK_CLK0]
set_property CONFIG.ASSOCIATED_BUSIF {M_AXI:S_AXI} [get_bd_ports /FCLK_CLK0]

assign_bd_address
validate_bd_design
save_bd_design

generate_target -force all [get_files ${BD_DIR}/${BD_NAME}.bd]
export_ip_user_files -of_objects [get_files ${BD_DIR}/${BD_NAME}.bd] -no_script -force -quiet
close_project

Tcl Shellを起動してTclコマンドを実行する

Tcl Consoleを起動します。

Tcl Shellの起動

Tcl Shellの起動

Linux環境の場合、bashなどのシェルから”vivado -mode tcl”を実行するとTcl Consoleを起動できます。

次に、作成したTclファイルが存在するディレクトリに移動します。ファイルをsourceすると、VivadoのGUIで行った処理がそのままTcl Shellで実行されます。

Tclの実行

Tclの実行

実行開始直後の様子

実行開始直後の様子

処理がすべて完了すると、現在のディレクトリに次のようなサブディレクトリが作成されて、その中にIPコアのRTLなどが生成されます。 このディレクトリで配布に必要なファイルは、run.tclだけです。その他のファイルはVivadoで生成可能です。つまり、run.tclさえあれば、任意のディレクトリにVivadoのデータを再生成できます。

生成されたディレクトリとファイル

生成されたディレクトリとファイル

Vivado GUIでの確認

コマンドラインで生成したプロジェクトは、VivadoのGUIで開くことができます。

Vivado GUIでのプロジェクト表示

Vivado GUIでのプロジェクト表示

その他

Tcl Shell以外にも、settings64.batを実行したコマンドプロンプトからもtclを実行できます(Windowsの場合)。

vivado -m64 -mode batch -source run.tcl
コマンドプロンプトからVivadoを実行

コマンドプロンプトからVivadoを実行

タイトルとURLをコピーしました