xilinx axi_iic IP使用分享

仿真环境:例化了两组axi_iic 的IP。一个slv一个mst。slv地址固定为0x33;7bit模式,iic总线速率为4000K。

仿真发现每次只能发送3byte数据,和实际不符。仿真仅作参考。由于iic为双向端口,通过例化顶层将IO连接,且需要进行上拉。

顶层文件:top_sim.sv

`timescale 1ns/1ps

module top_sim();
wire iic_sda;
wire iic_scl;


top u_top(
.scl_io_mst(iic_scl),
.sda_io_mst(iic_sda),
.scl_io_slv(iic_scl),
.sda_io_slv(iic_sda)
);

endmodule

仿真发送命令参考:top.sv

`timescale 1ns/1ps
module top(
inout scl_io_mst,
inout sda_io_mst,
inout scl_io_slv,
inout sda_io_slv
);
parameter PERIOD = 40;

reg clk;
reg rst;
//write channel
logic [8:0] s_axi_awaddr_slv;
logic [8:0] s_axi_awaddr_mst;
logic s_axi_awvalid;
logic s_axi_awvalid_mst;
logic s_axi_awready;
logic s_axi_awready_mst;
logic [3:0]s_axi_wstrb;
logic s_axi_wvalid;
logic s_axi_wvalid_mst;
logic s_axi_wready;
logic s_axi_wready_mst;
logic [31:0] s_axi_wdata_slv;
logic [31:0] s_axi_wdata_mst;
logic s_axi_bvalid;
logic s_axi_bvalid_mst;
logic s_axi_bready;
logic s_axi_bready_mst;
logic [1:0] s_axi_bresp;
logic [1:0] s_axi_bresp_mst;
//read channel
logic [8:0] s_axi_araddr_slv;
logic [8:0] s_axi_araddr_mst;
logic s_axi_arvalid;
logic s_axi_arvalid_mst;
logic s_axi_arready;
logic s_axi_arready_mst;
logic [31:0] s_axi_rdata_slv;
logic [31:0] s_axi_rdata_mst;
logic [1:0]  s_axi_rresp;
logic [1:0]  s_axi_rresp_mst;
logic s_axi_rvalid;
logic s_axi_rvalid_mst;
logic s_axi_rready;
logic s_axi_rready_mst;


logic iic_slv_done;
logic rst_mst;

initial begin
    clk = 0;
    forever #(PERIOD/2) clk = ~clk;
end
initial begin
    rst = 1'b0;
    #100
    rst = 1'b1;
end

//iic_slv device cfg
`define iic_slv_w u_axi_iic_slv.axi_lite_mst_iic_w
`define iic_slv_r u_axi_iic_slv.axi_lite_mst_iic_r
`define iic_mst_w u_axi_iic_mst.axi_lite_mst_iic_w
`define iic_mst_r u_axi_iic_mst.axi_lite_mst_iic_r

