|
|
@@ -0,0 +1,152 @@ |
|
|
|
class axi_drv extends uvm_driver#(axi_seq_item) |
|
|
|
|
|
|
|
`uvm_components_utils(axi_drv) |
|
|
|
|
|
|
|
virtual intf vif; |
|
|
|
axi_seq_item txn; |
|
|
|
|
|
|
|
int [31:0] temp[]; |
|
|
|
|
|
|
|
function new(string name="axi_drv",uvm_component parent); |
|
|
|
super.new(name.parent); |
|
|
|
endfunction |
|
|
|
|
|
|
|
function void build_phase(uvm_phase phase); |
|
|
|
|
|
|
|
uvm_config_db#(virtual intf)::get(this,"",vif,vif); |
|
|
|
txn=axi_seq_item::type_id::create(txn); |
|
|
|
|
|
|
|
endfunction |
|
|
|
|
|
|
|
task run_phase(uvm_phase phase); |
|
|
|
begin |
|
|
|
get_next_item(txn); |
|
|
|
drive(txn); |
|
|
|
item_done(); |
|
|
|
|
|
|
|
endtask |
|
|
|
|
|
|
|
task drive(txn); |
|
|
|
|
|
|
|
fork |
|
|
|
// reset(); |
|
|
|
write_add(txn); |
|
|
|
write_data(txn); |
|
|
|
read_add(txn); |
|
|
|
|
|
|
|
join |
|
|
|
endtask |
|
|
|
|
|
|
|
///////////////write addr/////////// |
|
|
|
|
|
|
|
task write_add(txn); |
|
|
|
int lower_wrap_boundary; |
|
|
|
int upper_wrap_boundary; |
|
|
|
int burst_len,burst_size; |
|
|
|
int total_trans; |
|
|
|
|
|
|
|
if(txn.write==1) |
|
|
|
begin |
|
|
|
@(vif.clk); |
|
|
|
vif.awid<=txn.awid; |
|
|
|
vif.awlen<=txn.awlen; |
|
|
|
vif.awsize<=txn.awsize; |
|
|
|
vif.awburst<=txn.awburst; |
|
|
|
|
|
|
|
/////////fixed burst///////////// |
|
|
|
|
|
|
|
if(txn.awburst==2'b00) |
|
|
|
begin |
|
|
|
vif.awaddr<=txn.awaddr; |
|
|
|
end |
|
|
|
|
|
|
|
/////////////incr burst////////////// |
|
|
|
|
|
|
|
else if(txn.awaddr==2'b01) |
|
|
|
begin |
|
|
|
vif.awaddr<=txn.awaddr; |
|
|
|
for(int i=0;i<awlen;i++) |
|
|
|
begin |
|
|
|
vif.awaddr<=txn.awaddr+(2**awsize); |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
//////////////////////wrap burst////////// |
|
|
|
|
|
|
|
else if(txn.awaddr==2'b10) |
|
|
|
begin |
|
|
|
if(awaddr%(2**awsize==0)) |
|
|
|
begin |
|
|
|
burst_len=awlen+1; |
|
|
|
burst_size=2**awsize; |
|
|
|
total_trans=burst_len*burst_size; |
|
|
|
|
|
|
|
lower_wrap_boundary=int'(awaddr/total_trans)*total_trans; |
|
|
|
upper_wrap_boundary=lower_wrap_boundary+total_trans; |
|
|
|
|
|
|
|
end |
|
|
|
end |
|
|
|
vif.awvalid<=1; |
|
|
|
wait(vif.awready); |
|
|
|
@(vif.clk); |
|
|
|
vif.awvalid<=0; |
|
|
|
end |
|
|
|
|
|
|
|
endtask |
|
|
|
|
|
|
|
//////////////write data/////////////// |
|
|
|
|
|
|
|
task write_data(txn); |
|
|
|
begin |
|
|
|
temp=new[txn.awlen+1]; |
|
|
|
|
|
|
|
forech(txn.wdata[i][j]) |
|
|
|
begin |
|
|
|
temp[i][8*j+:8]=data[i][j]; |
|
|
|
end |
|
|
|
|
|
|
|
for(i=0;i<awlen+1;i++) |
|
|
|
begin |
|
|
|
|
|
|
|
@(vif.clk); |
|
|
|
vif.wid<=txn.wid; |
|
|
|
vif.wdata<=temp[i]; |
|
|
|
vif.wlast<=(awlen==i)?1:0; |
|
|
|
end |
|
|
|
vif.wvalid<=1; |
|
|
|
wait(vif.wready) |
|
|
|
@(vif.clk); |
|
|
|
vif.wvalid<=0; |
|
|
|
end |
|
|
|
endtask |
|
|
|
|
|
|
|
///////////read addr/////////// |
|
|
|
|
|
|
|
task read_add(txn); |
|
|
|
begin |
|
|
|
if(!txn.write) |
|
|
|
begin |
|
|
|
@(vif.clk); |
|
|
|
vif.arid<=txn.arid; |
|
|
|
vif.araddr<=txn.araddr; |
|
|
|
vif.arlen<=txn.arlen; |
|
|
|
vif.arsize<=txn.arsize; |
|
|
|
vif.arburst<=txn.arburst; |
|
|
|
vif.arvalid<=1; |
|
|
|
wait(vif.arready); |
|
|
|
@(vif.clk); |
|
|
|
vif.arvalid<=0; |
|
|
|
end |
|
|
|
end |
|
|
|
endtask |
|
|
|
|
|
|
|
|
|
|
|
endclass |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|