|
- class axi_drv extends uvm_driver#(axi_tx);
- virtual axi_intf vif;
- `uvm_component_utils(axi_drv)
- `NEW_COMP
-
- function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- if(!uvm_config_db#(virtual axi_intf)::get(this, "", "vif", vif)) begin
- `uvm_error("CONFG_DB", "Not able to get axi intf handle")
- end
- endfunction
-
- task run_phase(uvm_phase phase);
- @(negedge vif.arst);//waiting for release the reset
- forever begin
- seq_item_port.get_next_item(req);
- req.print();
- drive_tx(req);
- seq_item_port.item_done();
- end
- endtask
-
- task drive_tx(axi_tx tx);
- if (tx.wr_rd == 1) begin
- write_addr(tx);
- write_data(tx);
- write_resp(tx);
- end
- if (tx.wr_rd == 0) begin
- read_addr(tx);
- read_data(tx);
- end
- endtask
-
- task write_addr(axi_tx tx);
- `uvm_info("AXI_TX", "write_addr", UVM_MEDIUM);
- //Master drives all write address channel signals (aw), it will drive at the posedge of clock
- @(vif.mst_cb);
- vif.mst_cb.awaddr <= tx.addr;
- vif.mst_cb.awlen <= tx.burst_len;
- vif.mst_cb.awsize <= tx.burst_size;
- vif.mst_cb.awburst <= tx.burst_type;
- vif.mst_cb.awid <= tx.txid;
- vif.mst_cb.awvalid <= 1'b1;
- wait (vif.mst_cb.awready == 1'b1);
- @(vif.mst_cb);
- vif.mst_cb.awaddr <= 0;
- vif.mst_cb.awlen <= 0;
- vif.mst_cb.awsize <= 0;
- vif.mst_cb.awburst <= 0;
- vif.mst_cb.awid <= 0;
- vif.mst_cb.awvalid <= 0;
- endtask
-
- task write_data(axi_tx tx);
- `uvm_info("AXI_TX", "write_data", UVM_MEDIUM);
- for (int i = 0; i <= tx.burst_len; i++) begin
- @(vif.mst_cb)
- vif.mst_cb.wdata <= tx.dataQ.pop_front();
- vif.mst_cb.wstrb <= 4'b1111; //need to be updated as per the burst size
- vif.mst_cb.wvalid <= 1'b1;
- vif.mst_cb.wid <= tx.txid;
- //wlast=1 will be in last beat
- if(i == tx.burst_len) vif.mst_cb.wlast <= 1'b1;
- else vif.mst_cb.wlast <= 0;
- wait(vif.mst_cb.wready == 1'b1);
- end
- //once data beats are done, then reset all signals to 0
- @(vif.mst_cb);
- vif.mst_cb.wvalid <= 0;
- vif.mst_cb.wlast <= 0;
- vif.mst_cb.wdata <= 0;
- vif.mst_cb.wstrb <= 0;
- vif.mst_cb.wid <= 0;
- endtask
-
- task write_resp(axi_tx tx);
- bit bvalid_f = 0;
- //`uvm_info("AXI_TX", "write_resp", UVM_MEDIUM);
- //write response is initiated by slave
- while (bvalid_f == 0) begin
- @(vif.mst_cb);
- bvalid_f = vif.mst_cb.bvalid;
- end
- vif.mst_cb.bready <= 1'b1;
- @(vif.mst_cb);
- vif.mst_cb.bready <= 1'b0;
- endtask
-
- task read_addr(axi_tx tx);
- `uvm_info("AXI_TX", "read_addr", UVM_MEDIUM);
- @(vif.mst_cb);
- vif.mst_cb.araddr <= tx.addr;
- vif.mst_cb.arlen <= tx.burst_len;
- vif.mst_cb.arsize <= tx.burst_size;
- vif.mst_cb.arburst <= tx.burst_type;
- vif.mst_cb.arid <= tx.txid;
- vif.mst_cb.arvalid <= 1'b1;
- wait (vif.mst_cb.arready == 1'b1);
- @(vif.mst_cb);
- vif.mst_cb.araddr <= 0;
- vif.mst_cb.arlen <= 0;
- vif.mst_cb.arsize <= 0;
- vif.mst_cb.arburst <= 0;
- vif.mst_cb.arid <= 0;
- vif.mst_cb.arvalid <= 0;
- endtask
-
- task read_data(axi_tx tx);
- bit rvalid_f = 0;
- `uvm_info("AXI_TX", "read_data", UVM_MEDIUM);
- //since read data is happening multiple times, then handshaking should do multiple times
- for (int i = 0; i <= tx.burst_len; i++) begin
- rvalid_f = 0;
- while (rvalid_f == 0) begin
- @(vif.mst_cb);
- rvalid_f = vif.mst_cb.rvalid;
- vif.mst_cb.rready <= 1'b1;
- end
- end
- @(vif.mst_cb);
- vif.mst_cb.rready <= 1'b0;
- endtask
-
- endclass
|