UVM(phase jump)
笔者在收集代码覆盖率时,曾发现无论自己打多少激励,FSM覆盖率总是cover不完全。分析后,发现是因为cover不到任意状态跳转复位状态。
一般咱们会将这种优先级低的case放在最后,甚至直接不验证。但是从完备性的角度考虑,这种case是需要验证到的。
但是这里引升了一个问题,DUT是消耗仿真时间的,任意时刻的随机复位势必会对我们的reference model造成影响。特别是当reference model是不消耗仿真时间的function时。
就这个问题,UVM具体又怎么做呢?是不是引出其他问题呢?本文就随机复位的情况,给出UVM的解决方案。
phase间的跳转
其实要验证随机的复位不难,只是需要调用到UVM实战第5章中讲到的phase jump的概念。我们需要做的是,在driver/monitor里对复位信号做一个实时监测,如果复位有效,就立即将phase跳转到reset phase里:
1 | begin |
注意,此处的rstn是低有效,所以监测的是rstn的下降沿。此时,UVM将自动将所有的组件跳转到reset phase里。
Jump后组件的处理
此刻我们需要将所有的组件还原到DUT上电复位的状态。即:
1 | driver:应该给出复位是的驱动 |
Jump后TLM的处理
对于喜欢用TLM_FIFO的朋友,我们也不能忘记将TLM中的FIFO清空。此时,我们仅仅需要调用TLM_FIFO的内置函数flush。以下是uvm_tlm_fifos.svh的源码:
1 | // Function: flush |
sequence和driver握手问题
在phase jump之后,会因为driver调用两次get_next_item()操作而出现UVM ERROR:
1 | UVM_ERROR @ 8514ns: uvm_test_top.env.agt_blake.seqr [uvm_test_top.env.agt_blake.seqr] Get_next_item called twice without item_done or get in between |
为解决这个问题,我们需要再次使用sequencer的内嵌函数stop_sequences()去清除所有对sequence的请求:
1 | class blake_sequencer extends uvm_sequencer #(blake_trans); |
以下是stop_sequences()在uvm_sequencer.svh中源码:
1 | // Function- stop_sequences |
references
- 张强. UVM 实战[M]. Ji xie gong ye chu ban she, 2014.