initial begin
    rst_mst = 0;
    iic_slv_done = 0;
    `iic_slv_w(9'h120,32'hf);    //rx_fifo deapth
    `iic_slv_w(9'h110,32'h66);  //slv address bit[0] NC
    `iic_slv_w(9'h100,32'h1);   //CR as slv
//    `iic_slv_r(9'h104,s_axi_rdata_slv); //read SR
    iic_slv_done = 1;
    rst_mst = 1;
    


end


axi_iic u_axi_iic_slv(
.clk          (clk ),
.rst          (rst ),
.s_axi_awaddr (s_axi_awaddr_slv ),
.s_axi_wdata  (s_axi_wdata_slv  ),
.s_axi_awvalid(s_axi_awvalid),
.s_axi_awready(s_axi_awready),
.s_axi_wstrb  (s_axi_wstrb  ),
.s_axi_wvalid (s_axi_wvalid ),
.s_axi_wready (s_axi_wready ),

.s_axi_bready (s_axi_bready),
.s_axi_bvalid (s_axi_bvalid),
.s_axi_bresp  (s_axi_bresp ),

.s_axi_araddr (s_axi_araddr_slv ),
.s_axi_arvalid(s_axi_arvalid),
.s_axi_arready(s_axi_arready),
.s_axi_rdata  (s_axi_rdata_slv  ),
.s_axi_rresp  (s_axi_rresp  ),
.s_axi_rvalid (s_axi_rvalid ),
.s_axi_rready (s_axi_rready )

);

axi_iic_1 u_axi_slv_iic_0(
.s_axi_aclk         (clk),
.s_axi_aresetn        (rst),
.iic2intc_irpt        (),//out
.s_axi_awaddr        (s_axi_awaddr_slv),
.s_axi_awvalid        (s_axi_awvalid),
.s_axi_awready        (s_axi_awready),//out
.s_axi_wdata        (s_axi_wdata_slv),
.s_axi_wstrb        (s_axi_wstrb),
.s_axi_wvalid        (s_axi_wvalid),
.s_axi_wready        (s_axi_wready),    //out
.s_axi_bvalid          (s_axi_bvalid),    //out
.s_axi_bready          (s_axi_bready),
.s_axi_araddr         (s_axi_araddr_slv),
.s_axi_bresp         (s_axi_bresp),    //out
.s_axi_arvalid         (s_axi_arvalid),
.s_axi_arready         (s_axi_arready),    //out
.s_axi_rdata         (s_axi_rdata_slv), //out
.s_axi_rresp         (s_axi_rresp), //out
.s_axi_rvalid         (s_axi_rvalid), //out
.s_axi_rready         (s_axi_rready),
.sda_i                 (sda_i_slv),
.sda_o                 (sda_o_slv),//out
.sda_t                 (sda_t_slv),//out
.scl_i                 (scl_i_slv),
.scl_o                 (scl_o_slv), //out
.scl_t                 (scl_t_slv), //out
.gpo                 ()  //out 


);

initial begin
    wait(rst_mst);
    `iic_mst_w(9'h120,32'hf);
    `iic_mst_w(9'h100,32'h2);
    `iic_mst_w(9'h100,32'h1);    
    @(posedge clk);
    `iic_mst_w(9'h108,32'h166);
    `iic_mst_w(9'h108,32'h01);
    `iic_mst_w(9'h100,32'hd);
    force s_axi_arvalid_mst = 1;
    `iic_mst_r(9'h020,s_axi_rdata_mst);
    wait (s_axi_rdata_mst == 32'hd4)
    begin
    force s_axi_arvalid_mst = 0;
    release s_axi_arvalid_mst;
    end
    ///w  byte
    @(posedge clk);
    `iic_mst_w(9'h108,32'h01);
    `iic_mst_w(9'h108,32'h205);
    `iic_mst_w(9'h100,32'hd);
    force s_axi_arvalid_mst = 1;
    `iic_mst_r(9'h104,s_axi_rdata_mst);
    wait (s_axi_rdata_mst == 32'hc4)
    begin
    force s_axi_arvalid_mst = 0;
    release s_axi_arvalid_mst;
    #25us;
    end
    `iic_mst_r(9'h020,s_axi_rdata_mst);
    `iic_mst_w(9'h100,32'h2);
    `iic_mst_w(9'h100,32'h0);
     repeat(10) begin
        `iic_mst_r(9'h020,s_axi_rdata_mst);
        $display("~~~~~~~~%h~~~~~~~",s_axi_rdata_mst);
        `iic_mst_w(9'h020,s_axi_rdata_mst);
    if (s_axi_rdata_mst == 32'hd0) begin
       $display("*******%h*******",s_axi_rdata_mst);
       break ;
    end
    end
    
//write twice
    `iic_mst_w(9'h100,32'h1);    
    @(posedge clk);
    `iic_mst_w(9'h108,32'h166);
    `iic_mst_w(9'h108,32'h01);
    `iic_mst_w(9'h100,32'hd);
    force s_axi_arvalid_mst = 1;
    `iic_mst_r(9'h020,s_axi_rdata_mst);
    wait (s_axi_rdata_mst == 32'hd4)
    begin
    force s_axi_arvalid_mst = 0;
    release s_axi_arvalid_mst;
    end
    ///w  byte
    @(posedge clk);
    `iic_mst_w(9'h108,32'h01);
    `iic_mst_w(9'h108,32'h205);
    `iic_mst_w(9'h100,32'hd);
    force s_axi_arvalid_mst = 1;
    `iic_mst_r(9'h104,s_axi_rdata_mst);
    wait (s_axi_rdata_mst == 32'hc4)
    begin
    force s_axi_arvalid_mst = 0;
    release s_axi_arvalid_mst;
    #25us;
    end
    `iic_mst_r(9'h020,s_axi_rdata_mst);
    `iic_mst_w(9'h100,32'h2);
    `iic_mst_w(9'h100,32'h0);
     repeat(10) begin
        `iic_mst_r(9'h020,s_axi_rdata_mst);
        $display("~~~~~~~~%h~~~~~~~",s_axi_rdata_mst);
        `iic_mst_w(9'h020,s_axi_rdata_mst);
    if (s_axi_rdata_mst == 32'hd0) begin
       $display("*******%h*******",s_axi_rdata_mst);
       break ;
    end
    end

    

end

axi_iic u_axi_iic_mst(
.clk          (clk ),
.rst          (rst_mst ),
.s_axi_awaddr (s_axi_awaddr_mst ),
.s_axi_wdata  (s_axi_wdata_mst  ),
.s_axi_awvalid(s_axi_awvalid),
.s_axi_awready(s_axi_awready),
.s_axi_wstrb  (s_axi_wstrb  ),
.s_axi_wvalid (s_axi_wvalid ),
.s_axi_wready (s_axi_wready ),

.s_axi_bready (s_axi_bready),
.s_axi_bvalid (s_axi_bvalid),
.s_axi_bresp  (s_axi_bresp ),

.s_axi_araddr (s_axi_araddr_mst ),
.s_axi_arvalid(s_axi_arvalid_mst),
.s_axi_arready(s_axi_arready_mst),
.s_axi_rdata  (s_axi_rdata_mst  ),
.s_axi_rresp  (s_axi_rresp_mst  ),
.s_axi_rvalid (s_axi_rvalid_mst ),
.s_axi_rready (s_axi_rready_mst )

);


axi_iic_0 u_axi_mst_iic_0(
.s_axi_aclk         (clk),
.s_axi_aresetn        (rst_mst),
.iic2intc_irpt        (),//out
.s_axi_awaddr        (s_axi_awaddr_mst),
.s_axi_awvalid        (s_axi_awvalid),
.s_axi_awready        (s_axi_awready),//out
.s_axi_wdata        (s_axi_wdata_mst),
.s_axi_wstrb        (s_axi_wstrb),
.s_axi_wvalid        (s_axi_wvalid),
.s_axi_wready        (s_axi_wready),    //out
.s_axi_bvalid          (s_axi_bvalid),    //out
.s_axi_bready          (s_axi_bready),
.s_axi_araddr         (s_axi_araddr_mst),
.s_axi_bresp         (s_axi_bresp),    //out
.s_axi_arvalid         (s_axi_arvalid_mst),
.s_axi_arready         (s_axi_arready_mst),    //out
.s_axi_rdata         (s_axi_rdata_mst), //out
.s_axi_rresp         (s_axi_rresp_mst), //out
.s_axi_rvalid         (s_axi_rvalid_mst), //out
.s_axi_rready         (s_axi_rready_mst),
.sda_i                 (sda_i_mst),
.sda_o                 (sda_o_mst),//out
.sda_t                 (sda_t_mst),//out
.scl_i                 (scl_i_mst),
.scl_o                 (scl_o_mst), //out
.scl_t                 (scl_t_mst), //out
.gpo                 ()  //out 


);


//iic mst
pullup(scl_io_mst);
pullup(sda_io_mst);

IOBUF iic_iobuf_mst(
    .I (scl_o_mst),
    .IO(scl_io_mst),
    .O (scl_i_mst),
    .T (scl_t_mst)
);

IOBUF iic_iobuf_sda_mst(
    .I (sda_o_mst),
    .IO(sda_io_mst),
    .O (sda_i_mst),
    .T (sda_t_mst)
);

//iic slv
pullup(scl_io_slv);
pullup(sda_io_slv);

IOBUF iic_iobuf_slv(
    .I (scl_o_slv),
    .IO(scl_io_slv),
    .O (scl_i_slv),
    .T (scl_t_slv)
);

IOBUF iic_iobuf_sda_slv(
    .I (sda_o_slv),
    .IO(sda_io_slv),
    .O (sda_i_slv),
    .T (sda_t_slv)
);

initial begin
    #2ms
    $finish(1);
end
endmodule

建立外部的axi_mst 任务去调用axi_iic:

module axi_iic(
input clk,
input rst,

//axi_mst_lite aw & w channel
output logic [8:0]  s_axi_awaddr,
output logic [31:0] s_axi_wdata,
output logic           s_axi_awvalid,
input  logic        s_axi_awready,
output logic [3:0]  s_axi_wstrb,
output logic           s_axi_wvalid,
input  logic            s_axi_wready,
//b channel
output logic           s_axi_bready,
input  logic          s_axi_bvalid,
input  logic [1:0]  s_axi_bresp,
//axi_mst_lite ar & r channel
output logic[8:0]  s_axi_araddr,
output logic          s_axi_arvalid,
input     logic      s_axi_arready,
input  logic [31:0]      s_axi_rdata,
input     logic      s_axi_rresp,
input     logic      s_axi_rvalid,
output logic          s_axi_rready

);

task axi_lite_mst_iic_w(
input [8:0]  ss_axi_awaddr,
input [31:0] ss_axi_wdata

);
begin    
    wait(rst);
    s_axi_awvalid = 1'b1;
    force top.s_axi_awready = 1'b1;
    wait(s_axi_awready);
    release top.s_axi_awready;
    s_axi_awaddr = ss_axi_awaddr;
    s_axi_wstrb = 4'hf;
    //write
    s_axi_wvalid = 1'b1;
    wait(s_axi_wready);
    s_axi_wdata = ss_axi_wdata;
    repeat(2) @(posedge clk);
    s_axi_wvalid = 1'b0;
    wait(s_axi_bvalid);
    repeat(10) @(posedge clk);
    s_axi_bready = 1;
    @(posedge clk);
    s_axi_bready = 0;
    @(posedge clk);
    
end
endtask

task axi_lite_mst_iic_r(
input [8:0] ss_axi_araddr,
output [31:0] ss_axi_rdata
);
begin
    s_axi_rready = 1;
    @(posedge clk);
    //read
    s_axi_arvalid = 1'b1;
//    force top.s_axi_arready = 1'b1;
    s_axi_araddr  = ss_axi_araddr;
    repeat(7) @(posedge clk);
    s_axi_arvalid = 1'b0;
//    repeat(3) @(posedge clk);
//    wait (s_axi_rvalid);
//    repeat(3) @(posedge clk);
    ss_axi_rdata = s_axi_rdata;

end
endtask

task axi_lite_slv_iic_w();
begin

end
endtask


task axi_lite_slv_iic_r();
begin

end
endtask

endmodule

 

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值