定义了reg0(数据寄存器),reg1(控制寄存器),reg2(输入/输出)
`timescale 1ns / 1ps
module axi_gpio_my
(
input S_AXI_ACLK,
input S_AXI_ARESETN,
inout [3:0]gpio,
//AR channel
input S_AXI_ARVALID,
output S_AXI_ARREADY,
input [4-1:0]S_AXI_ARADDR,
input [2:0]S_AXI_ARPROT,
//Rd channel
output [32-1:0]S_AXI_RDATA,
output [1:0]S_AXI_RRESP,
output S_AXI_RVALID,
input S_AXI_RREADY,
//AW channel
input S_AXI_AWVALID,
output S_AXI_AWREADY,
input [4-1:0]S_AXI_AWADDR,
input [2:0]S_AXI_AWPROT,
//Wr channel
input [32-1:0]S_AXI_WDATA,
input S_AXI_WVALID,
output S_AXI_WREADY,
input [4-1:0]S_AXI_WSTRB,//4'b1111. 4'b0011
//Wr Resp
output [1:0]S_AXI_BRESP,
output S_AXI_BVALID,
input S_AXI_BREADY
);
assign S_AXI_BRESP=2'b0;
reg axi_bvalid;
assign S_AXI_BVALID=axi_bvalid;
always @(posedge S_AXI_ACLK or negedge S_AXI_ARESETN)
if(~S_AXI_ARESETN)
axi_bvalid<=1'b0;
else
if(S_AXI_WVALID&S_AXI_WREADY)
axi_bvalid<=1'b1;
else
if(S_AXI_BREADY)
axi_bvalid<=1'b0;
reg [1:0]addr_word_w;
wire [1:0]addr_word_w_comb;
always @(posedge S_AXI_ACLK or negedge S_AXI_ARESETN)
if(~S_AXI_ARESETN)
addr_word_w<=0;
else
if(S_AXI_AWVALID&S_AXI_AWREADY)
addr_word_w<=S_AXI_AWADDR[3:2];
assign addr_word_w_comb=(S_AXI_AWVALID&S_AXI_AWREADY)?S_AXI_AWADDR[3:2]:addr_word_w;
assign S_AXI_AWREADY=1'b1;
reg [3:0]reg0;
reg [3:0]reg1;
wire [3:0]reg2;
reg wphase;
always @(posedge S_AXI_ACLK or negedge S_AXI_ARESETN)
if(~S_AXI_ARESETN)
wphase<=0;
else
if(S_AXI_AWVALID&S_AXI_AWREADY)
wphase<=1;
else
if(S_AXI_WVALID&S_AXI_WREADY)
wphase<=0;
assign S_AXI_WREADY=wphase;
always @(posedge S_AXI_ACLK or negedge S_AXI_ARESETN)
if(~S_AXI_ARESETN)
begin
reg0<=0;
reg1<=0;
end
else
if(S_AXI_WVALID&S_AXI_WREADY)
case(addr_word_w_comb)
2'd0:begin if(S_AXI_WSTRB[0]) reg0<=S_AXI_WDATA[3:0];end
2'd1:begin if(S_AXI_WSTRB[0]) reg1<=S_AXI_WDATA[3:0];end
endcase
assign S_AXI_ARREADY=1'b1;
assign S_AXI_RRESP=2'b0;
reg [32-1:0]rdata;
assign S_AXI_RDATA=rdata;
reg rvalid;
assign S_AXI_RVALID=rvalid;
always @(posedge S_AXI_ACLK or negedge S_AXI_ARESETN)
if(~S_AXI_ARESETN)
begin rvalid<=1'b0;rdata<=32'b0;end
else
if(S_AXI_ARVALID&S_AXI_ARREADY)
begin
rvalid<=1'b1;
case(S_AXI_ARADDR[3:2])
2'd0:rdata<={28'b0,reg0};
2'd1:rdata<={28'b0,reg1};
2'd2:rdata<={28'b0,reg2};
2'd3:rdata<=0;
endcase
end
else
if(S_AXI_RVALID&S_AXI_RREADY)
rvalid<=1'b0;
assign gpio[3]=reg1[3]?reg0[3]:1'bz;
assign gpio[2]=reg1[2]?reg0[2]:1'bz;
assign gpio[1]=reg1[1]?reg0[1]:1'bz;
assign gpio[0]=reg1[0]?reg0[0]:1'bz;
assign reg2=gpio;
endmodule