一步一步學ZedBoard & Zynq(四):基於AXI Lite 總線的從設備IP設計

URL: http://www.cnblogs.com/surpassal/archive/2012/10/09/Zynq_Lab4.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系統。需要注意的是,在選擇外設時,同樣不要添加任何外設

 

二、定製AXI IP

ARM PS系統創建結束後,就可以開始定製用戶自定義IP。XPS提供了Create or Import Peripheral Wizward 嚮導,使得用戶自定義IP的創建變得非常簡單。當然在熟悉了AXI IP核結構和代碼編寫規則後,可以直接編寫自己的IP核而不使用嚮導。這裏採用嚮導方式。

1、產生AXI IP外設模版

Hardware->Create or Import Peripheral Wizward ,啓動向導

歡迎界面

選擇從模板創建新外設

默認是將外設直接包含到當前XPS工程中

 填入外設名。注意必須都是小寫。這裏我們建立的是my_axi_ip。下面是版本控制,可以根據需要修改。同時面板的最下方還提示了將創建名爲my_axi_ip_v1_00_a的庫(其實就是一個目錄),所有實現這個IP的HDL文件都在這個庫中。

接下來要選擇外設總線的類型。AXI4_Lite爲最基本的AXI 總線,用於簡單處理,所有空間訪問都是通過地址/寄存器方式訪問,不支持突發;AXI4是標準AXI4總線標準,支持突然,支持高速;AXI4_Stream專門爲數據流而設計。

在IPIF (IP 接口) 配置,這裏配置接口的一些屬性,如是否是AXI 主/從設備等。我們所定製的IP是一個從設備,因而不需要使用主設備接口。

選擇需啊喲的寄存器數量。因爲我們只需要一個數據寄存器,這裏選1。

接下來就是IPIC(IP 互聯),也就是IP的接口信號。以BUS2開頭的信號,意味對IP來說,這些信號是輸入信號;同樣IP2BUS意味着輸出信號。

這裏一些信號做一些說明。

BUS2IP_WrCE(Write Chip Enable,寫使能)

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,寫數據)

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,字節使能)

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,讀反饋)

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很簡單,不要使用。

最後,需要選擇HDL類型、ISE工程支持和軟件驅動模板。因爲我比較習慣使用verilog,因而使用verilog模板。需要說明的是,IP接口仍然是VHDL編寫,只是用戶邏輯改用verilog。如果不需要使用軟件驅動模板的話,可以不選上。這裏選上了,但是後續編程的時候我並沒有用。

最後給出了外設的信息summary。支持,my_axi_ip"外殼"基本完成。後續我們只需要對user_logic進行編寫,並修改元件引腳即可。

2、編寫IP

修改.mpd文件,在目錄

Lab4\pcores\my_axi_ip_v1_00_a\data\

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

其中,第39行

PORT LED = "", DIR = O, VEC = [7:0]

是我們添加上的,表明我們爲其添加了一個名爲LED的端口,方向是輸出,長度是8位。其他行代碼爲默認,不需要修改。

 

修改用戶邏輯,在

