电子说
本文将接着分享sequencer的相关知识,对于sequencer的仲裁特性有几种可选,UVM_SEQ_ARB_FIFO ;UVM_SEQ_ARB_WEIGHTED;UVM_SEQ_ARB_RANDOM ;UVM_SEQ_ARB_STRICT_FIFO等。出其中三种需要特别区分外其它的模式可以满足绝大多数的仲裁需求。
在之前我们就谈到了,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的授权会落到各个优先级的请求上面,而UVM_SEQ_ARB_STRICT_RANDOM则只会将授权随机安排到最高优先级的请求上面,UVM_SEQ_ARB_STRICT_FIFO则不会随机授权,而是严格按照优先级以及抵达顺序来依次授权。没有特别要的要求,则用户不需要再额外自定义授权算法,因此使用UVM_SEQ_ARB_USER这一模式的情况不多见,其它的模式可以满足绝大多数的仲裁需求。
鉴于sequence在传送的优先级可以影响sequencer的仲裁授权,我们有必要结合sequencer的仲裁模式选择和sequence发送的优先级参数设置给出一段例码。通过这段例码,希望读者可以掌握如何设置仲裁模式和优先级的传递。
输出结果:
上面的例码中,seq1、seq2、seq3在同一时刻发起传送请求,通过`uvm_do_prio_with的宏,在发送sequence时可以传递优先级参数。由于将seq1与seq2设置为同样的高优先级,而seq3设置为较低的优先级,这样在随后的UVM_SEQ_ARB_STRICT_FIFO仲裁模式下,可以从输出结果看到,按照优先级高低和传送请求时间顺序,先将seq1和seq2中的item发送完毕,随后将seq3发送完。
除了在上面的sequence遵循仲裁机制,将自身的item发送完才结束自身的正常模式以外,在一些特殊情形下,有一些sequence需要有更高的权限取得sequencer的授权来访问driver。 例如需要响应中断的情形下,用于处理中断的sequence应该有更高的权限来获得sequencer的授权。为此,uvm_sequencer提供了两种锁定机制,分别可以通过lock()和grab()方法实现。这两种方法的区别在于:
lock()与unlock()这一对方法可以为sequence提供排外的访问权限,但前提条件是,该sequence首先需要按照sequencer的仲裁机制获得授权。而一旦sequence获得授权,则无需担心权限被收回,只有该sequence主动unlock它的sequencer主动解锁,才可以释放这一锁定的权限。lock()是一种阻塞的任务,只有获得了权限,它才会返回。
grab()与ungrab()也可以为sequence提供排外的访问权限,而且它只需要在sequencer下一次授权周期时就可以无条件地获得授权。与lock方法相比,grab方法无视同一时刻内发起传送请求的其它sequence,而唯一可以阻止它的只有已经预先获得授权的其它lock或者grab的sequence。
这里需要注意的是,由于“解铃还须系铃人”,如果sequence使用了lock()或者grab()方法,必须在sequence结束前调用unlock()或者ungrab()方法来释放权限,否则sequencer会进入死锁状态而无法继续为其余sequence授权。下面的给出一段例码,用来展示如何使用上述的方法实现锁定的sequence传送方式。
输出结果:
结合例码和输出结果,我们从中可以发现如下几点:
对于locks,在10ns时,它跟其它几个sequence一同向sequencer发起请求,按照仲裁模式,sequencer先后授权给seq1、seq2、seq3,最后才授权的locks。而locks在获得授权之后,就可以一直享有权限,而无需担心权限被sequencer收回。直到在locks结束前,用户需要通过unlock()方法返还权限。
对于grabs,尽管他在20ns时就发起了请求权限(实际上seq1、seq2、seq3也在同一时刻发起了权限请求),而由于权限已经被locks占用,所以它也无权收回权限。因此只有当locks在40ns结束时,grabs才可以在sequencer没有被锁定权限的状态下获得权限,而grabs获得权限是无视同一时刻发起请求的其它sequence的。同样地,在grabs结束前,也应当通过ungrab()方法释放权限,防止sequencer的死锁行为。
至此,我们就将sequence/item发送的方法和宏,以及sequence与sequencer之间的仲裁和授权请求方式为读者介绍完毕。
全部0条评论
快来发表一下你的评论吧 !