【UVM】宏替换生成test与default_sequence

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”

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
请逐行注释下面的代码:class riscv_instr_base_test extends uvm_test; riscv_instr_gen_config cfg; string test_opts; string asm_file_name = "riscv_asm_test"; riscv_asm_program_gen asm_gen; string instr_seq; int start_idx; uvm_coreservice_t coreservice; uvm_factory factory; uvm_component_utils(riscv_instr_base_test) function new(string name="", uvm_component parent=null); super.new(name, parent); void'($value$plusargs("asm_file_name=%0s", asm_file_name)); void'($value$plusargs("start_idx=%0d", start_idx)); endfunction virtual function void build_phase(uvm_phase phase); super.build_phase(phase); coreservice = uvm_coreservice_t::get(); factory = coreservice.get_factory(); uvm_info(gfn, "Create configuration instance", UVM_LOW) cfg = riscv_instr_gen_config::type_id::create("cfg"); uvm_info(gfn, "Create configuration instance...done", UVM_LOW) uvm_config_db#(riscv_instr_gen_config)::set(null, "*", "instr_cfg", cfg); if(cfg.asm_test_suffix != "") asm_file_name = {asm_file_name, ".", cfg.asm_test_suffix}; // Override the default riscv instruction sequence if($value$plusargs("instr_seq=%0s", instr_seq)) begin factory.set_type_override_by_name("riscv_instr_sequence", instr_seq); end if (riscv_instr_pkg::support_debug_mode) begin factory.set_inst_override_by_name("riscv_asm_program_gen", "riscv_debug_rom_gen", {gfn, ".asm_gen.debug_rom"}); end endfunction function void report_phase(uvm_phase phase); uvm_report_server rs; int error_count; rs = uvm_report_server::get_server(); error_count = rs.get_severity_count(UVM_WARNING) + rs.get_severity_count(UVM_ERROR) + rs.get_severity_count(UVM_FATAL); if (error_count == 0) begin uvm_info("", "TEST PASSED", UVM_NONE); end else begin uvm_info("", "TEST FAILED", UVM_NONE); end uvm_info("", "TEST GENERATION DONE", UVM_NONE); super.report_phase(phase); endfunction virtual function void apply_directed_instr(); endfunction task run_phase(uvm_phase phase); int fd; for(int i = 0; i < cfg.num_of_tests; i++) begin string test_name; randomize_cfg(); riscv_instr::create_instr_list(cfg); riscv_csr_instr::create_csr_filter(cfg); asm_gen = riscv_asm_program_gen::type_id::create("asm_gen", , gfn); asm_gen.cfg = cfg; asm_gen.get_directed_instr_stream(); test_name = $sformatf("%0s_%0d.S", asm_file_name, i+start_idx); apply_directed_instr(); uvm_info(gfn, "All directed instruction is applied", UVM_LOW) asm_gen.gen_program(); asm_gen.gen_test_file(test_name); end endtask virtual function void randomize_cfg(); DV_CHECK_RANDOMIZE_FATAL(cfg); uvm_info(`gfn, $sformatf("riscv_instr_gen_config is randomized:\n%0s", cfg.sprint()), UVM_LOW) endfunction endclass
最新发布
05-24

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搞IC的那些年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值