Lab4\pcores\my_axi_ip_v1_00_a\hdl\verilog\user_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 
 51 `uselib lib=unisims_ver
 52 `uselib lib=proc_common_v3_00_a
 53 
 54 module user_logic
 55 (
 56   // -- ADD USER PORTS BELOW THIS LINE ---------------
 57   LED,
 58   // -- ADD USER PORTS ABOVE THIS LINE ---------------
 59 
 60   // -- DO NOT EDIT BELOW THIS LINE ------------------
 61   // -- Bus protocol ports, do not add to or delete 
 62   Bus2IP_Clk,                     // Bus to IP clock
 63   Bus2IP_Resetn,                  // Bus to IP reset
 64   Bus2IP_Data,                    // Bus to IP data bus
 65   Bus2IP_BE,                      // Bus to IP byte enables
 66   Bus2IP_RdCE,                    // Bus to IP read chip enable
 67   Bus2IP_WrCE,                    // Bus to IP write chip enable
 68   IP2Bus_Data,                    // IP to Bus data bus
 69   IP2Bus_RdAck,                   // IP to Bus read transfer acknowledgement
 70   IP2Bus_WrAck,                   // IP to Bus write transfer acknowledgement
 71   IP2Bus_Error                    // IP to Bus error response
 72   // -- DO NOT EDIT ABOVE THIS LINE ------------------
 73 ); // user_logic
 74 
 75 // -- ADD USER PARAMETERS BELOW THIS LINE ------------
 76 // --USER parameters added here 
 77 // -- ADD USER PARAMETERS ABOVE THIS LINE ------------
 78 
 79 // -- DO NOT EDIT BELOW THIS LINE --------------------
 80 // -- Bus protocol parameters, do not add to or delete
 81 parameter C_NUM_REG                      = 1;
 82 parameter C_SLV_DWIDTH                   = 32;
 83 // -- DO NOT EDIT ABOVE THIS LINE --------------------
 84 
 85 // -- ADD USER PORTS BELOW THIS LINE -----------------
 86 output        [7:0]                        LED;
 87 // -- ADD USER PORTS ABOVE THIS LINE -----------------
 88 
 89 // -- DO NOT EDIT BELOW THIS LINE --------------------
 90 // -- Bus protocol ports, do not add to or delete
 91 input                                     Bus2IP_Clk;
 92 input                                     Bus2IP_Resetn;
 93 input      [C_SLV_DWIDTH-1 : 0]           Bus2IP_Data;
 94 input      [C_SLV_DWIDTH/8-1 : 0]         Bus2IP_BE;
 95 input      [C_NUM_REG-1 : 0]              Bus2IP_RdCE;
 96 input      [C_NUM_REG-1 : 0]              Bus2IP_WrCE;
 97 output     [C_SLV_DWIDTH-1 : 0]           IP2Bus_Data;
 98 output                                    IP2Bus_RdAck;
 99 output                                    IP2Bus_WrAck;
