UVM中uvm_driver的写法
书本上的一般写法:
`ifndef MY_DRIVER__SV
`define MY_DRIVER__SV
class my_driver extends uvm_driver#(my_transaction);
virtual my_if vif;
`uvm_component_utils(my_driver)
function new(string name = "my_driver", uvm_component parent = null);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
if(!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif))
`uvm_fatal("my_driver", "virtual interface must be set for vif!!!")
endfunction
extern task main_phase(uvm_phase phase);
extern task drive_one_pkt(my_transaction tr);
endclass
task my_driver::main_phase(uvm_phase phase);
vif.data <= 8'b0;
vif.valid <= 1'b0;
while(!vif.rst_n) //
@(posedge vif.clk); //
while(1) begin //
seq_item_port.get_next_item(req); //
drive_one_pkt(req); //
seq_item_port.item_done(); //
end
endtask
task my_driver::drive_one_pkt(my_transaction tr); //
byte unsigned data_q[];
int data_size;
data_size = tr.pack_bytes(data_q) / 8;
`uvm_info("my_driver", "begin to drive one pkt", UVM_LOW);
repeat(3) @(posedge vif.clk);
for ( int i = 0; i < data_size; i++ ) begin
@(posedge vif.clk);
vif.valid <= 1'b1;
vif.data <= data_q[i];
end
@(posedge vif.clk);
vif.valid <= 1'b0;
`uvm_info("my_driver", "end drive one pkt", UVM_LOW);
endtask
`endif
课本上的一般写法:有response
`ifndef MY_DRIVER__SV
`define MY_DRIVER__SV
class my_driver extends uvm_driver#(my_transaction);
virtual my_if vif;
`uvm_component_utils(my_driver)
function new(string name = "my_driver", uvm_component parent = null);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
if(!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif))
`uvm_fatal("my_driver", "virtual interface must be set for vif!!!")
endfunction
extern task main_phase(uvm_phase phase);
extern task drive_one_pkt(my_transaction tr);
endclass
task my_driver::main_phase(uvm_phase phase);
vif.data <= 8'b0;
vif.valid <= 1'b0;
while(!vif.rst_n) //
@(posedge vif.clk); //
while(1) begin
seq_item_port.get_next_item(req); //
drive_one_pkt(req); //
rsp = new("rsp"); //
rsp.set_id_info(req); //
seq_item_port.put_response(rsp); //
seq_item_port.item_done(); //
end
或者
while(1) begin
seq_item_port.get_next_item(req); //
drive_one_pkt(req); //
rsp = new("rsp"); //
rsp.set_id_info(req); //
seq_item_port.item_done(rsp); //
end
endtask
task my_driver::drive_one_pkt(my_transaction tr); //
byte unsigned data_q[];
int data_size;
data_size = tr.pack_bytes(data_q) / 8;
//`uvm_info("my_driver", "begin to drive one pkt", UVM_LOW);
repeat(3) @(posedge vif.clk);
for ( int i = 0; i < data_size; i++ ) begin
@(posedge vif.clk);
vif.valid <= 1'b1;
vif.data <= data_q[i];
end
@(posedge vif.clk);
vif.valid <= 1'b0;
//`uvm_info("my_driver", "end drive one pkt", UVM_LOW);
endtask
`endif
其他driver的写法:
class chnl_driver extends uvm_driver #(chnl_trans);
local virtual chnl_intf intf;
`uvm_component_utils(chnl_driver)
function new (string name = "chnl_driver", uvm_component parent);
super.new(name, parent);
endfunction
function void set_interface(virtual chnl_intf intf);
if(intf == null)
$error("interface handle is NULL, please check if target interface has been intantiated");
else
this.intf = intf;
endfunction
task run_phase(uvm_phase phase);
fork //
this.do_drive(); //
this.do_reset(); //
join //
endtask
task do_reset();
forever begin
@(negedge intf.rstn);
intf.ch_valid <= 0;
intf.ch_data <= 0;
intf.ch_data_p <= 0;
end
endtask
task do_drive(); //
chnl_trans req, rsp;
@(posedge intf.rstn);
forever begin
seq_item_port.get_next_item(req);
this.chnl_write(req);
void'($cast(rsp, req.clone()));
rsp.rsp = 1;
rsp.set_sequence_id(req.get_sequence_id());
seq_item_port.item_done(rsp);
end
endtask
task chnl_write(input chnl_trans t);
foreach(t.data[i]) begin
@(posedge intf.clk);
intf.drv_ck.ch_valid <= 1;
intf.drv_ck.ch_data <= t.data[i];
intf.drv_ck.ch_data_p <= get_parity(t.data[i]);
@(negedge intf.clk);
wait(intf.ch_wait === 'b0);
`uvm_info(get_type_name(), $sformatf("sent data 'h%8x", t.data[i]), UVM_HIGH)
repeat(t.data_nidles) chnl_idle();
end
repeat(t.pkt_nidles) chnl_idle();
endtask
task chnl_idle();
@(posedge intf.clk);
intf.drv_ck.ch_valid <= 0;
intf.drv_ck.ch_data <= 0;
intf.drv_ck.ch_data_p <= 0;
endtask
function get_parity(bit[31:0] data);
return ^data;
endfunction
endclass: chnl_driver


浙公网安备 33010602011771号