FPGA VIVADO:axi-lite 从机和主机
@TOC在这里插入代码片
前言
协议就不详细讲解了,直接看手册即可。下面主要如何写代码和关键的时序。
此外下面的代码可以直接用于实际工程
一、AXI-LITE 主机
数据转axi lite接口:
读/写数据FIFO缓存
仲裁:写优先
AXI LITE 总线输出
以下是axi-lite主机的代码:
主要思路:
先理清楚下面5个通道,一个一个来看,端口再多理顺了就好了
- AW
- W
- B
- AR
- R
上面是五个通道关键的名称,在写代码时,也按照这五个通道分别命名,就可以批量复制的写代码了!
代码设计思路:
- 采用背靠背的方式写AW通道和W通道
- 当握手完成,代表数据已经被从机捕获
- 使用fifo做批量数据缓存
// 数据转axi lite接口:
// 读/写数据FIFO缓存
// 仲裁:写优先
// AXI LITE 总线输出
module axi_master_driver#(parameter P_AXI_ADDR_WIDTH = 32,parameter P_AXI_DATA_WIDTH = 32
)(input M_AXI_CLK ,input M_AXI_RST_N ,input [P_AXI_ADDR_WIDTH - 1:0] M_SLAVE_BASE_ADDR ,output [P_AXI_ADDR_WIDTH - 1:0] M_AXI_AWADDR ,output [2 : 0] M_AXI_AWPROT ,output M_AXI_AWVALID ,input M_AXI_AWREADY ,output [P_AXI_DATA_WIDTH - 1:0] M_AXI_WDATA ,output [P_AXI_DATA_WIDTH/8 - 1:0] M_AXI_WSTRB , output M_AXI_WVALID , input M_AXI_WREADY , input [1:0] M_AXI_BRESP ,input M_AXI_BVALID ,output M_AXI_BREADY ,output [P_AXI_ADDR_WIDTH - 1:0] M_AXI_ARADDR ,output [2 : 0] M_AXI_ARPROT ,output M_AXI_ARVALID ,input M_AXI_ARREADY ,input [P_AXI_DATA_WIDTH - 1:0] M_AXI_RDATA ,input [1:0] M_AXI_RRESP ,input M_AXI_RVALID ,output M_AXI_RREADY ,input [P_AXI_ADDR_WIDTH - 1:0] i_awaddr ,input [P_AXI_DATA_WIDTH - 1:0] i_wdata ,input i_wdata_vld ,input [P_AXI_ADDR_WIDTH - 1:0] i_raddr ,input i_raddr_vld ,output [P_AXI_DATA_WIDTH - 1:0] o_rdata ,output [1:0] o_rresp ,output o_rdata_vld
);
// -------------------------------------------------------
logic [P_AXI_ADDR_WIDTH - 1:0] lg_M_AXI_AWADDR ;
logic [2 : 0] lg_M_AXI_AWPROT ;
logic lg_M_AXI_AWVALID ;
logic [P_AXI_DATA_WIDTH - 1:0] lg_M_AXI_WDATA ;
logic [P_AXI_DATA_WIDTH/8 - 1:0] lg_M_AXI_WSTRB ;
logic lg_M_AXI_WVALID ;
logic lg_M_AXI_BREADY ;
logic [P_AXI_ADDR_WIDTH - 1:0] lg_M_AXI_ARADDR ;
logic [2 : 0] lg_M_AXI_ARPROT ;
logic lg_M_AXI_ARVALID ;
logic lg_M_AXI_RREADY ;
logic [P_AXI_DATA_WIDTH - 1:0] lg_rdata ;
logic [1:0] lg_rresp ;
logic lg_rdata_vld ;
// --------------------------------------------------------
logic lg_aw_active ;
logic lg_w_active ;
logic lg_b_active ;
logic lg_ar_active ;
logic lg_r_active ;
// --------------------------------------------------------
logic lg_fifo_awaddr_rd_en ;
logic lg_fifo_awaddr_rd_en_d1 ;
logic [P_AXI_ADDR_WIDTH - 1:0] lg_fifo_awaddr_dout ;
logic lg_fifo_awaddr_full ;
logic lg_fifo_awaddr_almost_full ;
logic lg_fifo_awaddr_empty ;
logic lg_fifo_awaddr_valid ;
logic [4:0] lg_fifo_awaddr_data_count ;
logic lg_fifo_aw_prog_full ;logic lg_fifo_wdata_rd_en ;
logic [P_AXI_ADDR_WIDTH - 1:0] lg_fifo_wdata_dout ;
logic lg_fifo_wdata_full ;
logic lg_fifo_wdata_almost_full ;
logic lg_fifo_wdata_empty ;
logic lg_fifo_wdata_valid ;
logic [4:0] lg_fifo_wdata_data_count ;
logic lg_fifo_w_prog_full ;logic lg_fifo_araddr_rd_en ;
logic lg_fifo_araddr_rd_en_d1 ;
logic [P_AXI_ADDR_WIDTH - 1:0] lg_fifo_araddr_dout ;
logic lg_fifo_araddr_full ;
logic lg_fifo_araddr_almost_full ;
logic lg_fifo_araddr_empty ;
logic lg_fifo_araddr_valid ;
logic [4:0] lg_fifo_araddr_data_count ;
logic lg_fifo_ar_prog_full ;
// --------------------------------------------------------
logic lg_wr_run;
logic lg_rd_run;
// --------------------------------------------------------
assign M_AXI_AWADDR = lg_M_AXI_AWADDR ;
assign M_AXI_AWPROT = lg_M_AXI_AWPROT ;
assign M_AXI_AWVALID = lg_M_AXI_AWVALID ;
assign M_AXI_WDATA = lg_M_AXI_WDATA ;
assign M_AXI_WSTRB = lg_M_AXI_WSTRB ;
assign M_AXI_WVALID = lg_M_AXI_WVALID ;
assign M_AXI_BREADY = lg_M_AXI_BREADY ;
assign M_AXI_ARADDR = lg_M_AXI_ARADDR ;
assign M_AXI_ARPROT = lg_M_AXI_ARPROT ;
assign M_AXI_ARVALID = lg_M_AXI_ARVALID ;
assign M_AXI_RREADY = lg_M_AXI_RREADY ;
assign o_rdata = lg_rdata ;
assign o_rresp = lg_rresp ;
assign o_rdata_vld = lg_rdata_vld ;
// --------------------------------------------------------
assign lg_aw_active = M_AXI_AWVALID & M_AXI_AWREADY;
assign lg_w_active = M_AXI_WVALID & M_AXI_WREADY ;
assign lg_b_active = M_AXI_BVALID & M_AXI_BREADY ;
assign lg_ar_active = M_AXI_ARVALID & M_AXI_ARREADY;
assign lg_r_active = M_AXI_RVALID & M_AXI_RREADY ;// ---------------- 读写控制 ----------------------
// 背靠背,数据和地址同时写;
// ==============================
// ==============================
always@(posedge M_AXI_CLK) beginif(M_AXI_RST_N == 1'b0) lg_wr_run <= 'd0;else if(!lg_fifo_awaddr_empty)lg_wr_run <= 'd1;elselg_wr_run <= lg_wr_run;
endalways@(posedge M_AXI_CLK) beginif(M_AXI_RST_N == 1'b0) lg_fifo_awaddr_rd_en <= 'd0;else if(lg_aw_active)lg_fifo_awaddr_rd_en <= 'd0;else if(!lg_fifo_awaddr_empty & !lg_wr_run)lg_fifo_awaddr_rd_en <= 'd1;elselg_fifo_awaddr_rd_en <= 'd0;
endalways@(posedge M_AXI_CLK) beginlg_fifo_awaddr_rd_en_d1 <= lg_fifo_awaddr_rd_en;
endalways@(posedge M_AXI_CLK) beginif(M_AXI_RST_N == 1'b0) lg_rd_run <= 'd0;else if(lg_ar_active == 'd1)lg_rd_run <= 'd0;else if(!lg_fifo_araddr_empty & lg_fifo_awaddr_empty & !lg_wr_run)lg_rd_run <= 'd1;elselg_rd_run <= lg_rd_run;
endalways@(posedge M_AXI_CLK) beginif(M_AXI_RST_N == 1'b0) lg_fifo_araddr_rd_en <= 'd0;else if(!lg_fifo_araddr_empty & lg_fifo_awaddr_empty & !lg_wr_run & !lg_rd_run) lg_fifo_araddr_rd_en <= 'd1;elselg_fifo_araddr_rd_en <= 'd0;
end
always@(posedge M_AXI_CLK) beginlg_fifo_araddr_rd_en_d1 <= lg_fifo_araddr_rd_en;
end
// ================================================
// 写数据、地址FIFO缓存
// ================================================
fifo_axi_master_32x32 fifo_axi_master_aw (.clk (M_AXI_CLK ),.din (i_awaddr ), .wr_en (i_wdata_vld ), .rd_en (lg_fifo_awaddr_rd_en ), .dout (lg_fifo_awaddr_dout ), .full (lg_fifo_awaddr_full ), .almost_full(lg_fifo_awaddr_almost_full ), .empty (lg_fifo_awaddr_empty ), .valid (lg_fifo_awaddr_valid ),.data_count (lg_fifo_awaddr_data_count ),.prog_full (lg_fifo_aw_prog_full )
);fifo_axi_master_32x32 fifo_axi_master_w (.clk (M_AXI_CLK ),.din (i_wdata ), .wr_en (i_wdata_vld ), .rd_en (lg_fifo_awaddr_rd_en ), .dout (lg_fifo_wdata_dout ),.full (lg_fifo_wdata_full ),.almost_full(lg_fifo_wdata_almost_full ),.empty (lg_fifo_wdata_empty ),.valid (lg_fifo_wdata_valid ),.data_count (lg_fifo_wdata_data_count ),.prog_full (lg_fifo_w_prog_full )
);fifo_axi_master_32x32 fifo_axi_master_ar (.clk (M_AXI_CLK ),.din (i_raddr ), .wr_en (i_raddr_vld ), .rd_en (lg_fifo_araddr_rd_en ), .dout (lg_fifo_araddr_dout ),.full (lg_fifo_araddr_full ),.almost_full(lg_fifo_araddr_almost_full ),.empty (lg_fifo_araddr_empty ),.valid (lg_fifo_araddr_valid ),.data_count (lg_fifo_araddr_data_count ),.prog_full (lg_fifo_ar_prog_full )
);// ----------- axi 时序 ------------------ always@(posedge M_AXI_CLK) beginif(!M_AXI_RST_N) beginlg_M_AXI_AWADDR <= 'd0;lg_M_AXI_AWPROT <= 'd0;lg_M_AXI_AWVALID <= 'd0; endelse if(lg_aw_active) beginlg_M_AXI_AWADDR <= 'd0;lg_M_AXI_AWPROT <= 'd0;lg_M_AXI_AWVALID <= 'd0; end // 这里多打一拍的原因是因为fifo输出要延迟一拍else if(lg_fifo_awaddr_rd_en_d1) beginlg_M_AXI_AWADDR <= lg_fifo_awaddr_dout;lg_M_AXI_AWPROT <= 'd0;lg_M_AXI_AWVALID <= 'd1; endelse beginlg_M_AXI_AWADDR <= lg_M_AXI_AWADDR ;lg_M_AXI_AWPROT <= lg_M_AXI_AWPROT ;lg_M_AXI_AWVALID <= lg_M_AXI_AWVALID ; end
endalways@(posedge M_AXI_CLK) beginif(!M_AXI_RST_N) beginlg_M_AXI_WDATA <= 'd0;lg_M_AXI_WSTRB <= 'd0; lg_M_AXI_WVALID <= 'd0;endelse if(lg_w_active) beginlg_M_AXI_WDATA <= 'd0;lg_M_AXI_WSTRB <= 'd0; lg_M_AXI_WVALID <= 'd0;end else if(lg_fifo_awaddr_rd_en_d1) beginlg_M_AXI_WDATA <= lg_fifo_wdata_dout;lg_M_AXI_WSTRB <= 'hF ; lg_M_AXI_WVALID <= 'd1 ;endelse beginlg_M_AXI_WDATA <= lg_M_AXI_WDATA ;lg_M_AXI_WSTRB <= lg_M_AXI_WSTRB ;lg_M_AXI_WVALID <= lg_M_AXI_WVALID ; end
endalways@(posedge M_AXI_CLK) beginif(!M_AXI_RST_N) beginlg_M_AXI_BREADY <='d0;endelse if(lg_b_active) beginlg_M_AXI_BREADY <='d0; end else if(lg_w_active) beginlg_M_AXI_BREADY <='d1;endelse beginlg_M_AXI_BREADY <=lg_M_AXI_BREADY;end
endalways@(posedge M_AXI_CLK) beginif(!M_AXI_RST_N) beginlg_M_AXI_ARADDR <= 'd0;lg_M_AXI_ARPROT <= 'd0;lg_M_AXI_ARVALID <= 'd0; endelse if(lg_ar_active) beginlg_M_AXI_ARADDR <= 'd0;lg_M_AXI_ARPROT <= 'd0;lg_M_AXI_ARVALID <= 'd0; end else if(lg_fifo_araddr_rd_en_d1) beginlg_M_AXI_ARADDR <= lg_fifo_araddr_dout;lg_M_AXI_ARPROT <= 'd0;lg_M_AXI_ARVALID <= 'd1; endelse beginlg_M_AXI_ARADDR <= lg_M_AXI_ARADDR ;lg_M_AXI_ARPROT <= lg_M_AXI_ARPROT ;lg_M_AXI_ARVALID <= lg_M_AXI_ARVALID ; end
endalways@(posedge M_AXI_CLK) beginif(!M_AXI_RST_N) beginlg_M_AXI_RREADY <='d0;endelse if(lg_r_active) beginlg_M_AXI_RREADY <='d0; end else if(lg_ar_active) beginlg_M_AXI_RREADY <='d1;endelse beginlg_M_AXI_RREADY <=lg_M_AXI_RREADY;end
endalways@(posedge M_AXI_CLK) beginlg_rdata <= M_AXI_RDATA ;lg_rresp <= M_AXI_RRESP ;lg_rdata_vld <= M_AXI_RVALID ;
endendmodule
TB如下:
`timescale 1ns / 1psmodule tb_axi_master();logic clk=0;
logic rst_n=0;initial begin#1000;rst_n = 1;
endalways #(1000/100/2) clk = ~clk;// ==================================================
// ==================================================
// ==================================================
parameter P_AXI_ADDR_WIDTH =32;
parameter P_AXI_DATA_WIDTH =32;
logic M_AXI_CLK ;
logic M_AXI_RST_N ;
logic [P_AXI_ADDR_WIDTH - 1:0] M_SLAVE_BASE_ADDR ;
logic [P_AXI_ADDR_WIDTH - 1:0] M_AXI_AWADDR ;
logic [2 : 0] M_AXI_AWPROT ;
logic M_AXI_AWVALID ;
logic M_AXI_AWREADY ;
logic [P_AXI_DATA_WIDTH - 1:0] M_AXI_WDATA ;
logic [P_AXI_DATA_WIDTH/8 - 1:0]M_AXI_WSTRB ;
logic M_AXI_WVALID ;
logic M_AXI_WREADY ;
logic [1:0] M_AXI_BRESP ;
logic M_AXI_BVALID ;
logic M_AXI_BREADY ;
logic [P_AXI_ADDR_WIDTH - 1:0] M_AXI_ARADDR ;
logic [2 : 0] M_AXI_ARPROT ;
logic M_AXI_ARVALID ;
logic M_AXI_ARREADY ;
logic [P_AXI_DATA_WIDTH - 1:0] M_AXI_RDATA ;
logic [1:0] M_AXI_RRESP ;
logic M_AXI_RVALID ;
logic M_AXI_RREADY ;
logic [P_AXI_ADDR_WIDTH - 1:0] lg_i_waddr ;
logic [P_AXI_DATA_WIDTH - 1:0] lg_i_wdata ;
logic lg_i_wdata_vld ;
logic [P_AXI_ADDR_WIDTH - 1:0] lg_i_raddr ;
logic lg_i_raddr_vld ;
logic [P_AXI_DATA_WIDTH - 1:0] lg_o_rdata ;
logic [1:0] lg_o_rresp ;
logic lg_o_rdata_vld ;axi_master_driver#(
.P_AXI_ADDR_WIDTH(P_AXI_ADDR_WIDTH),
.P_AXI_DATA_WIDTH(P_AXI_DATA_WIDTH)
)
axi_master_driver(.M_AXI_CLK (clk ), .M_AXI_RST_N (rst_n ), .M_SLAVE_BASE_ADDR (32'd0 ), .M_AXI_AWADDR (M_AXI_AWADDR ), .M_AXI_AWPROT (M_AXI_AWPROT ), .M_AXI_AWVALID (M_AXI_AWVALID ), .M_AXI_AWREADY (M_AXI_AWREADY ), .M_AXI_WDATA (M_AXI_WDATA ), .M_AXI_WSTRB (M_AXI_WSTRB ), .M_AXI_WVALID (M_AXI_WVALID ), .M_AXI_WREADY (M_AXI_WREADY ), .M_AXI_BRESP (M_AXI_BRESP ), .M_AXI_BVALID (M_AXI_BVALID ), .M_AXI_BREADY (M_AXI_BREADY ), .M_AXI_ARADDR (M_AXI_ARADDR ), .M_AXI_ARPROT (M_AXI_ARPROT ), .M_AXI_ARVALID (M_AXI_ARVALID ), .M_AXI_ARREADY (M_AXI_ARREADY ), .M_AXI_RDATA (M_AXI_RDATA ), .M_AXI_RRESP (M_AXI_RRESP ), .M_AXI_RVALID (M_AXI_RVALID ), .M_AXI_RREADY (M_AXI_RREADY ), .i_awaddr (lg_i_waddr ), .i_wdata (lg_i_wdata ), .i_wdata_vld (lg_i_wdata_vld ), .i_raddr (lg_i_raddr ), .i_raddr_vld (lg_i_raddr_vld ), .o_rdata (lg_o_rdata ), .o_rresp (lg_o_rresp ), .o_rdata_vld (lg_o_rdata_vld )
);axi_slaver_v1_0_S00_AXI # ( .C_S_AXI_DATA_WIDTH(32),.C_S_AXI_ADDR_WIDTH(32)) axi_slaver_v1_0_S00_AXI_inst (.S_AXI_ACLK (clk ), .S_AXI_ARESETN(rst_n ),.S_AXI_AWADDR (M_AXI_AWADDR ), .S_AXI_AWPROT (M_AXI_AWPROT ),.S_AXI_AWVALID(M_AXI_AWVALID ),.S_AXI_AWREADY(M_AXI_AWREADY ),.S_AXI_WDATA (M_AXI_WDATA ),.S_AXI_WSTRB (M_AXI_WSTRB ),.S_AXI_WVALID (M_AXI_WVALID ),.S_AXI_WREADY (M_AXI_WREADY ),.S_AXI_BRESP (M_AXI_BRESP ),.S_AXI_BVALID (M_AXI_BVALID ),.S_AXI_BREADY (M_AXI_BREADY ),.S_AXI_ARADDR (M_AXI_ARADDR ),.S_AXI_ARPROT (M_AXI_ARPROT ),.S_AXI_ARVALID(M_AXI_ARVALID ),.S_AXI_ARREADY(M_AXI_ARREADY ),.S_AXI_RDATA (M_AXI_RDATA ),.S_AXI_RRESP (M_AXI_RRESP ),.S_AXI_RVALID (M_AXI_RVALID ),.S_AXI_RREADY (M_AXI_RREADY ));
logic [31:0] data;
initial beginlg_i_waddr =0;lg_i_wdata =0;lg_i_wdata_vld =0;lg_i_raddr =0;lg_i_raddr_vld =0;data =0;wait(rst_n);write_task(36,'h0000_0001);#100;write_task(36,'h0000_0000);write_task(12,'h5555_FFFF);write_task(16,'h5555_FFFF);write_task(20,'h5555_FFFF);rd_task('d24);rd_task('d28);write_task(32,'h5555_6666);rd_task('d32);
end// ====================== task ==============================task write_task(input [31:0] awaddr,input [31:0] wdata);begin:write_data@(posedge clk) beginlg_i_waddr <= 'd0;lg_i_wdata <= 'd0;lg_i_wdata_vld <= 'd0;end@(posedge clk) beginlg_i_waddr <= awaddr;lg_i_wdata <= wdata;lg_i_wdata_vld <= 'd1;end@(posedge clk) beginlg_i_waddr <= 'd0;lg_i_wdata <= 'd0;lg_i_wdata_vld <= 'd0;endend
endtask task rd_task(input [31:0] araddr);begin:rd_data@(posedge clk) beginlg_i_raddr <= 'd0;lg_i_raddr_vld <= 'd0;end@(posedge clk) beginlg_i_raddr <= araddr;lg_i_raddr_vld <= 'd1;end@(posedge clk) beginlg_i_raddr <= 'd0;lg_i_raddr_vld <= 'd0;endend
endtask
endmodule
这里有一个写代码的技巧:
如果想实现一个时序如下:只想在run开始后,拉高一个使能一个周期
那么,可以这么写代码:
// (!lg_fifo_awaddr_empty)最为run的触发信号,en想拉高一拍,则en的触发信号使用run的触发信号+run的取反 =》 可以得到en和run同时拉高,且en只拉高一拍
always@(posedge M_AXI_CLK) beginif(M_AXI_RST_N == 1'b0) lg_wr_run <= 'd0;else if(!lg_fifo_awaddr_empty)lg_wr_run <= 'd1;elselg_wr_run <= lg_wr_run;
endalways@(posedge M_AXI_CLK) beginif(M_AXI_RST_N == 1'b0) lg_fifo_awaddr_rd_en <= 'd0;else if(lg_aw_active)lg_fifo_awaddr_rd_en <= 'd0;else if(!lg_fifo_awaddr_empty & !lg_wr_run)lg_fifo_awaddr_rd_en <= 'd1;elselg_fifo_awaddr_rd_en <= 'd0;
end
1.1 FIFO
这里再做一个FIFO的扩展,FIFO用的确实很多,这里再对FIFO的时序做一个巩固。
我这里FIFO的IP配置如下:
例化如下:
fifo_axi_master_32x32 fifo_axi_master_aw (.clk (M_AXI_CLK ),.din (i_awaddr ), .wr_en (i_wdata_vld ), .rd_en (lg_fifo_awaddr_rd_en ), .dout (lg_fifo_awaddr_dout ), .full (lg_fifo_awaddr_full ), .almost_full(lg_fifo_awaddr_almost_full ), .empty (lg_fifo_awaddr_empty ), .valid (lg_fifo_awaddr_valid ),.data_count (lg_fifo_awaddr_data_count ),.prog_full (lg_fifo_aw_prog_full )
);
在这个代码运行过程中,针对FIFO信号的各个关键时序进行说明;
从时序上看,当写入或者读出数据,empty count dout都是在下一个时钟周期进行更新
接着,我尝试只写不读,看看pfull和afull和full的关系(我这里设置fifo的深度为32),时序如下:
我这里使用count计数是和数据的写入是同步的,当采集到31时(fifo里面已经有了31个数据),且在写数据,那么此时full拉高,下一个时钟周期,才能读到full,这样会存在反压失败的情况。
对于afull和pfull(我这设置为29),分别为当写为31个数据时afull会拉高(采样到vld拉高之后拉高,即会延迟一拍),当写入29个数据时pfull会拉高(采样到vld拉高之后拉高,即会延迟一拍).
关于反压不丢数,可以看我另外一篇博客:
FPGA FIFO系列 - FIFO使用中需要注意的若干问题
二 AXI-LITE 从机
关于从机,可以直接用VIVADO提供的代码:
只需要关注下axi_araddr和axi_awaddr两个信号里面地址需要修改一下就好了。此外对于外部的写入和读取,就按照需要的进行修改即可
`timescale 1 ns / 1 psmodule axi_slaver_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 busparameter integer C_S_AXI_DATA_WIDTH = 32,// Width of S_AXI address busparameter integer C_S_AXI_ADDR_WIDTH = 8)(// Users to add ports here// User ports ends// Do not modify the ports beyond this line// Global Clock Signalinput wire S_AXI_ACLK,// Global Reset Signal. This Signal is Active LOWinput 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 signalsreg [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 = 5;//----------------------------------------------//-- Signals for user logic register space example//------------------------------------------------//-- Number of Slave Registers 64reg [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;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg4;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg5;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg6;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg7;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg8;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg9;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg10;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg11;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg12;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg13;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg14;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg15;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg16;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg17;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg18;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg19;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg20;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg21;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg22;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg23;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg24;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg25;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg26;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg27;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg28;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg29;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg30;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg31;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg32;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg33;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg34;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg35;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg36;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg37;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg38;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg39;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg40;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg41;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg42;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg43;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg44;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg45;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg46;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg47;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg48;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg49;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg50;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg51;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg52;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg53;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg54;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg55;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg56;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg57;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg58;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg59;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg60;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg61;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg62;reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg63;wire slv_reg_rden;wire slv_reg_wren;reg [C_S_AXI_DATA_WIDTH-1:0] reg_data_out;integer byte_index;reg aw_en;// I/O Connections assignmentsassign 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 = axi_rdata;assign S_AXI_RRESP = axi_rresp;assign S_AXI_RVALID = axi_rvalid;// Implement axi_awready generation// axi_awready is asserted for one S_AXI_ACLK clock cycle when both// S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is// de-asserted when reset is low.
// 严格1对1关系,所以需要aw和w通道同时拉高(AXI_FULL因为是突发传输,所以就不会对齐(只发一个地址,后面都是突发递增))// 给出ready,其实这时已经采集到了;主机实在ready之后才释放vldalways @( posedge S_AXI_ACLK )beginif ( S_AXI_ARESETN == 1'b0 )beginaxi_awready <= 1'b0;aw_en <= 1'b1;end elsebegin // 防止连续写两个地址,因此引入 aw_en; aw_en 决定当前是否写完,知道响应握手成功if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en) // 拉高一个周期的方式,前置拉高条件+拉高后取反条件;拉高时机就是和采集和条件是同一拍begin// slave is ready to accept write address when // there is a valid write address and write data// on the write address and data bus. This design // expects no outstanding transactions. axi_awready <= 1'b1;aw_en <= 1'b0;endelse if (S_AXI_BREADY && axi_bvalid)beginaw_en <= 1'b1;axi_awready <= 1'b0;endelse beginaxi_awready <= 1'b0;endend end // Implement axi_awaddr latching// This process is used to latch the address when both // S_AXI_AWVALID and S_AXI_WVALID are valid.
// 这里对AWaddr进行寄存always @( posedge S_AXI_ACLK )beginif ( S_AXI_ARESETN == 1'b0 )beginaxi_awaddr <= 0;end elsebegin if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en)begin// Write Address latching axi_awaddr <= S_AXI_AWADDR;endend end // Implement axi_wready generation// axi_wready is asserted for one S_AXI_ACLK clock cycle when both// S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is // de-asserted when reset is low.
// 类似的对wready进行同步给出always @( posedge S_AXI_ACLK )beginif ( S_AXI_ARESETN == 1'b0 )beginaxi_wready <= 1'b0;end elsebegin if (~axi_wready && S_AXI_WVALID && S_AXI_AWVALID && aw_en )begin// slave is ready to accept write data when // there is a valid write address and write data// on the write address and data bus. This design // expects no outstanding transactions. axi_wready <= 1'b1;endelsebeginaxi_wready <= 1'b0;endend end // Implement memory mapped register select and write logic generation// The write data is accepted and written to memory mapped registers when// axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to// select byte enables of slave registers while writing.// These registers are cleared when reset (active low) is applied.// Slave register write enable is asserted when valid address and data are available// and the slave is ready to accept the write address and write data.assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID;always @( posedge S_AXI_ACLK )beginif ( S_AXI_ARESETN == 1'b0 )beginslv_reg0 <= 0;slv_reg1 <= 0;slv_reg2 <= 0;slv_reg3 <= 0;slv_reg4 <= 0;slv_reg5 <= 0;slv_reg6 <= 0;slv_reg7 <= 0;slv_reg8 <= 0;slv_reg9 <= 0;slv_reg10 <= 0;slv_reg11 <= 0;slv_reg12 <= 0;slv_reg13 <= 0;slv_reg14 <= 0;slv_reg15 <= 0;slv_reg16 <= 0;slv_reg17 <= 0;slv_reg18 <= 0;slv_reg19 <= 0;slv_reg20 <= 0;slv_reg21 <= 0;slv_reg22 <= 0;slv_reg23 <= 0;slv_reg24 <= 0;slv_reg25 <= 0;slv_reg26 <= 0;slv_reg27 <= 0;slv_reg28 <= 0;slv_reg29 <= 0;slv_reg30 <= 0;slv_reg31 <= 0;slv_reg32 <= 0;slv_reg33 <= 0;slv_reg34 <= 0;slv_reg35 <= 0;slv_reg36 <= 0;slv_reg37 <= 0;slv_reg38 <= 0;slv_reg39 <= 0;slv_reg40 <= 0;slv_reg41 <= 0;slv_reg42 <= 0;slv_reg43 <= 0;slv_reg44 <= 0;slv_reg45 <= 0;slv_reg46 <= 0;slv_reg47 <= 0;slv_reg48 <= 0;slv_reg49 <= 0;slv_reg50 <= 0;slv_reg51 <= 0;slv_reg52 <= 0;slv_reg53 <= 0;slv_reg54 <= 0;slv_reg55 <= 0;slv_reg56 <= 0;slv_reg57 <= 0;slv_reg58 <= 0;slv_reg59 <= 0;slv_reg60 <= 0;slv_reg61 <= 0;slv_reg62 <= 0;slv_reg63 <= 0;end else beginif (slv_reg_wren)begincase ( axi_awaddr[5:0] )6'h00:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 0slv_reg0[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h01:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 1slv_reg1[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h02:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 2slv_reg2[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h03:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 3slv_reg3[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h04:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 4slv_reg4[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h05:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 5slv_reg5[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h06:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 6slv_reg6[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h07:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 7slv_reg7[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h08:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 8slv_reg8[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h09:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 9slv_reg9[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h0A:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 10slv_reg10[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h0B:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 11slv_reg11[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h0C:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 12slv_reg12[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h0D:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 13slv_reg13[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h0E:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 14slv_reg14[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h0F:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 15slv_reg15[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h10:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 16slv_reg16[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h11:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 17slv_reg17[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h12:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 18slv_reg18[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h13:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 19slv_reg19[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h14:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 20slv_reg20[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h15:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 21slv_reg21[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h16:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 22slv_reg22[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h17:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 23slv_reg23[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h18:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 24slv_reg24[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h19:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 25slv_reg25[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h1A:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 26slv_reg26[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h1B:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 27slv_reg27[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h1C:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 28slv_reg28[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h1D:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 29slv_reg29[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h1E:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 30slv_reg30[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h1F:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 31slv_reg31[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h20:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 32slv_reg32[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h21:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 33slv_reg33[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h22:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 34slv_reg34[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h23:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 35slv_reg35[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h24:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 36slv_reg36[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h25:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 37slv_reg37[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h26:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 38slv_reg38[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h27:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 39slv_reg39[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h28:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 40slv_reg40[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h29:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 41slv_reg41[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h2A:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 42slv_reg42[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h2B:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 43slv_reg43[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h2C:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 44slv_reg44[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h2D:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 45slv_reg45[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h2E:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 46slv_reg46[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h2F:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 47slv_reg47[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h30:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 48slv_reg48[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h31:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 49slv_reg49[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h32:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 50slv_reg50[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h33:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 51slv_reg51[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h34:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 52slv_reg52[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h35:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 53slv_reg53[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h36:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 54slv_reg54[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h37:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 55slv_reg55[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h38:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 56slv_reg56[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h39:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 57slv_reg57[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h3A:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 58slv_reg58[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h3B:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 59slv_reg59[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h3C:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 60slv_reg60[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h3D:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 61slv_reg61[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h3E:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 62slv_reg62[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end 6'h3F:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 63slv_reg63[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end default : beginslv_reg0 <= slv_reg0;slv_reg1 <= slv_reg1;slv_reg2 <= slv_reg2;slv_reg3 <= slv_reg3;slv_reg4 <= slv_reg4;slv_reg5 <= slv_reg5;slv_reg6 <= slv_reg6;slv_reg7 <= slv_reg7;slv_reg8 <= slv_reg8;slv_reg9 <= slv_reg9;slv_reg10 <= slv_reg10;slv_reg11 <= slv_reg11;slv_reg12 <= slv_reg12;slv_reg13 <= slv_reg13;slv_reg14 <= slv_reg14;slv_reg15 <= slv_reg15;slv_reg16 <= slv_reg16;slv_reg17 <= slv_reg17;slv_reg18 <= slv_reg18;slv_reg19 <= slv_reg19;slv_reg20 <= slv_reg20;slv_reg21 <= slv_reg21;slv_reg22 <= slv_reg22;slv_reg23 <= slv_reg23;slv_reg24 <= slv_reg24;slv_reg25 <= slv_reg25;slv_reg26 <= slv_reg26;slv_reg27 <= slv_reg27;slv_reg28 <= slv_reg28;slv_reg29 <= slv_reg29;slv_reg30 <= slv_reg30;slv_reg31 <= slv_reg31;slv_reg32 <= slv_reg32;slv_reg33 <= slv_reg33;slv_reg34 <= slv_reg34;slv_reg35 <= slv_reg35;slv_reg36 <= slv_reg36;slv_reg37 <= slv_reg37;slv_reg38 <= slv_reg38;slv_reg39 <= slv_reg39;slv_reg40 <= slv_reg40;slv_reg41 <= slv_reg41;slv_reg42 <= slv_reg42;slv_reg43 <= slv_reg43;slv_reg44 <= slv_reg44;slv_reg45 <= slv_reg45;slv_reg46 <= slv_reg46;slv_reg47 <= slv_reg47;slv_reg48 <= slv_reg48;slv_reg49 <= slv_reg49;slv_reg50 <= slv_reg50;slv_reg51 <= slv_reg51;slv_reg52 <= slv_reg52;slv_reg53 <= slv_reg53;slv_reg54 <= slv_reg54;slv_reg55 <= slv_reg55;slv_reg56 <= slv_reg56;slv_reg57 <= slv_reg57;slv_reg58 <= slv_reg58;slv_reg59 <= slv_reg59;slv_reg60 <= slv_reg60;slv_reg61 <= slv_reg61;slv_reg62 <= slv_reg62;slv_reg63 <= slv_reg63;endendcaseendendend // Implement write response logic generation// The write response and response valid signals are asserted by the slave // when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. // This marks the acceptance of address and indicates the status of // write transaction.always @( posedge S_AXI_ACLK )beginif ( S_AXI_ARESETN == 1'b0 )beginaxi_bvalid <= 0;axi_bresp <= 2'b0;end elsebegin if (axi_awready && S_AXI_AWVALID && ~axi_bvalid && axi_wready && S_AXI_WVALID)begin// indicates a valid write response is availableaxi_bvalid <= 1'b1;axi_bresp <= 2'b0; // 'OKAY' response end // work error responses in futureelsebeginif (S_AXI_BREADY && axi_bvalid) //check if bready is asserted while bvalid is high) //(there is a possibility that bready is always asserted high) beginaxi_bvalid <= 1'b0; end endendend // Implement axi_arready generation// axi_arready is asserted for one S_AXI_ACLK clock cycle when// S_AXI_ARVALID is asserted. axi_awready is // de-asserted when reset (active low) is asserted. // The read address is also latched when S_AXI_ARVALID is // asserted. axi_araddr is reset to zero on reset assertion.always @( posedge S_AXI_ACLK )beginif ( S_AXI_ARESETN == 1'b0 )beginaxi_arready <= 1'b0;axi_araddr <= 32'b0;end elsebegin if (~axi_arready && S_AXI_ARVALID)begin// indicates that the slave has acceped the valid read addressaxi_arready <= 1'b1;// Read address latchingaxi_araddr <= S_AXI_ARADDR;endelsebeginaxi_arready <= 1'b0;endend end // Implement axi_arvalid generation// axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both // S_AXI_ARVALID and axi_arready are asserted. The slave registers // data are available on the axi_rdata bus at this instance. The // assertion of axi_rvalid marks the validity of read data on the // bus and axi_rresp indicates the status of read transaction.axi_rvalid // is deasserted on reset (active low). axi_rresp and axi_rdata are // cleared to zero on reset (active low). always @( posedge S_AXI_ACLK )beginif ( S_AXI_ARESETN == 1'b0 )beginaxi_rvalid <= 0;axi_rresp <= 0;end elsebegin if (axi_arready && S_AXI_ARVALID && ~axi_rvalid)begin// Valid read data is available at the read data busaxi_rvalid <= 1'b1;axi_rresp <= 2'b0; // 'OKAY' responseend else if (axi_rvalid && S_AXI_RREADY)begin// Read data is accepted by the masteraxi_rvalid <= 1'b0;end endend // Implement memory mapped register select and read logic generation// Slave register read enable is asserted when valid address is available// and the slave is ready to accept the read address.assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid;always @(*)begin// Address decoding for reading registerscase ( axi_araddr[5:0] )6'h00 : reg_data_out <= slv_reg0;6'h01 : reg_data_out <= slv_reg1;6'h02 : reg_data_out <= slv_reg2;6'h03 : reg_data_out <= slv_reg3;6'h04 : reg_data_out <= slv_reg4;6'h05 : reg_data_out <= slv_reg5;6'h06 : reg_data_out <= slv_reg6;6'h07 : reg_data_out <= slv_reg7;6'h08 : reg_data_out <= slv_reg8;6'h09 : reg_data_out <= slv_reg9;6'h0A : reg_data_out <= slv_reg10;6'h0B : reg_data_out <= slv_reg11;6'h0C : reg_data_out <= slv_reg12;6'h0D : reg_data_out <= slv_reg13;6'h0E : reg_data_out <= slv_reg14;6'h0F : reg_data_out <= slv_reg15;6'h10 : reg_data_out <= slv_reg16;6'h11 : reg_data_out <= slv_reg17;6'h12 : reg_data_out <= slv_reg18;6'h13 : reg_data_out <= slv_reg19;6'h14 : reg_data_out <= slv_reg20;6'h15 : reg_data_out <= slv_reg21;6'h16 : reg_data_out <= slv_reg22;6'h17 : reg_data_out <= slv_reg23;6'h18 : reg_data_out <= slv_reg24;6'h19 : reg_data_out <= slv_reg25;6'h1A : reg_data_out <= slv_reg26;6'h1B : reg_data_out <= slv_reg27;6'h1C : reg_data_out <= slv_reg28;6'h1D : reg_data_out <= slv_reg29;6'h1E : reg_data_out <= slv_reg30;6'h1F : reg_data_out <= slv_reg31;6'h20 : reg_data_out <= slv_reg32;6'h21 : reg_data_out <= slv_reg33;6'h22 : reg_data_out <= slv_reg34;6'h23 : reg_data_out <= slv_reg35;6'h24 : reg_data_out <= slv_reg36;6'h25 : reg_data_out <= slv_reg37;6'h26 : reg_data_out <= slv_reg38;6'h27 : reg_data_out <= slv_reg39;6'h28 : reg_data_out <= slv_reg40;6'h29 : reg_data_out <= slv_reg41;6'h2A : reg_data_out <= slv_reg42;6'h2B : reg_data_out <= slv_reg43;6'h2C : reg_data_out <= slv_reg44;6'h2D : reg_data_out <= slv_reg45;6'h2E : reg_data_out <= slv_reg46;6'h2F : reg_data_out <= slv_reg47;6'h30 : reg_data_out <= slv_reg48;6'h31 : reg_data_out <= slv_reg49;6'h32 : reg_data_out <= slv_reg50;6'h33 : reg_data_out <= slv_reg51;6'h34 : reg_data_out <= slv_reg52;6'h35 : reg_data_out <= slv_reg53;6'h36 : reg_data_out <= slv_reg54;6'h37 : reg_data_out <= slv_reg55;6'h38 : reg_data_out <= slv_reg56;6'h39 : reg_data_out <= slv_reg57;6'h3A : reg_data_out <= slv_reg58;6'h3B : reg_data_out <= slv_reg59;6'h3C : reg_data_out <= slv_reg60;6'h3D : reg_data_out <= slv_reg61;6'h3E : reg_data_out <= slv_reg62;6'h3F : reg_data_out <= slv_reg63;default : reg_data_out <= 0;endcaseend// Output register or memory read dataalways @( posedge S_AXI_ACLK )beginif ( S_AXI_ARESETN == 1'b0 )beginaxi_rdata <= 0;end elsebegin // When there is a valid read address (S_AXI_ARVALID) with // acceptance of read address by the slave (axi_arready), // output the read dada if (slv_reg_rden)beginaxi_rdata <= reg_data_out; // register read dataend endend // Add user logic here// User logic endsendmodule
工程链接:
工程