|
|
@@ -1,62 +1,14 @@ |
|
|
|
//driver |
|
|
|
class driver extends uvm_driver #(packet); |
|
|
|
`uvm_component_utils(driver) |
|
|
|
|
|
|
|
`uvm_component_utils(driver) |
|
|
|
virtual axi_if vif; |
|
|
|
packet pkt; |
|
|
|
|
|
|
|
function new(string name="driver", uvm_component parent=null); |
|
|
|
super.new(name, parent); |
|
|
|
endfunction |
|
|
|
|
|
|
|
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"); |
|
|
@@ -64,208 +16,268 @@ endfunction |
|
|
|
`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 |
|
|
|
task reset_dut(); |
|
|
|
repeat (3) begin |
|
|
|
//write address channel |
|
|
|
vif.awvalid <= 0; |
|
|
|
vif.awready <= 0; |
|
|
|
vif.awid <= 0; |
|
|
|
vif.awlen <= 0; |
|
|
|
vif.awsize <= 0; |
|
|
|
vif.awaddr <= 0; |
|
|
|
vif.awburst <= 0; |
|
|
|
//write data channel (w) |
|
|
|
vif.wvalid <= 0; |
|
|
|
vif.wready <= 0; |
|
|
|
vif.wid <= 0; |
|
|
|
vif.wdata <= 0; |
|
|
|
vif.wstrb <= 0; |
|
|
|
vif.wlast <= 0; |
|
|
|
//write response channel (b) |
|
|
|
vif.bready <= 0; |
|
|
|
vif.bvalid <= 0; |
|
|
|
vif.bid <= 0; |
|
|
|
vif.bresp <= 0; |
|
|
|
///////////////read address channel (ar) |
|
|
|
vif.arvalid <= 0; |
|
|
|
vif.arready <= 0; |
|
|
|
vif.arid <= 0; |
|
|
|
vif.arlen <= 0; |
|
|
|
vif.arsize <= 0; |
|
|
|
vif.araddr <= 0; |
|
|
|
vif.arburst <= 0; |
|
|
|
/////////// read data channel (r) |
|
|
|
vif.rvalid <= 0; |
|
|
|
vif.rready <= 0; |
|
|
|
vif.rid <= 0; |
|
|
|
vif.rdata <= 0; |
|
|
|
vif.rstrb <= 0; |
|
|
|
vif.rlast <= 0; |
|
|
|
vif.rresp <= 0; |
|
|
|
|
|
|
|
//1 clk delay |
|
|
|
@(posedge vif.clk); |
|
|
|
`uvm_info(get_type_name(),"*** Reset Applied by driver ***",UVM_MEDIUM) |
|
|
|
end |
|
|
|
endtask |
|
|
|
|
|
|
|
virtual task run_phase(uvm_phase phase); |
|
|
|
reset_dut(); |
|
|
|
forever begin |
|
|
|
seq_item_port.get_next_item(pkt); |
|
|
|
`uvm_info(get_type_name(),"*** Driver Received the transaction by sequencer ***",UVM_MEDIUM) |
|
|
|
|
|
|
|
//--------------------------------------------------------- |
|
|
|
//---------------------------------------------------------- |
|
|
|
//////////////////////////////////////// WRITE ADDRESS CHANNEL |
|
|
|
|
|
|
|
task write_address_pkt_channel(); |
|
|
|
|
|
|
|
`uvm_info("MASTER_DRIVER",$sformatf("PRINTING FROM DRIVER \n %s",pkt.sprint()),UVM_HIGH) |
|
|
|
|
|
|
|
endtask |
|
|
|
case (pkt.awburst) |
|
|
|
|
|
|
|
/////////////////////////////////////// SEND TO DUT |
|
|
|
2'b00 : write_address_fixed_burst; |
|
|
|
2'b01 : write_address_incr_burst; |
|
|
|
2'b10 : write_address_wrap_burst; |
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
endcase |
|
|
|
|
|
|
|
|
|
|
|
endtask |
|
|
|
//////////////////////////////////////// WRAP address BURST |
|
|
|
task write_address_wrap_burst(); |
|
|
|
begin |
|
|
|
int start_addr=(`INT pkt.awaddr/((pkt.awlen+1)*(2**pkt.awsize)))*((pkt.awlen+1)*(2**pkt.awsize)); |
|
|
|
int end_addr=(start_addr + ((pkt.awlen+1)*(2**pkt.awsize))); |
|
|
|
|
|
|
|
for (int i=0; i< (pkt.awlen+1);i++) |
|
|
|
begin |
|
|
|
vif.awaddr <= pkt.awaddr; |
|
|
|
|
|
|
|
if(vif.awaddr == end_addr) |
|
|
|
vif.awaddr <= start_addr; |
|
|
|
else |
|
|
|
vif.awaddr <= vif.awaddr+ (2**vif.awsize); |
|
|
|
vif.awid <= pkt.awid; |
|
|
|
vif.awvalid<= 1; |
|
|
|
wait(vif.awready); |
|
|
|
vif.awvalid<=0; |
|
|
|
end |
|
|
|
write_data_wrap_burst(); |
|
|
|
endtask |
|
|
|
/////////////////////////////////////// wrapBURST |
|
|
|
|
|
|
|
/////////////////////////////////////// WRITE ADDRESS CHANNEL |
|
|
|
|
|
|
|
task driver::write_address_channel(); |
|
|
|
task write_data_wrap_burst(); |
|
|
|
|
|
|
|
write_address_sema.get(1); |
|
|
|
if (vif.awvalid || vif.wvalid ||( vif.awvalid &&vif.wvalid)) |
|
|
|
foreach(pkt.wdata[i]) |
|
|
|
begin |
|
|
|
|
|
|
|
write_address = write_address_queue.pop_front(); |
|
|
|
case (pkt.wstrobe[i]) |
|
|
|
|
|
|
|
4'b0001 : vif.wdata [7:0] <= pkt.wdata[i]; |
|
|
|
4'b0010 : vif.wdata [15:8] <= pkt.wdata[i]; |
|
|
|
4'b0100 : vif.wdata [23:16] <= pkt.wdata[i]; |
|
|
|
4'b1000 : vif.wdata [31:24] <= pkt.wdata[i]; |
|
|
|
4'b0011 : vif.wdata [15:0] <= pkt.wdata[i]; |
|
|
|
4'b1100 : vif.wdata [31:16] <= pkt.wdata[i]; |
|
|
|
4'b1110 : vif.wdata [31:8] <= pkt.wdata[i]; |
|
|
|
4'b1111 : vif.wdata [31:0] <= pkt.wdata[i]; |
|
|
|
|
|
|
|
@(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; |
|
|
|
endcase |
|
|
|
|
|
|
|
@(vif.driver); |
|
|
|
vif.wstrobe <= pkt.wstrobe[i]; |
|
|
|
vif.wid <= pkt.wid; |
|
|
|
|
|
|
|
if (i == pkt.awlen ) |
|
|
|
vif.wlast <= 1; |
|
|
|
else |
|
|
|
vif.wlast <= 0; |
|
|
|
|
|
|
|
wait (vif.driver.awready); |
|
|
|
vif.wvalid <= 1; |
|
|
|
|
|
|
|
vif.driver.awvalid <= 0; |
|
|
|
|
|
|
|
write_data_sema.put(1); |
|
|
|
write_address_sema.put(1); |
|
|
|
|
|
|
|
repeat(2) |
|
|
|
@(vif.driver); |
|
|
|
endtask |
|
|
|
wait (vif.wready); |
|
|
|
|
|
|
|
//////////////////////////////////////// WRITE DATA CHANNEL |
|
|
|
vif.wlast <= 0; |
|
|
|
vif.wvalid <= 0; |
|
|
|
|
|
|
|
|
|
|
|
task driver::write_data_channel(); |
|
|
|
end |
|
|
|
write_response_channel (); |
|
|
|
endtask |
|
|
|
|
|
|
|
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); |
|
|
|
//////////////////////////////////////// INCR address INCREMENT BURST |
|
|
|
|
|
|
|
endtask |
|
|
|
task write_address_incr_burst(); |
|
|
|
vif.awlen <=pkt.awlen; |
|
|
|
for(int i=0; i<(awlen +1);i++) |
|
|
|
begin |
|
|
|
vif.awaddr<=pkt.awaddr; |
|
|
|
vif.awid <= pkt.awid; |
|
|
|
vif.awvalid<= 1; |
|
|
|
pkt.awaddr<= pkt.awaddr +(2**vif.awsize); |
|
|
|
wait(vif.awready); |
|
|
|
vif.awvalid<=0; |
|
|
|
|
|
|
|
/////////////////////////////////////// INCREMENT BURST |
|
|
|
end |
|
|
|
write_data_incr_burst(); |
|
|
|
endtask |
|
|
|
/////////////////////////////////////// write data INCREMENT BURST |
|
|
|
|
|
|
|
task driver::incr_burst(); |
|
|
|
task write_data_incr_burst(); |
|
|
|
|
|
|
|
foreach(write_data.wdata[i]) |
|
|
|
if (vif.awvalid || vif.wvalid ||( vif.awvalid &&vif.wvalid)) |
|
|
|
foreach(pkt.wdata[i]) |
|
|
|
begin |
|
|
|
|
|
|
|
case (write_data.wstrobe[i]) |
|
|
|
case (pkt.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]; |
|
|
|
4'b0001 : vif.wdata [7:0] <= pkt.wdata[i]; |
|
|
|
4'b0010 : vif.wdata [15:8] <= pkt.wdata[i]; |
|
|
|
4'b0100 : vif.wdata [23:16] <= pkt.wdata[i]; |
|
|
|
4'b1000 : vif.wdata [31:24] <= pkt.wdata[i]; |
|
|
|
4'b0011 : vif.wdata [15:0] <= pkt.wdata[i]; |
|
|
|
4'b1100 : vif.wdata [31:16] <= pkt.wdata[i]; |
|
|
|
4'b1110 : vif.wdata [31:8] <= pkt.wdata[i]; |
|
|
|
4'b1111 : vif.wdata [31:0] <= pkt.wdata[i]; |
|
|
|
|
|
|
|
endcase |
|
|
|
|
|
|
|
vif.driver.wstrobe <= write_data.wstrobe[i]; |
|
|
|
vif.driver.wid <= write_data.wid; |
|
|
|
vif.wstrobe <= pkt.wstrobe[i]; |
|
|
|
vif.wid <= pkt.wid; |
|
|
|
|
|
|
|
if (i == write_data.burst_len - 1) |
|
|
|
vif.driver.wlast <= 1; |
|
|
|
if (i == pkt.awlen ) |
|
|
|
vif.wlast <= 1; |
|
|
|
else |
|
|
|
vif.driver.wlast <= 0; |
|
|
|
vif.wlast <= 0; |
|
|
|
|
|
|
|
vif.driver.wvalid <= 1; |
|
|
|
vif.wvalid <= 1; |
|
|
|
|
|
|
|
@(vif.driver); |
|
|
|
|
|
|
|
wait (vif.driver.wready); |
|
|
|
wait (vif.wready); |
|
|
|
|
|
|
|
vif.driver.wlast <= 0; |
|
|
|
vif.driver.wvalid <= 0; |
|
|
|
vif.wlast <= 0; |
|
|
|
vif.wvalid <= 0; |
|
|
|
|
|
|
|
@(vif.driver); |
|
|
|
|
|
|
|
end |
|
|
|
write_response_channel (); |
|
|
|
endtask |
|
|
|
///////////////write address fixed burst |
|
|
|
task write_address_fixed_burst (); |
|
|
|
vif.awlen <= 4'b0000; |
|
|
|
vif.awid <= pkt.awid; |
|
|
|
vif.awaddr <= pkt.awaddr; |
|
|
|
vif.awvalid<= 1; |
|
|
|
wait(vif.awready); |
|
|
|
vif.awvalid<=0; |
|
|
|
write_data_fixed_burst(); |
|
|
|
|
|
|
|
/////////////////////////////////////// FIXED BURST |
|
|
|
endtask |
|
|
|
|
|
|
|
task driver::fixed_burst (); |
|
|
|
|
|
|
|
foreach(write_data.wdata[i]) |
|
|
|
////////////////////////////////////// write data first burst |
|
|
|
|
|
|
|
task write_data_fixed_burst (); |
|
|
|
if (vif.awvalid || vif.wvalid ||( vif.awvalid &&vif.wvalid)) |
|
|
|
foreach(pkt.wdata[i]) |
|
|
|
begin |
|
|
|
|
|
|
|
case (write_data.awsize) |
|
|
|
case (pkt.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]; |
|
|
|
3'b000 : vif.wdata[7:0] <= pkt.wdata[i]; |
|
|
|
3'b001 : vif.wdata[15:0] <= pkt.wdata[i]; |
|
|
|
3'b010 : vif.wdata[31:0] <= pkt.wdata[i]; |
|
|
|
3'b011 : vif.wdata[63:0] <= pkt.wdata[i]; |
|
|
|
3'b100 : vif.wdata[127:0] <= pkt.wdata[i]; |
|
|
|
3'b101 : vif.wdata[255:0] <= pkt.wdata[i]; |
|
|
|
3'b110 : vif.wdata[511:0] <= pkt.wdata[i]; |
|
|
|
3'b110 : vif.wdata[1023:0] <= pkt.wdata[i]; |
|
|
|
|
|
|
|
|
|
|
|
endcase |
|
|
|
|
|
|
|
vif.driver.wid <= write_data.wid; |
|
|
|
vif.wid <= pkt.wid; |
|
|
|
|
|
|
|
if (i == write_data.burst_len - 1) |
|
|
|
vif.driver.wlast <= 1; |
|
|
|
if (i == pkt.awlen) |
|
|
|
vif.wlast <= 1; |
|
|
|
else |
|
|
|
vif.driver.wlast <= 0; |
|
|
|
vif.wlast <= 0; |
|
|
|
vif.wvalid <= 1; |
|
|
|
wait (vif.wready); |
|
|
|
vif.wlast <= 0; |
|
|
|
vif.wvalid <= 0; |
|
|
|
|
|
|
|
vif.driver.wvalid <= 1; |
|
|
|
|
|
|
|
@(vif.driver); |
|
|
|
|
|
|
|
wait (vif.driver.wready); |
|
|
|
|
|
|
|
vif.driver.wlast <= 0; |
|
|
|
vif.driver.wvalid <= 0; |
|
|
|
|
|
|
|
@(vif.driver); |
|
|
|
end |
|
|
|
write_response_channel (); |
|
|
|
|
|
|
|
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); |
|
|
|
task write_response_channel (); |
|
|
|
if (vif.awvalid && vif.awready && vif.awlast) |
|
|
|
|
|
|
|
wait(vif.driver.bvalid) |
|
|
|
wait(vif.bvalid) |
|
|
|
begin |
|
|
|
|
|
|
|
write_response.bid = vif.driver.bid; |
|
|
|
write_response.bresp = vif.driver.bresp; |
|
|
|
vif.bid = pkt.bid; |
|
|
|
vif.bresp = pkt.bresp; |
|
|
|
end |
|
|
|
vif.bready <= 1; |
|
|
|
|
|
|
|
vif.driver.bready <= 1; |
|
|
|
@(vif.driver); |
|
|
|
|
|
|
|
foreach (write_response_queue[i]) |
|
|
|
foreach (vif.wdata[i]) |
|
|
|
begin |
|
|
|
if (write_response_queue[i].awid == write_response.bid) |
|
|
|
if (vif.awid == vif.bid) |
|
|
|
begin |
|
|
|
case (write_response.bresp) |
|
|
|
case (vif.bresp) |
|
|
|
|
|
|
|
2'b00 : s = "Transaction OKAY"; |
|
|
|
2'b01 : s = "Transaction FAILED"; |
|
|
@@ -276,118 +288,310 @@ task driver::write_response_channel (); |
|
|
|
|
|
|
|
`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); |
|
|
|
vif.bready <= 0; |
|
|
|
|
|
|
|
write_response_sema.put(1); |
|
|
|
write_response_sema_1.put(1); |
|
|
|
|
|
|
|
endtask |
|
|
|
|
|
|
|
/////////////////////////////////////// READ ADDRESS CHANNEL |
|
|
|
|
|
|
|
task driver::read_address_channel(); |
|
|
|
task read_address_pkt_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) |
|
|
|
`uvm_info("MASTER_DRIVER",$sformatf("PRINTING FROM DRIVER \n %s",pkt.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.arid <= pkt.arid; |
|
|
|
vif.araddr <= pkt.araddr; |
|
|
|
vif.arlen <= pkt.arlen; |
|
|
|
vif.arsize <= pkt.arsize; |
|
|
|
vif.arburst <= pkt.arburst; |
|
|
|
vif.arvalid <= 1; |
|
|
|
|
|
|
|
@(vif.driver); |
|
|
|
@(vif); |
|
|
|
|
|
|
|
wait (vif.driver.arready); |
|
|
|
wait (vif.arready); |
|
|
|
|
|
|
|
vif.driver.arvalid <= 0; |
|
|
|
vif.arvalid <= 0; |
|
|
|
|
|
|
|
read_data_response_sema.put(1); |
|
|
|
read_address_sema.put(1); |
|
|
|
pkt_sema.put(1); |
|
|
|
|
|
|
|
repeat(2) |
|
|
|
@(vif.driver); |
|
|
|
@(vif); |
|
|
|
endtask |
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//////////////////////////////////////// WRITE ADDRESS CHANNEL |
|
|
|
|
|
|
|
////////////////////////////////////////// READ DATA AND RESPONSE CHANNEL |
|
|
|
task read_address_pkt_channel(); |
|
|
|
|
|
|
|
task driver::read_data_response_channel(); |
|
|
|
|
|
|
|
read_data_response_sema.get(2); |
|
|
|
read_data_response_sema_1.get(1); |
|
|
|
`uvm_info("MASTER_DRIVER",$sformatf("PRINTING FROM DRIVER \n %s",pkt.sprint()),UVM_HIGH) |
|
|
|
|
|
|
|
read_data = read_data_response_queue.pop_front(); |
|
|
|
|
|
|
|
case (read_data.awburst) |
|
|
|
case (pkt.awburst) |
|
|
|
|
|
|
|
2'b00 : rd_incr_burst; |
|
|
|
2'b01 : rd_incr_burst; |
|
|
|
2'b10 : rd_incr_burst; |
|
|
|
2'b00 : read_address_fixed_burst; |
|
|
|
2'b01 : read_address_incr_burst; |
|
|
|
2'b10 : read_address_wrap_burst; |
|
|
|
|
|
|
|
endcase |
|
|
|
|
|
|
|
|
|
|
|
read_data_response_sema_1.put(1); |
|
|
|
read_data_response_sema.put(1); |
|
|
|
|
|
|
|
endtask |
|
|
|
//////////////////////////////////////// WRAP address BURST |
|
|
|
task read_address_wrap_burst(); |
|
|
|
begin |
|
|
|
int start_read_addr=(`INT pkt.araddr/((pkt.arlen+1)*(2**pkt.arsize)))*((pkt.arlen+1)*(2**pkt.arsize)); |
|
|
|
int end_read_addr=(start_read_addr + ((pkt.arlen+1)*(2**pkt.arsize))); |
|
|
|
|
|
|
|
for (int i=0; i< (pkt.arlen+1);i++) |
|
|
|
begin |
|
|
|
vif.araddr <= pkt.araddr; |
|
|
|
|
|
|
|
if(vif.araddr == end_read_addr) |
|
|
|
vif.araddr <= start_read_addr; |
|
|
|
else |
|
|
|
vif.araddr <= vif.araddr+ (2**vif.arsize); |
|
|
|
vif.arid <= pkt.arid; |
|
|
|
vif.arvalid<= 1; |
|
|
|
wait(vif.arready); |
|
|
|
vif.arvalid<=0; |
|
|
|
end |
|
|
|
read_data_wrap_burst(); |
|
|
|
endtask |
|
|
|
/////////////////////////////////////// wrapBURST |
|
|
|
|
|
|
|
task read_data_wrap_burst(); |
|
|
|
|
|
|
|
if (vif.arvalid || vif.rvalid ||( vif.arvalid &&vif.rvalid)) |
|
|
|
|
|
|
|
vif.arid <= pkt.rid; |
|
|
|
|
|
|
|
if (i == pkt.arlen ) |
|
|
|
vif.rlast <= 1; |
|
|
|
else |
|
|
|
vif.rlast <= 0; |
|
|
|
|
|
|
|
vif.rvalid <= 1; |
|
|
|
|
|
|
|
////////////////////////////////////////// READ INCREMENT BURST |
|
|
|
|
|
|
|
task driver::rd_incr_burst(); |
|
|
|
wait (vif.rready); |
|
|
|
|
|
|
|
for (int i = 0;i < read_data.arlen+1; i++) |
|
|
|
begin |
|
|
|
|
|
|
|
wait(vif.driver.rvalid); |
|
|
|
vif.rlast <= 0; |
|
|
|
vif.rvalid <= 0; |
|
|
|
|
|
|
|
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) |
|
|
|
end |
|
|
|
if (vif.arvalid && vif.arready && vif.arlast) |
|
|
|
|
|
|
|
wait(vif.rvalid) |
|
|
|
begin |
|
|
|
|
|
|
|
vif.rid = pkt.rid; |
|
|
|
vif.rresp = pkt.rresp; |
|
|
|
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"; |
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
`uvm_info("MASTER_DRIVER",$sformatf("\n\n \t\t\t\t\t\t %s RESPONSE FOR THE DATA \n",s),UVM_MEDIUM) |
|
|
|
|
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
vif.rready <= 0; |
|
|
|
|
|
|
|
endtask |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////// INCR address INCREMENT BURST |
|
|
|
|
|
|
|
task read_address_incr_burst(); |
|
|
|
vif.arlen <=pkt.arlen; |
|
|
|
for(int i=0; i<(arlen +1);i++) |
|
|
|
begin |
|
|
|
vif.araddr<=pkt.araddr; |
|
|
|
vif.arid <= pkt.arid; |
|
|
|
vif.arvalid<= 1; |
|
|
|
pkt.araddr<= pkt.araddr +(2**vif.arsize); |
|
|
|
wait(vif.arready); |
|
|
|
vif.arvalid<=0; |
|
|
|
|
|
|
|
end |
|
|
|
read_data_incr_burst(); |
|
|
|
endtask |
|
|
|
/////////////////////////////////////// read data INCREMENT BURST |
|
|
|
|
|
|
|
task read_data_incr_burst(); |
|
|
|
|
|
|
|
if (vif.arvalid || vif.rvalid ||( vif.arvalid &&vif.rvalid)) |
|
|
|
vif.rid <= pkt.rid; |
|
|
|
|
|
|
|
endcase |
|
|
|
for(int i=0; i<(arlen +1);i++) |
|
|
|
begin |
|
|
|
vif.rdata <= pkt.rdata; |
|
|
|
if (i == pkt.arlen ) |
|
|
|
vif.rlast <= 1; |
|
|
|
else |
|
|
|
vif.rlast <= 0; |
|
|
|
|
|
|
|
vif.rvalid <= 1; |
|
|
|
|
|
|
|
|
|
|
|
repeat(read_data.rready_d) |
|
|
|
@(vif.driver); |
|
|
|
wait (vif.rready); |
|
|
|
|
|
|
|
vif.driver.rready <= 1; |
|
|
|
vif.rlast <= 0; |
|
|
|
vif.rvalid <= 0; |
|
|
|
|
|
|
|
|
|
|
|
@(vif.driver); |
|
|
|
end |
|
|
|
if (vif.arvalid && vif.arready && vif.arlast) |
|
|
|
|
|
|
|
vif.driver.rready <= 0; |
|
|
|
wait(vif.rvalid) |
|
|
|
begin |
|
|
|
|
|
|
|
@(vif.driver); |
|
|
|
vif.rid = pkt.rid; |
|
|
|
vif.rresp = pkt.rresp; |
|
|
|
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\n \t\t\t\t\t\t %s RESPONSE FOR THE DATA \n",s),UVM_MEDIUM) |
|
|
|
|
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
vif.rready <= 0; |
|
|
|
|
|
|
|
|
|
|
|
endtask |
|
|
|
///////////////read address fixed burst |
|
|
|
task read_address_fixed_burst (); |
|
|
|
begin |
|
|
|
vif.arlen <= 4'b0000; |
|
|
|
vif.arid <= pkt.arid; |
|
|
|
vif.araddr <= pkt.araddr; |
|
|
|
vif.arvalid<= 1; |
|
|
|
wait(vif.arready); |
|
|
|
vif.arvalid<=0; |
|
|
|
end |
|
|
|
read_data_fixed_burst(); |
|
|
|
|
|
|
|
endtask |
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////// read data first burst |
|
|
|
|
|
|
|
task read_data_fixed_burst (); |
|
|
|
if (vif.arvalid || vif.rvalid ||( vif.arvalid &&vif.rvalid)) |
|
|
|
foreach(pkt.rdata[i]) |
|
|
|
begin |
|
|
|
|
|
|
|
case (pkt.arsize) |
|
|
|
|
|
|
|
3'b000 : vif.rdata[7:0] <= pkt.rdata[i]; |
|
|
|
3'b001 : vif.rdata[15:0] <= pkt.rdata[i]; |
|
|
|
3'b010 : vif.rdata[31:0] <= pkt.rdata[i]; |
|
|
|
3'b011 : vif.rdata[63:0] <= pkt.rdata[i]; |
|
|
|
3'b100 : vif.rdata[127:0] <= pkt.rdata[i]; |
|
|
|
3'b101 : vif.rdata[255:0] <= pkt.rdata[i]; |
|
|
|
3'b110 : vif.rdata[511:0] <= pkt.rdata[i]; |
|
|
|
3'b110 : vif.rdata[1023:0] <= pkt.rdata[i]; |
|
|
|
|
|
|
|
|
|
|
|
endcase |
|
|
|
|
|
|
|
vif.rid <= pkt.rid; |
|
|
|
|
|
|
|
if (i == pkt.arlen) |
|
|
|
vif.rlast <= 1; |
|
|
|
else |
|
|
|
vif.rlast <= 0; |
|
|
|
vif.rvalid <= 1; |
|
|
|
wait (vif.rready); |
|
|
|
vif.rlast <= 0; |
|
|
|
vif.rvalid <= 0; |
|
|
|
|
|
|
|
|
|
|
|
read_data.control = 5; |
|
|
|
`uvm_info("MASTER_DRIVER",$sformatf("PRINTING FROM DRIVER \n %s",read_data.sprint()),UVM_MEDIUM) |
|
|
|
end |
|
|
|
if (vif.arvalid && vif.arready && vif.arlast) |
|
|
|
|
|
|
|
wait(vif.rvalid) |
|
|
|
begin |
|
|
|
|
|
|
|
vif.rid = pkt.rid; |
|
|
|
vif.rresp = pkt.rresp; |
|
|
|
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\n \t\t\t\t\t\t %s RESPONSE FOR THE DATA \n",s),UVM_MEDIUM) |
|
|
|
|
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
vif.rready <= 0; |
|
|
|
|
|
|
|
endtask |
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
|
|
|
|
|
if(pkt.op==RESET) begin |
|
|
|
reset_dut(); |
|
|
|
end |
|
|
|
//Write operation support |
|
|
|
else if(pkt.op == WRITE) begin |
|
|
|
`uvm_info(get_type_name(),"*** WRITE packet is received in driver ***",UVM_MEDIUM) |
|
|
|
begin |
|
|
|
write_address_pkt_channel(); |
|
|
|
end |
|
|
|
|
|
|
|
//read operation support |
|
|
|
else if( pkt.op == READ) |
|
|
|
begin |
|
|
|
read_address_pkt_channel(); |
|
|
|
//put read drive logic here |
|
|
|
end |
|
|
|
|
|
|
|
seq_item_port.item_done(); |
|
|
|
end |
|
|
|
endtask |
|
|
|
endclass |
|
|
|
|
|
|
|
|