参数分为两类,一类显示在GUI界面中(可以由用户设置)可以在GUI界面中;另一类则不显示在GUI界面中(不能由用户设置,其参数值通常是由GUI 中显示的参数来确定的)。
Is it possible in Vivado to package a custom IP with relative paths for all rtl
看这段描述是说,如果封装IP时引用了IP所在目录之外的文件,则这些引用文件会使用绝对路径。这时,在确保路径正确的情况下,手动修改component.xml中的绝对路径为相对路径即可。
封装了一个IP,使用了AXI接口,因此需要进行地址映射的分配。进行了如下三种尝试,
case 1:封装IP时,base address设为0x10000000,此时在BD中两个IP自动分配的地址相同,修改它们的基地址时出错
case 2:封装IP时,base address设为0x10000000,此时在BD中两个IP自动分配的地址不同,但修改它们的基地址时出错
help ipx::*
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 接口。 如果您的设计中没有任何总线接口,您可以放心地忽略此警告。
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 集成器的参数传播特性确定
IP_Flow 19-3158 - FREQ_HZ bus parameter missing from AXI interface when interface is not associated to a clock
2018.2 Vivado IP Flows - Generate RTL kernel gives three parameter warnings related to an RTL kernel wizard IP block
添加Utility XIT/TTCL的group,并添加logo图片,将Type从image修改成logo
为方便计,将常用的tcl命令写成脚本,直接通过custom tcl命令执行,
打开IP封装界面,选择需要封到总线里的端口,选择"Create Interface Definition",
此时,会弹出界面,来设置生成总线的存储位置,此处选择存放在封装IP的目录中,
生成总线的各个信号名称,是和端口名称一致的,可以直接使用,也可以重新修改,
如果总线的信号名称有修改,需要进行port的映射,如下
之后封装IP,并添加到IP路径中,会发现vivado能扫描到封装的IP以及相应的总线接口,在bd文件中添加IP后,会发现各个端口集成在总线接口中
在封装IP自定义总线接口时,能看到生成了如下的xml文件,其中包含了总线接口的定义,
在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;
在vivado的安装路径的IP文件夹下,其实存在多个版本的IP,但是通过IP Catlog使用IP时,却只能使用最新版本的IP;如果将旧版IP拷贝到别处,手动添加到IP仓库中后,则旧版IP可用,但vivado会提示同一IP出现两次,IP仓库中的IP会处于active状态。
这一发现提示我们,可用将旧版vivado的IP放到新版vivado的IP仓库中,这一的话,在使用新版本vivado打开旧版工程时,就不用升级IP了。
实测了一下,
目前来看,如果想将网表封装在IP中,或者在BD文件中使用,则一个比较好的方式是,将网表通过write_verilog或write_vhdl的方式转换成HDL网表。
在工程中,将elf关联到综合、仿真中,然后在封装IP时选择封装BD设计即可。不过,有一点要注意,一般含MicroBlaz的BD,复位信号都是低有效,这个复位信号的有效电平最好不要修改。如果复位改为高有效,则单独使用BD文件时没什么问题,但如果使用封装的IP,则会发现复位依然是低电平有效。
xilinx的一些IP,如axi_lite_ipif、axi_master_burst等,在IP Catlog中不显示,原因是在component.xml中,ishidden属性设置成了true,可以修改成false。
一个例子如下,
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]]
参考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]]]
TemplaTcl: a Tcl template engine