From 9efcfe8891394b58cf2d692b3c44a69ee44239b8 Mon Sep 17 00:00:00 2001 From: charan_vabanagiri Date: Thu, 9 May 2024 12:47:20 +0530 Subject: [PATCH] axidriver --- axi_driver.sv | 460 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 460 insertions(+) create mode 100755 axi_driver.sv diff --git a/axi_driver.sv b/axi_driver.sv new file mode 100755 index 0000000..a37fb07 --- /dev/null +++ b/axi_driver.sv @@ -0,0 +1,460 @@ +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 <=pkt.arlen; + for(int i=0; i<(arlen +1);i++) + begin + vif.araddr<=pkt.araddr; + vif.arid <= pkt.arid; + vif.arvalid<= 1; + pkt.araddr<= pkt.araddr +(2**vif.arsize); + 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 + 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 <= pkt.arid; + vif.araddr <= pkt.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 +