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

版权声明:本文为u012780083原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。