1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Vivado で IP を作る Tcl スクリプト

1
Posted at

はじめに

Xilinx 社のFPGA開発環境の Vivado、いちいち GUI でマウスボタンをポチポチするのは面倒です。
Vivado は Tcl スクリプトでバッチ処理が出来るので、決まり切った仕事なら Tcl スクリプトを書いて処理させたほうが楽です。

また、ユーザーが作った RTL を IP 化しておくと、Vivado の Block Design で利用したり、パラメーターを GUI から変更可能に出来たりして便利です。

この記事では、Vivado でユーザーが作った RTL を IP 化 する Tclスクリプトを解説します。

環境

  • Xilinx Vivado 2023.1
  • Xilinx Vivado 2025.1

Tclスクリプトの説明

1 あらかじめ使用する定数を定義しておく

この記事では、IP を作るための各種定数を設定しておく Tcl スクリプトを setting.tcl として用意しておきます。

例えばIP の名前(ip_name)、バージョン(ip_version/ip_core_revision)、ベンダー名(ip_vendor_name)、ライブラリ名(ip_library_name)、簡単な説明(ip_description)、IPを作るディレクトリ(ip_root_directory)を次のように定義しておきます。

また、IP を作る際は Vivado プロジェクトが必要になるので、そのプロジェクトの名前(project_name)と、プロジェクトを作るディレクトリ(project_directory) もあわせて定義しておきます。

この記事では『VHDL で書くマージソーター(ArgSort IP)』@Qiita で紹介した ArgSort IP を作る際に使用した Tcl スクリプトを例に示します。

setting.tcl
#
# setting.tcl  Tcl script for create project and generate IP
#
set ip_name                 "ArgSort_AXI"
set ip_version              "1.7"
set ip_core_revision        1
set ip_vendor_name          "ikwzm"
set ip_description          "ArgSort_AXI"
set ip_library_name         "Merge_Sorter"
set ip_root_directory       [file join [file dirname [info script]] ".." "argsort_axi_$ip_version"]

set project_name            "argsort_axi"
set project_directory       [file join [file dirname [info script]] "work"]
set device_parts            "xc7z010clg400-1"

IP を作る Tcl スクリプト(create_ip.tcl)の先頭には、上述の setting.tcl を読み込むようにしておきます。

create_ip.tcl
#
# create_ip.tcl  Tcl script for create project and generate IP
#
source [file join [file dirname [info script]] "setting.tcl"]

2 新しい空のプロジェクトを作る

まずまっさらのプロジェクトを作ります。なお、Vivado の新しいプロジェクトを作る Tcl スクリプトは以下の記事で別途紹介しています。詳しいことはそちらを参照してください。

この記事では、Tcl スクリプトのみをあげておきます。

create_ip.tcl
#
# Create project
#
cd [file dirname [info script]]
create_project -force $project_name $project_directory
#
# Set project properties
#
set_property "part"               $device_parts    [get_projects $project_name]
set_property "default_lib"        "xil_defaultlib" [get_projects $project_name]
set_property "simulator_language" "Mixed"          [get_projects $project_name]
set_property "target_language"    "VHDL"           [get_projects $project_name]
#
# Create fileset "sources_1"
#
if {[string equal [get_filesets -quiet sources_1] ""]} {
    create_fileset -srcset sources_1
}
#
# Create fileset "constrs_1"
#
if {[string equal [get_filesets -quiet constrs_1] ""]} {
    create_fileset -constrset constrs_1
}
#
# Create fileset "sim_1"
#
if {[string equal [get_filesets -quiet sim_1] ""]} {
    create_fileset -simset sim_1
}
#
# Create run "synth_1" and set property
#
if {[string equal [get_runs -quiet synth_1] ""]} {
    create_run -name synth_1 -part $device_parts -flow "Vivado Synthesis 2014" -strategy "Vivado Synthesis Defaults" -constrset constrs_1
} else {
  # set_property flow     "Vivado Synthesis 2014"     [get_runs synth_1]
    set_property strategy "Vivado Synthesis Defaults" [get_runs synth_1]
    set_property strategy "Flow_PerfOptimized_High"   [get_runs synth_1]
}
current_run -synthesis [get_runs synth_1]
#
# Create run "impl_1" and set property
#
if {[string equal [get_runs -quiet impl_1] ""]} {
    create_run -name impl_1 -part $device_parts -flow "Vivado Implementation 2014" -strategy "Vivado Implementation Defaults" -constrset constrs_1 -parent_run synth_1
} else {
  # set_property flow     "Vivado Implementation 2014"     [get_runs impl_1]
    set_property strategy "Vivado Implementation Defaults" [get_runs impl_1]
    set_property strategy "Performance_Explore"            [get_runs impl_1]
}
current_run -implementation [get_runs impl_1]

