基于7A50T FPGA开发套件的工业通信管理机设计(四)自定义IP封装
使用AXI总线对寄存器进行读写的时序也不是很复杂,这里同样以MDCR寄存器为例,讲解AXI总线读写该寄存器的实现方式。
写MDCR寄存器
要实现写寄存器,需要有一个写请求信号,写请求信号的产生方式如下:
wire slv_reg_wren = s00_axi_wready && s00_axi_wvalid && s00_axi_awready && s00_axi_awvalid;
即当s00_axi_awready,s00_axi_awvalid,s00_axi_wready,s00_axi_wvalid有效时,待写入的数据将会被写入s00_axi_awaddr指定的寄存器中,同时,s00_axi_wstrb控制32位总线上,具体哪几个字节被写入。以下为写入数据到寄存器的代码。
读MDCR寄存器
要实现读寄存器,需要有一个写请求信号,写请求信号的产生方式如下
wire slv_reg_rden = s00_axi_arready & s00_axi_arvalid & ~s00_axi_rvalid;
按照以上方式完成所有寄存器的读写逻辑的编写,就实现了通过AXI总线操作自定义IP的所有逻辑,然后就可以通过MicroBlaze处理器来实现控制数据的收发了。
接下来,将在Vivado中完成对本自定义IP的封装,使本IP能够被MicroBlaze处理器直接读写控制。
`timescale 1 ns / 1 ps
module modbus_ip_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 = 10,
// Parameters of Axi Slave Bus Interface S_AXI_INTR
parameter integer C_S_AXI_INTR_DATA_WIDTH = 32,
parameter integer C_S_AXI_INTR_ADDR_WIDTH = 5,
parameter integer C_NUM_OF_INTR = 1,
parameter C_INTR_SENSITIVITY = 32'hFFFFFFFF,
parameter C_INTR_ACTIVE_STATE = 32'hFFFFFFFF,
parameter integer C_IRQ_SENSITIVITY = 1,
parameter integer C_IRQ_ACTIVE_STATE = 1
)
(
// Users to add ports here
// 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
modbus_ip modbus_ip(
.S_AXI_ACLK(s00_axi_aclk),
.S_AXI_ARESETN(s00_axi_aresetn),
.s00_axi_awaddr(s00_axi_awaddr),//写地址
.s00_axi_awprot(s00_axi_awprot),//写通道保护类型。这个信号表示该事务的特权和安全级别,并确定是否该事务是一个数据存取或指令的访问
.s00_axi_awvalid(s00_axi_awvalid),//写地址有效。这个信号表示该主信令有效的写地址和控制信息
.s00_axi_awready(s00_axi_awready),//写地址准备好了。该信号指示从器件准备好接受一个地址和相关联的控制信号
.s00_axi_wdata(s00_axi_wdata),//写数据
.s00_axi_wstrb(s00_axi_wstrb),//写选通。这个信号表明该字节通道持有效数据。每一bit对应 WDATA一个字节
.s00_axi_wvalid(s00_axi_wvalid),//写有效。这个信号表示有效的写数据和选通信号都可用
.s00_axi_wready(s00_axi_wready),//写准备好了。该信号指示从器件可以接受写数据
.s00_axi_bresp(s00_axi_bresp),//写响应。这个信号表示写事务处理的状态
.s00_axi_bvalid(s00_axi_bvalid),//写响应有效。此信号表明写命令的有效写入响应
.s00_axi_bready(s00_axi_bready),//响应准备。该信号指示在主主机可以接受一个响应信号
.s00_axi_araddr(s00_axi_araddr),//读地址
.s00_axi_arprot(s00_axi_arprot),//保护类型。这个信号表示该事务的特权和安全级别,并确定是否该事务是一个数据存取或指令的访问
.s00_axi_arvalid(s00_axi_arvalid),//读地址有效。此信号表明该信道此时能有效读出地址和控制信息
.s00_axi_arready(s00_axi_arready),//读地址准备好了。该信号指示从器件准备好接受一个地址和相关联的控制信号
.s00_axi_rdata(s00_axi_rdata),//读数据
.s00_axi_rresp(s00_axi_rresp),//读取响应。这个信号表明读事务处理的状态
.s00_axi_rvalid(s00_axi_rvalid),//读数据有效。此信号表明该信道此时能有效读出数据
.s00_axi_rready(s00_axi_rready),//读数据准备好了。该信号指示从器件准备好接收数据
.CPU_IRQ(),
.Rs232_Tx(Rs232_Tx),
.Rs232_Rx(Rs232_Rx),
.Rs232_Dir(Rs232_Dir)
);
endmodule
不错 跟着小编学习一下