zoukankan      html  css  js  c++  java
  • 一步一步学ZedBoard & Zynq(四):基于AXI Lite 总线的从设备IP设计

    本帖最后由 xinxincaijq 于 2013-1-9 10:27 编辑

    一步一步学ZedBoard & Zynq(四):基于AXI Lite 总线的从设备IP设计

    转自博客:http://www.eeboard.com/bbs/thread-6206-1-1.html
    本小节通过使用XPS中的定制IP向导(ipwiz),为已经存在的ARM PS 系统添加用户自定IP(Custom IP ),了解AXI Lite IP基本结构,并掌握AXI Lite IP的定制方法,为后续编写复杂AXI IP打下基础。同时本小节IP定制方法同样适用于MicroBlaze处理系统。

    本小节定制的是简单LED的IP,只有一个数据寄存器,向其写值就可以控制8个LED相应亮灭。
    更多更新请关注我的博客:@超群天晴 http://www.cnblogs.com/surpassal/

    硬件平台:Digilent ZedBoard

    开发环境:Windows XP 32 bit

    软件: XPS 14.2 +SDK 14.2

    一、创建ARM PS系统

    同前面几节一样,首先使用XPS创建ARM PS系统。需要注意的是,在选择外设时,同样不要添加任何外设
    2012100918271949.jpg 
    二、定制AXI IP

    ARM PS系统创建结束后,就可以开始定制用户自定义IP。XPS提供了Create or Import Peripheral Wizward 向导,使得用户自定义IP的创建变得非常简单。当然在熟悉了AXI IP核结构和代码编写规则后,可以直接编写自己的IP核而不使用向导。这里采用向导方式。

    1、产生AXI IP外设模版

    Hardware->Create or Import Peripheral Wizward ,启动向导
    2012100918280550.jpg 
    欢迎界面
    2012100918281937.jpg 
    选择从模板创建新外设
    2012100918282972.jpg 
    默认是将外设直接包含到当前XPS工程中
    2012100918283516.jpg 
    填入外设名。注意必须都是小写。这里我们建立的是my_axi_ip。下面是版本控制,可以根据需要修改。同时面板的最下方还提示了将创建名为my_axi_ip_v1_00_a的库(其实就是一个目录),所有实现这个IP的HDL文件都在这个库中。2012100918544093.jpg 
    接下来要选择外设总线的类型。AXI4_Lite为最基本的AXI 总线,用于简单处理,所有空间访问都是通过地址/寄存器方式访问,不支持突发;AXI4是标准AXI4总线标准,支持突然,支持高速;AXI4_Stream专门为数据流而设计。
    2012100918550133.jpg 
    在IPIF (IP 接口) 配置,这里配置接口的一些属性,如是否是AXI 主/从设备等。我们所定制的IP是一个从设备,因而不需要使用主设备接口。
    2012100918551472.jpg 
    选择需啊哟的寄存器数量。因为我们只需要一个数据寄存器,这里选1。
    2012100918555983.jpg 
    接下来就是IPIC(IP 互联),也就是IP的接口信号。以BUS2开头的信号,意味对IP来说,这些信号是输入信号;同样IP2BUS意味着输出信号。

    这里一些信号做一些说明。
    2012100918560998.jpg 

    BUS2IP_WrCE(Write Chip Enable,写使能)
    1. Active high chip enable bus to the user logic. These chip enables are asserted only during active write transaction requests with the target address space and in conjunction with the corresponding sub-address within the space. Typically used for user logic writable registers selection.
    复制代码
    BUS2IP_Data(Write Data,写数据)
    1. Write data bus to the user logic. Write data is accepted by the user logic during a write operation by assertion of the write acknowledgement signal and the rising edge of the Bus2IP_Clk.
    复制代码
    BUS2IP_BE(Byte Enable,字节使能)
    1. Byte Enable qualifiers for the requested read or write operation to the user logic. A bit in the Bus2IP_BE set to '1' indicates that the associated byte lane contains valid data. For example, if Bus2IP_BE = 0011, this indicates that byte lanes 2 and 3 contain valid data.
    复制代码
    IPBUS2_RdAck(Read Acknowledgement,读反馈)
    1. Active high read data qualifier providing the read acknowledgement from the user logic. Read data on the IP2Bus_Data bus is deemed valid at the rising edge of the Bus2IP_Clk and IP2Bus_RdAck asserted high by the user logic.
    复制代码
    接下来需要使用需要使用BFM (Bus Functional Models, 总线功能模型)对外设进行仿真。本例IP很简单,不要使用。
    2012100918563341.jpg 
    最后,需要选择HDL类型、ISE工程支持和软件驱动模板。因为我比较习惯使用verilog,因而使用verilog模板。需要说明的是,IP接口仍然是VHDL编写,只是用户逻辑改用verilog。如果不需要使用软件驱动模板的话,可以不选上。这里选上了,但是后续编程的时候我并没有用。
    2012100918565461.jpg 
    最后给出了外设的信息summary。支持,my_axi_ip"外壳"基本完成。后续我们只需要对user_logic进行编写,并修改元件引脚即可。
    2012100918571728.jpg 
    2、编写IP

    修改.mpd文件,在目录
    Lab4pcoresmy_axi_ip_v1_00_adata
    1.   ###################################################################
    2.   ##
    3.   ## Name     : my_axi_ip
    4.   ## Desc     : Microprocessor Peripheral Description
    5.   ##          : Automatically generated by PsfUtility
    6.   ##
    7.   ###################################################################

    8.   BEGIN my_axi_ip

    9. ## Peripheral Options
    10. OPTION IPTYPE = PERIPHERAL
    11. OPTION IMP_NETLIST = TRUE
    12. OPTION HDL = MIXED
    13. OPTION IP_GROUP = MICROBLAZE:USER
    14. OPTION DESC = MY_AXI_IP
    15. OPTION ARCH_SUPPORT_MAP = (others=DEVELOPMENT)


    16. ## Bus Interfaces
    17. BUS_INTERFACE BUS = S_AXI, BUS_STD = AXI, BUS_TYPE = SLAVE

    18. ## Generics for VHDL or Parameters for Verilog
    19. PARAMETER C_S_AXI_DATA_WIDTH = 32, DT = INTEGER, BUS = S_AXI, ASSIGNMENT = CONSTANT
    20. PARAMETER C_S_AXI_ADDR_WIDTH = 32, DT = INTEGER, BUS = S_AXI, ASSIGNMENT = CONSTANT
    21. PARAMETER C_S_AXI_MIN_SIZE = 0x000001ff, DT = std_logic_vector, BUS = S_AXI
    22. PARAMETER C_USE_WSTRB = 0, DT = INTEGER
    23. PARAMETER C_DPHASE_TIMEOUT = 8, DT = INTEGER
    24. PARAMETER C_BASEADDR = 0xffffffff, DT = std_logic_vector, MIN_SIZE = 0x100, PAIR = C_HIGHADDR, ADDRESS = BASE, BUS = S_AXI
    25. PARAMETER C_HIGHADDR = 0x00000000, DT = std_logic_vector, PAIR = C_BASEADDR, ADDRESS = HIGH, BUS = S_AXI
    26. PARAMETER C_FAMILY = virtex6, DT = STRING
    27. PARAMETER C_NUM_REG = 1, DT = INTEGER
    28. PARAMETER C_NUM_MEM = 1, DT = INTEGER
    29. PARAMETER C_SLV_AWIDTH = 32, DT = INTEGER
    30. PARAMETER C_SLV_DWIDTH = 32, DT = INTEGER
    31. PARAMETER C_S_AXI_PROTOCOL = AXI4LITE, TYPE = NON_HDL, ASSIGNMENT = CONSTANT, DT = STRING, BUS = S_AXI

    32. ## Ports
    33. PORT LED = "", DIR = O, VEC = [7:0]
    34. PORT S_AXI_ACLK = "", DIR = I, SIGIS = CLK, BUS = S_AXI
    35. PORT S_AXI_ARESETN = ARESETN, DIR = I, SIGIS = RST, BUS = S_AXI
    36. PORT S_AXI_AWADDR = AWADDR, DIR = I, VEC = [(C_S_AXI_ADDR_WIDTH-1):0], ENDIAN = LITTLE, BUS = S_AXI
    37. PORT S_AXI_AWVALID = AWVALID, DIR = I, BUS = S_AXI
    38. PORT S_AXI_WDATA = WDATA, DIR = I, VEC = [(C_S_AXI_DATA_WIDTH-1):0], ENDIAN = LITTLE, BUS = S_AXI
    39. PORT S_AXI_WSTRB = WSTRB, DIR = I, VEC = [((C_S_AXI_DATA_WIDTH/8)-1):0], ENDIAN = LITTLE, BUS = S_AXI
    40. PORT S_AXI_WVALID = WVALID, DIR = I, BUS = S_AXI
    41. PORT S_AXI_BREADY = BREADY, DIR = I, BUS = S_AXI
    42. PORT S_AXI_ARADDR = ARADDR, DIR = I, VEC = [(C_S_AXI_ADDR_WIDTH-1):0], ENDIAN = LITTLE, BUS = S_AXI
    43. PORT S_AXI_ARVALID = ARVALID, DIR = I, BUS = S_AXI
    44. PORT S_AXI_RREADY = RREADY, DIR = I, BUS = S_AXI
    45. PORT S_AXI_ARREADY = ARREADY, DIR = O, BUS = S_AXI
    46. PORT S_AXI_RDATA = RDATA, DIR = O, VEC = [(C_S_AXI_DATA_WIDTH-1):0], ENDIAN = LITTLE, BUS = S_AXI
    47. PORT S_AXI_RRESP = RRESP, DIR = O, VEC = [1:0], BUS = S_AXI
    48. PORT S_AXI_RVALID = RVALID, DIR = O, BUS = S_AXI
    49. PORT S_AXI_WREADY = WREADY, DIR = O, BUS = S_AXI
    50. PORT S_AXI_BRESP = BRESP, DIR = O, VEC = [1:0], BUS = S_AXI
    51. PORT S_AXI_BVALID = BVALID, DIR = O, BUS = S_AXI
    52. PORT S_AXI_AWREADY = AWREADY, DIR = O, BUS = S_AXI

    53. END
    复制代码
    其中,第39行
    1. PORT LED = "", DIR = O, VEC = [7:0]
    复制代码
    是我们添加上的,表明我们为其添加了一个名为LED的端口,方向是输出,长度是8位。其他行代码为默认,不需要修改。

    修改用户逻辑,在
    Lab4pcoresmy_axi_ip_v1_00_ahdlveriloguser_logic.v
    1. //----------------------------------------------------------------------------
    2. // user_logic.v - module
    3. //----------------------------------------------------------------------------
    4. //
    5. // ***************************************************************************
    6. // ** Copyright (c) 1995-2012 Xilinx, Inc.  All rights reserved.            **
    7. // **                                                                       **
    8. // ** Xilinx, Inc.                                                          **
    9. // ** XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"         **
    10. // ** AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND       **
    11. // ** SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,        **
    12. // ** OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,        **
    13. // ** APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION           **
    14. // ** THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,     **
    15. // ** AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE      **
    16. // ** FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY              **
    17. // ** WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE               **
    18. // ** IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR        **
    19. // ** REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF       **
    20. // ** INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS       **
    21. // ** FOR A PARTICULAR PURPOSE.                                             **
    22. // **                                                                       **
    23. // ***************************************************************************
    24. //
    25. //----------------------------------------------------------------------------
    26. // Filename:          user_logic.v
    27. // Version:           1.00.a
    28. // Description:       User logic module.
    29. // Date:              Tue Oct 09 18:28:06 2012 (by Create and Import Peripheral Wizard)
    30. // Verilog Standard:  Verilog-2001
    31. //----------------------------------------------------------------------------
    32. // Naming Conventions:
    33. //   active low signals:                    "*_n"
    34. //   clock signals:                         "clk", "clk_div#", "clk_#x"
    35. //   reset signals:                         "rst", "rst_n"
    36. //   generics:                              "C_*"
    37. //   user defined types:                    "*_TYPE"
    38. //   state machine next state:              "*_ns"
    39. //   state machine current state:           "*_cs"
    40. //   combinatorial signals:                 "*_com"
    41. //   pipelined or register delay signals:   "*_d#"
    42. //   counter signals:                       "*cnt*"
    43. //   clock enable signals:                  "*_ce"
    44. //   internal version of output port:       "*_i"
    45. //   device pins:                           "*_pin"
    46. //   ports:                                 "- Names begin with Uppercase"
    47. //   processes:                             "*_PROCESS"
    48. //   component instantiations:              "<ENTITY_>I_<#|FUNC>"
    49. //----------------------------------------------------------------------------

    50. `uselib lib=unisims_ver
    51. `uselib lib=proc_common_v3_00_a

    52. module user_logic
    53. (
    54.    // -- ADD USER PORTS BELOW THIS LINE ---------------
    55.    LED,
    56.    // -- ADD USER PORTS ABOVE THIS LINE ---------------

    57.    // -- DO NOT EDIT BELOW THIS LINE ------------------
    58.    // -- Bus protocol ports, do not add to or delete 
    59.    Bus2IP_Clk,                     // Bus to IP clock
    60.    Bus2IP_Resetn,                  // Bus to IP reset
    61.    Bus2IP_Data,                    // Bus to IP data bus
    62.    Bus2IP_BE,                      // Bus to IP byte enables
    63.    Bus2IP_RdCE,                    // Bus to IP read chip enable
    64.    Bus2IP_WrCE,                    // Bus to IP write chip enable
    65.    IP2Bus_Data,                    // IP to Bus data bus
    66.    IP2Bus_RdAck,                   // IP to Bus read transfer acknowledgement
    67.    IP2Bus_WrAck,                   // IP to Bus write transfer acknowledgement
    68.    IP2Bus_Error                    // IP to Bus error response
    69.    // -- DO NOT EDIT ABOVE THIS LINE ------------------
    70. ); // user_logic

    71. // -- ADD USER PARAMETERS BELOW THIS LINE ------------
    72. // --USER parameters added here 
    73. // -- ADD USER PARAMETERS ABOVE THIS LINE ------------

    74. // -- DO NOT EDIT BELOW THIS LINE --------------------
    75. // -- Bus protocol parameters, do not add to or delete
    76. parameter C_NUM_REG                      = 1;
    77. parameter C_SLV_DWIDTH                   = 32;
    78. // -- DO NOT EDIT ABOVE THIS LINE --------------------

    79. // -- ADD USER PORTS BELOW THIS LINE -----------------
    80. output        [7:0]                        LED;
    81. // -- ADD USER PORTS ABOVE THIS LINE -----------------

    82. // -- DO NOT EDIT BELOW THIS LINE --------------------
    83. // -- Bus protocol ports, do not add to or delete
    84. input                                     Bus2IP_Clk;
    85. input                                     Bus2IP_Resetn;
    86. input      [C_SLV_DWIDTH-1 : 0]           Bus2IP_Data;
    87. input      [C_SLV_DWIDTH/8-1 : 0]         Bus2IP_BE;
    88. input      [C_NUM_REG-1 : 0]              Bus2IP_RdCE;
    89. input      [C_NUM_REG-1 : 0]              Bus2IP_WrCE;
    90. output     [C_SLV_DWIDTH-1 : 0]           IP2Bus_Data;
    91. output                                    IP2Bus_RdAck;
    92. output                                    IP2Bus_WrAck;
    93. output                                    IP2Bus_Error;
    94. // -- DO NOT EDIT ABOVE THIS LINE --------------------

    95. //----------------------------------------------------------------------------
    96. // Implementation
    97. //----------------------------------------------------------------------------

    98.    // --USER nets declarations added here, as needed for user logic

    99.    // Nets for user logic slave model s/w accessible register example
    100.    reg        [C_SLV_DWIDTH-1 : 0]           slv_reg0;
    101.    wire       [0 : 0]                        slv_reg_write_sel;
    102.    wire       [0 : 0]                        slv_reg_read_sel;
    103.    reg        [C_SLV_DWIDTH-1 : 0]           slv_ip2bus_data;
    104.    wire                                      slv_read_ack;
    105.    wire                                      slv_write_ack;
    106.    integer                                   byte_index, bit_index;

    107.    // USER logic implementation added here
    108.      assign LED    = slv_reg0[7:0];
    109.    // ------------------------------------------------------
    110.    // Example code to read/write user logic slave model s/w accessible registers
    111.    // 
    112.    // Note:
    113.    // The example code presented here is to show you one way of reading/writing
    114.    // software accessible registers implemented in the user logic slave model.
    115.    // Each bit of the Bus2IP_WrCE/Bus2IP_RdCE signals is configured to correspond
    116.    // to one software accessible register by the top level template. For example,
    117.    // if you have four 32 bit software accessible registers in the user logic,
    118.    // you are basically operating on the following memory mapped registers:
    119.    // 
    120.    //    Bus2IP_WrCE/Bus2IP_RdCE   Memory Mapped Register
    121.    //                     "1000"   C_BASEADDR + 0x0
    122.    //                     "0100"   C_BASEADDR + 0x4
    123.    //                     "0010"   C_BASEADDR + 0x8
    124.    //                     "0001"   C_BASEADDR + 0xC
    125.    // 
    126.    // ------------------------------------------------------

    127.    assign
    128.      slv_reg_write_sel = Bus2IP_WrCE[0:0],
    129.      slv_reg_read_sel  = Bus2IP_RdCE[0:0],
    130.      slv_write_ack     = Bus2IP_WrCE[0],
    131.      slv_read_ack      = Bus2IP_RdCE[0];
    132.      


    133.    // implement slave model register(s)
    134.    always @( posedge Bus2IP_Clk )
    135.      begin

    136.        if ( Bus2IP_Resetn == 1'b0 )
    137.          begin
    138.            slv_reg0 <= 0;
    139.          end
    140.        else
    141.          case ( slv_reg_write_sel )
    142.            1'b1 :
    143.              for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
    144.                if ( Bus2IP_BE[byte_index] == 1 )
    145.                  slv_reg0[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
    146.            default : begin
    147.              slv_reg0 <= slv_reg0;
    148.                      end
    149.          endcase

    150.      end // SLAVE_REG_WRITE_PROC

    151.    // implement slave model register read mux
    152.    always @( slv_reg_read_sel or slv_reg0 )
    153.      begin 

    154.        case ( slv_reg_read_sel )
    155.          1'b1 : slv_ip2bus_data <= slv_reg0;
    156.          default : slv_ip2bus_data <= 0;
    157.        endcase

    158.      end // SLAVE_REG_READ_PROC

    159.    // ------------------------------------------------------------
    160.    // Example code to drive IP to Bus signals
    161.    // ------------------------------------------------------------

    162. assign IP2Bus_Data = (slv_read_ack == 1'b1) ? slv_ip2bus_data :  0 ;
    163.    assign IP2Bus_WrAck = slv_write_ack;
    164.    assign IP2Bus_RdAck = slv_read_ack;
    165.    assign IP2Bus_Error = 0;

    166. endmodule
    复制代码
    代码中57、86行
    1. LED,
    2. output        [7:0]                        LED;
    复制代码
    表明在用户逻辑中,定义了名为LED的端口,方向是输出,长度为8。

    代码中119行
    1. assign LED    = slv_reg0[7:0];
    复制代码
    表明将slv_reg0的低8位传递给输出端口LED。其实就是实现了数据寄存器的值作用到输出端口的功能。

    需要将用户逻辑和IPIF连接上,需要完成user_logic的例化
    Lab4pcoresmy_axi_ip_v1_00_ahdlvhdlmy_axi_ip.vhd
    1. ------------------------------------------------------------------------------
    2. -- my_axi_ip.vhd - entity/architecture pair
    3. ------------------------------------------------------------------------------
    4. -- IMPORTANT:
    5. -- DO NOT MODIFY THIS FILE EXCEPT IN THE DESIGNATED SECTIONS.
    6. --
    7. -- SEARCH FOR --USER TO DETERMINE WHERE CHANGES ARE ALLOWED.
    8. --
    9. -- TYPICALLY, THE ONLY ACCEPTABLE CHANGES INVOLVE ADDING NEW
    10. -- PORTS AND GENERICS THAT GET PASSED THROUGH TO THE INSTANTIATION
    11. -- OF THE USER_LOGIC ENTITY.
    12. ------------------------------------------------------------------------------
    13. --
    14. -- ***************************************************************************
    15. -- ** Copyright (c) 1995-2012 Xilinx, Inc.  All rights reserved.            **
    16. -- **                                                                       **
    17. -- ** Xilinx, Inc.                                                          **
    18. -- ** XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"         **
    19. -- ** AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND       **
    20. -- ** SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,        **
    21. -- ** OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,        **
    22. -- ** APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION           **
    23. -- ** THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,     **
    24. -- ** AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE      **
    25. -- ** FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY              **
    26. -- ** WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE               **
    27. -- ** IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR        **
    28. -- ** REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF       **
    29. -- ** INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS       **
    30. -- ** FOR A PARTICULAR PURPOSE.                                             **
    31. -- **                                                                       **
    32. -- ***************************************************************************
    33. --
    34. ------------------------------------------------------------------------------
    35. -- Filename:          my_axi_ip.vhd
    36. -- Version:           1.00.a
    37. -- Description:       Top level design, instantiates library components and user logic.
    38. -- Date:              Tue Oct 09 18:28:06 2012 (by Create and Import Peripheral Wizard)
    39. -- VHDL Standard:     VHDL'93
    40. ------------------------------------------------------------------------------
    41. -- Naming Conventions:
    42. --   active low signals:                    "*_n"
    43. --   clock signals:                         "clk", "clk_div#", "clk_#x"
    44. --   reset signals:                         "rst", "rst_n"
    45. --   generics:                              "C_*"
    46. --   user defined types:                    "*_TYPE"
    47. --   state machine next state:              "*_ns"
    48. --   state machine current state:           "*_cs"
    49. --   combinatorial signals:                 "*_com"
    50. --   pipelined or register delay signals:   "*_d#"
    51. --   counter signals:                       "*cnt*"
    52. --   clock enable signals:                  "*_ce"
    53. --   internal version of output port:       "*_i"
    54. --   device pins:                           "*_pin"
    55. --   ports:                                 "- Names begin with Uppercase"
    56. --   processes:                             "*_PROCESS"
    57. --   component instantiations:              "<ENTITY_>I_<#|FUNC>"
    58. ------------------------------------------------------------------------------

    59. library ieee;
    60. use ieee.std_logic_1164.all;
    61. use ieee.std_logic_arith.all;
    62. use ieee.std_logic_unsigned.all;

    63. library proc_common_v3_00_a;
    64. use proc_common_v3_00_a.proc_common_pkg.all;
    65. use proc_common_v3_00_a.ipif_pkg.all;

    66. library axi_lite_ipif_v1_01_a;
    67. use axi_lite_ipif_v1_01_a.axi_lite_ipif;

    68. ------------------------------------------------------------------------------
    69. -- Entity section
    70. ------------------------------------------------------------------------------
    71. -- Definition of Generics:
    72. --   C_S_AXI_DATA_WIDTH           -- AXI4LITE slave: Data width
    73. --   C_S_AXI_ADDR_WIDTH           -- AXI4LITE slave: Address Width
    74. --   C_S_AXI_MIN_SIZE             -- AXI4LITE slave: Min Size
    75. --   C_USE_WSTRB                  -- AXI4LITE slave: Write Strobe
    76. --   C_DPHASE_TIMEOUT             -- AXI4LITE slave: Data Phase Timeout
    77. --   C_BASEADDR                   -- AXI4LITE slave: base address
    78. --   C_HIGHADDR                   -- AXI4LITE slave: high address
    79. --   C_FAMILY                     -- FPGA Family
    80. --   C_NUM_REG                    -- Number of software accessible registers
    81. --   C_NUM_MEM                    -- Number of address-ranges
    82. --   C_SLV_AWIDTH                 -- Slave interface address bus width
    83. --   C_SLV_DWIDTH                 -- Slave interface data bus width
    84. --
    85. -- Definition of Ports:
    86. --   S_AXI_ACLK                   -- AXI4LITE slave: Clock 
    87. --   S_AXI_ARESETN                -- AXI4LITE slave: Reset
    88. --   S_AXI_AWADDR                 -- AXI4LITE slave: Write address
    89. --   S_AXI_AWVALID                -- AXI4LITE slave: Write address valid
    90. --   S_AXI_WDATA                  -- AXI4LITE slave: Write data
    91. --   S_AXI_WSTRB                  -- AXI4LITE slave: Write strobe
    92. --   S_AXI_WVALID                 -- AXI4LITE slave: Write data valid
    93. --   S_AXI_BREADY                 -- AXI4LITE slave: Response ready
    94. --   S_AXI_ARADDR                 -- AXI4LITE slave: Read address
    95. --   S_AXI_ARVALID                -- AXI4LITE slave: Read address valid
    96. --   S_AXI_RREADY                 -- AXI4LITE slave: Read data ready
    97. --   S_AXI_ARREADY                -- AXI4LITE slave: read addres ready
    98. --   S_AXI_RDATA                  -- AXI4LITE slave: Read data
    99. --   S_AXI_RRESP                  -- AXI4LITE slave: Read data response
    100. --   S_AXI_RVALID                 -- AXI4LITE slave: Read data valid
    101. --   S_AXI_WREADY                 -- AXI4LITE slave: Write data ready
    102. --   S_AXI_BRESP                  -- AXI4LITE slave: Response
    103. --   S_AXI_BVALID                 -- AXI4LITE slave: Resonse valid
    104. --   S_AXI_AWREADY                -- AXI4LITE slave: Wrte address ready
    105. ------------------------------------------------------------------------------

    106. entity my_axi_ip is
    107.    generic
    108.    (
    109.      -- ADD USER GENERICS BELOW THIS LINE ---------------
    110.      --USER generics added here
    111.      -- ADD USER GENERICS ABOVE THIS LINE ---------------

    112.      -- DO NOT EDIT BELOW THIS LINE ---------------------
    113.      -- Bus protocol parameters, do not add to or delete
    114.      C_S_AXI_DATA_WIDTH             : integer              := 32;
    115.      C_S_AXI_ADDR_WIDTH             : integer              := 32;
    116.      C_S_AXI_MIN_SIZE               : std_logic_vector     := X"000001FF";
    117.      C_USE_WSTRB                    : integer              := 0;
    118.      C_DPHASE_TIMEOUT               : integer              := 8;
    119.      C_BASEADDR                     : std_logic_vector     := X"FFFFFFFF";
    120.      C_HIGHADDR                     : std_logic_vector     := X"00000000";
    121.      C_FAMILY                       : string               := "virtex6";
    122.      C_NUM_REG                      : integer              := 1;
    123.      C_NUM_MEM                      : integer              := 1;
    124.      C_SLV_AWIDTH                   : integer              := 32;
    125.      C_SLV_DWIDTH                   : integer              := 32
    126.      -- DO NOT EDIT ABOVE THIS LINE ---------------------
    127.    );
    128.    port
    129.    (
    130.      -- ADD USER PORTS BELOW THIS LINE ------------------
    131.      LED                                : out std_logic_vector(7 downto 0);
    132.      -- ADD USER PORTS ABOVE THIS LINE ------------------

    133.      -- DO NOT EDIT BELOW THIS LINE ---------------------
    134.      -- Bus protocol ports, do not add to or delete
    135.      S_AXI_ACLK                     : in  std_logic;
    136.      S_AXI_ARESETN                  : in  std_logic;
    137.      S_AXI_AWADDR                   : in  std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
    138.      S_AXI_AWVALID                  : in  std_logic;
    139.      S_AXI_WDATA                    : in  std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
    140.      S_AXI_WSTRB                    : in  std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0);
    141.      S_AXI_WVALID                   : in  std_logic;
    142.      S_AXI_BREADY                   : in  std_logic;
    143.      S_AXI_ARADDR                   : in  std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
    144.      S_AXI_ARVALID                  : in  std_logic;
    145.      S_AXI_RREADY                   : in  std_logic;
    146.      S_AXI_ARREADY                  : out std_logic;
    147.      S_AXI_RDATA                    : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
    148.      S_AXI_RRESP                    : out std_logic_vector(1 downto 0);
    149.      S_AXI_RVALID                   : out std_logic;
    150.      S_AXI_WREADY                   : out std_logic;
    151.      S_AXI_BRESP                    : out std_logic_vector(1 downto 0);
    152.      S_AXI_BVALID                   : out std_logic;
    153.      S_AXI_AWREADY                  : out std_logic
    154.      -- DO NOT EDIT ABOVE THIS LINE ---------------------
    155.    );

    156.    attribute MAX_FANOUT : string;
    157.    attribute SIGIS : string;
    158.    attribute MAX_FANOUT of S_AXI_ACLK       : signal is "10000";
    159.    attribute MAX_FANOUT of S_AXI_ARESETN       : signal is "10000";
    160.    attribute SIGIS of S_AXI_ACLK       : signal is "Clk";
    161.    attribute SIGIS of S_AXI_ARESETN       : signal is "Rst";
    162. end entity my_axi_ip;

    163. ------------------------------------------------------------------------------
    164. -- Architecture section
    165. ------------------------------------------------------------------------------

    166. architecture IMP of my_axi_ip is

    167.    constant USER_SLV_DWIDTH                : integer              := C_S_AXI_DATA_WIDTH;

    168.    constant IPIF_SLV_DWIDTH                : integer              := C_S_AXI_DATA_WIDTH;

    169.    constant ZERO_ADDR_PAD                  : std_logic_vector(0 to 31) := (others => '0');
    170.    constant USER_SLV_BASEADDR              : std_logic_vector     := C_BASEADDR;
    171.    constant USER_SLV_HIGHADDR              : std_logic_vector     := C_HIGHADDR;

    172.    constant IPIF_ARD_ADDR_RANGE_ARRAY      : SLV64_ARRAY_TYPE     := 
    173.      (
    174.        ZERO_ADDR_PAD & USER_SLV_BASEADDR,  -- user logic slave space base address
    175.        ZERO_ADDR_PAD & USER_SLV_HIGHADDR   -- user logic slave space high address
    176.      );

    177.    constant USER_SLV_NUM_REG               : integer              := 1;
    178.    constant USER_NUM_REG                   : integer              := USER_SLV_NUM_REG;
    179.    constant TOTAL_IPIF_CE                  : integer              := USER_NUM_REG;

    180.    constant IPIF_ARD_NUM_CE_ARRAY          : INTEGER_ARRAY_TYPE   := 
    181.      (
    182.        0  => (USER_SLV_NUM_REG)            -- number of ce for user logic slave space
    183.      );

    184.    ------------------------------------------
    185.    -- Index for CS/CE
    186.    ------------------------------------------
    187.    constant USER_SLV_CS_INDEX              : integer              := 0;
    188.    constant USER_SLV_CE_INDEX              : integer              := calc_start_ce_index(IPIF_ARD_NUM_CE_ARRAY, USER_SLV_CS_INDEX);

    189.    constant USER_CE_INDEX                  : integer              := USER_SLV_CE_INDEX;

    190.    ------------------------------------------
    191.    -- IP Interconnect (IPIC) signal declarations
    192.    ------------------------------------------
    193.    signal ipif_Bus2IP_Clk                : std_logic;
    194.    signal ipif_Bus2IP_Resetn             : std_logic;
    195.    signal ipif_Bus2IP_Addr               : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
    196.    signal ipif_Bus2IP_RNW                : std_logic;
    197.    signal ipif_Bus2IP_BE                 : std_logic_vector(IPIF_SLV_DWIDTH/8-1 downto 0);
    198.    signal ipif_Bus2IP_CS                 : std_logic_vector((IPIF_ARD_ADDR_RANGE_ARRAY'LENGTH)/2-1 downto 0);
    199.    signal ipif_Bus2IP_RdCE               : std_logic_vector(calc_num_ce(IPIF_ARD_NUM_CE_ARRAY)-1 downto 0);
    200.    signal ipif_Bus2IP_WrCE               : std_logic_vector(calc_num_ce(IPIF_ARD_NUM_CE_ARRAY)-1 downto 0);
    201.    signal ipif_Bus2IP_Data               : std_logic_vector(IPIF_SLV_DWIDTH-1 downto 0);
    202.    signal ipif_IP2Bus_WrAck              : std_logic;
    203.    signal ipif_IP2Bus_RdAck              : std_logic;
    204.    signal ipif_IP2Bus_Error              : std_logic;
    205.    signal ipif_IP2Bus_Data               : std_logic_vector(IPIF_SLV_DWIDTH-1 downto 0);
    206.    signal user_Bus2IP_RdCE               : std_logic_vector(USER_NUM_REG-1 downto 0);
    207.    signal user_Bus2IP_WrCE               : std_logic_vector(USER_NUM_REG-1 downto 0);
    208.    signal user_IP2Bus_Data               : std_logic_vector(USER_SLV_DWIDTH-1 downto 0);
    209.    signal user_IP2Bus_RdAck              : std_logic;
    210.    signal user_IP2Bus_WrAck              : std_logic;
    211.    signal user_IP2Bus_Error              : std_logic;

    212.    ------------------------------------------
    213.    -- Component declaration for verilog user logic
    214.    ------------------------------------------
    215.    component user_logic is
    216.      generic
    217.      (
    218.        -- ADD USER GENERICS BELOW THIS LINE ---------------
    219.        --USER generics added here
    220.        -- ADD USER GENERICS ABOVE THIS LINE ---------------

    221.        -- DO NOT EDIT BELOW THIS LINE ---------------------
    222.        -- Bus protocol parameters, do not add to or delete
    223.        C_NUM_REG                      : integer              := 1;
    224.        C_SLV_DWIDTH                   : integer              := 32
    225.        -- DO NOT EDIT ABOVE THIS LINE ---------------------
    226.      );
    227.      port
    228.      (
    229.        -- ADD USER PORTS BELOW THIS LINE ------------------
    230.        LED                                : out std_logic_vector(7 downto 0);
    231.        -- ADD USER PORTS ABOVE THIS LINE ------------------

    232.        -- DO NOT EDIT BELOW THIS LINE ---------------------
    233.        -- Bus protocol ports, do not add to or delete
    234.        Bus2IP_Clk                     : in  std_logic;
    235.        Bus2IP_Resetn                  : in  std_logic;
    236.        Bus2IP_Data                    : in  std_logic_vector(C_SLV_DWIDTH-1 downto 0);
    237.        Bus2IP_BE                      : in  std_logic_vector(C_SLV_DWIDTH/8-1 downto 0);
    238.        Bus2IP_RdCE                    : in  std_logic_vector(C_NUM_REG-1 downto 0);
    239.        Bus2IP_WrCE                    : in  std_logic_vector(C_NUM_REG-1 downto 0);
    240.        IP2Bus_Data                    : out std_logic_vector(C_SLV_DWIDTH-1 downto 0);
    241.        IP2Bus_RdAck                   : out std_logic;
    242.        IP2Bus_WrAck                   : out std_logic;
    243.        IP2Bus_Error                   : out std_logic
    244.        -- DO NOT EDIT ABOVE THIS LINE ---------------------
    245.      );
    246.    end component user_logic;

    247. begin

    248.    ------------------------------------------
    249.    -- instantiate axi_lite_ipif
    250.    ------------------------------------------
    251.    AXI_LITE_IPIF_I : entity axi_lite_ipif_v1_01_a.axi_lite_ipif
    252.      generic map
    253.      (
    254.        C_S_AXI_DATA_WIDTH             => IPIF_SLV_DWIDTH,
    255.        C_S_AXI_ADDR_WIDTH             => C_S_AXI_ADDR_WIDTH,
    256.        C_S_AXI_MIN_SIZE               => C_S_AXI_MIN_SIZE,
    257.        C_USE_WSTRB                    => C_USE_WSTRB,
    258.        C_DPHASE_TIMEOUT               => C_DPHASE_TIMEOUT,
    259.        C_ARD_ADDR_RANGE_ARRAY         => IPIF_ARD_ADDR_RANGE_ARRAY,
    260.        C_ARD_NUM_CE_ARRAY             => IPIF_ARD_NUM_CE_ARRAY,
    261.        C_FAMILY                       => C_FAMILY
    262.      )
    263.      port map
    264.      (
    265.        S_AXI_ACLK                     => S_AXI_ACLK,
    266.        S_AXI_ARESETN                  => S_AXI_ARESETN,
    267.        S_AXI_AWADDR                   => S_AXI_AWADDR,
    268.        S_AXI_AWVALID                  => S_AXI_AWVALID,
    269.        S_AXI_WDATA                    => S_AXI_WDATA,
    270.        S_AXI_WSTRB                    => S_AXI_WSTRB,
    271.        S_AXI_WVALID                   => S_AXI_WVALID,
    272.        S_AXI_BREADY                   => S_AXI_BREADY,
    273.        S_AXI_ARADDR                   => S_AXI_ARADDR,
    274.        S_AXI_ARVALID                  => S_AXI_ARVALID,
    275.        S_AXI_RREADY                   => S_AXI_RREADY,
    276.        S_AXI_ARREADY                  => S_AXI_ARREADY,
    277.        S_AXI_RDATA                    => S_AXI_RDATA,
    278.        S_AXI_RRESP                    => S_AXI_RRESP,
    279.        S_AXI_RVALID                   => S_AXI_RVALID,
    280.        S_AXI_WREADY                   => S_AXI_WREADY,
    281.        S_AXI_BRESP                    => S_AXI_BRESP,
    282.        S_AXI_BVALID                   => S_AXI_BVALID,
    283.        S_AXI_AWREADY                  => S_AXI_AWREADY,
    284.        Bus2IP_Clk                     => ipif_Bus2IP_Clk,
    285.        Bus2IP_Resetn                  => ipif_Bus2IP_Resetn,
    286.        Bus2IP_Addr                    => ipif_Bus2IP_Addr,
    287.        Bus2IP_RNW                     => ipif_Bus2IP_RNW,
    288.        Bus2IP_BE                      => ipif_Bus2IP_BE,
    289.        Bus2IP_CS                      => ipif_Bus2IP_CS,
    290.        Bus2IP_RdCE                    => ipif_Bus2IP_RdCE,
    291.        Bus2IP_WrCE                    => ipif_Bus2IP_WrCE,
    292.        Bus2IP_Data                    => ipif_Bus2IP_Data,
    293.        IP2Bus_WrAck                   => ipif_IP2Bus_WrAck,
    294.        IP2Bus_RdAck                   => ipif_IP2Bus_RdAck,
    295.        IP2Bus_Error                   => ipif_IP2Bus_Error,
    296.        IP2Bus_Data                    => ipif_IP2Bus_Data
    297.      );

    298.    ------------------------------------------
    299.    -- instantiate User Logic
    300.    ------------------------------------------
    301.    USER_LOGIC_I : component user_logic
    302.      generic map
    303.      (
    304.        -- MAP USER GENERICS BELOW THIS LINE ---------------
    305.        --USER generics mapped here
    306.        -- MAP USER GENERICS ABOVE THIS LINE ---------------

    307.        C_NUM_REG                      => USER_NUM_REG,
    308.        C_SLV_DWIDTH                   => USER_SLV_DWIDTH
    309.      )
    310.      port map
    311.      (
    312.        -- MAP USER PORTS BELOW THIS LINE ------------------
    313.        LED                            => LED,
    314.        -- MAP USER PORTS ABOVE THIS LINE ------------------

    315.        Bus2IP_Clk                     => ipif_Bus2IP_Clk,
    316.        Bus2IP_Resetn                  => ipif_Bus2IP_Resetn,
    317.        Bus2IP_Data                    => ipif_Bus2IP_Data,
    318.        Bus2IP_BE                      => ipif_Bus2IP_BE,
    319.        Bus2IP_RdCE                    => user_Bus2IP_RdCE,
    320.        Bus2IP_WrCE                    => user_Bus2IP_WrCE,
    321.        IP2Bus_Data                    => user_IP2Bus_Data,
    322.        IP2Bus_RdAck                   => user_IP2Bus_RdAck,
    323.        IP2Bus_WrAck                   => user_IP2Bus_WrAck,
    324.        IP2Bus_Error                   => user_IP2Bus_Error
    325.      );

    326.    ------------------------------------------
    327.    -- connect internal signals
    328.    ------------------------------------------
    329.    ipif_IP2Bus_Data <= user_IP2Bus_Data;
    330.    ipif_IP2Bus_WrAck <= user_IP2Bus_WrAck;
    331.    ipif_IP2Bus_RdAck <= user_IP2Bus_RdAck;
    332.    ipif_IP2Bus_Error <= user_IP2Bus_Error;

    333.    user_Bus2IP_RdCE <= ipif_Bus2IP_RdCE(USER_NUM_REG-1 downto 0);
    334.    user_Bus2IP_WrCE <= ipif_Bus2IP_WrCE(USER_NUM_REG-1 downto 0);

    335. end IMP;
    复制代码
    137行
    1. LED                                : out std_logic_vector(7 downto 0);
    复制代码
    定义IP的端口为LED,这里需要和之前修改MPD文件一致。

    232-268行为元件声明
    1. ------------------------------------------
    2. -- Component declaration for verilog user logic
    3. ------------------------------------------
    4. component user_logic is
    5.    generic
    6.    (
    7.      -- ADD USER GENERICS BELOW THIS LINE ---------------
    8.      --USER generics added here
    9.      -- ADD USER GENERICS ABOVE THIS LINE ---------------

    10.      -- DO NOT EDIT BELOW THIS LINE ---------------------
    11.      -- Bus protocol parameters, do not add to or delete
    12.      C_NUM_REG                      : integer              := 1;
    13.      C_SLV_DWIDTH                   : integer              := 32
    14.      -- DO NOT EDIT ABOVE THIS LINE ---------------------
    15.    );
    16.    port
    17.    (
    18.      -- ADD USER PORTS BELOW THIS LINE ------------------
    19.      LED                                : out std_logic_vector(7 downto 0);
    20.      -- ADD USER PORTS ABOVE THIS LINE ------------------

    21.      -- DO NOT EDIT BELOW THIS LINE ---------------------
    22.      -- Bus protocol ports, do not add to or delete
    23.      Bus2IP_Clk                     : in  std_logic;
    24.      Bus2IP_Resetn                  : in  std_logic;
    25.      Bus2IP_Data                    : in  std_logic_vector(C_SLV_DWIDTH-1 downto 0);
    26.      Bus2IP_BE                      : in  std_logic_vector(C_SLV_DWIDTH/8-1 downto 0);
    27.      Bus2IP_RdCE                    : in  std_logic_vector(C_NUM_REG-1 downto 0);
    28.      Bus2IP_WrCE                    : in  std_logic_vector(C_NUM_REG-1 downto 0);
    29.      IP2Bus_Data                    : out std_logic_vector(C_SLV_DWIDTH-1 downto 0);
    30.      IP2Bus_RdAck                   : out std_logic;
    31.      IP2Bus_WrAck                   : out std_logic;
    32.      IP2Bus_Error                   : out std_logic
    33.      -- DO NOT EDIT ABOVE THIS LINE ---------------------
    34.    );
    35. end component user_logic;
    复制代码
    323-352行为user_logic元件例化。VHDL是不区分大小写的。
    1. ------------------------------------------
    2. -- instantiate User Logic
    3. ------------------------------------------
    4. USER_LOGIC_I : component user_logic
    5.    generic map
    6.    (
    7.      -- MAP USER GENERICS BELOW THIS LINE ---------------
    8.      --USER generics mapped here
    9.      -- MAP USER GENERICS ABOVE THIS LINE ---------------

    10.      C_NUM_REG                      => USER_NUM_REG,
    11.      C_SLV_DWIDTH                   => USER_SLV_DWIDTH
    12.    )
    13.    port map
    14.    (
    15.      -- MAP USER PORTS BELOW THIS LINE ------------------
    16.      LED                            => LED,
    17.      -- MAP USER PORTS ABOVE THIS LINE ------------------

    18.      Bus2IP_Clk                     => ipif_Bus2IP_Clk,
    19.      Bus2IP_Resetn                  => ipif_Bus2IP_Resetn,
    20.      Bus2IP_Data                    => ipif_Bus2IP_Data,
    21.      Bus2IP_BE                      => ipif_Bus2IP_BE,
    22.      Bus2IP_RdCE                    => user_Bus2IP_RdCE,
    23.      Bus2IP_WrCE                    => user_Bus2IP_WrCE,
    24.      IP2Bus_Data                    => user_IP2Bus_Data,
    25.      IP2Bus_RdAck                   => user_IP2Bus_RdAck,
    26.      IP2Bus_WrAck                   => user_IP2Bus_WrAck,
    27.      IP2Bus_Error                   => user_IP2Bus_Error
    28.    );
    复制代码
    这几个文件修改后保存。

    Project->Rescan User Repositories(更新用户仓库?),让XPS识别到对IP所做的修改

    2012100919002227.jpg 
    三、将自定义IP核添加到PS系统

    同第三篇一样,需要将IP添加到PS系统中。
    在Ports标签中,需要将我们定义的LED端口设置为外部端口,外部引脚名按照Zedboard的习惯,定义为LD
    2012100919035410.jpg 
    在Address标签中,设定IP的地址。XPS支持自定义定制范围、空间大小等。可以使用默认设置,也可以手动设置。这里我设置基地址为0x40000000,其实也就是我们设定的数据寄存器的地址为0x40000000。如果有更多的寄存器,会以4字节offset 地址的方式访问即可。
    2012100919041031.jpg 
    最后一样修改ucf文件,完成约束。
    1. NET LD[0] LOC = T22  | IOSTANDARD=LVCMOS33;  # "LD0"
    2. NET LD[1] LOC = T21  | IOSTANDARD=LVCMOS33;  # "LD1"
    3. NET LD[2] LOC = U22  | IOSTANDARD=LVCMOS33;  # "LD2"
    4. NET LD[3] LOC = U21  | IOSTANDARD=LVCMOS33;  # "LD3"
    5. NET LD[4] LOC = V22  | IOSTANDARD=LVCMOS33;  # "LD4"
    6. NET LD[5] LOC = W22  | IOSTANDARD=LVCMOS33;  # "LD5"
    7. NET LD[6] LOC = U19  | IOSTANDARD=LVCMOS33;  # "LD6"
    8. NET LD[7] LOC = U14  | IOSTANDARD=LVCMOS33;  # "LD7"
    复制代码
    最后对这个系统编译,生成bitstream文件,并将硬件配置导入到SDK,并启动SDK。

    四、使用SDK编写IP核驱动程序和应用程序

    打开SDK,可以从系统信息system.xml中看到我们的系统信息。可以看到我们实例化连接到系统的ip是my_axi_ip_0,基地址是0x4000000。

    2012100919102326.jpg 
    建立软件工程后,修改main代码,如下
    1. //@超群天晴 http://www.cnblogs.com/surpassal/
    2. #include <stdio.h>
    3. #include "xparameters.h"
    4. #include "xil_types.h"
    5. #include "xstatus.h"
    6. #include "xil_io.h"//包含xil_io头文件,完成对绝对地址的访问
    7. #include "platform.h"

    8. #define LED_DATA_REG 0x40000000

    9. void print(char *ptr);
    10. void delay(unsigned int delaytime);
    11. void LED_Play(unsigned char led);


    12. int main(void)
    13. {

    14.      init_platform();

    15.      print("ZedBoard LAB4: MY_AXI_LEDs ");
    16.      print("超群天晴 2012年10月8日22:12:31 ");

    17.      LED_Play(0x03);
    18.      while(1);

    19.      cleanup_platform();

    20.      return 0;
    21. }


    22. void delay(unsigned int delaytime)
    23. {
    24.      int i;
    25.      for(i=0;i<delaytime;i++)
    26.          ;
    27. }

    28. void LED_Play(unsigned char led)
    29. {
    30.      for(;;)
    31.      {
    32.          led=(led<<1)|(led>>7);
    33.          Xil_Out32(LED_DATA_REG,led);
    34.          delay(50000000);
    35.      }
    36. }
    复制代码
    定义了两个函数
    1. void delay(unsigned int delaytime);
    2. void LED_Play(unsigned char led);
    复制代码
    其中delay()为延时函数,参数为延时时间,100000000大约延时1s;

    LED_Play()为LED流水灯函数,参数是流水初始值。在程序里面设定的是0x2,也就LD0、LD1最开始亮,然后流水。



    其中第8行
    1. #define LED_DATA_REG 0x40000000
    复制代码
    使用宏定义,定义LED_DATA_REG,实际上就是自定义IP的基地址。

    第44行
    1. Xil_Out32(LED_DATA_REG,led);
    复制代码
    使用了xil_io.h提供的绝对地址访问函数Xil_Out32(u32 OutAddress, u32 Value),定义如下
    1. /*****************************************************************************/
    2. /**
    3. *
    4. * Performs an output operation for a 32-bit memory location by writing the
    5. * specified Value to the the specified address.
    6. *
    7. * @param    OutAddress contains the address to perform the output operation
    8. *        at.
    9. * @param    Value contains the Value to be output at the specified address.
    10. *
    11. * @return    None.
    12. *
    13. * @note        None.
    14. *
    15. ******************************************************************************/
    16. void Xil_Out32(u32 OutAddress, u32 Value)
    17. {
    18.      /* write the contents of the I/O location and then synchronize the I/O
    19.       * such that the I/O operation completes before proceeding on
    20.       */
    21.      *(volatile u32 *) OutAddress = Value;
    22.      SYNCHRONIZE_IO;
    23. }
    复制代码
    可以看出,其实现的功能就是向32位绝对地址OutAddress中写入32位无符号值Value。参考这样的写法,可以将地址访问修改
    1. #define LED_DATA_ADDR 0x40000000
    2. #define LED_DATA_REG(x) *(volatile unsigned int *) LED_DATA_ADDR = x
    复制代码
    然后修改寄存器的值,只需要修改LED_DATA_REG(x)参数x的值即可。

    四、运行结果

    编译下载之后,可以从超级终端看到调试信息
    2012100912205281.jpg 

    同时Zedboard上的 LD 流水
    2012100912152462.jpg 
    2012100912155477.jpg 
    2012100912153831.jpg 
    ================================
    备注:

    有关AXI协议,请参考
    AXI Bus Functional Model v1.1 Product Brief
    AXI Reference Guide (AXI)

    更多资料,请参考

    AXI IP Documentation
    ================================
    完整工程代码:  Lab4.rar (4.73 MB, 下载次数: 19) 


    相关阅读:

    一步一步学ZedBoard & Zynq()ZedBoard的第一个工程Helloworld
    一步一步学ZedBoard & Zynq():使用PL做流水灯
    一步一步学ZedBoard & Zynq():使用自带外设IPARM PS访问FPGA
    一步一步学ZedBoard & Zynq():在ZedBoard上运行linux并编写linux下的应用程序HelloWorld
    一步一步学ZedBoard & Zynq()Zedboard上的USB摄像头(V4L2接口)的图片采集
    一步一步学ZedBoard & Zynq()USB摄像头图片采集+QT显示

    人生天地之间,若白驹之过郤(隙),忽然而已
  • 相关阅读:
    bzoj5328: [Sdoi2018]物理实验
    HDU
    bzoj4820: [Sdoi2017]硬币游戏
    bzoj4600: [Sdoi2016]硬币游戏
    阿里云配置防火墙规则
    博客园 添加 Live 2D 模型
    R语言做逻辑回归
    R语言错误的提示(中英文翻译)
    用随机森林分类
    python 切换虚拟环境
  • 原文地址:https://www.cnblogs.com/xiabodan/p/4038646.html
Copyright © 2011-2022 走看看