3 sources_1 にVHDLファイルを追加する。

この例ではVHDLファイルを追加する方法を説明していますが、同様の方法でVerilogファイルを追加することも出来るはずです。

VHDLファイルをsources_1 に追加する場合は次のようにします。
VHDLファイルは多数あることが多いので、まずはファイルセットに追加するためのプロシージャ(add_vhdl_file)を定義しておきます。
ファイルセットに追加する際、ファイルそのものをプロジェクトにコピーする場合は次のように import_files を使用します。

create_ip.tcl
#
# Add files
#
proc add_vhdl_file {fileset_name library_name file_name} {
    set file     [file normalize $file_name   ]
    set fileset  [get_filesets   $fileset_name]
    set file_obj [import_files -norecurse -fileset $fileset $file]
    set_property "file_type" "VHDL"        $file_obj
    set_property "library"   $library_name $file_obj
}

上記プロシージャを使って、追加したいVHDLファイルを指定します。

次のように追加したいVHDLファイルを別のスクリプトファイルと用意しておき(この例では add_sources.tcl)、そのファイルを読み込むことも可能です。

create_ip.tcl
source add_sources.tcl

このような add_sources.tcl を作る際には、次の記事の「Create add_sources.tcl」も参考にしてください。

4 IP パッケージプロジェクトを作る

Vivado のプロジェクトから、さらに ipx::package_project を使って IP パッケージ専用のプロジェクトをつくります。

create_ip.tcl
#
# Create IP-Package project
#
ipx::package_project -root_dir $ip_root_directory -vendor $ip_vendor_name -library $ip_library_name -taxonomy /UserIP -generated_files -import_files -force

5 バスインターフェースを指定する

IP が使うバスインターフェースを指定します。指定するバスインターフェースは IP によって異なります。この例(ArgSort IP)では、すでに Vivado で定義済みの AXI4 Memory MappedAXI4-Stream を指定しています。

create_ip.tcl
#
# Infer Bus Interfaces
#
ipx::infer_bus_interfaces xilinx.com:interface:aximm_rtl:1.0 [ipx::current_core]
ipx::infer_bus_interfaces xilinx.com:interface:axis_rtl:1.0  [ipx::current_core]

なお、IP のポート名が Vivado で定義済みのバスインターフェースの命名規則にしたがっている場合は、自動認識するため、特にポートとのマッピングは必要ありません。例えば、ArgSort IP の entity は次のようになっています。

