使用vivado封装IP

文章目录

    • Basics
    • 定制IP的参数
    • Enablement Expression
    • 封装IP时使用了绝对路径
    • 封装IP时设置Address Map Addr
    • 相关tcl
    • 修正警告
      • Bus Interface 'clk': ASSOCIATED_BUSIF bus parameter is missing.
      • rst识别成低有效复位
      • Bus Interface 'up_axi': FREQ_HZ bus parameter missing from AXI interface when interface is not associated to a clock.
    • 打开IP-XACT来管理IP
    • Package as a library core
    • 自定义IP包含xilinx ip时的选项
    • 自定义IP时设置logo
    • 封装IP时生成自定义总线接口
    • 使用vivado自定义总线接口
    • 在BD中添加RTL Module时使用自定义总线接口
    • 将旧版vivado IP添加到新版vivado IP仓库中
    • 将HDL源码(含网表文件)封为IP
    • 将MicroBlaze/MCS的bd文件(含elf)封装为IP
    • AR
      • AR66292 - Vivado IP Flows - Sub-core reference is not updated for migrated project even though the parent IP core was upgraded
      • AR75421 - Using Packaged IP library core and referencing as VHDL library
      • AR65277 封装IP时,设置动态端口
    • 其他
      • 一些IP在catlog中不显示
      • 设置动态端口时,使用tcl
      • 设置AXI总线端口的映射时,使用tcl
  • ttcl

Basics

  • Vivado IP 封装器可以自动 推断IP的 时钟和复位接口, 这样有助于在 IPI验证BD文件中验证封装IP的时钟、复位信号
  • 对于自定义的IP,可以在IP Catlog中出现多个版本
    使用vivado封装IP_第1张图片
  • 可以在封装IP时,设置parameter的类型、范围;并提供启用表达式,实现一些定制功能

定制IP的参数

参数分为两类,一类显示在GUI界面中(可以由用户设置)可以在GUI界面中;另一类则不显示在GUI界面中(不能由用户设置,其参数值通常是由GUI 中显示的参数来确定的)。
使用vivado封装IP_第2张图片

  • 添加参数时,只能添加在自定义 GUI 中使用的参数
  • 删除参数后,IP则会使用相应参数的默认值
    使用vivado封装IP_第3张图片

Enablement Expression

使用vivado封装IP_第4张图片

封装IP时使用了绝对路径

Is it possible in Vivado to package a custom IP with relative paths for all rtl

使用vivado封装IP_第5张图片
看这段描述是说,如果封装IP时引用了IP所在目录之外的文件,则这些引用文件会使用绝对路径。这时,在确保路径正确的情况下,手动修改component.xml中的绝对路径为相对路径即可。

封装IP时设置Address Map Addr

IP Packager “Addressing and Memory” customizations?
在这里插入图片描述

封装了一个IP,使用了AXI接口,因此需要进行地址映射的分配。进行了如下三种尝试,

case 1:封装IP时,base address设为0x10000000,此时在BD中两个IP自动分配的地址相同,修改它们的基地址时出错
使用vivado封装IP_第6张图片

case 2:封装IP时,base address设为0x10000000,此时在BD中两个IP自动分配的地址不同,但修改它们的基地址时出错
使用vivado封装IP_第7张图片

case 3:封装IP时,base address设为0,此时在BD中两个IP自动分配的地址不同,可以修改它们的基地址
使用vivado封装IP_第8张图片

相关tcl

help ipx::*

使用vivado封装IP_第9张图片

修正警告

Bus Interface ‘clk’: ASSOCIATED_BUSIF bus parameter is missing.

使用vivado封装IP_第10张图片

The IP Packager checks for the ASSOCIATED_BUSIF parameter for all clock interfaces.The reason for the warning is that IP Integrator works best with interfaces, and it was expected that user would typically be using AXI interfaces. If you do not have any bus interfaces in your design, you can safely ignore this warning.

IP Packager 会检查所有时钟接口的 ASSOCIATED_BUSIF 参数。发出警告的原因是 IP Integrator 最适用于接口,并且预计用户通常会使用 AXI 接口。 如果您的设计中没有任何总线接口,您可以放心地忽略此警告。

使用vivado封装IP_第11张图片

rst识别成低有效复位

