ソースを参照

manoj files

master
manojkumar 8ヶ月前
コミット
82db6b6fb2
1個のファイルの変更471行の追加267行の削除
  1. +471
    -267
      axi_driver.sv

+ 471
- 267
axi_driver.sv ファイルの表示

@@ -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



読み込み中…
キャンセル
保存