argsort_axi.vhd(長いので折りたたみ)
argsort_axi.vhd
library ieee;
use     ieee.std_logic_1164.all;
entity  ArgSort_AXI is
    generic (
        MRG_WAYS            : --! @brief MERGE WAY SIZE :
                              integer :=  4;
        MRG_WORDS           : --! @brief MERGE WORD SIZE :
                              integer :=  1;
        WORD_BITS           : --! @brief SORT WORD BIT SIZE :
                              integer := 32;
        INDEX_BITS          : --! @brief INDEX BIT SIZE :
                              integer := 32;
        COMP_SIGN           : --! @brief COMPARE SIGN :
                              boolean := FALSE;
        SORT_ORDER          : --! @brief SORT ORDER :
                              integer :=  0;
        SORT_SIZE_BITS      : --! @brief SORT SIZE BITS :
                              integer range 1 to 32 := 28;
        MRG_FIFO_SIZE       : --! @brief MERGE FIFO SIZE :
                              integer := 16;
        STM_FEEDBACK        : --! @brief STREAM FEED BACK NUMBER :
                              integer :=  0;
        STM_IN_QUEUE_SIZE   : --! @brief STREAM IN QUEUE SIZE :
                              integer :=  0;
        CSR_AXI_ADDR_WIDTH  : --! @brief CSR I/F AXI ADDRRESS WIDTH :
                              integer := 12;
        CSR_AXI_DATA_WIDTH  : --! @brief CSR I/F AXI DATA WIDTH :
                              integer := 32;
        STM_AXI_ADDR_WIDTH  : --! @brief STREAM IN/OUT AXI ADDRESS WIDTH :
                              integer := 32;
        STM_AXI_DATA_WIDTH  : --! @brief STREAM IN/OUT AXI DATA WIDTH :
                              integer := 64;
        STM_AXI_ID_WIDTH    : --! @brief STREAM IN/OUT AXI ID WIDTH :
                              integer := 1;
        STM_AXI_USER_WIDTH  : --! @brief STREAM IN/OUT AXI ADDRESS USER WIDTH :
                              integer := 2;
        STM_AXI_ID_BASE     : --! @brief STREAM IN/OUT AXI ID BASE :
                              integer := 0;
        STM_RD_AXI_XFER_SIZE: --! @brief STREAM IN  AXI MAX XFER SIZE :
                              integer := 11;
        STM_RD_AXI_BUF_SIZE : --! @brief STREAM IN  AXI BUFFER SIZE :
                              integer := 0;
        STM_RD_AXI_QUEUE    : --! @brief STREAM IN  AXI QUEUE SIZE :
                              integer := 4;
        STM_RD_AXI_DATA_REGS: --! @brief STREAM IN  AXI DATA REGISTER :
                              integer := 2;
        STM_RD_AXI_ACK_REGS : --! @brief STREAM IN  AXI ACKNOWLEDGE REGISTER :
                              integer range 0 to 1 := 1;
        STM_WR_AXI_XFER_SIZE: --! @brief STREAM OUT AXI MAX XFER SIZE :
                              integer := 11;
        STM_WR_AXI_BUF_SIZE : --! @brief STREAM OUT AXI BUFFER SIZE :
                              integer := 0;
        STM_WR_AXI_QUEUE    : --! @brief STREAM OUT AXI QUEUE SIZE :
                              integer := 4;
        STM_WR_AXI_REQ_REGS : --! @brief STREAM OUT AXI REQUEST REGISTER :
                              integer range 0 to 1 := 1;
        STM_WR_AXI_ACK_REGS : --! @brief STREAM OUT AXI ACKNOWLEDGE REGISTER :
                              integer range 0 to 1 := 1;
        STM_WR_AXI_RESP_REGS: --! @brief STREAM OUT AXI RESPONSE REGISTER :
                              integer range 0 to 1 := 1;
        MRG_AXI_ADDR_WIDTH  : --! @brief MERGE IN/OUT AXI ADDRESS WIDTH :
                              integer := 32;
        MRG_AXI_DATA_WIDTH  : --! @brief MERGE IN/OUT AXI DATA WIDTH :
                              integer := 64;
        MRG_AXI_ID_WIDTH    : --! @brief MERGE IN/OUT AXI ID WIDTH :
                              integer := 1;
        MRG_AXI_USER_WIDTH  : --! @brief MERGE IN/OUT AXI ADDRESS USER WIDTH :
                              integer := 2;
        MRG_AXI_ID_BASE     : --! @brief MERGE IN/OUT AXI ID BASE :
                              integer := 0;
        MRG_RD_AXI_XFER_SIZE: --! @brief MERGE IN  AXI MAX XFER SIZE :
                              integer := 11;
        MRG_RD_AXI_BUF_SIZE : --! @brief MERGE IN  AXI BUFFER SIZE :
                              integer := 0;
        MRG_RD_AXI_QUEUE    : --! @brief MERGE IN  AXI QUEUE SIZE :
                              integer := 4;
        MRG_RD_AXI_DATA_REGS: --! @brief MERGE IN  AXI DATA REGISTER :
                              integer := 2;
        MRG_RD_AXI_ACK_REGS : --! @brief MERGE IN  AXI ACKNOWLEDGE REGISTER :
                              integer range 0 to 1 := 1;
        MRG_RD_ARB_NODE_NUM : --! @brief MERGE IN  ARBITER NODE SIZE :
                              integer := 4;
        MRG_RD_ARB_PIPELINE : --! @brief MERGE IN  ARBITER PIPELINE :
                              integer := 0;
        MRG_RD_PRE_STATE    : --! @brief MERGE IN  PRE STATE :
                              integer := 0;
        MRG_WR_AXI_XFER_SIZE: --! @brief MERGE OUT AXI MAX XFER SIZE :
                              integer := 11;
        MRG_WR_AXI_BUF_SIZE : --! @brief MERGE OUT AXI BUFFER SIZE :
                              integer := 0;
        MRG_WR_AXI_QUEUE    : --! @brief MERGE OUT AXI QUEUE SIZE :
                              integer := 4;
        MRG_WR_AXI_REQ_REGS : --! @brief MERGE OUT AXI REQUEST REGISTER :
                              integer range 0 to 1 := 1;
        MRG_WR_AXI_ACK_REGS : --! @brief MERGE OUT AXI ACKNOWLEDGE REGISTER :
                              integer range 0 to 1 := 1;
        MRG_WR_AXI_RESP_REGS: --! @brief MERGE OUT AXI RESPONSE REGISTER :
                              integer range 0 to 1 := 1;
        DEBUG_ENABLE        : --! @brief DEBUG ENABLE :
                              integer range 0 to 1 := 0
    );
    port(
    -------------------------------------------------------------------------------
    -- Clock / Reset Signals.
    -------------------------------------------------------------------------------
        ACLK                : in  std_logic;
        ARESETn             : in  std_logic;
    -------------------------------------------------------------------------------
    -- Control Status Register I/F AXI4 Read Address Channel Signals.
    -------------------------------------------------------------------------------
        CSR_AXI_ARADDR      : in  std_logic_vector(CSR_AXI_ADDR_WIDTH   -1 downto 0);
        CSR_AXI_ARVALID     : in  std_logic;
        CSR_AXI_ARREADY     : out std_logic;
    ------------------------------------------------------------------------------
    -- Control Status Register I/F AXI4 Read Data Channel Signals.
    ------------------------------------------------------------------------------
        CSR_AXI_RDATA       : out std_logic_vector(CSR_AXI_DATA_WIDTH   -1 downto 0);
        CSR_AXI_RRESP       : out std_logic_vector(1 downto 0);  
        CSR_AXI_RVALID      : out std_logic;
        CSR_AXI_RREADY      : in  std_logic;
    ------------------------------------------------------------------------------
    -- Control Status Register I/F AXI4 Write Address Channel Signals.
    ------------------------------------------------------------------------------
        CSR_AXI_AWADDR      : in  std_logic_vector(CSR_AXI_ADDR_WIDTH   -1 downto 0);
        CSR_AXI_AWVALID     : in  std_logic;
        CSR_AXI_AWREADY     : out std_logic;
    ------------------------------------------------------------------------------
    -- Control Status Register I/F AXI4 Write Data Channel Signals.
    ------------------------------------------------------------------------------
        CSR_AXI_WDATA       : in  std_logic_vector(CSR_AXI_DATA_WIDTH   -1 downto 0);
        CSR_AXI_WSTRB       : in  std_logic_vector(CSR_AXI_DATA_WIDTH/8 -1 downto 0);
        CSR_AXI_WVALID      : in  std_logic;
        CSR_AXI_WREADY      : out std_logic;
    ------------------------------------------------------------------------------
    -- Control Status Register I/F AXI4 Write Response Channel Signals.
    ------------------------------------------------------------------------------
        CSR_AXI_BRESP       : out std_logic_vector(1 downto 0);
        CSR_AXI_BVALID      : out std_logic;
        CSR_AXI_BREADY      : in  std_logic;
    -------------------------------------------------------------------------------
    -- STREAM IN/OUT AXI4 Read Address Channel Signals.
    -------------------------------------------------------------------------------
        STM_AXI_ARID        : out std_logic_vector(STM_AXI_ID_WIDTH    -1 downto 0);
        STM_AXI_ARADDR      : out std_logic_vector(STM_AXI_ADDR_WIDTH  -1 downto 0);
        STM_AXI_ARLEN       : out std_logic_vector(7 downto 0);
        STM_AXI_ARSIZE      : out std_logic_vector(2 downto 0);
        STM_AXI_ARBURST     : out std_logic_vector(1 downto 0);
        STM_AXI_ARLOCK      : out std_logic_vector(0 downto 0);
        STM_AXI_ARCACHE     : out std_logic_vector(3 downto 0);
        STM_AXI_ARPROT      : out std_logic_vector(2 downto 0);
        STM_AXI_ARQOS       : out std_logic_vector(3 downto 0);
        STM_AXI_ARREGION    : out std_logic_vector(3 downto 0);
        STM_AXI_ARUSER      : out std_logic_vector(STM_AXI_USER_WIDTH  -1 downto 0);
        STM_AXI_ARVALID     : out std_logic;
        STM_AXI_ARREADY     : in  std_logic;
    -------------------------------------------------------------------------------
    -- STREAM IN/OUT AXI4 Read Data Channel Signals.
    -------------------------------------------------------------------------------
        STM_AXI_RID         : in  std_logic_vector(STM_AXI_ID_WIDTH    -1 downto 0);
        STM_AXI_RDATA       : in  std_logic_vector(STM_AXI_DATA_WIDTH  -1 downto 0);
        STM_AXI_RRESP       : in  std_logic_vector(1 downto 0);
        STM_AXI_RLAST       : in  std_logic;
        STM_AXI_RVALID      : in  std_logic;
        STM_AXI_RREADY      : out std_logic;
    -------------------------------------------------------------------------------
    -- STREAM IN/OUT AXI4 Write Address Channel Signals.
    -------------------------------------------------------------------------------
        STM_AXI_AWID        : out std_logic_vector(STM_AXI_ID_WIDTH    -1 downto 0);
        STM_AXI_AWADDR      : out std_logic_vector(STM_AXI_ADDR_WIDTH  -1 downto 0);
        STM_AXI_AWLEN       : out std_logic_vector(7 downto 0);
        STM_AXI_AWSIZE      : out std_logic_vector(2 downto 0);
        STM_AXI_AWBURST     : out std_logic_vector(1 downto 0);
        STM_AXI_AWLOCK      : out std_logic_vector(0 downto 0);
        STM_AXI_AWCACHE     : out std_logic_vector(3 downto 0);
        STM_AXI_AWPROT      : out std_logic_vector(2 downto 0);
        STM_AXI_AWQOS       : out std_logic_vector(3 downto 0);
        STM_AXI_AWREGION    : out std_logic_vector(3 downto 0);
        STM_AXI_AWUSER      : out std_logic_vector(STM_AXI_USER_WIDTH  -1 downto 0);
        STM_AXI_AWVALID     : out std_logic;
        STM_AXI_AWREADY     : in  std_logic;
    -------------------------------------------------------------------------------
    -- STREAM IN/OUT AXI4 Write Data Channel Signals.
    -------------------------------------------------------------------------------
        STM_AXI_WID         : out std_logic_vector(STM_AXI_ID_WIDTH    -1 downto 0);
        STM_AXI_WDATA       : out std_logic_vector(STM_AXI_DATA_WIDTH  -1 downto 0);
        STM_AXI_WSTRB       : out std_logic_vector(STM_AXI_DATA_WIDTH/8-1 downto 0);
        STM_AXI_WLAST       : out std_logic;
        STM_AXI_WVALID      : out std_logic;
        STM_AXI_WREADY      : in  std_logic;
    -------------------------------------------------------------------------------
    -- STREAM IN/OUT AXI4 Write Response Channel Signals.
    -------------------------------------------------------------------------------
        STM_AXI_BID         : in  std_logic_vector(STM_AXI_ID_WIDTH    -1 downto 0);
        STM_AXI_BRESP       : in  std_logic_vector(1 downto 0);
        STM_AXI_BVALID      : in  std_logic;
        STM_AXI_BREADY      : out std_logic;
    -------------------------------------------------------------------------------
    -- MERGE IN/OUT AXI4 Read Address Channel Signals.
    -------------------------------------------------------------------------------
        MRG_AXI_ARID        : out std_logic_vector(MRG_AXI_ID_WIDTH    -1 downto 0);
        MRG_AXI_ARADDR      : out std_logic_vector(MRG_AXI_ADDR_WIDTH  -1 downto 0);
        MRG_AXI_ARLEN       : out std_logic_vector(7 downto 0);
        MRG_AXI_ARSIZE      : out std_logic_vector(2 downto 0);
        MRG_AXI_ARBURST     : out std_logic_vector(1 downto 0);
        MRG_AXI_ARLOCK      : out std_logic_vector(0 downto 0);
        MRG_AXI_ARCACHE     : out std_logic_vector(3 downto 0);
        MRG_AXI_ARPROT      : out std_logic_vector(2 downto 0);
        MRG_AXI_ARQOS       : out std_logic_vector(3 downto 0);
        MRG_AXI_ARREGION    : out std_logic_vector(3 downto 0);
        MRG_AXI_ARUSER      : out std_logic_vector(MRG_AXI_USER_WIDTH  -1 downto 0);
        MRG_AXI_ARVALID     : out std_logic;
        MRG_AXI_ARREADY     : in  std_logic;
    -------------------------------------------------------------------------------
    -- MERGE IN/OUT AXI4 Read Data Channel Signals.
    -------------------------------------------------------------------------------
        MRG_AXI_RID         : in  std_logic_vector(MRG_AXI_ID_WIDTH    -1 downto 0);
        MRG_AXI_RDATA       : in  std_logic_vector(MRG_AXI_DATA_WIDTH  -1 downto 0);
        MRG_AXI_RRESP       : in  std_logic_vector(1 downto 0);
        MRG_AXI_RLAST       : in  std_logic;
        MRG_AXI_RVALID      : in  std_logic;
        MRG_AXI_RREADY      : out std_logic;
    -------------------------------------------------------------------------------
    -- MERGE IN/OUT AXI4 Write Address Channel Signals.
    -------------------------------------------------------------------------------
        MRG_AXI_AWID        : out std_logic_vector(MRG_AXI_ID_WIDTH    -1 downto 0);
        MRG_AXI_AWADDR      : out std_logic_vector(MRG_AXI_ADDR_WIDTH  -1 downto 0);
        MRG_AXI_AWLEN       : out std_logic_vector(7 downto 0);
        MRG_AXI_AWSIZE      : out std_logic_vector(2 downto 0);
        MRG_AXI_AWBURST     : out std_logic_vector(1 downto 0);
        MRG_AXI_AWLOCK      : out std_logic_vector(0 downto 0);
        MRG_AXI_AWCACHE     : out std_logic_vector(3 downto 0);
        MRG_AXI_AWPROT      : out std_logic_vector(2 downto 0);
        MRG_AXI_AWQOS       : out std_logic_vector(3 downto 0);
        MRG_AXI_AWREGION    : out std_logic_vector(3 downto 0);
        MRG_AXI_AWUSER      : out std_logic_vector(MRG_AXI_USER_WIDTH  -1 downto 0);
        MRG_AXI_AWVALID     : out std_logic;
        MRG_AXI_AWREADY     : in  std_logic;
    -------------------------------------------------------------------------------
    -- MERGE IN/OUT AXI4 Write Data Channel Signals.
    -------------------------------------------------------------------------------
        MRG_AXI_WID         : out std_logic_vector(MRG_AXI_ID_WIDTH    -1 downto 0);
        MRG_AXI_WDATA       : out std_logic_vector(MRG_AXI_DATA_WIDTH  -1 downto 0);
        MRG_AXI_WSTRB       : out std_logic_vector(MRG_AXI_DATA_WIDTH/8-1 downto 0);
        MRG_AXI_WLAST       : out std_logic;
        MRG_AXI_WVALID      : out std_logic;
        MRG_AXI_WREADY      : in  std_logic;
    -------------------------------------------------------------------------------
    -- MERGE IN/OUT AXI4 Write Response Channel Signals.
    -------------------------------------------------------------------------------
        MRG_AXI_BID         : in  std_logic_vector(MRG_AXI_ID_WIDTH    -1 downto 0);
        MRG_AXI_BRESP       : in  std_logic_vector(1 downto 0);
        MRG_AXI_BVALID      : in  std_logic;
        MRG_AXI_BREADY      : out std_logic;
    -------------------------------------------------------------------------------
    -- Interrupt Request
    -------------------------------------------------------------------------------
        INTERRUPT           : out std_logic
    );
