//注意:1,axi_lite是一个字符一个字符传输;2,保证先锁地址再写数据
module dut_axi_lite_slave #
(
parameter integer C_S_AXI_DATA_WIDTH=32,
parameter integer C_S_AXI_ADD_WIDTH=6
)
(
//时钟和复位信号
input wire S_AXI_ACLK,
input wire S_AXI_ARESETN,
//写地址通道
input wire [C_S_AXI_ADDR_WIDTH-1:0] S_AXI_AWADDR,
input wire [2:0] S_AXI_AWPROT,
input wire S_AXI_AWVALID,
output wire S_AXI_AWREADY,
//写数据通道
input wire [C_S_AXI_DATA_WIDTH-1:0] S_AXI_WDATA,
input wire [(C_S_AXI_DATA_WIDTH/8)-1:0] S_AXI_WSTRB,
input wire S_AXI_WVALID,
output wire S_AXI_WREADY,
//写响应通道
output wire [1:0] S_AXI_BRESP,
output wire S_AXI_BVALID,
input wire S_AXI_BREADY,
//读地址通道
input wire [C_S_AXI_ADDR_WIDTH-1:0] S_AXI_ARADDR,
input wire [2:0] S_AXI_ARPROT,
input wire S_AXI_ARVALID,
output wire S_AXI_ARREADY,
//读数据通道
output wire [C_S_AXI_DATA_WIDTH-1:0] S_AXI_RDATA,
output wire [1:0] S_AXI_RRESP,
output wire S_AXI_RVALID,
input wire S_AXI_RREADY
);
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;
localparam integer ADDR_LSB =(C_S_AXI_DATA_WIDTH/32)+1;
localparam integer OPT_MEM_ADDR_BITS=4-1;
wire slv_reg_rden;
wire slv_reg_wren;
reg [C_S_AXI_DATA_WIDTH-1:0] reg_data_out;
integer byte_index;
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=axi_rdata;
assign S_AXI_RVALID=axi_rvalid;
assign S_AXI_RRESP=axi_rresp;
//写
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
axi_awready<=1'b0;
end
else
begin
if(~axi_awready && S_AXI_AWVALID && S_AXI_WVALID)
begin
axi_awready<=1'b1;
end
else
begin
axi_awready<=1'b0;
end
end
end
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
axi_awaddr<=1'b0;
end
else
begin
if(~axi_awready && S_AXI_AWVALID && S_AXI_WVALID)
begin
axi_awaddr<=S_AXI_AWADDR;
end
end
end
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
axi_wready<=1'b0;
end
else
begin
if(~axi_wready && S_AXI_WVALID && S_AXI_AWVALID)
begin
axi_wready<=1'b1;
end
else
begin
axi_wready<=1'b0;
end
end
end
assign slv_reg_wren=axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID;
//写响应
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
axi_bvalid<=1'b0;
axi_bresp<=2'b0;
end
else
begin
if(axi_awready && S_AXI_WVALID && ~axi_bvalid && axi_awready && S_AXI_AWVALID)
begin
axi_bvalid<=1'b1;
axi_bresp<=2'b0
end
else
begin
if(S_AXI_BREADY&&axi_bvalid)
begin
axi_bvalid<=1'b0;
end
end
end
end
//读
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
axi_arready<=1'b0;
axi_araddr<=32'b0;
end
else
begin
if(~axi_arready && S_AXI_ARVALID)
begin
axi_arready<=1'b1;
axi_araddr<=S_AXI_ARADDR;
end
else
begin
axi_arready<=1'b0;
end
end
end
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
axi_rvalid<=1'b0;
axi_rresp<=0;
end
else
begin
if(axi_arready && S_AXI_ARVALID && ~axi_rvalid)
begin
axi_rvalid<=1'b1;
axi_rresp<=2'b0;
end
else if(axi_rvalid && S_AXI_RREADY)
begin
axi_rvalid<=1'b0;
end
end
end
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
axi_rdata<=0;
end
else
begin
if(slv_reg_rden)
begin
axi_rdata<=reg_data_out;
end
end
end
assign slv_reg_rden=axi_aready & S_AXI_ARVALID & ~axi_rvalid;
always@(*)
begin
case(axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB])
'd0:reg_data_out<=slv_reg0;
'd1:reg_data_out<=slv_reg1;
'd2:reg_data_out<=slv_reg2;
'd3:reg_data_out<=slv_reg3;
'd4:reg_data_out<=slv_reg4;
'd5:reg_data_out<=slv_reg5;
'd6:reg_data_out<=slv_reg6;
'd7:reg_data_out<=slv_reg7;
'd8:reg_data_out<=slv_reg8;
'd9:reg_data_out<=slv_reg9;
'd10:reg_data_out<=slv_reg10;
'd11:reg_data_out<=slv_reg11;
'd12:reg_data_out<=slv_reg12;
'd13:reg_data_out<=slv_reg13;
'd14:reg_data_out<=slv_reg14;
'd15:reg_data_out<=slv_reg15;
default:reg_data_out<=0;
endcase
end
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg0;
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
slv_reg0<=0;
end
else
begin
if(slv_reg_wren&(axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]=='d0))
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
slv_reg0[(byte_index*8)+:8]<=S_AXI_WDATA[(byte_index*8)+:8];
end
end
end
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg1;
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
slv_reg1<=0;
end
else
begin
if(slv_reg_wren&(axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]=='d0))
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
slv_reg1[(byte_index*8)+:8]<=S_AXI_WDATA[(byte_index*8)+:8];
end
end
end
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg2;
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
slv_reg2<=0;
end
else
begin
if(slv_reg_wren&(axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]=='d0))
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
slv_reg2[(byte_index*8)+:8]<=S_AXI_WDATA[(byte_index*8)+:8];
end
end
end
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg3;
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
slv_reg3<=0;
end
else
begin
if(slv_reg_wren&(axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]=='d0))
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
slv_reg3[(byte_index*8)+:8]<=S_AXI_WDATA[(byte_index*8)+:8];
end
end
end
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg4;
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
slv_reg4<=0;
end
else
begin
if(slv_reg_wren&(axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]=='d0))
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
slv_reg4[(byte_index*8)+:8]<=S_AXI_WDATA[(byte_index*8)+:8];
end
end
end
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg5;
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
slv_reg5<=0;
end
else
begin
if(slv_reg_wren&(axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]=='d0))
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
slv_reg5[(byte_index*8)+:8]<=S_AXI_WDATA[(byte_index*8)+:8];
end
end
end
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg6;
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
slv_reg6<=0;
end
else
begin
if(slv_reg_wren&(axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]=='d0))
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
slv_reg6[(byte_index*8)+:8]<=S_AXI_WDATA[(byte_index*8)+:8];
end
end
end
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg7;
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
slv_reg7<=0;
end
else
begin
if(slv_reg_wren&(axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]=='d0))
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
slv_reg7[(byte_index*8)+:8]<=S_AXI_WDATA[(byte_index*8)+:8];
end
end
end
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg8;
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
slv_reg8<=0;
end
else
begin
if(slv_reg_wren&(axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]=='d0))
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
slv_reg8[(byte_index*8)+:8]<=S_AXI_WDATA[(byte_index*8)+:8];
end
end
end
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg9;
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
slv_reg9<=0;
end
else
begin
if(slv_reg_wren&(axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]=='d0))
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
slv_reg9[(byte_index*8)+:8]<=S_AXI_WDATA[(byte_index*8)+:8];
end
end
end
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg10;
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
slv_reg10<=0;
end
else
begin
if(slv_reg_wren&(axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]=='d0))
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
slv_reg10[(byte_index*8)+:8]<=S_AXI_WDATA[(byte_index*8)+:8];
end
end
end
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg11;
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
slv_reg11<=0;
end
else
begin
if(slv_reg_wren&(axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]=='d0))
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
slv_reg11[(byte_index*8)+:8]<=S_AXI_WDATA[(byte_index*8)+:8];
end
end
end
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg12;
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
slv_reg12<=0;
end
else
begin
if(slv_reg_wren&(axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]=='d0))
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
slv_reg12[(byte_index*8)+:8]<=S_AXI_WDATA[(byte_index*8)+:8];
end
end
end
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg13;
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
slv_reg13<=0;
end
else
begin
if(slv_reg_wren&(axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]=='d0))
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
slv_reg13[(byte_index*8)+:8]<=S_AXI_WDATA[(byte_index*8)+:8];
end
end
end
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg14;
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
slv_reg14<=0;
end
else
begin
if(slv_reg_wren&(axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]=='d0))
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
slv_reg14[(byte_index*8)+:8]<=S_AXI_WDATA[(byte_index*8)+:8];
end
end
end
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg15;
always@(posedge S_AXI_ACLK)
begin
if(S_AXI_ARESETN==1'b0)
begin
slv_reg15<=0;
end
else
begin
if(slv_reg_wren&(axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]=='d0))
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
slv_reg15[(byte_index*8)+:8]<=S_AXI_WDATA[(byte_index*8)+:8];
end
end
end
endmodule