使用vivado封装IP_第12张图片

For reset signals that end with n such as resetn and aresetn which implies an active-Low signal, the interface automatically sets the POLARITY parameter to active_Low. This parameter is used in the Vivado IP integrator to determine if the reset is properly connected when the block diagram is generated. For all other reset interfaces, the POLARITY parameter is not set, and is determined through the parameter propagation feature of IP integrator.

对于以 n 结尾的复位信号,例如 resetn 和 aresetn,这意味着低电平有效信号,接口会自动将 POLARITY 参数设置为 active_Low。 该参数用于 Vivado IP 集成器中,用于在生成框图时确定复位是否正确连接。 对于所有其他复位接口,不设置 POLARITY 参数,通过 IP 集成器的参数传播特性确定

Bus Interface ‘up_axi’: FREQ_HZ bus parameter missing from AXI interface when interface is not associated to a clock.

IP_Flow 19-3158 - FREQ_HZ bus parameter missing from AXI interface when interface is not associated to a clock

使用vivado封装IP_第13张图片
2018.2 Vivado IP Flows - Generate RTL kernel gives three parameter warnings related to an RTL kernel wizard IP block

打开IP-XACT来管理IP

使用vivado封装IP_第14张图片

Package as a library core

使用vivado封装IP_第15张图片

自定义IP包含xilinx ip时的选项

使用vivado封装IP_第16张图片
使用vivado封装IP_第17张图片

自定义IP时设置logo

添加Utility XIT/TTCL的group,并添加logo图片,将Type从image修改成logo
使用vivado封装IP_第18张图片
为方便计,将常用的tcl命令写成脚本,直接通过custom tcl命令执行,
使用vivado封装IP_第19张图片

封装IP时生成自定义总线接口

打开IP封装界面,选择需要封到总线里的端口,选择"Create Interface Definition",
使用vivado封装IP_第20张图片
此时,会弹出界面,来设置生成总线的存储位置,此处选择存放在封装IP的目录中,
使用vivado封装IP_第21张图片
生成总线的各个信号名称,是和端口名称一致的,可以直接使用,也可以重新修改,
使用vivado封装IP_第22张图片
如果总线的信号名称有修改,需要进行port的映射,如下
使用vivado封装IP_第23张图片
之后封装IP,并添加到IP路径中,会发现vivado能扫描到封装的IP以及相应的总线接口,在bd文件中添加IP后,会发现各个端口集成在总线接口中
使用vivado封装IP_第24张图片

使用vivado自定义总线接口

使用vivado封装IP_第25张图片

在BD中添加RTL Module时使用自定义总线接口

在封装IP自定义总线接口时,能看到生成了如下的xml文件,其中包含了总线接口的定义,
使用vivado封装IP_第26张图片
在VHDL文件中,使用attribute进行总线接口的映射,如下

library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

entity test_1 is
port (
    clk      : in  std_logic;
    data_0   : in  std_logic_vector(3 downto 0);
    data_1   : in  std_logic_vector(3 downto 0);
    data_2   : in  std_logic_vector(3 downto 0);
    data_3   : in  std_logic_vector(3 downto 0);
    ctrl_0   : out std_logic_vector(3 downto 0);
    ctrl_1   : out std_logic_vector(3 downto 0)
);
end test_1;

architecture Behavioral of test_1 is
   
    signal data : unsigned(5 downto 0);

    attribute X_INTERFACE_INFO : string;
    attribute X_INTERFACE_INFO of data_0 : signal is "xilinx.com:user:DATA_CTRL_BUS:1.0 DATA_CTRL_BUS data_A";
    attribute X_INTERFACE_INFO of data_1 : signal is "xilinx.com:user:DATA_CTRL_BUS:1.0 DATA_CTRL_BUS data_B";
    attribute X_INTERFACE_INFO of data_2 : signal is "xilinx.com:user:DATA_CTRL_BUS:1.0 DATA_CTRL_BUS data_C";
    attribute X_INTERFACE_INFO of data_3 : signal is "xilinx.com:user:DATA_CTRL_BUS:1.0 DATA_CTRL_BUS data_D";
    attribute X_INTERFACE_INFO of ctrl_0 : signal is "xilinx.com:user:DATA_CTRL_BUS:1.0 DATA_CTRL_BUS ctrl_A";
    attribute X_INTERFACE_INFO of ctrl_1 : signal is "xilinx.com:user:DATA_CTRL_BUS:1.0 DATA_CTRL_BUS ctrl_B";