end ArgSort_AXI;

上記のような entity の場合、Vivado は CSR_AXI_ で始まるポート群、STM_AXI_ で始まるポート群、MRG_AXI_ で始まるポート群を各々 CSR_AXI という AXI4-Lite Slave I/FSTM_AXI という AXI4 Memory Mapped Master I/FMRG_AXI という AXI4 Memory Mapped Master I/F として解釈します。

自動認識されない場合は、Tcl スクリプトで手動でポートとマッピングする必要があります。あるいは、Vivado で自動認識できるようにポート名を変更するか、ポート名を変更したラッパーをかぶせたほうが簡単かもしれません。

6 サポートするデバイスを定義する

この例(ArgSort IP)では、ほとんどのデバイスをサポートしています。

create_ip.tcl
#
# Set Supported Families
#
set_property supported_families {zynq Production virtex7 Production qvirtex7 Production kintex7 Production kintex7l Production qkintex7 Production qkintex7l Production artix7 Production artix7l Production aartix7 Production qartix7 Production zynq Production qzynq Production azynq Production zynquplus Production} [ipx::current_core]

7 IP の各種属性(property)を設定する

IP の名前(ip_name)、バージョン(ip_version/ip_core_revision)、簡単な説明(ip_description)を IP に設定します。

create_ip.tcl
#
# Set Core Version
#
set_property version       $ip_version       [ipx::current_core]
set_property core_revision $ip_core_revision [ipx::current_core]
set_property name          $ip_name          [ipx::current_core]
set_property display_name  $ip_name          [ipx::current_core]
set_property description   $ip_description   [ipx::current_core]

8 IP の各種ファイル生成する

最後に各種ファイルを生成して ip_root_directory で指定したディレクトリに保存します。

create_ip.tcl
#
# Generate files
#
ipx::create_xgui_files       [ipx::current_core]
ipx::update_checksums        [ipx::current_core]
ipx::save_core               [ipx::current_core]
#
# Close and Done.
#
close_project

GUI の設定

この記事で紹介した Tcl スクリプトは IP として必要最低限のものしか作りません。そのままでも IP として使えないことはないのですが、Vivado の Block Design からパラメーターを設定する場合は、次のように少し GUI が貧弱です(というかパラメーターが多すぎてよくわからない)。

Fig.1 ArgSort IP 貧弱な GUI

そこで次の記事で IP の GUI を変更する方法を紹介する予定です(近日公開)。

  • 『Vivado で IP の GUI を整える Tclスクリプト』@Qiita

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?