TEST宏
// ``作用为分割两个单词
// (这个操作不会引入空格)(重点!宏替换是按照单词索引,空格
// 和``都可以分割单词)
// `"特殊的双引号,使用特殊的双引号,引号内的东西也会被宏替换掉
// 如果是普通的双引号,双引号里面有关宏的单词不会被替换
// 注意:特殊的双引号也是双引号,其表现出来的就是双引号
// `\代表普通的斜线,因为斜线在宏里默认代表分隔符。这个是使用斜线的本身义
`define Generate_test(testname,seqname) \
class testname extends uvm_test; \
env top_env; \
`uvm_component_utils(testname) \
function new(string name = "testname", uvm_component parent = null); \
super.new(name, parent); \
endfunction \
function void build_phase(uvm_phase phase); \
super.build_phase(phase); \
top_env = env::type_id::create("top_env", this); \
uvm_config_db#(uvm_object_wrapper)::set(this, \
"top_env.agent_aa.sequencer.main_phase", \
"default_sequence", \
seqname``::type_id::get()); \
endfunction\
endclass\
//default_sequence方式启动sequence
//只需要在某个component的build_phase中设置
//(最好在最顶层的class里面启动sequence,比如uvm_test类或其衍生类)
// 然后在sequence里还要加入特殊的举手操作
软件包
package pack1; //pack1头
import uvm_pkg::*; //+UVM
`include "uvm_macros.svh"//+工厂
//A-item
class item_a extends uvm_sequence_item;
rand bit [7:0] data_a;
`uvm_object_utils_begin(item_a)
`uvm_field_int(data_a,UVM_ALL_ON)
`uvm_object_utils_end
function new(string name = "item_a");
super.new(name);
endfunction
endclass
//A-sequence
class seq_a extends uvm_sequence;
int database = 4;
`uvm_object_utils(seq_a)
function new(string name = "seq_a");
super.new(name);
endfunction
task body();
item_a req;
if(starting_phase != null) //default_sequence use
starting_phase.raise_objection(this);//default_sequence use
repeat(3) begin
#20ns;
`uvm_do_with(
req,
{data_a inside {[database:database+9]};}
)
end
#20ns;
if(starting_phase != null) //default_sequence use
starting_phase.drop_objection(this);//default_sequence use
endtask
endclass
//A-sequencer
class seqr_a extends uvm_sequencer;
`uvm_component_utils(seqr_a)
function new(string name = "seqr_a", uvm_component parent = null);
super.new(name, parent);
endfunction
endclass
//A-driver
class dri_a extends uvm_driver;
`uvm_component_utils(dri_a)
function new(string name = "dri_a", uvm_component parent = null);
super.new(name, parent);
endfunction
task run_phase(uvm_phase phase);
uvm_sequence_item temp;
item_a req;
forever begin
seq_item_port.get_next_item(temp);
void'($cast(req,temp));
$display("\n=================================================");
`uvm_info("dri_a","driver already recive item", UVM_LOW)
`uvm_info("dri_a",$sformatf("item in sequence:%s",req.get_parent_sequence().get_name()), UVM_LOW)
`uvm_info("data",$sformatf("%d",req.data_a), UVM_LOW)
$display("=================================================\n");
seq_item_port.item_done();
end
endtask
endclass
//A-agent
class agent_a extends uvm_agent;
dri_a driver;
seqr_a sequencer;
`uvm_component_utils(agent_a)
function new(string name = "agent_a", uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
driver = dri_a::type_id::create("driver", this);
sequencer = seqr_a::type_id::create("sequencer", this);
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
driver.seq_item_port.connect(sequencer.seq_item_export);
endfunction
endclass
//A-agent
class env extends uvm_env;
agent_a agent_aa;
`uvm_component_utils(env)
function new(string name = "env", uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
agent_aa = agent_a::type_id::create("agent_aa", this);
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
endfunction
endclass
`Generate_test(my_test,seq_a)
endpackage
仿真module
module hardware1;
import pack1::*;
import uvm_pkg::*; //+UVM
initial begin
run_test("my_test");
end
endmodule
结果
可以看到成功的用宏的方式生成了一个名为my_test的“uvm_test”