begin
    
    process(clk)
    begin
        if rising_edge(clk) then    
            data   <= resize(unsigned(data_0),6) + resize(unsigned(data_1),6) + resize(unsigned(data_2),6) + resize(unsigned(data_3),6);
                
            ctrl_0 <= std_logic_vector(data(3 downto 0));
            ctrl_1 <= std_logic_vector(data(5 downto 2));
        end if;
    end process;
end Behavioral;
--------------------------------------------------------------------------
library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
entity test_2 is
port (
    clk      : in  std_logic;
    data_0   : out std_logic_vector(3 downto 0);
    data_1   : out std_logic_vector(3 downto 0);
    data_2   : out std_logic_vector(3 downto 0);
    data_3   : out std_logic_vector(3 downto 0);
    ctrl_0   : in  std_logic_vector(3 downto 0);
    ctrl_1   : in  std_logic_vector(3 downto 0);
    dout     : out std_logic_vector(7 downto 0)
);
end test_2;

architecture Behavioral of test_2 is
    
    attribute X_INTERFACE_INFO : string;
    attribute X_INTERFACE_INFO of data_0 : signal is "xilinx.com:user:DATA_CTRL_BUS:1.0 DATA_CTRL_BUS data_A";
    attribute X_INTERFACE_INFO of data_1 : signal is "xilinx.com:user:DATA_CTRL_BUS:1.0 DATA_CTRL_BUS data_B";
    attribute X_INTERFACE_INFO of data_2 : signal is "xilinx.com:user:DATA_CTRL_BUS:1.0 DATA_CTRL_BUS data_C";
    attribute X_INTERFACE_INFO of data_3 : signal is "xilinx.com:user:DATA_CTRL_BUS:1.0 DATA_CTRL_BUS data_D";
    attribute X_INTERFACE_INFO of ctrl_0 : signal is "xilinx.com:user:DATA_CTRL_BUS:1.0 DATA_CTRL_BUS ctrl_A";
    attribute X_INTERFACE_INFO of ctrl_1 : signal is "xilinx.com:user:DATA_CTRL_BUS:1.0 DATA_CTRL_BUS ctrl_B";
    
begin
    
    process(clk)
    begin
        if rising_edge(clk) then    
            data_0 <= X"0";
            data_1 <= X"1";
            data_2 <= X"2";
            data_3 <= X"3";
            
            dout   <= ctrl_0 & ctrl_1;
        end if;
    end process;
end Behavioral;

在BD中使用add module添加RTL文件,效果如下,
使用vivado封装IP_第27张图片

将旧版vivado IP添加到新版vivado IP仓库中

在vivado的安装路径的IP文件夹下,其实存在多个版本的IP,但是通过IP Catlog使用IP时,却只能使用最新版本的IP;如果将旧版IP拷贝到别处,手动添加到IP仓库中后,则旧版IP可用,但vivado会提示同一IP出现两次,IP仓库中的IP会处于active状态。
使用vivado封装IP_第28张图片
这一发现提示我们,可用将旧版vivado的IP放到新版vivado的IP仓库中,这一的话,在使用新版本vivado打开旧版工程时,就不用升级IP了。
使用vivado封装IP_第29张图片

将HDL源码(含网表文件)封为IP

实测了一下,

  • 当网表文件为dcp时,不能封装IP
  • 当网表文件为edif时,能够封装IP
  • 如果一个HDL模块中例化了dcp或edif网表,则在BD文件中,不能通过Add RTL Module的方式加入该HDL模块

目前来看,如果想将网表封装在IP中,或者在BD文件中使用,则一个比较好的方式是,将网表通过write_verilog或write_vhdl的方式转换成HDL网表。

将MicroBlaze/MCS的bd文件(含elf)封装为IP

在工程中,将elf关联到综合、仿真中,然后在封装IP时选择封装BD设计即可。不过,有一点要注意,一般含MicroBlaz的BD,复位信号都是低有效,这个复位信号的有效电平最好不要修改。如果复位改为高有效,则单独使用BD文件时没什么问题,但如果使用封装的IP,则会发现复位依然是低电平有效。
使用vivado封装IP_第30张图片

