|
|
@@ -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< (txn.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;
|
|
|
|
txn.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.reset==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
|
|
|
|
|