首页 > 代码库 > Learn ZYNC (5)
Learn ZYNC (5)
今天为了熟悉axiLite的自定义ip核设计,
把LED和SW的往AXI总线输入输出定义在一个ip核中,
BD设计如下:
ip核顶层文件(增加了LED_Out和SW_In的定义)mygpio_v1.0.v:
module mygpio_v1_0 # ( // Users to add parameters here // User parameters ends // Do not modify the parameters beyond this line // Parameters of Axi Slave Bus Interface S00_AXI parameter integer C_S00_AXI_DATA_WIDTH = 32, parameter integer C_S00_AXI_ADDR_WIDTH = 4 ) ( // Users to add ports here//*****************my code*********************************** input wire [7:0] SW_In, output wire [7:0] LED_Out, // User ports ends // Do not modify the ports beyond this line // Ports of Axi Slave Bus Interface S00_AXI input wire s00_axi_aclk, input wire s00_axi_aresetn, input wire [C_S00_AXI_ADDR_WIDTH-1 : 0] s00_axi_awaddr, input wire [2 : 0] s00_axi_awprot, input wire s00_axi_awvalid, output wire s00_axi_awready, input wire [C_S00_AXI_DATA_WIDTH-1 : 0] s00_axi_wdata, input wire [(C_S00_AXI_DATA_WIDTH/8)-1 : 0] s00_axi_wstrb, input wire s00_axi_wvalid, output wire s00_axi_wready, output wire [1 : 0] s00_axi_bresp, output wire s00_axi_bvalid, input wire s00_axi_bready, input wire [C_S00_AXI_ADDR_WIDTH-1 : 0] s00_axi_araddr, input wire [2 : 0] s00_axi_arprot, input wire s00_axi_arvalid, output wire s00_axi_arready, output wire [C_S00_AXI_DATA_WIDTH-1 : 0] s00_axi_rdata, output wire [1 : 0] s00_axi_rresp, output wire s00_axi_rvalid, input wire s00_axi_rready );// Instantiation of Axi Bus Interface S00_AXI mygpio_v1_0_S00_AXI # ( .C_S_AXI_DATA_WIDTH(C_S00_AXI_DATA_WIDTH), .C_S_AXI_ADDR_WIDTH(C_S00_AXI_ADDR_WIDTH) ) mygpio_v1_0_S00_AXI_inst (//*****************************my code*************************** .SW_In(SW_In), .LED_Out(LED_Out), .S_AXI_ACLK(s00_axi_aclk), .S_AXI_ARESETN(s00_axi_aresetn), .S_AXI_AWADDR(s00_axi_awaddr), .S_AXI_AWPROT(s00_axi_awprot), .S_AXI_AWVALID(s00_axi_awvalid), .S_AXI_AWREADY(s00_axi_awready), .S_AXI_WDATA(s00_axi_wdata), .S_AXI_WSTRB(s00_axi_wstrb), .S_AXI_WVALID(s00_axi_wvalid), .S_AXI_WREADY(s00_axi_wready), .S_AXI_BRESP(s00_axi_bresp), .S_AXI_BVALID(s00_axi_bvalid), .S_AXI_BREADY(s00_axi_bready), .S_AXI_ARADDR(s00_axi_araddr), .S_AXI_ARPROT(s00_axi_arprot), .S_AXI_ARVALID(s00_axi_arvalid), .S_AXI_ARREADY(s00_axi_arready), .S_AXI_RDATA(s00_axi_rdata), .S_AXI_RRESP(s00_axi_rresp), .S_AXI_RVALID(s00_axi_rvalid), .S_AXI_RREADY(s00_axi_rready) ); // Add user logic here // User logic ends endmodule
ip核实现文件mygpio_v1_0_S00_AXI.v:
module mygpio_v1_0_S00_AXI # ( // Users to add parameters here // User parameters ends // Do not modify the parameters beyond this line // Width of S_AXI data bus parameter integer C_S_AXI_DATA_WIDTH = 32, // Width of S_AXI address bus parameter integer C_S_AXI_ADDR_WIDTH = 4 ) ( // Users to add ports here//*********************my code **************************************** input wire [7:0] SW_In, output wire [7:0] LED_Out, // User ports ends // Do not modify the ports beyond this line // Global Clock Signal input wire S_AXI_ACLK, // Global Reset Signal. This Signal is Active LOW input wire S_AXI_ARESETN, // Write address (issued by master, acceped by Slave) input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_AWADDR, // Write channel Protection type. This signal indicates the // privilege and security level of the transaction, and whether // the transaction is a data access or an instruction access. input wire [2 : 0] S_AXI_AWPROT, // Write address valid. This signal indicates that the master signaling // valid write address and control information. input wire S_AXI_AWVALID, // Write address ready. This signal indicates that the slave is ready // to accept an address and associated control signals. output wire S_AXI_AWREADY, // Write data (issued by master, acceped by Slave) input wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_WDATA, // Write strobes. This signal indicates which byte lanes hold // valid data. There is one write strobe bit for each eight // bits of the write data bus. input wire [(C_S_AXI_DATA_WIDTH/8)-1 : 0] S_AXI_WSTRB, // Write valid. This signal indicates that valid write // data and strobes are available. input wire S_AXI_WVALID, // Write ready. This signal indicates that the slave // can accept the write data. output wire S_AXI_WREADY, // Write response. This signal indicates the status // of the write transaction. output wire [1 : 0] S_AXI_BRESP, // Write response valid. This signal indicates that the channel // is signaling a valid write response. output wire S_AXI_BVALID, // Response ready. This signal indicates that the master // can accept a write response. input wire S_AXI_BREADY, // Read address (issued by master, acceped by Slave) input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_ARADDR, // Protection type. This signal indicates the privilege // and security level of the transaction, and whether the // transaction is a data access or an instruction access. input wire [2 : 0] S_AXI_ARPROT, // Read address valid. This signal indicates that the channel // is signaling valid read address and control information. input wire S_AXI_ARVALID, // Read address ready. This signal indicates that the slave is // ready to accept an address and associated control signals. output wire S_AXI_ARREADY, // Read data (issued by slave) output wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_RDATA, // Read response. This signal indicates the status of the // read transfer. output wire [1 : 0] S_AXI_RRESP, // Read valid. This signal indicates that the channel is // signaling the required read data. output wire S_AXI_RVALID, // Read ready. This signal indicates that the master can // accept the read data and response information. input wire S_AXI_RREADY ); // AXI4LITE signals reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_awaddr; reg axi_awready; reg axi_wready; reg [1 : 0] axi_bresp; reg axi_bvalid; reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_araddr; reg axi_arready; reg [C_S_AXI_DATA_WIDTH-1 : 0] axi_rdata; reg [1 : 0] axi_rresp; reg axi_rvalid; // Example-specific design signals // local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH // ADDR_LSB is used for addressing 32/64 bit registers/memories // ADDR_LSB = 2 for 32 bits (n downto 2) // ADDR_LSB = 3 for 64 bits (n downto 3) localparam integer ADDR_LSB = (C_S_AXI_DATA_WIDTH/32) + 1; localparam integer OPT_MEM_ADDR_BITS = 1; //---------------------------------------------- //-- Signals for user logic register space example//*********************my code **************************************** wire [31:0] reg0_wire; reg [31:0] SW_Reg0; reg [31:0] SW_Reg1; //------------------------------------------------ //-- Number of Slave Registers 4 reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg0; reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg1; reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg2; reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg3; wire slv_reg_rden; wire slv_reg_wren; reg [C_S_AXI_DATA_WIDTH-1:0] reg_data_out; integer byte_index; // I/O Connections assignments assign S_AXI_AWREADY = axi_awready; assign S_AXI_WREADY = axi_wready; assign S_AXI_BRESP = axi_bresp; assign S_AXI_BVALID = axi_bvalid; assign S_AXI_ARREADY = axi_arready; assign S_AXI_RDATA = http://www.mamicode.com/axi_rdata;>在这个文件中,我注释了AXI总线在写数据时对于slv_reg0写的定义,因为在我们的用户代码中使用一条reg0_wire将slv_reg0连到了sw_ul子核中,并且在子核中对reg0定义写操作(即将sw的状态输出到slv_reg0),然后另一段代码会将其放入reg_data_out,最后在slv_reg_rden线的输出为1时,它会进一步被送往axi_rdata,并通过数据总线S_AXI_RDATA输出。
ip核内包含的子文件sw_ul.v
module sw_ul( input S_AXI_ACLK, input slv_reg_rden, input [1:0] axi_araddr, input aresetn, input [7:0] SW_In, output reg [31:0] rdata ); reg [31:0] SW_Reg0; reg [31:0] SW_Reg1; always @(posedge S_AXI_ACLK) begin if ( aresetn == 1‘b0 ) begin SW_Reg0 <= 0; SW_Reg1 <= 0; rdata <= 0; end else begin if(slv_reg_rden) begin if(axi_araddr == 2‘h0) begin SW_Reg0 <= SW_In; SW_Reg1 <= SW_Reg0; rdata[7:0] <= SW_Reg1[7:0]; end end end endendmoduleip核内包含的子文件led_ul.v
module led_ul( input S_AXI_ACLK, input slv_reg_wren, input [1:0] axi_awaddr, input [31:0] S_AXI_WDATA, input aresetn, output reg [7:0] LED ); always @( posedge S_AXI_ACLK ) begin if( aresetn == 1‘b0 ) begin LED <= 8‘b10011001; end else begin if (slv_reg_wren && (axi_awaddr == 2‘h1)) begin LED <= S_AXI_WDATA[7:0]; end// LED <= 8‘b11111111;// if (slv_reg_wren)// begin// case(axi_awaddr)// 2‘h1:// begin// LED <= S_AXI_WDATA[7:0];// LED <= 8‘b00000001;// end// 2‘h0:// begin// LED <= 8‘b00000000;// end// default:// begin// LED <= 8‘b11111111;// end// endcase// end end endendmoduleEDK中standalone程序:
#include <stdio.h>#include "xparameters.h"#include "xil_io.h"#include "mygpio.h"#include "platform.h"int main(){ u32 inData = http://www.mamicode.com/0;>刚开始一直都测试不成功,一直得不到ip核中axi_araddr等于1的状态(即写第一个slv_reg1),后来看到了MYGPIO_S00_AXI_SLV_REG1_OFFSET=4,寄存器设置时设置的是32b,就是4Byte,灯只用到了其中最后的8bit,地址从0x43C00000开始,编号为1的寄存器地址应该是0x43C00004(存储器字长=1B)。(我们的ip核中,reg0用来存放sw读出的数据,而reg1用来从axi总线给led灯传送数据)。参考文献:懒兔子教程
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。