100 output                                    IP2Bus_Error;
101 // -- DO NOT EDIT ABOVE THIS LINE --------------------
102 
103 //----------------------------------------------------------------------------
104 // Implementation
105 //----------------------------------------------------------------------------
106 
107   // --USER nets declarations added here, as needed for user logic
108 
109   // Nets for user logic slave model s/w accessible register example
110   reg        [C_SLV_DWIDTH-1 : 0]           slv_reg0;
111   wire       [0 : 0]                        slv_reg_write_sel;
112   wire       [0 : 0]                        slv_reg_read_sel;
113   reg        [C_SLV_DWIDTH-1 : 0]           slv_ip2bus_data;
114   wire                                      slv_read_ack;
115   wire                                      slv_write_ack;
116   integer                                   byte_index, bit_index;
117 
118   // USER logic implementation added here
119     assign LED    = slv_reg0[7:0];
120   // ------------------------------------------------------
121   // Example code to read/write user logic slave model s/w accessible registers
122   // 
123   // Note:
124   // The example code presented here is to show you one way of reading/writing
125   // software accessible registers implemented in the user logic slave model.
126   // Each bit of the Bus2IP_WrCE/Bus2IP_RdCE signals is configured to correspond
127   // to one software accessible register by the top level template. For example,
128   // if you have four 32 bit software accessible registers in the user logic,
129   // you are basically operating on the following memory mapped registers:
130   // 
131   //    Bus2IP_WrCE/Bus2IP_RdCE   Memory Mapped Register
132   //                     "1000"   C_BASEADDR + 0x0
133   //                     "0100"   C_BASEADDR + 0x4
134   //                     "0010"   C_BASEADDR + 0x8
135   //                     "0001"   C_BASEADDR + 0xC
136   // 
137   // ------------------------------------------------------
138 
139   assign
140     slv_reg_write_sel = Bus2IP_WrCE[0:0],
141     slv_reg_read_sel  = Bus2IP_RdCE[0:0],
142     slv_write_ack     = Bus2IP_WrCE[0],
143     slv_read_ack      = Bus2IP_RdCE[0];
144     
145 
146 
147   // implement slave model register(s)
148   always @( posedge Bus2IP_Clk )
149     begin
150 
151       if ( Bus2IP_Resetn == 1'b0 )
152         begin
153           slv_reg0 <= 0;
154         end
155       else
156         case ( slv_reg_write_sel )
157           1'b1 :
158             for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
159               if ( Bus2IP_BE[byte_index] == 1 )
160                 slv_reg0[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
161           default : begin
162             slv_reg0 <= slv_reg0;
163                     end
164         endcase
165 
166     end // SLAVE_REG_WRITE_PROC
167 
168   // implement slave model register read mux
169   always @( slv_reg_read_sel or slv_reg0 )
170     begin 
171 
172       case ( slv_reg_read_sel )
173         1'b1 : slv_ip2bus_data <= slv_reg0;
174         default : slv_ip2bus_data <= 0;
175       endcase
176 
177     end // SLAVE_REG_READ_PROC
178 
179   // ------------------------------------------------------------
180   // Example code to drive IP to Bus signals
181   // ------------------------------------------------------------
182 
183 assign IP2Bus_Data = (slv_read_ack == 1'b1) ? slv_ip2bus_data :  0 ;
184   assign IP2Bus_WrAck = slv_write_ack;
185   assign IP2Bus_RdAck = slv_read_ack;
186   assign IP2Bus_Error = 0;
187 
188 endmodule
複製代碼

代碼中57、86行

LED,
output        [7:0]                        LED;

表明在用戶邏輯中,定義了名爲LED的端口,方向是輸出,長度爲8。

代碼中119行

assign LED    = slv_reg0[7:0];

表明將slv_reg0的低8位傳遞給輸出端口LED。其實就是實現了數據寄存器的值作用到輸出端口的功能。

 

需要將用戶邏輯和IPIF連接上,需要完成user_logic的例化

Lab4\pcores\my_axi_ip_v1_00_a\hdl\vhdl\my_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 
 60 library ieee;
 61 use ieee.std_logic_1164.all;
 62 use ieee.std_logic_arith.all;
 63 use ieee.std_logic_unsigned.all;
 64 
 65 library proc_common_v3_00_a;
 66 use proc_common_v3_00_a.proc_common_pkg.all;
 67 use proc_common_v3_00_a.ipif_pkg.all;
 68 
 69 library axi_lite_ipif_v1_01_a;
 70 use axi_lite_ipif_v1_01_a.axi_lite_ipif;
 71 
 72 ------------------------------------------------------------------------------
 73 -- Entity section
 74 ------------------------------------------------------------------------------
 75 -- Definition of Generics:
 76 --   C_S_AXI_DATA_WIDTH           -- AXI4LITE slave: Data width
 77 --   C_S_AXI_ADDR_WIDTH           -- AXI4LITE slave: Address Width
 78 --   C_S_AXI_MIN_SIZE             -- AXI4LITE slave: Min Size
 79 --   C_USE_WSTRB                  -- AXI4LITE slave: Write Strobe
 80 --   C_DPHASE_TIMEOUT             -- AXI4LITE slave: Data Phase Timeout
 81 --   C_BASEADDR                   -- AXI4LITE slave: base address
 82 --   C_HIGHADDR                   -- AXI4LITE slave: high address
 83 --   C_FAMILY                     -- FPGA Family
 84 --   C_NUM_REG                    -- Number of software accessible registers
 85 --   C_NUM_MEM                    -- Number of address-ranges
 86 --   C_SLV_AWIDTH                 -- Slave interface address bus width
 87 --   C_SLV_DWIDTH                 -- Slave interface data bus width
 88 --
 89 -- Definition of Ports:
 90 --   S_AXI_ACLK                   -- AXI4LITE slave: Clock 
 91 --   S_AXI_ARESETN                -- AXI4LITE slave: Reset
 92 --   S_AXI_AWADDR                 -- AXI4LITE slave: Write address
 93 --   S_AXI_AWVALID                -- AXI4LITE slave: Write address valid
 94 --   S_AXI_WDATA                  -- AXI4LITE slave: Write data
 95 --   S_AXI_WSTRB                  -- AXI4LITE slave: Write strobe
 96 --   S_AXI_WVALID                 -- AXI4LITE slave: Write data valid
 97 --   S_AXI_BREADY                 -- AXI4LITE slave: Response ready
 98 --   S_AXI_ARADDR                 -- AXI4LITE slave: Read address
 99 --   S_AXI_ARVALID                -- AXI4LITE slave: Read address valid
100 --   S_AXI_RREADY                 -- AXI4LITE slave: Read data ready
101 --   S_AXI_ARREADY                -- AXI4LITE slave: read addres ready
102 --   S_AXI_RDATA                  -- AXI4LITE slave: Read data
103 --   S_AXI_RRESP                  -- AXI4LITE slave: Read data response
104 --   S_AXI_RVALID                 -- AXI4LITE slave: Read data valid
105 --   S_AXI_WREADY                 -- AXI4LITE slave: Write data ready
106 --   S_AXI_BRESP                  -- AXI4LITE slave: Response
107 --   S_AXI_BVALID                 -- AXI4LITE slave: Resonse valid
108 --   S_AXI_AWREADY                -- AXI4LITE slave: Wrte address ready
109 ------------------------------------------------------------------------------
110 
111 entity my_axi_ip is
112   generic
113   (
114     -- ADD USER GENERICS BELOW THIS LINE ---------------
115     --USER generics added here
116     -- ADD USER GENERICS ABOVE THIS LINE ---------------
117 
118     -- DO NOT EDIT BELOW THIS LINE ---------------------
119     -- Bus protocol parameters, do not add to or delete
120     C_S_AXI_DATA_WIDTH             : integer              := 32;
121     C_S_AXI_ADDR_WIDTH             : integer              := 32;
122     C_S_AXI_MIN_SIZE               : std_logic_vector     := X"000001FF";
123     C_USE_WSTRB                    : integer              := 0;
124     C_DPHASE_TIMEOUT               : integer              := 8;
125     C_BASEADDR                     : std_logic_vector     := X"FFFFFFFF";
126     C_HIGHADDR                     : std_logic_vector     := X"00000000";
127     C_FAMILY                       : string               := "virtex6";
128     C_NUM_REG                      : integer              := 1;
129     C_NUM_MEM                      : integer              := 1;
130     C_SLV_AWIDTH                   : integer              := 32;
131     C_SLV_DWIDTH                   : integer              := 32
132     -- DO NOT EDIT ABOVE THIS LINE ---------------------
133   );
134   port
135   (
136     -- ADD USER PORTS BELOW THIS LINE ------------------
137     LED                                : out std_logic_vector(7 downto 0);
138     -- ADD USER PORTS ABOVE THIS LINE ------------------
139 
140     -- DO NOT EDIT BELOW THIS LINE ---------------------
141     -- Bus protocol ports, do not add to or delete
142     S_AXI_ACLK                     : in  std_logic;
143     S_AXI_ARESETN                  : in  std_logic;
144     S_AXI_AWADDR                   : in  std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
145     S_AXI_AWVALID                  : in  std_logic;
146     S_AXI_WDATA                    : in  std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
147     S_AXI_WSTRB                    : in  std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0);
148     S_AXI_WVALID                   : in  std_logic;
149     S_AXI_BREADY                   : in  std_logic;
150     S_AXI_ARADDR                   : in  std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
151     S_AXI_ARVALID                  : in  std_logic;
152     S_AXI_RREADY                   : in  std_logic;
153     S_AXI_ARREADY                  : out std_logic;
154     S_AXI_RDATA                    : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
155     S_AXI_RRESP                    : out std_logic_vector(1 downto 0);
156     S_AXI_RVALID                   : out std_logic;
157     S_AXI_WREADY                   : out std_logic;
158     S_AXI_BRESP                    : out std_logic_vector(1 downto 0);
159     S_AXI_BVALID                   : out std_logic;
160     S_AXI_AWREADY                  : out std_logic
161     -- DO NOT EDIT ABOVE THIS LINE ---------------------
162   );
163 
164   attribute MAX_FANOUT : string;
165   attribute SIGIS : string;
166   attribute MAX_FANOUT of S_AXI_ACLK       : signal is "10000";
167   attribute MAX_FANOUT of S_AXI_ARESETN       : signal is "10000";
168   attribute SIGIS of S_AXI_ACLK       : signal is "Clk";
169   attribute SIGIS of S_AXI_ARESETN       : signal is "Rst";
170 end entity my_axi_ip;
171 
172 ------------------------------------------------------------------------------
173 -- Architecture section
174 ------------------------------------------------------------------------------
175 
176 architecture IMP of my_axi_ip is
177 
178   constant USER_SLV_DWIDTH                : integer              := C_S_AXI_DATA_WIDTH;
179 
180   constant IPIF_SLV_DWIDTH                : integer              := C_S_AXI_DATA_WIDTH;
181 
182   constant ZERO_ADDR_PAD                  : std_logic_vector(0 to 31) := (others => '0');
183   constant USER_SLV_BASEADDR              : std_logic_vector     := C_BASEADDR;
184   constant USER_SLV_HIGHADDR              : std_logic_vector     := C_HIGHADDR;
185 
186   constant IPIF_ARD_ADDR_RANGE_ARRAY      : SLV64_ARRAY_TYPE     := 
187     (
188       ZERO_ADDR_PAD & USER_SLV_BASEADDR,  -- user logic slave space base address
189       ZERO_ADDR_PAD & USER_SLV_HIGHADDR   -- user logic slave space high address
190     );
191 
192   constant USER_SLV_NUM_REG               : integer              := 1;
193   constant USER_NUM_REG                   : integer              := USER_SLV_NUM_REG;
194   constant TOTAL_IPIF_CE                  : integer              := USER_NUM_REG;
195 
196   constant IPIF_ARD_NUM_CE_ARRAY          : INTEGER_ARRAY_TYPE   := 
197     (
198       0  => (USER_SLV_NUM_REG)            -- number of ce for user logic slave space
199     );
200 
201   ------------------------------------------
202   -- Index for CS/CE
203   ------------------------------------------
204   constant USER_SLV_CS_INDEX              : integer              := 0;
205   constant USER_SLV_CE_INDEX              : integer              := calc_start_ce_index(IPIF_ARD_NUM_CE_ARRAY, USER_SLV_CS_INDEX);
206 
207   constant USER_CE_INDEX                  : integer              := USER_SLV_CE_INDEX;
208 
209   ------------------------------------------
210   -- IP Interconnect (IPIC) signal declarations
211   ------------------------------------------
212   signal ipif_Bus2IP_Clk                : std_logic;
213   signal ipif_Bus2IP_Resetn             : std_logic;
214   signal ipif_Bus2IP_Addr               : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
215   signal ipif_Bus2IP_RNW                : std_logic;
216   signal ipif_Bus2IP_BE                 : std_logic_vector(IPIF_SLV_DWIDTH/8-1 downto 0);
217   signal ipif_Bus2IP_CS                 : std_logic_vector((IPIF_ARD_ADDR_RANGE_ARRAY'LENGTH)/2-1 downto 0);
218   signal ipif_Bus2IP_RdCE               : std_logic_vector(calc_num_ce(IPIF_ARD_NUM_CE_ARRAY)-1 downto 0);
219   signal ipif_Bus2IP_WrCE               : std_logic_vector(calc_num_ce(IPIF_ARD_NUM_CE_ARRAY)-1 downto 0);
220   signal ipif_Bus2IP_Data               : std_logic_vector(IPIF_SLV_DWIDTH-1 downto 0);
221   signal ipif_IP2Bus_WrAck              : std_logic;
222   signal ipif_IP2Bus_RdAck              : std_logic;
223   signal ipif_IP2Bus_Error              : std_logic;
224   signal ipif_IP2Bus_Data               : std_logic_vector(IPIF_SLV_DWIDTH-1 downto 0);
225   signal user_Bus2IP_RdCE               : std_logic_vector(USER_NUM_REG-1 downto 0);
226   signal user_Bus2IP_WrCE               : std_logic_vector(USER_NUM_REG-1 downto 0);
227   signal user_IP2Bus_Data               : std_logic_vector(USER_SLV_DWIDTH-1 downto 0);
228   signal user_IP2Bus_RdAck              : std_logic;
229   signal user_IP2Bus_WrAck              : std_logic;
230   signal user_IP2Bus_Error              : std_logic;
231 
232   ------------------------------------------
233   -- Component declaration for verilog user logic
234   ------------------------------------------
235   component user_logic is
236     generic
237     (
238       -- ADD USER GENERICS BELOW THIS LINE ---------------
239       --USER generics added here
240       -- ADD USER GENERICS ABOVE THIS LINE ---------------
241 
242       -- DO NOT EDIT BELOW THIS LINE ---------------------
243       -- Bus protocol parameters, do not add to or delete
244       C_NUM_REG                      : integer              := 1;
245       C_SLV_DWIDTH                   : integer              := 32
246       -- DO NOT EDIT ABOVE THIS LINE ---------------------
247     );
248     port
249     (
250       -- ADD USER PORTS BELOW THIS LINE ------------------
251       LED                                : out std_logic_vector(7 downto 0);
252       -- ADD USER PORTS ABOVE THIS LINE ------------------
253 
254       -- DO NOT EDIT BELOW THIS LINE ---------------------
255       -- Bus protocol ports, do not add to or delete
256       Bus2IP_Clk                     : in  std_logic;
257       Bus2IP_Resetn                  : in  std_logic;
258       Bus2IP_Data                    : in  std_logic_vector(C_SLV_DWIDTH-1 downto 0);
259       Bus2IP_BE                      : in  std_logic_vector(C_SLV_DWIDTH/8-1 downto 0);
260       Bus2IP_RdCE                    : in  std_logic_vector(C_NUM_REG-1 downto 0);
261       Bus2IP_WrCE                    : in  std_logic_vector(C_NUM_REG-1 downto 0);
262       IP2Bus_Data                    : out std_logic_vector(C_SLV_DWIDTH-1 downto 0);
263       IP2Bus_RdAck                   : out std_logic;
264       IP2Bus_WrAck                   : out std_logic;
265       IP2Bus_Error                   : out std_logic
266       -- DO NOT EDIT ABOVE THIS LINE ---------------------
267     );
268   end component user_logic;
269 
270 begin
271 
272   ------------------------------------------
273   -- instantiate axi_lite_ipif
274   ------------------------------------------
275   AXI_LITE_IPIF_I : entity axi_lite_ipif_v1_01_a.axi_lite_ipif
276     generic map
277     (
278       C_S_AXI_DATA_WIDTH             => IPIF_SLV_DWIDTH,
279       C_S_AXI_ADDR_WIDTH             => C_S_AXI_ADDR_WIDTH,
280       C_S_AXI_MIN_SIZE               => C_S_AXI_MIN_SIZE,
281       C_USE_WSTRB                    => C_USE_WSTRB,
282       C_DPHASE_TIMEOUT               => C_DPHASE_TIMEOUT,
283       C_ARD_ADDR_RANGE_ARRAY         => IPIF_ARD_ADDR_RANGE_ARRAY,
284       C_ARD_NUM_CE_ARRAY             => IPIF_ARD_NUM_CE_ARRAY,
285       C_FAMILY                       => C_FAMILY
286     )
287     port map
288     (
289       S_AXI_ACLK                     => S_AXI_ACLK,
290       S_AXI_ARESETN                  => S_AXI_ARESETN,
291       S_AXI_AWADDR                   => S_AXI_AWADDR,
292       S_AXI_AWVALID                  => S_AXI_AWVALID,
293       S_AXI_WDATA                    => S_AXI_WDATA,
294       S_AXI_WSTRB                    => S_AXI_WSTRB,
295       S_AXI_WVALID                   => S_AXI_WVALID,
296       S_AXI_BREADY                   => S_AXI_BREADY,
297       S_AXI_ARADDR                   => S_AXI_ARADDR,
298       S_AXI_ARVALID                  => S_AXI_ARVALID,
299       S_AXI_RREADY                   => S_AXI_RREADY,
300       S_AXI_ARREADY                  => S_AXI_ARREADY,
301       S_AXI_RDATA                    => S_AXI_RDATA,
302       S_AXI_RRESP                    => S_AXI_RRESP,
303       S_AXI_RVALID                   => S_AXI_RVALID,
304       S_AXI_WREADY                   => S_AXI_WREADY,
305       S_AXI_BRESP                    => S_AXI_BRESP,
306       S_AXI_BVALID                   => S_AXI_BVALID,
307       S_AXI_AWREADY                  => S_AXI_AWREADY,
308       Bus2IP_Clk                     => ipif_Bus2IP_Clk,
309       Bus2IP_Resetn                  => ipif_Bus2IP_Resetn,
310       Bus2IP_Addr                    => ipif_Bus2IP_Addr,
311       Bus2IP_RNW                     => ipif_Bus2IP_RNW,
312       Bus2IP_BE                      => ipif_Bus2IP_BE,
313       Bus2IP_CS                      => ipif_Bus2IP_CS,
314       Bus2IP_RdCE                    => ipif_Bus2IP_RdCE,
315       Bus2IP_WrCE                    => ipif_Bus2IP_WrCE,
316       Bus2IP_Data                    => ipif_Bus2IP_Data,
317       IP2Bus_WrAck                   => ipif_IP2Bus_WrAck,
318       IP2Bus_RdAck                   => ipif_IP2Bus_RdAck,
319       IP2Bus_Error                   => ipif_IP2Bus_Error,
320       IP2Bus_Data                    => ipif_IP2Bus_Data
321     );
322 
323   ------------------------------------------
324   -- instantiate User Logic
325   ------------------------------------------
326   USER_LOGIC_I : component user_logic
327     generic map
328     (
329       -- MAP USER GENERICS BELOW THIS LINE ---------------
330       --USER generics mapped here
331       -- MAP USER GENERICS ABOVE THIS LINE ---------------
332 
333       C_NUM_REG                      => USER_NUM_REG,
334       C_SLV_DWIDTH                   => USER_SLV_DWIDTH
335     )
336     port map
337     (
338       -- MAP USER PORTS BELOW THIS LINE ------------------
339       LED                            => LED,
340       -- MAP USER PORTS ABOVE THIS LINE ------------------
341 
342       Bus2IP_Clk                     => ipif_Bus2IP_Clk,
343       Bus2IP_Resetn                  => ipif_Bus2IP_Resetn,
344       Bus2IP_Data                    => ipif_Bus2IP_Data,
345       Bus2IP_BE                      => ipif_Bus2IP_BE,
346       Bus2IP_RdCE                    => user_Bus2IP_RdCE,
347       Bus2IP_WrCE                    => user_Bus2IP_WrCE,
348       IP2Bus_Data                    => user_IP2Bus_Data,
349       IP2Bus_RdAck                   => user_IP2Bus_RdAck,
350       IP2Bus_WrAck                   => user_IP2Bus_WrAck,
351       IP2Bus_Error                   => user_IP2Bus_Error
352     );
353 
354   ------------------------------------------
355   -- connect internal signals
356   ------------------------------------------
357   ipif_IP2Bus_Data <= user_IP2Bus_Data;
358   ipif_IP2Bus_WrAck <= user_IP2Bus_WrAck;
359   ipif_IP2Bus_RdAck <= user_IP2Bus_RdAck;
360   ipif_IP2Bus_Error <= user_IP2Bus_Error;
361 
362   user_Bus2IP_RdCE <= ipif_Bus2IP_RdCE(USER_NUM_REG-1 downto 0);
363   user_Bus2IP_WrCE <= ipif_Bus2IP_WrCE(USER_NUM_REG-1 downto 0);
364 
365 end IMP;
複製代碼

137行 

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 
11     -- DO NOT EDIT BELOW THIS LINE ---------------------
12     -- Bus protocol parameters, do not add to or delete
13     C_NUM_REG                      : integer              := 1;
14     C_SLV_DWIDTH                   : integer              := 32
15     -- DO NOT EDIT ABOVE THIS LINE ---------------------
16   );
17   port
18   (
19     -- ADD USER PORTS BELOW THIS LINE ------------------
20     LED                                : out std_logic_vector(7 downto 0);
21     -- ADD USER PORTS ABOVE THIS LINE ------------------
22 
23     -- DO NOT EDIT BELOW THIS LINE ---------------------
24     -- Bus protocol ports, do not add to or delete
25     Bus2IP_Clk                     : in  std_logic;
26     Bus2IP_Resetn                  : in  std_logic;
27     Bus2IP_Data                    : in  std_logic_vector(C_SLV_DWIDTH-1 downto 0);
28     Bus2IP_BE                      : in  std_logic_vector(C_SLV_DWIDTH/8-1 downto 0);
29     Bus2IP_RdCE                    : in  std_logic_vector(C_NUM_REG-1 downto 0);
30     Bus2IP_WrCE                    : in  std_logic_vector(C_NUM_REG-1 downto 0);
31     IP2Bus_Data                    : out std_logic_vector(C_SLV_DWIDTH-1 downto 0);
32     IP2Bus_RdAck                   : out std_logic;
33     IP2Bus_WrAck                   : out std_logic;
34     IP2Bus_Error                   : out std_logic
35     -- DO NOT EDIT ABOVE THIS LINE ---------------------
36   );
37 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 
11     C_NUM_REG                      => USER_NUM_REG,
12     C_SLV_DWIDTH                   => USER_SLV_DWIDTH
13   )
14   port map
15   (
16     -- MAP USER PORTS BELOW THIS LINE ------------------
17     LED                            => LED,
18     -- MAP USER PORTS ABOVE THIS LINE ------------------
19 
20     Bus2IP_Clk                     => ipif_Bus2IP_Clk,
21     Bus2IP_Resetn                  => ipif_Bus2IP_Resetn,
22     Bus2IP_Data                    => ipif_Bus2IP_Data,
23     Bus2IP_BE                      => ipif_Bus2IP_BE,
24     Bus2IP_RdCE                    => user_Bus2IP_RdCE,
25     Bus2IP_WrCE                    => user_Bus2IP_WrCE,
26     IP2Bus_Data                    => user_IP2Bus_Data,
27     IP2Bus_RdAck                   => user_IP2Bus_RdAck,
28     IP2Bus_WrAck                   => user_IP2Bus_WrAck,
29     IP2Bus_Error                   => user_IP2Bus_Error
30   );
複製代碼

這幾個文件修改後保存。

Project->Rescan User Repositories(更新用戶倉庫?),讓XPS識別到對IP所做的修改

 

三、將自定義IP核添加到PS系統

同第三篇一樣,需要將IP添加到PS系統中。

在Ports標籤中,需要將我們定義的LED端口設置爲外部端口,外部引腳名按照Zedboard的習慣,定義爲LD

在Address標籤中,設定IP的地址。XPS支持自定義定製範圍、空間大小等。可以使用默認設置,也可以手動設置。這裏我設置基地址爲0x40000000,其實也就是我們設定的數據寄存器的地址爲0x40000000。如果有更多的寄存器,會以4字節offset 地址的方式訪問即可。

最後一樣修改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。

 

建立軟件工程後,修改main代碼,如下

複製代碼
//@超羣天晴 http://www.cnblogs.com/surpassal/
 1 #include <stdio.h>
 2 #include "xparameters.h"
 3 #include "xil_types.h"
 4 #include "xstatus.h"
 5 #include "xil_io.h"//包含xil_io頭文件,完成對絕對地址的訪問
 6 #include "platform.h"
 7 
 8 #define LED_DATA_REG 0x40000000
 9 
10 void print(char *ptr);
11 void delay(unsigned int delaytime);
12 void LED_Play(unsigned char led);
13 
14 
15 int main(void)
16 {
17 
18     init_platform();
19 
20     print("ZedBoard LAB4: MY_AXI_LEDs\n\r");
21     print("超羣天晴 2012年10月8日22:12:31\n\r");
22 
23     LED_Play(0x03);
24     while(1);
25 
26     cleanup_platform();
27 
28     return 0;
29 }
30 
31 
32 void delay(unsigned int delaytime)
33 {
34     int i;
35     for(i=0;i<delaytime;i++)
36         ;
37 }
38 
39 void LED_Play(unsigned char led)
40 {
41     for(;;)
42     {
43         led=(led<<1)|(led>>7);
44         Xil_Out32(LED_DATA_REG,led);
45         delay(50000000);
46     }
47 }
複製代碼

定義了兩個函數

void delay(unsigned int delaytime);
void LED_Play(unsigned char led);

其中delay()爲延時函數,參數爲延時時間,100000000大約延時1s;

LED_Play()爲LED流水燈函數,參數是流水初始值。在程序裏面設定的是0x2,也就LD0、LD1最開始亮,然後流水。

 

其中第8行

#define LED_DATA_REG 0x40000000

使用宏定義,定義LED_DATA_REG,實際上就是自定義IP的基地址。

第44行

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的值即可。

四、運行結果

編譯下載之後,可以從超級終端看到調試信息

同時Zedboard上的 LD 流水

 

================================

備註:

有關AXI協議,請參考

AXI Bus Functional Model v1.1 Product Brief

AXI Reference Guide (AXI)

更多資料,請參考

AXI IP Documentation

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章