sequence

一.transaction

1.声明随机变量并添加约束

class ue_transaction extends  uvm_sequence_item;

typedef enum{IDLE,SET_SCALER,WR_BASE_NUMBER} trans_type;

	rand  	 	trans_type   	        	ttype;

	randc bit	[`NO_WIDTH-1:0]  			no; 
	randc bit	[`BASE_NUMBER_WIDTH-1:0]  	base_number; 
	randc bit	[`SCALER_WIDTH-1:0]  		wr_scaler;
	rand  int 			    				idle_cycles;
		  bit   [`SCALER_WIDTH-1:0] 		rd_scaler;
		  bit								rd_valid;
		  bit	[`RD_DATA_WIDTH-1:0]		rd_data;


	constraint cstr {
		soft idle_cycles inside {[0:2]};
		soft idle_cycles dist {[0:50],[1:25],[2:30]};

工作状态有3种:IDLE  //  SET_SCALER  //  WR_BASE_NUMBER

软约束可以被覆盖,优先级较低;如果都是硬约束,约束冲突则会随机失败;

2.域的自动化

`uvm_object_utils_begin(ue_transaction)
	   `uvm_field_enum     (trans_type,ttype , UVM_ALL_ON)
	   `uvm_field_int      (no, UVM_ALL_ON)
	   `uvm_field_int      (base_number, UVM_ALL_ON)
	   `uvm_field_int      (wr_scaler, UVM_ALL_ON)
	   `uvm_field_int      (rd_scaler, UVM_ALL_ON)
	   `uvm_field_int      (rd_valid, UVM_ALL_ON)
	   `uvm_field_int      (rd_data, UVM_ALL_ON)
	   `uvm_field_int      (idle_cycles, UVM_ALL_ON)
	 `uvm_object_utils_end

使用宏定义后,可以使用uvm自带的方法

3.打印信息

function new(string name = "ue_trans_inst");
 	  super.new(name);
 	  `uvm_info(get_type_name(), "obj created", UVM_FULL)
 	endfunction


 	function void print_info(string stage);
 		string s;
 		s={s,$sformatf("\n=========%s==============\n",stage)};
 		s={s,$sformatf("no:%0d\t",no)};
 		s={s,$sformatf("trans_type:%s\t",ttype)};
 		s={s,$sformatf("base_number:%d\t",base_number)};
 		s={s,$sformatf("wr_scaler:%d\t",wr_scaler)};
 		s={s,$sformatf("rd_scaler:%d\t",rd_scaler)};
 		s={s,$sformatf("rd_data:%d\t",rd_data)};
 		s={s,$sformatf("idle_cycles:%d\n",idle_cycles)};
		s={s,"=======================================================\n"};
 		$display("%s",s);
 		
 	endfunction:print_info

二.sequencer

class ue_sequencer extends uvm_sequencer #(ue_transaction);

  `uvm_component_utils(ue_sequencer)
  extern function new(string name ="ue_sequencer",uvm_component parent = null);
  extern function void build();

endclass


//--------------------------------------------------------------------------------------------------------
// sv
//--------------------------------------------------------------------------------------------------------
function ue_sequencer::new(string name ="ue_sequencer",uvm_component parent = null);
  super.new(name, parent);
  `uvm_info(get_type_name(), $sformatf("created"), UVM_LOW)
endfunction : new

function void ue_sequencer::build();
	super.build();
	`uvm_info(get_type_name(), "built", UVM_LOW)
endfunction : build

        sequencer的结构非常简单, 继承于uvm_sequencer,使用宏注册。后续的new与build中也基本没有内容。

三.sequence

1.base_sequence

class ue_base_sequense extends uvm_sequence #(ue_transaction);
	ue_transaction m_trans;
	`uvm_object_utils(ue_base_sequense)


	extern function new(string name="ue_base_sequense");
	extern function int get_rand_number_except(int min_thre,int max_thre,int except_num);
	extern function int get_rand_number(int min_thre,int max_thre);
endclass 


function ue_base_sequense::new(string name="ue_base_sequense");
	  super.new(name);  
endfunction : new


function int ue_base_sequense::get_rand_number_except(int min_thre,int max_thre,int except_num);
	int val=get_rand_number( min_thre, max_thre);
	while(val==except_num)
		val=get_rand_number( min_thre, max_thre);
	return val;	
endfunction


function int ue_base_sequense::get_rand_number(int min_thre,int max_thre);
	int val;
	void'(std::randomize(val) with { val inside {[min_thre:max_thre]};});
	return val;
endfunction

        base_sequence包含sequence的基本方法,后续的测试用例中使用配套的直接继承于base_sequence的sequence。(虽然后续个人没找到使用该方法的地方)

2.base_sequence_lib

{

subseq_set_scaler:                设定scaler

class subseq_set_scaler extends  ue_base_sequense;
	rand bit [`SCALER_WIDTH-1:0]    scaler; 
	
	`uvm_object_utils(subseq_set_scaler)
	function new(string name="subseq_set_scaler");
	  super.new(name);  
	endfunction : new

	virtual task body();	
		`uvm_do_with(req, {no==0;base_number==0;wr_scaler == local::scaler;ttype==ue_transaction::SET_SCALER;idle_cycles==0;})
		get_response(rsp);
		if(scaler!=rsp.rd_scaler)
		 	`uvm_error("SET_SCALER_ERR", $sformatf("subseq_set_scaler err, exp:%0d act:%0d",scaler,rsp.rd_scaler))
		else
			`uvm_info(get_type_name(),$sformatf("subseq_set_scaler success"), UVM_LOW)
	endtask : body
endclass : subseq_set_scaler

subseq_wr_number:            写入base_number

class subseq_wr_base_number extends  ue_base_sequense;
	rand logic [ 7:0]    base_number;
	rand int 			idle_cycles;
	rand int 			no;

	`uvm_object_utils(subseq_wr_base_number)

	function new(string name="");
	  super.new(name);  
	endfunction : new

	virtual task body();
		`uvm_do_with(req, {no==local::no;base_number== local::base_number;ttype==ue_transaction::WR_BASE_NUMBER;idle_cycles==local::idle_cycles;})
		get_response(rsp);
	endtask : body
endclass : subseq_wr_base_number

subseq_idle:                         idle

class subseq_idle extends  ue_base_sequense;

	rand int 			idle_cycles;

	`uvm_object_utils(subseq_idle)

	function new(string name="subseq_idle");
	  super.new(name);  
	  `uvm_info(get_type_name(), $sformatf("created"), UVM_LOW)
	endfunction : new

	virtual task body();
		`uvm_do_with(req, {no==0;ttype==ue_transaction::IDLE;idle_cycles==local::idle_cycles;})
		// get_response(rsp);
	endtask : body
endclass : subseq_idle

}

        通过继承base_sequence,生成了三个sequence,对应于三个test,run不同的test其实就是不同的sequence在起作用。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值