cuter

[Zed测评] Xilinx IP核的结构和文件组织

0
阅读(8300)

        前几天研究了怎么利用XPS向导新建自己的IP核,从而实现PS和PL的协同工作,逻辑使用的是《PL实现简单的VGA测试》一文中的代码,整个流程还算顺利,但由于综合和实现过程中出现了几个貌似和引脚分配相关的严重警告,总是没法生成bitstream。期间,由于不熟悉XPS的使用,诸如MPD文件的意义之类的,一直怀疑是自己在某个环节出错,而没有怀疑逻辑代码,毕竟代码已经使用PL验证过了。所以就把IP新建向导过程中XPS生成的、涉及到的一些重要文件都认真研究、学习了一下,才基本可以肯定操作没有问题。最后发现问题出在VGA测试画面上,用PL测试VGA显示时,我直接对VGA的RGB引脚进行赋值,生成了一幅“左红右绿”的固定测试画面,把这部分的赋值语句添加到IP核中会出现严重警告,导致无法生成bitstream。这个还没搞明白是为什么……最后,我是将IP核的slv_reg0赋值给RGB,又利用ps向slv_reg0写入数据,才实现了测试画面的产生。

        在过程中主要学习了Xilinx IP核的结构和文件组织,做一下笔记。

        向导生成的相关文件保存在edk文件夹的pcores文件夹下:

clip_image001

        从资源管理器中,可以大致看出IP核文件夹的组织结构,下面给出一个完整的文件夹结构图:

clip_image003

        下面,逐个分析每个文件的作用。

1、data目录

        data目录存放的是IP的配置文件,如 mpd 文件和 pao 文件等。

        1.1、mpd(Microprocessor Peripheral Defination,外设定义)文件:mpd文件定义了该IP和外部互联的接口,以及需要外部指定的参数。这个文件有一部分是向导自动生成的,用户自定义的端口和参数要自己手动修改。看一下所生成的文件内容:

	   1:  #########################################################
	   2:  ##
	   3:  ##
	   4:  ## Name     : vga
	   5:  ## Desc     : Microprocessor Peripheral Description
	   6:  ##          : Automatically generated by PsfUtility
	   7:  ##
	   8:  #########################################################
	   9:  ##
	  10:   
	  11:  BEGIN vga
	  12:   
	  13:  ## Peripheral Options
	  14:  OPTION IPTYPE = PERIPHERAL
	  15:  OPTION IMP_NETLIST = TRUE
	  16:  OPTION HDL = VHDL
	  17:  OPTION IP_GROUP = MICROBLAZE:USER
	  18:  OPTION DESC = VGA
	  19:  OPTION LONG_DESC = a simple vga test ip, timing is generated by ip itself, test data get from the axi bus register.
	  20:  OPTION ARCH_SUPPORT_MAP = (others=DEVELOPMENT)
	  21:   
	  22:   
	  23:  ## Bus Interfaces
	  24:  BUS_INTERFACE BUS = S_AXI, BUS_STD = AXI, BUS_TYPE = SLAVE
	  25:   
	  26:  ## Generics for VHDL or Parameters for Verilog
	  27:  PARAMETER C_S_AXI_DATA_WIDTH = 32, DT = INTEGER, BUS = S_AXI, ASSIGNMENT = CONSTANT
	  28:  PARAMETER C_S_AXI_ADDR_WIDTH = 32, DT = INTEGER, BUS = S_AXI, ASSIGNMENT = CONSTANT
	  29:  PARAMETER C_S_AXI_MIN_SIZE = 0x000001ff, DT = std_logic_vector, BUS = S_AXI
	  30:  PARAMETER C_USE_WSTRB = 0, DT = INTEGER
	  31:  PARAMETER C_DPHASE_TIMEOUT = 8, DT = INTEGER
	  32:  PARAMETER C_BASEADDR = 0xffffffff, DT = std_logic_vector, MIN_SIZE = 0x100, PAIR = C_HIGHADDR, ADDRESS = BASE, BUS = S_AXI
	  33:  PARAMETER C_HIGHADDR = 0x00000000, DT = std_logic_vector, PAIR = C_BASEADDR, ADDRESS = HIGH, BUS = S_AXI
	  34:  PARAMETER C_FAMILY = virtex6, DT = STRING
	  35:  PARAMETER C_NUM_REG = 1, DT = INTEGER
	  36:  PARAMETER C_NUM_MEM = 1, DT = INTEGER
	  37:  PARAMETER C_SLV_AWIDTH = 32, DT = INTEGER
	  38:  PARAMETER C_SLV_DWIDTH = 32, DT = INTEGER
	  39:  PARAMETER C_S_AXI_PROTOCOL = AXI4LITE, TYPE = NON_HDL, ASSIGNMENT = CONSTANT, DT = STRING, BUS = S_AXI
	  40:   
	  41:  ## Ports
	  42:  PORT axi_hs = "", DIR = O
	  43:  PORT axi_vs = "", DIR = O
	  44:  PORT axi_red = "", DIR = O, VEC = [3:0]
	  45:  PORT axi_green = "", DIR = O, VEC = [3:0]
	  46:  PORT axi_blue = "", DIR = O, VEC = [3:0]
	  47:   
	  48:   
	  49:  PORT S_AXI_ACLK = "", DIR = I, SIGIS = CLK, BUS = S_AXI
	  50:  PORT S_AXI_ARESETN = ARESETN, DIR = I, SIGIS = RST, BUS = S_AXI
	  51:  PORT S_AXI_AWADDR = AWADDR, DIR = I, VEC = [(C_S_AXI_ADDR_WIDTH-1):0], ENDIAN = LITTLE, BUS = S_AXI
	  52:  PORT S_AXI_AWVALID = AWVALID, DIR = I, BUS = S_AXI
	  53:  PORT S_AXI_WDATA = WDATA, DIR = I, VEC = [(C_S_AXI_DATA_WIDTH-1):0], ENDIAN = LITTLE, BUS = S_AXI
	  54:  PORT S_AXI_WSTRB = WSTRB, DIR = I, VEC = [((C_S_AXI_DATA_WIDTH/8)-1):0], ENDIAN = LITTLE, BUS = S_AXI
	  55:  PORT S_AXI_WVALID = WVALID, DIR = I, BUS = S_AXI
	  56:  PORT S_AXI_BREADY = BREADY, DIR = I, BUS = S_AXI
	  57:  PORT S_AXI_ARADDR = ARADDR, DIR = I, VEC = [(C_S_AXI_ADDR_WIDTH-1):0], ENDIAN = LITTLE, BUS = S_AXI
	  58:  PORT S_AXI_ARVALID = ARVALID, DIR = I, BUS = S_AXI
	  59:  PORT S_AXI_RREADY = RREADY, DIR = I, BUS = S_AXI
	  60:  PORT S_AXI_ARREADY = ARREADY, DIR = O, BUS = S_AXI
	  61:  PORT S_AXI_RDATA = RDATA, DIR = O, VEC = [(C_S_AXI_DATA_WIDTH-1):0], ENDIAN = LITTLE, BUS = S_AXI
	  62:  PORT S_AXI_RRESP = RRESP, DIR = O, VEC = [1:0], BUS = S_AXI
	  63:  PORT S_AXI_RVALID = RVALID, DIR = O, BUS = S_AXI
	  64:  PORT S_AXI_WREADY = WREADY, DIR = O, BUS = S_AXI
	  65:  PORT S_AXI_BRESP = BRESP, DIR = O, VEC = [1:0], BUS = S_AXI
	  66:  PORT S_AXI_BVALID = BVALID, DIR = O, BUS = S_AXI
	  67:  PORT S_AXI_AWREADY = AWREADY, DIR = O, BUS = S_AXI
	  68:   
	  69:  END

        其中,42~46行是我手动添加的代码,解释一下44行:

        IP核vga,有一个名为axi_red的端口(PORT);该端口为输出端口(DIR=O);端口宽度为4(VEC=[3:0]);""表明该端口没有默认连接(可以在XPS选择连接到哪里)。MPD文件的语法还是有一些的,有些属性的定义和XBD(Xilinx Board Description)文件有关,详细的内容可以参考《Platform Specification Format Reference Manual》,附件给出该文件。

        需要注意的是XPS通过MPD文件对IP核的端口进行识别,所以新建自己的IP核时,手动修改MPD文件是不可避免的,而且需要注意和接口vhd文件(my_core.vhd)中的端口和参数保持一致。

        1.2、pao(Peripheral Analyze Order,外设分析顺序)文件,看一下文件内容:

##############################################################################
## Filename:          E:/Xilinx/ps_vga/ps_vga.srcs/sources_1/edk/cpu/pcores/vga_v1_00_a/data/vga_v2_1_0.pao
## Description:       Peripheral Analysis Order
## Date:              Sun Dec 09 22:34:17 2012 (by Create and Import Peripheral Wizard)
##############################################################################

lib proc_common_v3_00_a  all
lib axi_lite_ipif_v1_01_a  all
lib vga_v1_00_a user_logic vhdl
lib vga_v1_00_a vga vhdl

     可以看出pao文件定义了需要综合的源文件以及使用什么样的顺序进行综合。

        1.3、BBD(Black-Box Definition)文件,用来管理你用到的黑盒部分的硬件网表文件,指明了这些网标文件的存放位置。之所以成为黑盒,是因为你看不到它的内部情况,不知道怎样实现,但是知道它的输入输出接口,可以直接调用。通常,付费IP都会以Black-Box的形式交付。

2、hdl目录

        hdl目录里面有所有的设计文件,包括.v和.vhd。简单的IP核只需要两个文件就可以了,一个主要用于外部互联,主要是和AXI总线的接口,自动命名为my_core.vhd,另一个主要用于实现用户逻辑,自动命名为user_logic.vhd。因为AXI总线接口模块都是以VHDL语言描述,user logic文件可以用verilog编写,所以,xilinx为了方便管理不同类型的设计文件,因而细分了verilog和vhdl两个文件夹存放设计文件。user_logic并不是与外界直接相连,而是作为一个子模块被my_core调用,my_core负责与总线以及其他模块相连,IP核的所有用户逻辑都要设计成子模块例化到my_core中,封装成一个整体,形成一个完成的IP。

3、doc目录

        这个目录我建的IP核没有生成这个目录,估计无关紧要,描述性的文档吧。