class driver extends uvm_driver #(seq); `uvm_component_utils(driver) virtual axi_driver_if vif; sequence seq; function new(string name="driver", uvm_component parent=null); super.new(name, parent); endfunction virtual function void build_phase(uvm_phase phase); super.build_phase(phase); seq=sequence::type_id::create("seq"); if(!uvm_config_db#(virtual axi_driver_if)::get(this," ","vif",vif)) `uvm_error("driver"," Interface not set"); endfunction task reset(); begin vif.awvalid <= 0; vif.awready <= 0; vif.awid <= 0; vif.awlen <= 0; vif.awsize <= 0; vif.awaddr <= 0; vif.awburst <= 0; vif.wvalid <= 0; vif.wready <= 0; vif.wid <= 0; vif.wdata <= 0; vif.wstrb <= 0; vif.wlast <= 0; vif.bready <= 0; vif.bvalid <= 0; vif.bid <= 0; vif.bresp <= 0; vif.arvalid <= 0; vif.arready <= 0; vif.arid <= 0; vif.arlen <= 0; vif.arsize <= 0; vif.araddr <= 0; vif.arburst <= 0; vif.rvalid <= 0; vif.rready <= 0; vif.rid <= 0; vif.rdata <= 0; vif.rstrb <= 0; vif.rlast <= 0; vif.rresp <= 0; @(posedge vif.clk); `uvm_info(get_type_name(),"reset applied",UVM_MEDIUM) end endtask virtual task run_phase(uvm_phase phase); reset(); seq_tem_port.get_next_item(txn); if(wr_rd==1) begin wrtie_address(); write_data(); write_response(); end else begin read_address(); read_data(); end endtask virtual task write_address(); vif.awready<=0; vif.awaddr<= txn.awaddr; vif.awsize<= txn.awsize; vif.awlen<= txn.awlen; vif.awcache<= txn.awcache; vif.awburst<= txn.awburst; vif.awvalid<=1'b1; case (txn.awburst) 2'b00 : write_ad_fixed_burst; 2'b01 : write_ad_incr_burst; 2'b10 : write_ad_wrap_burst; endcase while(vif.awready==0) $display("within loop"); begin @(posedge vif.clk); if(vif.awvalid==1) begin awready=1; $display("write address phase is completed"); end end vif.awvalid=0; endtask ////////////////// wridte_fixed burst//////////////// virtual task write_ad_fixed_burst(); vif.awlen <= txn.awlen; vif.awid <= txn.awid; vif.awaddr <= txn.awaddr; vif.awsize<= txn.awsize; vif.awvalid<= 1; wait(vif.awready); vif.awvalid<=0; write_data(); endtask virtual task write_data(); vif.wready<=0; for(int i=0;i<=txn.awlen+1;i++) begin $display("write data started"); vif.wdata<=txn.wdata[i]; vif.wstrb<=txn.wstrb[i]; vif.wid<=txn.wid; vif.wvalid<=1'b1; if(i=txn.awlen+1) vif.wlast=1; while (wready=0) begin @(posedge vif.clk) if (vif.wready==1) txn.wready=1; end vif.wlast=0; vif.wvalid=0; vif.wready=0; $display("write data completed"); end write_ad_incr(); endtask //////////////////////write_address_incremental///////////////// virtual task write_ad_incr(); vif.awlen <= txn.awlen; for(int i=0; i<(txn.awlen +1);i++) vif.awid <= txn.awid; vif.awaddr <= txn.awaddr; vif.awsize<= txn.awsize; txn.awaddr<= txn.awaddr+(2**awsize); vif.awvalid<= 1; wait(vif.awready); vif.awvalid<=0; write_data(); endtask virtual task write_data(); vif.wready<=0; for(int i=0;i<=txn.awlen+1;i++) begin $display("write data started"); vif.wdata<=txn.wdata[i]; vif.wstrb<=txn.wstrb[i]; vif.wid<=txn.wid; vif.wvalid<=1'b1; if(i=txn.awlen+1) vif.wlast=1; while (wready=0) begin @(posedge vif.clk) if (vif.wready==1) txn.wready=1; end vif.wlast=0; vif.wvalid=0; vif.wready=0; $display("write data completed"); write_ad_wrap(); end endtask ///////////wri_address_wrap/////////////////////// virtual task write_ad_wrap(); vif.awlen <= '{1,3,7,15}; vif.awid <= txn.awid; vif.awaddr <= txn.awaddr; vif.awsize<= txn.awsize; begin int burst_length=(awlen+1); int burst_size=(awsize+1); int lower_boundary=INT[awaddr/(burst_length*burst_size)]*(burst_length*burst_size); int upper_boundary=lower_boundar+(burst_length*burst_size); for (int i=0; i< (pkt.awlen+1);i++) begin if(vif.awaddr==upper_boundary) vif.awaddr=lower_boundary; else vif.awaddr <= vif.awaddr+ (2**vif.awsize); vif.awvalid<= 1; wait(vif.awready); vif.awvalid<=0; end write_data(); endtask virtual task write_data(); vif.wready<=0; for(int i=0;i<=txn.awlen+1;i++) begin $display("write data started"); vif.wdata<=txn.wdata[i]; vif.wstrb<=txn.wstrb[i]; vif.wid<=txn.wid; vif.wvalid<=1'b1; if(i=txn.awlen+1) vif.wlast=1; while (wready=0) begin @(posedge vif.clk) if (vif.wready==1) txn.wready=1; end vif.wlast=0; vif.wvalid=0; vif.wready=0; $display("write data completed"); write_response(); end endtask virtual task write_response(); if(vif.wvalid&&vif.wready&&vif.wlast) wait(bvalid) begin vif.bid = pkt.bid; vif.bresp = pkt.bresp; end vif.bready <= 1 ; for(i=0;i<=awlen+1;i++) begin if(vif.awid==vif.bid) case(vif.bresp) 2'b00:"okay"; 2'b01:"exclusive okay"; 2'b10:"slave error"; 2'b11:"decode error"; endcase end vif.bready<=0; endtask ///////////////////////Read address//////////////////////////////////////////////// task read_adress(); `uvm_info("master_driver",$sformatf("message from driver\n %s",pkt.sprint()),UVM_HIGH) vif.arid <= pkt.arid; vif.araddr <= pkt.araddr; vif.arlen <= pkt.arlen; vif.arsize <= pkt.arsize; vif.arburst <= pkt.arburst; vif.arvalid <= 1; `uvm_info("master_driver",$sformatf("message from driver \n %s",pkt.sprint()),UVM_HIGH) case (txn.arburst) 2'b00 : read_address_fixed_burst; 2'b01 : read_address_incr_burst; 2'b10 : read_address_wrap_burst; endcase @(posedge vif.clk); wait (vif.arready); vif.arvalid <= 0; endtask //////////////////////////////////////// raed wrap burst//////////////////// virtual task read_ad_wrap(); vif.awlen <= '{1,3,7,15}; vif.arid <= txn.arid; vif.araddr <= txn.araddr; vif.arsize<= txn.arsize; begin int burst_length=(arlen+1); int burst_size=(arsize+1); int lower_boundary=INT[araddr/(burst_length*burst_size)]*(burst_length*burst_size); int upper_boundary=lower_boundar+(burst_length*burst_size); for (int i=0; i< (pkt.arlen+1);i++) begin if(vif.araddr==upper_boundary) vif.araddr=lower_boundary; else vif.araddr <= vif.araddr+ (2**vif.arsize); vif.arvalid<= 1; wait(vif.arready); vif.arvalid<=0; end read_data1(); endtask virtual task read_data1(); vif.rready<=0; for(int i=0;i<=txn.arlen+1;i++) begin $display("read data started"); vif.rdata<=txn.rdata[i]; vif.rid<=txn.rid; vif.rvalid<=1'b1; if(i=txn.arlen+1) vif.rlast=1; while (rready=0) begin @(posedge vif.clk) if (vif.rready==1) txn.rready=1; end vif.rlast=0; vif.rvalid=0; $display("read data completed"); end foreach (vif.rdata[i]) begin if (vif.arid == vif.rid) begin case (vif.rresp) 2'b00 : s = "Transaction OKAY"; 2'b01 : s = "Transaction FAILED"; 2'b10 : s = "SLAVE ERROR"; 2'b11 : s = "DEEOCDE ERROR"; endcase `uvm_info("axi master_driver",$sformatf("\n t %s response for the received data \n",s),UVM_MEDIUM) end end vif.rready <= 0; endtask //////////////////////////////////////// INCR address //////////////// task read_address_incr_burst(); vif.arlen <=txn.arlen; for(int i=0; i<(arlen +1);i++) begin vif.araddr<=txn.araddr; vif.arid <= txn.arid; vif.arvalid<= 1; pkt.araddr<= txn.araddr +(2**vif.arsize); wait(vif.arready); vif.arvalid<=0; end read_data(); endtask virtual task read_data(); vif.rready<=0; for(int i=0;i<=txn.arlen+1;i++) begin $display("read data started"); vif.rdata<=txn.rdata[i]; vif.rid<=txn.rid; vif.rvalid<=1'b1; if(i=txn.arlen+1) vif.rlast=1; while (rready=0) begin @(posedge vif.clk) if (vif.rready==1) txn.rready=1; end vif.rlast=0; vif.rvalid=0; $display("read data completed"); end vif.rready <= 1; foreach (vif.rdata[i]) begin if (vif.arid == vif.rid) begin case (vif.rresp) 2'b00 : s = "Transaction OKAY"; 2'b01 : s = "Transaction FAILED"; 2'b10 : s = "SLAVE ERROR"; 2'b11 : s = "DEEOCDE ERROR"; endcase `uvm_info("master_driver",$sformatf("\n\t %s response for the recieved data \n",s),UVM_MEDIUM) end end vif.rready <= 0; endtask ///////////////read address fixed burst//////////////////////// task read_address_fixed_burst (); begin vif.arlen <= txn.arlen; vif.arid <= txn.arid; vif.araddr <= txn.araddr; vif.arvalid<= 1; wait(vif.arready); vif.arvalid<=0; end rd_dt_fixed_burst(); endtask task rd_dt_fixed_burst (); vif.rready<=0; for(int i=0;i<=txn.arlen+1;i++) begin $display("read data started"); vif.rdata<=txn.rdata[i]; vif.rid<=txn.rid; vif.rvalid<=1'b1; if(i=txn.arlen+1) vif.rlast=1; while (rready=0) begin @(posedge vif.clk) if (vif.rready==1) txn.rready=1; end vif.rlast=0; vif.rvalid=0; $display("read data completed"); end foreach (vif.rdata[i]) begin if (vif.arid == vif.rid) begin case (vif.rresp) 2'b00 : s = "Transaction OKAY"; 2'b01 : s = "Transaction FAILED"; 2'b10 : s = "SLAVE ERROR"; 2'b11 : s = "DEEOCDE ERROR"; endcase `uvm_info("master_driver",$sformatf("\n\t %s response for recieved data \n",s),UVM_MEDIUM) end end vif.rready <= 0; endtask if(txn.resest==1) begin reset(); end //Write operation support else if(txn.wr_rd==1) begin `uvm_info(get_type_name()," write packet is received in driver ",UVM_MEDIUM) begin write_address(); end //read operation support else if( txn.wr_rd==0) begin read_address(); end seq_item_port.item_done(); end endtask endclass