start():

在这里插入图片描述

  • sequence.strat(sequencer,parent_sequence,优先级) ,第一个参数是需要挂载的sequencer;第二个是parent_sequence,一般传入this或者不传入;第三个是优先级;第四个call_pre_post默认为1,则自动执行pre_body/ post_body()函数
  • start 执行 pre_start,body等函数。此时就完成了sequence的启动过程。
  • 所有sequence都要在sequencer中启动,当sequence启动的时候, 在sequence的 task start 内,会调用 set_item_context() 函数,在 set_item_context() 函数内,会调用 set_sequencer() 函数完成挂载,给m_sequencer赋值
  • set_sequencer 函数 会使m_sequencer 句柄指向执行当前 sequence 的 sequencer,即指向 env.vsqr
  • 如果没有指定挂载的sequencer,则挂载到parent_sequence的sequencer上

`uvm_do() 宏:

相比直接调用start函数,uvm_do()宏节省了sequence的实例化和随机化的步骤

在这里插入图片描述

uvm_do系列宏:

在这里插入图片描述

第一类:uvm_do类

  • uvm_do:只有一个参数,即产生的transaction
  • uvm_do_pri(ority):除了第一个参数transaction外,还有一个参数priority优先级,sequencer的仲裁机制根据transaction的优先级来进行选择。没指定优先级时默认为-1,指定时的数值是大于等于-1的整数,数字越大,优先级越高
  • uvm_do_with:第一个参数transaction,第二个参数constraints,在随机化时对transaction的某些字段进行约束
  • uvm_do_pri_with:前两者的结合

第二类:uvm_do_on类

  • uvm_do_on:on表示展示出来,就是显式地指定产生的这个transaction具体是哪个sequencer来发送。它有两个参数,对应的就是transaction的指针和sequencer的指针。而对于uvm_do而言,它默认的sequencer就是调用uvm_do宏的这个sequence在启动时指定的sequencer

在同一sequencer上启动多个sequence

UVM支持同一时刻在同一sequencer上启动多个sequence,并使用sequence的仲裁机制决定发送顺序

uvm_do 宏 设置 transaction 优先级

  • uvm_do 或 uvm_do_with 宏时,产生的 transaction 优先级是默认的优先级(即1)。可通过 uvm_do_pri 及uvm_do_pri_with 改变所产生的 transaction 的优先级
  • uvm_do_pri 与 uvm_do_pri_with 的第二个参数是优先级,其数值必须是一个大于等于-1的整数。数字越大优先级越高
  • 要使优先级起作用,应设置 sqr 为 SEQ_ARB_STRICT_FIFO 或 SEQ_ARB_STRICT_RANDOM

sequencer的仲裁算法:

  • SEQ_ARB_FIFO 默认算法,按照“先入先出”的顺序,不考虑优先级
    SEQ_ARB_WEIGHTED 加权的仲裁
    SEQ_ARB_RANDOM 完全随机选择
    SEQ_ARB_STRICT_FIFO 严格按照优先级,同一优先级的sequence按先入先出的顺序
    SEQ_ARB_STRICT_RANDOM 严格按照优先级,同一优先级的sequence随机从最高优先级中选择
    SEQ_ARB_USER 用户可以自定义
// sequence

class sequence0 extends uvm_sequence #(my_transaction);
	...
	virtual task body();
		...
		repeat (5) begin
			`uvm_do_pri(m_trans, 100)  // 设置优先级为100
			`uvm_info("sequence0", "send one transaction", UVM_MEDIUM)
	end
	#100;
	...
	endtask
	...
endclass

class sequence1 extends uvm_sequence #(my_transaction);
	...
	virtual task body();
		...
		repeat (5) begin
			`uvm_do_pri_with(m_trans, 200, {m_trans.pload.size < 500;})  // 设置优先级为200
			`uvm_info("sequence1", "send one transaction", UVM_MEDIUM)
		end
		...
	endtask
	...
endclass
// case

task my_case0::main_phase(uvm_phase phase);
	sequence0 seq0;
	sequence1 seq1;
	seq0 = new("seq0");
	seq0.starting_phase = phase;
	seq1 = new("seq1");
	seq1.starting_phase = phase
	
	env.i_agt.sqr.set_arbitration(SEQ_ARB_STRICT_FIFO);  // 启动优先级配置
	
	fork
		seq0.start(env.i_agt.sqr);
		seq1.start(env.i_agt.sqr);
	join
endtask


seq.start(sqr) 设置 sequence 优先级

sequence启动时指定其优先级

 task my_case0::main_phase(uvm_phase phase);
	... 
	
	env.i_agt.sqr.set_arbitration(SEQ_ARB_STRICT_FIFO);   // 启动优先级配置
	
	fork
		seq0.start(env.i_agt.sqr, null, 100);  // 第一个参数是sequencer,第二个参数是parent sequence(可设为null),第三个参数是优先级,不指定则此值为-1,不能设置为小于-1的数字。
		seq1.start(env.i_agt.sqr, null, 200);
	join
endtask


default_sequence:

test中将sequence通过config_db机制set到相应的sequencer(virtual sequencer)的main_phase中

在build_phase中将某个sequence配置成某个sequencer的动态运行的phase中(如main_phase)的default_sequence, 那么在仿真执行到main_phase的时候,squencer的default_sequence就会启动

实际上default_sequence会调用start任务,有两种调用方式:

// 方式一

function void my_case0::build_phase(uvm_phase phase);
	super.build_phase(phase);
	`uvm_config_db#(ubm_object_wrapper)::set(this,  // 第一个参数是指定seqr的路径        
										 "env.in_agent.sqr.main_phase",  // 第二个参数是指定要执行的phase阶段
					  					 "default_sequence",  // 第三个参数是指定你的seq
										 sequence_base::type_id::get());  // uvm_config_db设置default_sequencer
endfunction
// 方式二

function void my_case0::build_phase(uvm_phase phase);
   case0_sequence cseq;                                              //
   super.build_phase(phase);
   cseq = new("cseq");                                               //
   uvm_config_db#(uvm_sequence_base)::set(this,                      //
                                         "env.i_agt.sqr.main_phase", //
                                         "default_sequence",         //
                                          cseq);                     //
endfunction

start_item/finish_item封装函数以及sequence,sequencer,driver的握手关系如下图:

在这里插入图片描述


Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