sequencer的仲裁机制
uvm_sequencer类自建了仲裁机制来保证多个sequence在同时挂载到sequencer时,可以按照仲裁规则允许特定sequence中的item优先通过。
在实际使用中,可以通过uvm_sequencer::set_arbitration(UVM_SEQ_ARB_TYPE val)
函数来设置仲裁模式,UVM_SEQ_ARB_TYPE有以下几种值供选择:
- UVM_SEQ_ARB_FIFO:默认模式,来自于sequences的发送请求,按照FIFO先进先出的方式依次授权。和优先级没有关系。
- UVM_SEQ_ARB_WEIGHTED:不用sequence的发送请求,按照它们的优先级权重随机授权。
- UVM_SEQ_ARB_RANDOM:不同的请求会被随机授权,无视它们抵达顺序和优先级。
- UVM_SEQ_ARB_STRICT_FIFO:不同的请求,按照它们优先级以及到达的顺序依次授权,因此与优先级和抵达时间都有关。
- UVM_SEQ_ARB_STRICT_RANDOM:不同的请求,按照它们的最高优先级随机授权,与抵达时间无关。
- UVM_SEQ_ARB_USER:用户自定义仲裁方法user_priority_arbitration()
来裁定哪个sequence的请求被优先授权。
在上述的仲裁模式中,与priority相关的模式有UVM_SEQ_ARB_WEIGHTED、UVM_SEQ_ARB_STRICT_FIFO、UVM_SEQ_ARB_STRICT_RANDOM。这三者的区别在于:UVM_SEQ_ARB_WEIGHTED的授权可能会落到各个优先级sequence的请求上面;UVM_SEQ_ARB_STRICT_RANDOM只会讲授权随机安排在最高优先级的请求上; UVM_SEQ_ARB_STRICT_FIFO严格按照优先级以及抵达顺序依次授权。
//实例
class bus_trans extends uvm_sequence_item;
rand int data;
...
endclass
class child_seq extends uvm_sequence;
rand int base:
...
task body();
bus_trans req;
repeat(2) `uvm_do_with(req, {
data inside{
[base:base+9]};})
endtask
endclass
class top_seq extends uvm_sequence;
...
task_body():
child_seq seq1, seq2, seq3;
m_sequencer.set_arbitration(UVM_SEQ_ARB_STRICT_FFIFO);
fork
`uvm_do_prt_with(seq1, 500, {
base == 10;})
`uvm_do_prt_with