AR

AR66292 - Vivado IP Flows - Sub-core reference is not updated for migrated project even though the parent IP core was upgraded

使用vivado封装IP_第31张图片

AR75421 - Using Packaged IP library core and referencing as VHDL library

使用vivado封装IP_第32张图片

AR65277 封装IP时,设置动态端口

使用vivado封装IP_第33张图片

其他

一些IP在catlog中不显示

xilinx的一些IP,如axi_lite_ipif、axi_master_burst等,在IP Catlog中不显示,原因是在component.xml中,ishidden属性设置成了true,可以修改成false。

设置动态端口时,使用tcl

一个例子如下,

use strict;
use warnings;

my $line;
my $idx = 0;

for ($idx=0;$idx<32;$idx=$idx+1)
{
    $line  = sprintf("set_property driver_value 0 [ipx::get_ports *_%d -of_objects [ipx::current_core]]\n",$idx);
    $line .= sprintf("set_property enablement_dependency {\$NUM_OF_CHANNELS>%d} [ipx::get_ports *_%d -of_objects [ipx::current_core]]\n",$idx,$idx);
    print $line;
}
set_property driver_value 0 [ipx::get_ports *_0 -of_objects [ipx::current_core]]
set_property enablement_dependency {$NUM_OF_CHANNELS>0} [ipx::get_ports *_0 -of_objects [ipx::current_core]]
set_property driver_value 0 [ipx::get_ports *_1 -of_objects [ipx::current_core]]
set_property enablement_dependency {$NUM_OF_CHANNELS>1} [ipx::get_ports *_1 -of_objects [ipx::current_core]]
set_property driver_value 0 [ipx::get_ports *_2 -of_objects [ipx::current_core]]
set_property enablement_dependency {$NUM_OF_CHANNELS>2} [ipx::get_ports *_2 -of_objects [ipx::current_core]]
set_property driver_value 0 [ipx::get_ports *_3 -of_objects [ipx::current_core]]

端口可选输出
使用vivado封装IP_第34张图片

设置AXI总线端口的映射时,使用tcl

参考Infer AXI interface in block design

一个例子如下,

set_property abstraction_type_vlnv xilinx.com:interface:aximm_rtl:1.0 [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property bus_type_vlnv xilinx.com:interface:aximm:1.0 [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
ipx::remove_port_map rdata [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
ipx::remove_port_map wdata [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]

ipx::add_port_map BVALID [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_bvalid [ipx::get_port_maps BVALID -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map RREADY [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_rready [ipx::get_port_maps RREADY -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map BREADY [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_bready [ipx::get_port_maps BREADY -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map AWVALID [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_awvalid [ipx::get_port_maps AWVALID -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map AWPROT [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_awprot [ipx::get_port_maps AWPROT -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map WDATA [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_wdata [ipx::get_port_maps WDATA -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map RRESP [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_rresp [ipx::get_port_maps RRESP -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map ARPROT [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_arprot [ipx::get_port_maps ARPROT -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map RVALID [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_rvalid [ipx::get_port_maps RVALID -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map ARADDR [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_araddr [ipx::get_port_maps ARADDR -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map AWADDR [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_awaddr [ipx::get_port_maps AWADDR -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map ARREADY [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_arready [ipx::get_port_maps ARREADY -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map WREADY [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_wready [ipx::get_port_maps WREADY -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map WVALID [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_wvalid [ipx::get_port_maps WVALID -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map ARVALID [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_arvalid [ipx::get_port_maps ARVALID -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map WSTRB [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_wstrb [ipx::get_port_maps WSTRB -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map BRESP [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_bresp [ipx::get_port_maps BRESP -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map RDATA [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_rdata [ipx::get_port_maps RDATA -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]
ipx::add_port_map AWREADY [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]
set_property physical_name s_axi_3_awready [ipx::get_port_maps AWREADY -of_objects [ipx::get_bus_interfaces s_axi_3 -of_objects [ipx::current_core]]]

ttcl

TemplaTcl: a Tcl template engine

你可能感兴趣的:(#,Vivado,vivado)