Zynq學習筆記二之zynq_axi4_lite從機編寫

//注意: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

















































































 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章