|
@@ -0,0 +1,195 @@ |
|
|
|
|
|
|
|
|
|
|
|
class axi_driver extends uvm_driver; |
|
|
|
|
|
`uvm_component_utils(axi_driver) |
|
|
|
|
|
seq_item s; |
|
|
|
|
|
virtual interface vif; |
|
|
|
|
|
int lower_boundary; |
|
|
|
|
|
int upper_boundary; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function new(string name="driver",uvm_component parent); |
|
|
|
|
|
super.new(name,parent); |
|
|
|
|
|
endfunction |
|
|
|
|
|
|
|
|
|
|
|
function void build_phase(uvm_component phase); |
|
|
|
|
|
super.build_phase(phase); |
|
|
|
|
|
if(!uvm_config_db(virtual intf)::get(this," ","vif",vif); |
|
|
|
|
|
`uvm_fatal("driver interface failed"); |
|
|
|
|
|
endfunction |
|
|
|
|
|
|
|
|
|
|
|
task run_phase(uvm_phase phase); |
|
|
|
|
|
forever |
|
|
|
|
|
begin |
|
|
|
|
|
s = seq_item::type_id::create("s"); |
|
|
|
|
|
seq_item_port.get_next_item(s); |
|
|
|
|
|
drive_logic(s); |
|
|
|
|
|
seq_item_port.item_done(); |
|
|
|
|
|
end |
|
|
|
|
|
endtask |
|
|
|
|
|
|
|
|
|
|
|
task drive_logic(); |
|
|
|
|
|
reset(); |
|
|
|
|
|
fork |
|
|
|
|
|
write_address(); |
|
|
|
|
|
write_data(); |
|
|
|
|
|
write_response(); |
|
|
|
|
|
read_address(); |
|
|
|
|
|
read_data(); |
|
|
|
|
|
join |
|
|
|
|
|
endtask |
|
|
|
|
|
|
|
|
|
|
|
task reset(); |
|
|
|
|
|
@(posedge vif.clk) |
|
|
|
|
|
|
|
|
|
|
|
vif.awid <= 0; |
|
|
|
|
|
vif.awaddr <= 0; |
|
|
|
|
|
vif.awlen <= 0; |
|
|
|
|
|
vif.awsize <= 0; |
|
|
|
|
|
vif.awburst <= 0; |
|
|
|
|
|
vif.awvalid <= 0; |
|
|
|
|
|
vif.awready<=0 |
|
|
|
|
|
|
|
|
|
|
|
vif.wid <= 0; |
|
|
|
|
|
vif.wdata <= 0; |
|
|
|
|
|
vif.wstrobe <= 0; |
|
|
|
|
|
vif.wlast <= 0; |
|
|
|
|
|
vif.wvalid <= 0; |
|
|
|
|
|
vif.wready<=0; |
|
|
|
|
|
|
|
|
|
|
|
vif.bid <= 0; |
|
|
|
|
|
vif.bresp <= 0; |
|
|
|
|
|
vif.bvalid <=0; |
|
|
|
|
|
vif.bready <=0; |
|
|
|
|
|
|
|
|
|
|
|
vif.arid <= 0; |
|
|
|
|
|
vif.araddress <= 0; |
|
|
|
|
|
vif.arlen <= 0; |
|
|
|
|
|
vif.arsize <= 0; |
|
|
|
|
|
vif.arburst <= 0; |
|
|
|
|
|
vif.arvalid <= 0; |
|
|
|
|
|
vif.arready<=0 |
|
|
|
|
|
|
|
|
|
|
|
vif.rid <= 0; |
|
|
|
|
|
vif.rdata <= 0; |
|
|
|
|
|
vif.rlast <= 0; |
|
|
|
|
|
vif.rvalid <= 0; |
|
|
|
|
|
vif.rready<=0; |
|
|
|
|
|
endtask |
|
|
|
|
|
|
|
|
|
|
|
task write_address(); |
|
|
|
|
|
@(posedge vif.clk) |
|
|
|
|
|
if(wr_rd==1) |
|
|
|
|
|
vif.awid <= s.awid; |
|
|
|
|
|
vif.awaddr <= s.awaddr; |
|
|
|
|
|
|
|
|
|
|
|
if(awburst==2'b01) |
|
|
|
|
|
awaddr<=awaddr+(2**awsize); |
|
|
|
|
|
|
|
|
|
|
|
if(awburst==2'b10) |
|
|
|
|
|
begin |
|
|
|
|
|
lower_boundary<=(awaddr%((awlen+1)(2**awsize)))*((awlen+1)(2**awsize)); |
|
|
|
|
|
upper_boundary<=lower_boundary+((awlen+1)(2**awsize)); |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
vif.awlen <= s.awlen; |
|
|
|
|
|
vif.awsize <= s.awsize; |
|
|
|
|
|
vif.awburst <= s.awburst; |
|
|
|
|
|
vif.awvalid <= 1; |
|
|
|
|
|
@(posedge vif.clk) |
|
|
|
|
|
wait(vif.awready) |
|
|
|
|
|
vif.awvalid <= 0; |
|
|
|
|
|
endtask |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
task write_data(); |
|
|
|
|
|
@(posedge vif.clk) |
|
|
|
|
|
vif.wid <= s.wid; |
|
|
|
|
|
vif.wdata <= s.wdata[i]; |
|
|
|
|
|
vif.wstrobe <= s.wstrobe[i]; |
|
|
|
|
|
vif.wlast <= s.wlast; |
|
|
|
|
|
vif.wvalid <= 1; |
|
|
|
|
|
|
|
|
|
|
|
for(int i=0;i<awlen+1;i=i+1) |
|
|
|
|
|
begin |
|
|
|
|
|
if(i==awlen+1) |
|
|
|
|
|
vif.wlast <= 1; |
|
|
|
|
|
|
|
|
|
|
|
@(posedge vif.clk) |
|
|
|
|
|
wait(vif.wready) |
|
|
|
|
|
vif.wvalid<=0; |
|
|
|
|
|
vif.wlast <= 0; |
|
|
|
|
|
end |
|
|
|
|
|
endtask |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
task write_response(); |
|
|
|
|
|
@(posedge vif.clk) |
|
|
|
|
|
vif.bid <= s.bid; |
|
|
|
|
|
vif.bresp <= s.bresp; |
|
|
|
|
|
vif.bvalid <= 1; |
|
|
|
|
|
@(posedge vif.clk) |
|
|
|
|
|
wait(vif.bready) |
|
|
|
|
|
vif.bvalid<=0; |
|
|
|
|
|
endtask |
|
|
|
|
|
|
|
|
|
|
|
task read_address(); |
|
|
|
|
|
@(posedge vif.clk) |
|
|
|
|
|
if(wr_rd==0) |
|
|
|
|
|
vif.arid <= s.arid; |
|
|
|
|
|
vif.araddr <= s.araddr; |
|
|
|
|
|
|
|
|
|
|
|
if(arburst==2'b01) |
|
|
|
|
|
araddr<=araddr+(2**arsize); |
|
|
|
|
|
|
|
|
|
|
|
if(arburst==2'b10) |
|
|
|
|
|
begin |
|
|
|
|
|
lower_boundary<=(araddr%((arlen+1)(2**arsize)))*((arlen+1)(2**arsize)); |
|
|
|
|
|
upper_boundary<=lower_boundary+((arlen+1)(2**arsize)); |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vif.arlen <= s.arlen; |
|
|
|
|
|
vif.arsize <= s.arsize; |
|
|
|
|
|
vif.arburst <= s.arburst; |
|
|
|
|
|
vif.arvalid <= 1; |
|
|
|
|
|
@(posedge vif.clk) |
|
|
|
|
|
wait(vif.arready) |
|
|
|
|
|
vif.arvalid <= 0; |
|
|
|
|
|
endtask |
|
|
|
|
|
|
|
|
|
|
|
task read_data(); |
|
|
|
|
|
@(posedge vif.clk) |
|
|
|
|
|
vif.rid <= s.rid; |
|
|
|
|
|
vif.rdata <= s.rdata; |
|
|
|
|
|
vif.rlast <= s.rlast; |
|
|
|
|
|
vif.rresp <= s.rresp; |
|
|
|
|
|
vif.rvalid <= 1; |
|
|
|
|
|
|
|
|
|
|
|
for(int i=0;i<=arlen+1;i=i+1) |
|
|
|
|
|
begin |
|
|
|
|
|
if(i==arlen+1) |
|
|
|
|
|
vif.rlast <= 1; |
|
|
|
|
|
|
|
|
|
|
|
@(posedge vif.clk) |
|
|
|
|
|
wait(vif.rready) |
|
|
|
|
|
vif.rvalid<=0; |
|
|
|
|
|
vif.rlast <= 0; |
|
|
|
|
|
end |
|
|
|
|
|
endtask |
|
|
|
|
|
endclass |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|