class driver extends uvm_driver #(packet); `uvm_component_utils(driver) virtual axi_if vif; int data_bus_byte; packet write_address_queue [$]; packet write_address; packet write_data_queue [$]; packet write_data; packet write_response_queue [$]; packet read_address_queue [$]; packet read_address; packet read_data_response_queue [$]; packet read_data; semaphore write_address_sema = new (1); semaphore write_data_sema = new (1); semaphore write_data_sema_1 = new (1); semaphore write_response_sema = new (1); semaphore write_response_sema_1 = new (1); semaphore read_address_sema = new (1); semaphore read_data_response_sema = new (1); semaphore read_data_response_sema_1 = new (1); extern function new (string name = "driver", uvm_component parent); extern function void build_phase (uvm_phase phase); extern function void connect_phase (uvm_phase phase); extern task run_phase (uvm_phase phase); extern task send_to_dut (); extern task write_address_channel (); extern task write_data_channel (); extern task fixed_burst (); extern task incr_burst(); extern task write_response_channel (); extern task read_address_channel (); extern task read_data_response_channel (); extern task rd_incr_burst(); endclass //////////////////////////////////////// NEW FUNCTION function driver::new (string name = "driver", uvm_component parent); super.new (name,parent); endfunction /////////////////////////////////////// BUILD PHASE virtual function void build_phase(uvm_phase phase); super.build_phase(phase); pkt=packet::type_id::create("pkt"); if(!uvm_config_db#(virtual axi_if)::get(this,"","vif",vif)) `uvm_error("drv","Unable to access Interface"); endfunction ///////////////////////////////////////////////////// RUN PHASE task driver::run_phase (uvm_phase phase); forever begin seq_item_port.get_next_item(req); send_to_dut(); seq_item_port.item_done(); end endtask /////////////////////////////////////// SEND TO DUT task driver::send_to_dut (); write_address_queue.push_back (req); write_data_queue.push_back (req); write_response_queue.push_back (req); read_address_queue.push_back (req); read_data_response_queue.push_back(req); fork write_address_channel(); write_data_channel(); write_response_channel(); read_address_channel (); read_data_response_channel (); join_any endtask /////////////////////////////////////// WRITE ADDRESS CHANNEL task driver::write_address_channel(); write_address_sema.get(1); write_address = write_address_queue.pop_front(); @(vif.driver); req.control = 1; `uvm_info("MASTER_DRIVER",$sformatf("PRINTING FROM DRIVER \n %s",write_address.sprint()),UVM_HIGH) vif.driver.awid <= write_address.awid; vif.driver.awaddr <= write_address.awaddr; vif.driver.awlen <= write_address.awlen; vif.driver.awsize <= write_address.awsize; vif.driver.awburst <= write_address.awburst; vif.driver.awvalid <= 1; @(vif.driver); wait (vif.driver.awready); vif.driver.awvalid <= 0; write_data_sema.put(1); write_address_sema.put(1); repeat(2) @(vif.driver); endtask //////////////////////////////////////// WRITE DATA CHANNEL task driver::write_data_channel(); write_data_sema.get(2); write_data_sema_1.get(1); write_data = write_data_queue.pop_front(); @(vif.driver); write_data.control = 2; `uvm_info("MASTER_DRIVER",$sformatf("PRINTING FROM DRIVER \n %s",write_data.sprint()),UVM_HIGH) case (write_data.awburst) 2'b00 : fixed_burst; 2'b01 : incr_burst; 2'b10 : incr_burst; endcase write_data_sema.put(1); write_data_sema_1.put(1); write_response_sema.put(1); read_address_sema.put(1); endtask /////////////////////////////////////// INCREMENT BURST task driver::incr_burst(); foreach(write_data.wdata[i]) begin case (write_data.wstrobe[i]) 4'b0001 : vif.driver.wdata [7:0] <= write_data.wdata[i]; 4'b0010 : vif.driver.wdata [15:8] <= write_data.wdata[i]; 4'b0100 : vif.driver.wdata [23:16] <= write_data.wdata[i]; 4'b1000 : vif.driver.wdata [31:24] <= write_data.wdata[i]; 4'b0011 : vif.driver.wdata [15:0] <= write_data.wdata[i]; 4'b1100 : vif.driver.wdata [31:16] <= write_data.wdata[i]; 4'b1110 : vif.driver.wdata [31:8] <= write_data.wdata[i]; 4'b1111 : vif.driver.wdata <= write_data.wdata[i]; endcase vif.driver.wstrobe <= write_data.wstrobe[i]; vif.driver.wid <= write_data.wid; if (i == write_data.burst_len - 1) vif.driver.wlast <= 1; else vif.driver.wlast <= 0; vif.driver.wvalid <= 1; @(vif.driver); wait (vif.driver.wready); vif.driver.wlast <= 0; vif.driver.wvalid <= 0; @(vif.driver); end endtask /////////////////////////////////////// FIXED BURST task driver::fixed_burst (); foreach(write_data.wdata[i]) begin case (write_data.awsize) 2'b00 : vif.driver.wdata[7:0] <= write_data.wdata[i]; 2'b01 : vif.driver.wdata[15:0] <= write_data.wdata[i]; 2'b10 : vif.driver.wdata[31:0] <= write_data.wdata[i]; endcase vif.driver.wid <= write_data.wid; if (i == write_data.burst_len - 1) vif.driver.wlast <= 1; else vif.driver.wlast <= 0; vif.driver.wvalid <= 1; @(vif.driver); wait (vif.driver.wready); vif.driver.wlast <= 0; vif.driver.wvalid <= 0; @(vif.driver); end endtask /////////////////////////////////////// WRITE RESPONSE CHANNEL task driver::write_response_channel (); string s; packet write_response = packet::type_id::create("Response"); write_response_sema.get(2); write_response_sema_1.get(1); @(vif.driver); wait(vif.driver.bvalid) write_response.bid = vif.driver.bid; write_response.bresp = vif.driver.bresp; vif.driver.bready <= 1; @(vif.driver); foreach (write_response_queue[i]) begin if (write_response_queue[i].awid == write_response.bid) begin case (write_response.bresp) 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\n \t\t\t\t\t\t %s RESPONSE FOR THE DATA \n",s),UVM_MEDIUM) write_response_queue[i].control = 1; `uvm_info("MASTER_DRIVER",$sformatf("\n %s \n",write_response_queue[i].sprint),UVM_MEDIUM); write_response_queue[i].control = 2; `uvm_info("MASTER_DRIVER",$sformatf("\n %s \n",write_response_queue[i].sprint),UVM_MEDIUM); write_response_queue.delete(i); break; end end vif.driver.bready <= 0; @(vif.driver); write_response_sema.put(1); write_response_sema_1.put(1); endtask /////////////////////////////////////// READ ADDRESS CHANNEL task driver::read_address_channel(); read_address_sema.get(1); read_address = read_address_queue.pop_front(); @(vif.driver); read_address.control = 4; `uvm_info("MASTER_DRIVER",$sformatf("PRINTING FROM DRIVER \n %s",read_address.sprint()),UVM_HIGH) vif.driver.arid <= read_address.arid; vif.driver.araddr <= read_address.araddr; vif.driver.arlen <= read_address.arlen; vif.driver.arsize <= read_address.arsize; vif.driver.arburst <= read_address.arburst; vif.driver.arvalid <= 1; @(vif.driver); wait (vif.driver.arready); vif.driver.arvalid <= 0; read_data_response_sema.put(1); read_address_sema.put(1); repeat(2) @(vif.driver); endtask ////////////////////////////////////////// READ DATA AND RESPONSE CHANNEL task driver::read_data_response_channel(); read_data_response_sema.get(2); read_data_response_sema_1.get(1); read_data = read_data_response_queue.pop_front(); case (read_data.awburst) 2'b00 : rd_incr_burst; 2'b01 : rd_incr_burst; 2'b10 : rd_incr_burst; endcase read_data_response_sema_1.put(1); read_data_response_sema.put(1); endtask ////////////////////////////////////////// READ INCREMENT BURST task driver::rd_incr_burst(); for (int i = 0;i < read_data.arlen+1; i++) begin wait(vif.driver.rvalid); case (read_data.arsize) 2'b00 : read_data.rdata.push_back(vif.driver.rdata[7:0]); 2'b01 : read_data.rdata.push_back(vif.driver.rdata[15:0]); 2'b10 : read_data.rdata.push_back(vif.driver.rdata[31:0]); endcase case(vif.driver.rresp) 2'b00 : read_data.rresp[i] = "TRANSACTION OKAY \n"; 2'b01 : read_data.rresp[i] = "TRANSACTION FAILED \n"; 2'b10 : read_data.rresp[i] = "SLAVE ERROR \n"; 2'b11 : read_data.rresp[i] = "DECODE ERROR \n"; endcase repeat(read_data.rready_d) @(vif.driver); vif.driver.rready <= 1; @(vif.driver); vif.driver.rready <= 0; @(vif.driver); end read_data.control = 5; `uvm_info("MASTER_DRIVER",$sformatf("PRINTING FROM DRIVER \n %s",read_data.sprint()),UVM_MEDIUM) endtask