玩转赛灵思Zedboard开发板(5):基于AXI Lite总线的从设备IP设计

PLD开发板

1人已加入

描述

  电子发烧友网核心提示:ZedBoard开发板上的Zynq是一个ARM PS(processing system, 双核A9 + 存储管理 + 外设)+ PL(programable Logic) 结构,如果不使用PL,zynq的开发和普通的ARM 开发一样。不同的是ARM PS是可配置,因而硬件信息是不固定的。这也是zynq灵活性的一个表现。电子发烧友网编辑现为读者整合《玩转赛灵思Zedboard开发板》系列文章, 其中包括在ZedBoard开发板上的一些应用实例。其内容包括:

  玩转赛灵思Zedboard开发板(1):ZedBoard详解

  玩转赛灵思Zedboard开发板(2):ZedBoard最简单的测试工程

  玩转赛灵思Zedboard开发板(3):基于Zynq PL的流水灯

  玩转赛灵思Zedboard开发板(4):如何使用自带外设IP让ARM PS访问FPGA?

  本文为玩转赛灵思Zedboard开发板(5):基于AXI Lite 总线的从设备IP设计内容精彩,敬请对电子发烧友网保持密切关注。本小节通过使用XPS中的定制IP向导(ipwiz),为已经存在的ARM PS 系统添加用户自定IP(Custom IP ),了解AXI Lite IP基本结构,并掌握AXI Lite IP的定制方法,为后续编写复杂AXI IP打下基础。同时本小节IP定制方法同样适用于MicroBlaze处理系统。本小节定制的是简单LED的IP,只有一个数据寄存器,向其写值就可以控 制8个LED相应亮灭。更多赛灵思(Xilinx)Zedboard基础知识、相关手册以及应用实例将陆续推出,以飨读者,敬请期待。【本文的完整工程文件下载:见本文最后。】

  硬件平台:Digilent ZedBoard;开发环境:Windows XP 32 bit;软件: XPS 14.2 +SDK 14.2。

  一、创建ARM PS系统

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

FPGA开发板

  二、定制AXI IP

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

  1、产生AXI IP外设模版

  Hardware->Create or Import Peripheral Wizward ,启动向导

FPGA开发板

  欢迎界面

FPGA开发板

  选择从模板创建新外设

FPGA开发板

  默认是将外设直接包含到当前XPS工程中

FPGA开发板

  填入外设名。注意必须都是小写。这里我们建立的是my_axi_ip。下面是版本控制,可以根据需要修改。同时面板的最下方还提示了将创建名为my_axi_ip_v1_00_a的库(其实就是一个目录),所有实现这个IP的HDL文件都在这个库中。

FPGA开发板

  接下来要选择外设总线的类型。AXI4_Lite为最基本的AXI 总线,用于简单处理,所有空间访问都是通过地址/寄存器方式访问,不支持突发;AXI4是标准AXI4总线标准,支持突然,支持高速;AXI4_Stream专门为数据流而设计。

FPGA开发板

  在IPIF (IP 接口) 配置,这里配置接口的一些属性,如是否是AXI 主/从设备等。我们所定制的IP是一个从设备,因而不需要使用主设备接口。

FPGA开发板

  选择需要的寄存器数量。因为我们只需要一个数据寄存器,这里选1。

FPGA开发板

  接下来就是IPIC(IP 互联),也就是IP的接口信号。以BUS2开头的信号,意味对IP来说,这些信号是输入信号;同样IP2BUS意味着输出信号。

  这里一些信号做一些说明。

FPGA开发板

  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很简单,不要使用。

FPGA开发板

  最后,需要选择HDL类型、ISE工程支持和软件驱动模板。因为我比较习惯使用verilog,因而使用verilog模板。需要说明的是,IP接口仍然是VHDL编写,只是用户逻辑改用verilog。如果不需要使用软件驱动模板的话,可以不选上。这里选上了,但是后续编程的时候我并没有用。

FPGA开发板

  最后给出了外设的信息summary。支持,my_axi_ip"外壳"基本完成。后续我们只需要对user_logic进行编写,并修改元件引脚即可。

FPGA开发板

  2、编写IP

  修改.mpd文件,在目录

  Lab4pcoresmy_axi_ip_v1_00_adata

 
FPGA开发板

FPGA开发板

  其中,第39行

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

  是我们添加上的,表明我们为其添加了一个名为LED的端口,方向是输出,长度是8位。其他行代码为默认,不需要修改。

  修改用户逻辑,在

  Lab4pcoresmy_axi_ip_v1_00_ahdlveriloguser_logic.v
FPGA开发板
FPGA开发板
FPGA开发板
FPGA开发板
FPGA开发板
FPGA开发板
FPGA开发板

  代码中57、86行

  LED,

  output [7:0] LED;

  表明在用户逻辑中,定义了名为LED的端口,方向是输出,长度为8。

  代码中119行

  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: "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所做的修改

FPGA开发板

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

  同第三篇一样,需要将IP添加到PS系统中。

  在Ports标签中,需要将我们定义的LED端口设置为外部端口,外部引脚名按照Zedboard的习惯,定义为LD

FPGA开发板

  在Address标签中,设定IP的地址。XPS支持自定义定制范围、空间大小等。可以使用默认设置,也可以手动设置。这里我设置基地址为 0x40000000,其实也就是我们设定的数据寄存器的地址为0x40000000。如果有更多的寄存器,会以4字节offset 地址的方式访问即可。

FPGA开发板

  最后一样修改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。

FPGA开发板

  建立软件工程后,修改main代码,如下

  //@超群天晴 http://www.cnblogs.com/surpassal/ 1 #include

  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 ");

  21 print("超群天晴 2012年10月8日22:12:31 ");

  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

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

  五、运行结果

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

FPGA开发板

  同时Zedboard上的 LD 流水

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

  备注:

  有关AXI协议,请参考

  AXI Bus Functional Model v1.1 Product Brief

  AXI Reference Guide (AXI)

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

  完整工程代码定制简单LED的IP核的设计源代码(Lab4.rar)

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
评论(0)
发评论
zjutlxk 2013-11-13
0 回复 举报
楼主 能加你的qq吗,现在也在搞zynq 搞了一个多月了,现在很多不懂的地方,想和你交流,谢谢。我不知道这个论坛怎么私信,希望你能和我一起讨论 收起回复

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分