VivadoのGUIでプロジェクトを作成すると、色々なファイルが生成されます。そのプロジェクトのデータを配布する場合、ファイルに絶対パスなどが含まれていると、データの再現性に不安が残ります。また、配布は必要最低限の設定ファイルだけにして、RTLなどのデータは配布先の環境で生成できた方がいろいろと都合が良いです。
Vivadoの中で、GUIへの依存度が高いと思われるのが、IP Integratorです。IP Integratorでは、GUIを使ってIPを接続し、目的とするシステムを簡単に作成することができます。
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に表示されます。
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という名前で外部ポートとして出力
コマンドライン用の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を起動します。
Linux環境の場合、bashなどのシェルから”vivado -mode tcl”を実行するとTcl Consoleを起動できます。
次に、作成したTclファイルが存在するディレクトリに移動します。ファイルをsourceすると、VivadoのGUIで行った処理がそのままTcl Shellで実行されます。
処理がすべて完了すると、現在のディレクトリに次のようなサブディレクトリが作成されて、その中にIPコアのRTLなどが生成されます。 このディレクトリで配布に必要なファイルは、run.tclだけです。その他のファイルはVivadoで生成可能です。つまり、run.tclさえあれば、任意のディレクトリにVivadoのデータを再生成できます。
Vivado GUIでの確認
コマンドラインで生成したプロジェクトは、VivadoのGUIで開くことができます。
その他
Tcl Shell以外にも、settings64.batを実行したコマンドプロンプトからもtclを実行できます(Windowsの場合)。
vivado -m64 -mode batch -source run.tcl