关于AXI Lite的问题
为什么我写的AXI Lite在使用AXI Lite Slave IP的时候可以正常握手,但是在使用AXI Lite接口的BRAM的时候就没有办法正常握手了,我找不到问题在哪里,希望有大佬解答一下
使用AXI Lite Slave IP正常握手的样子

使用AXI Lite Slave IP正常握手的样子

这个是我的BRAM IP配置






TOP层源码
`timescale 1ns / 1ps
module top
#(
parameter USER_ADDR_WIDTH = 32 ,
parameter USER_DATA_WIDTH = 32 ,
parameter AXI_ADDR_WIDTH = 32 ,
parameter AXI_DATA_WIDTH = 32
)
(
input wire sys_rst_n ,
input wire user_w_clk ,
input wire user_r_clk ,
input wire axi_clk ,
input wire user_w_en ,
input wire [USER_ADDR_WIDTH-1 : 0] user_w_addr ,
input wire [USER_DATA_WIDTH-1 : 0] user_w_data ,
input wire user_w_ready ,
input wire user_r_en ,
input wire [USER_ADDR_WIDTH-1 : 0] user_r_addr ,
output wire [USER_DATA_WIDTH-1 : 0] user_r_data ,
output wire user_r_data_vid
);
wire [32-1:0] m_axi_aw_addr ;
wire m_axi_aw_vid ;
wire m_axi_aw_ready ;
wire [2:0] m_axi_aw_port ;
wire [32-1:0] m_axi_w_data ;
wire m_axi_w_vid ;
wire m_axi_w_ready ;
wire [3:0] m_axi_w_strb ;
wire m_axi_b_resp ;
wire m_axi_b_vid ;
wire m_axi_b_ready ;
wire wr_data_fifo_err;
wire wr_cmd_fifo_err ;
wire [32-1:0] m_axi_ar_addr ;
wire m_axi_ar_vid ;
wire m_axi_ar_ready ;
wire [2:0] m_axi_ar_port ;
wire [32-1:0] m_axi_r_data ;
wire m_axi_r_vid ;
wire m_axi_r_ready ;
wire m_axi_r_resp ;
axi_lite_write inst_axi_lite_write
(
.axi_clk ( axi_clk ),
.user_clk ( user_w_clk ),
.sys_rst_n ( sys_rst_n ),
.user_w_en ( user_w_en ),
.user_w_addr ( user_w_addr ),
.user_w_data ( user_w_data ),
.user_w_ready ( user_w_ready ),
.m_axi_aw_addr ( m_axi_aw_addr ),
.m_axi_aw_vid ( m_axi_aw_vid ),
.m_axi_aw_ready ( m_axi_aw_ready ),
.m_axi_aw_port ( m_axi_aw_port ),
.m_axi_w_data ( m_axi_w_data ),
.m_axi_w_vid ( m_axi_w_vid ),
.m_axi_w_ready ( m_axi_w_ready ),
.m_axi_w_strb ( m_axi_w_strb ),
.m_axi_b_resp ( m_axi_b_resp ),
.m_axi_b_vid ( m_axi_b_vid ),
.m_axi_b_ready ( m_axi_b_ready )
);
axi_lite_read inst_axi_lite_read
(
.axi_clk ( axi_clk ),
.user_clk ( axi_clk ),
.sys_rst_n ( sys_rst_n ),
.user_r_en ( user_r_en ),
.user_r_addr ( user_r_addr ),
.user_r_data ( user_r_data ),
.user_r_data_vid ( user_r_data_vid ),
.m_axi_ar_addr ( m_axi_ar_addr ),
.m_axi_ar_vid ( m_axi_ar_vid ),
.m_axi_ar_ready ( m_axi_ar_ready ),
.m_axi_ar_port ( m_axi_ar_port ),
.m_axi_r_data ( m_axi_r_data ),
.m_axi_r_vid ( m_axi_r_vid ),
.m_axi_r_ready ( m_axi_r_ready ),
.m_axi_r_resp ( m_axi_r_resp )
);
wire rsta_busy;
wire rstb_busy;
BRAM_w32xd1024 inst_BRAM_w32xd1024 (
.rsta_busy ( rsta_busy ),
.rstb_busy ( rstb_busy ),
.s_aclk ( axi_clk ),
.s_aresetn ( sys_rst_n ),
.s_axi_awaddr ( m_axi_aw_addr ),
.s_axi_awvalid ( m_axi_aw_vid ),
.s_axi_awready ( m_axi_aw_ready ),
.s_axi_wdata ( m_axi_w_data ),
.s_axi_wstrb ( m_axi_w_strb ),
.s_axi_wvalid ( m_axi_w_vid ),
.s_axi_wready ( m_axi_w_ready ),
.s_axi_bresp ( m_axi_b_resp ),
.s_axi_bvalid ( m_axi_b_vid ),
.s_axi_bready ( m_axi_b_ready ),
.s_axi_araddr ( m_axi_ar_addr ),
.s_axi_arvalid ( m_axi_ar_vid ),
.s_axi_arready ( m_axi_b_ready ),
.s_axi_rdata ( m_axi_r_data ),
.s_axi_rresp ( m_axi_r_resp ),
.s_axi_rvalid ( m_axi_r_vid ),
.s_axi_rready ( m_axi_r_ready )
);
endmodule
AXI Lite Write写源码
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2025/07/14 15:50:03
// Design Name:
// Module Name: axi_lite_write
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module axi_lite_write
#(
parameter USER_ADDR_WIDTH = 32 , //用户地址位宽
parameter USER_DATA_WIDTH = 32 , //用户地址位宽
parameter AXI_ADDR_WIDTH = 32 , //AXI地址位宽
parameter AXI_DATA_WIDTH = 32 //AXI数据位宽
)
(
input wire axi_clk ,
input wire user_clk ,
input wire sys_rst_n ,
/* 用户接口 */
//用户写通道
input wire user_w_en , //用户写使能
input wire [USER_ADDR_WIDTH-1 : 0] user_w_addr , //用户写地址
input wire [USER_DATA_WIDTH-1 : 0] user_w_data , //用户写数据
input wire user_w_ready , //用户写准备好信号
/*AXI Lite Master接口*/
//写地址通道
output wire [AXI_ADDR_WIDTH-1 : 0] m_axi_aw_addr , //AXI写地址
output wire m_axi_aw_vid , //AXI写地址主机有效信号
input wire m_axi_aw_ready , //AXI写地址从机准备好信号
output wire [2:0] m_axi_aw_port , //AXI保护类型,安全等级,默认保持为3'b000
//写数据通道
output wire [AXI_DATA_WIDTH-1 : 0] m_axi_w_data , //AXI写数据
output wire m_axi_w_vid , //AXI写数据主机有效信号
input wire m_axi_w_ready , //AXI写数据从机准备好信号
output wire [AXI_DATA_WIDTH/8-1:0] m_axi_w_strb , //AXI写数据掩码信号
//写响应通道
input wire m_axi_b_resp , //AXI从机写响应信号
input wire m_axi_b_vid , //AXI从机写响应有效信号
output wire m_axi_b_ready //AXI主机响应准备好信号
);
// localparam ADDR_IDLE = 0 ;
// localparam ADDR_PRE_WRITE = 1 ;
// localparam ADDR_WRITE = 2 ;
// localparam ADDR_END = 3 ;
reg r_axi_aw_vid ;
reg r_axi_w_vid ;
//用户复位同步信号
reg user_rst_n_sync_d0 ;
reg user_rst_n_sync_d1 ;
reg user_rst_n ;
//AXI复位同步信号
reg axi_rst_n_sync_d0 ;
reg axi_rst_n_sync_d1 ;
reg axi_rst_n ;
//FIFO变量
reg fifo_addr_wr_en ; //地址FIFO写使能
reg [AXI_ADDR_WIDTH-1 : 0] fifo_addr_din ; //地址FIFO写数据
reg fifo_addr_rd_en ; //地址FIFO读使能
wire[AXI_ADDR_WIDTH-1 : 0] fifo_addr_dout ; //地址FIFO读数据
wire fifo_addr_empty ; //地址FIFO空信号
wire fifo_addr_full ; //地址FIFO满信号
wire[5:0] fifo_rd_count ; //地址FIFO读统计
wire[5:0] fifo_wr_count ; //地址FIFO写统计
reg fifo_data_wr_en ; //地址FIFO写使能
reg [AXI_ADDR_WIDTH-1 : 0] fifo_data_din ; //地址FIFO写数据
reg fifo_data_rd_en ; //地址FIFO读使能
wire[AXI_ADDR_WIDTH-1 : 0] fifo_data_dout ; //地址FIFO读数据
wire fifo_data_empty ; //地址FIFO空信号
wire fifo_data_full ; //地址FIFO满信号
wire[5:0] fifo_data_rd_count ; //地址FIFO读统计
wire[5:0] fifo_data_wr_count ; //地址FIFO写统计
typedef enum logic [3:0] {
ADDR_IDLE = 3'b000,
ADDR_PRE_WRITE = 3'b001,
ADDR_WRITE = 3'b010,
ADDR_END = 3'b100
} state_t;
state_t state_c, state_n;
// //状态机变量
// reg [3:0] state_c ;
// reg [3:0] state_n ;
assign m_axi_aw_port = 3'b0 ;
assign m_axi_aw_addr = fifo_addr_dout ;
assign m_axi_aw_vid = r_axi_aw_vid ;
assign m_axi_w_strb = 4'b0 ;
assign m_axi_w_data = fifo_data_dout ;
assign m_axi_w_vid = r_axi_w_vid ;
assign m_axi_b_ready = (fifo_wr_count>=28)?1'b0:1'b1;
/************************************************************************************\
用户复位信号打拍处理
\************************************************************************************/
always @(posedge user_clk) begin
user_rst_n_sync_d0 <= sys_rst_n;
user_rst_n_sync_d1 <= user_rst_n_sync_d0;
user_rst_n <= user_rst_n_sync_d1;
end
/************************************************************************************\
AXI复位信号打拍处理
\************************************************************************************/
always @(posedge user_clk) begin
axi_rst_n_sync_d0 <= sys_rst_n;
axi_rst_n_sync_d1 <= axi_rst_n_sync_d0;
axi_rst_n <= axi_rst_n_sync_d1;
end
/************************************************************************************\
地址FIFO写使能信号 && 地址FIFO写入数据
\************************************************************************************/
always @(posedge user_clk or negedge user_rst_n) begin
if(user_w_en)begin
fifo_addr_wr_en <= 1'b1;
fifo_data_wr_en <= 1'b1;
fifo_addr_din <= user_w_addr;
fifo_data_din <= user_w_data;
end
else begin
fifo_addr_wr_en <= 1'b0;
fifo_data_wr_en <= 1'b0;
fifo_addr_din <= 'd0;
fifo_data_din <= 'd0;
end
end
/************************************************************************************\
状态机第一段
\************************************************************************************/
always @(posedge axi_clk or negedge axi_rst_n) begin
if (!user_rst_n) begin
state_c <= ADDR_IDLE;
end
else begin
state_c <= state_n;
end
end
/************************************************************************************\
状态机第二段
\************************************************************************************/
always @(*) begin
case (state_c)
ADDR_IDLE : begin
if(!fifo_addr_empty)
state_n = ADDR_PRE_WRITE;
else
state_n = state_c;
end
ADDR_PRE_WRITE : begin
state_n = ADDR_WRITE;
end
ADDR_WRITE : begin
if(m_axi_b_vid & m_axi_b_ready)
state_n = ADDR_END;
else
state_n = state_c;
end
ADDR_END : begin
state_n = ADDR_IDLE;
end
default : state_n = ADDR_IDLE;
endcase
end
/************************************************************************************\
状态机第三段-----fifo_addr_rd_en
\************************************************************************************/
always @(posedge axi_clk or negedge axi_rst_n) begin
if(state_c == ADDR_PRE_WRITE)begin
fifo_addr_rd_en <= 1'b1;
fifo_data_rd_en <= 1'b1;
end
else begin
fifo_addr_rd_en <= 1'b0;
fifo_data_rd_en <= 1'b0;
end
end
/************************************************************************************\
状态机第三段-----r_axi_aw_vid
\************************************************************************************/
always @(posedge axi_clk or negedge axi_rst_n) begin
if(!axi_rst_n) begin
r_axi_aw_vid <= 1'b0;
end
else if(m_axi_aw_vid & m_axi_aw_ready) begin
r_axi_aw_vid <= 1'b0;
end
else if(state_c == ADDR_PRE_WRITE)begin
r_axi_aw_vid <= 1'b1;
end
else begin
r_axi_aw_vid <= r_axi_aw_vid;
end
end
/************************************************************************************\
状态机第三段-----r_axi_w_vid
\************************************************************************************/
always @(posedge axi_clk or negedge axi_rst_n) begin
if(!axi_rst_n) begin
r_axi_w_vid <= 1'b0;
end
else if(m_axi_w_vid & m_axi_w_ready) begin
r_axi_w_vid <= 1'b0;
end
else if(state_c == ADDR_PRE_WRITE)begin
r_axi_w_vid <= 1'b1;
end
else begin
r_axi_w_vid <= r_axi_w_vid;
end
end
fifo_w32xd32 fifo_w32xd32_write_addr
(
.wr_clk ( user_clk ), // input wire wr_clk
.rd_clk ( axi_clk ), // input wire rd_clk
.din ( fifo_addr_din ), // input wire [31 : 0] din
.wr_en ( fifo_addr_wr_en ), // input wire wr_en
.rd_en ( fifo_addr_rd_en ), // input wire rd_en
.dout ( fifo_addr_dout ), // output wire [31 : 0] dout
.full ( fifo_addr_full ), // output wire full
.empty ( fifo_addr_empty ), // output wire empty
.rd_data_count ( fifo_rd_count ), // output wire [4 : 0] rd_data_count
.wr_data_count ( fifo_wr_count ) // output wire [4 : 0] wr_data_count
);
fifo_w32xd32 fifo_w32xd32_write_data
(
.wr_clk ( user_clk ), // input wire wr_clk
.rd_clk ( axi_clk ), // input wire rd_clk
.din ( fifo_data_din ), // input wire [31 : 0] din
.wr_en ( fifo_data_wr_en ), // input wire wr_en
.rd_en ( fifo_data_rd_en ), // input wire rd_en
.dout ( fifo_data_dout ), // output wire [31 : 0] dout
.full ( fifo_data_full ), // output wire full
.empty ( fifo_data_empty ), // output wire empty
.rd_data_count ( fifo_data_rd_count ), // output wire [4 : 0] rd_data_count
.wr_data_count ( fifo_data_wr_count ) // output wire [4 : 0] wr_data_count
);
endmodule