How to handle Reset in UVM如何在 UVM 中处理 Reset
1) Introduction: 1) 简介:
One of the fundamental requirement in Electronic Design is to put the Design into a known state after the power is switched ON . This process of putting the Design into a known state is technically synchronized & achieved using a dedicated signal popularly called “ Reset ” signal. We know that after power is switched ON, we Assert the Reset signal to the Design to put it into a known state and after certain time (usually in terms of number of clocks) the Reset signal is De-asserted to bring the Design Under Test (DUT) out of Reset. Assertion or De-assertion of Reset signal will depend on Active HIGH or Active LOW conditions. It is expected that after Reset signal is De-asserted, DUT achieves the known state as per the specification of the Design. So this is a simplified way to explain “How Reset signal directly relates to a Design’s operation”.
电子设计的基本要求之一是在电源打开后将设计置于已知状态。这种将设计置于已知状态的过程在技术上是同步的,并使用一种通常称为“重置”信号的专用信号来实现。我们知道,在电源打开后,我们将 Reset 信号置位给 Design,使其进入已知状态,并在一定时间后(通常以 clocks 数量为单位)De-assert reset,以使被测设计 (DUT) 退出 Reset。Reset 信号的置位或取消置低将取决于高电平有效或低电平有效条件。预计在 Reset 信号被置低后, DUT 会根据 Design 的规范达到已知状态。因此,这是解释 “Reset 信号如何与 Design's operation 直接相关” 的简化方法。
2) Reset generation for Module Verification by UVC:2) 通过 UVC 进行模块验证的重置生成:
To verify the Design Under Test (DUT), we know, we construct a Verification Environment aka Testbench around the DUT which may contains several Components or Transactors serving multiple purposes or tasks supporting the activities happening inside the Verification Environment. If you have not already visited, you may like to refer one of my previous posts to know more about the UVM Verification Components. In the whole given Testbench setup, once Reset process is started, the default state of the Testbench components as well as DUT needs to be achieved. The Reset process could be triggered by the initial Reset or intermediate Reset occurred during the Sequences execution in UVM. Since multiple Resets can occur in a single simulation, hence we should ensure that the DUT and Testbench can handle multiple Reset conditions.
为了验证被测设计 (DUT),我们知道,我们围绕 DUT 构建了一个验证环境,也称为测试平台,其中可能包含多个组件或事务处理器,用于多种目的或任务,支持验证环境中发生的活动。如果您还没有访问过,您可以参考我之前的一篇文章来了解有关 UVM 验证组件的更多信息。在整个给定的 Testbench 设置中,一旦 Reset 过程启动,就需要达到 Testbench 组件和 DUT 的默认状态。Reset 过程可能由初始 Reset 触发,也可能由 UVM 中序列执行期间发生的中间 Reset 触发。由于单个仿真中可能发生多个 Resets,因此我们应该确保 DUT 和 Testbench 可以处理多个 Reset 条件。
In this post, we’ll see how to generate the Reset signal from the UVC (Universal Verification Component) which is also popularly called VIP (Verification IP) developed using UVM . The primary focus in this post is – How to use the UVM Phasing Mechanism to generate the Reset Assertion and De-Assertion conditions. Along with Reset generation, we’ll also see – How to handle the Reset handling inside UVM Testbench components like **Driver, Monitor, Scoreboard & Sequences along with smooth resetting of various defined Variables, Data Structures e.g. Queues, Arrays and/or temporary Memory elements **whichever exists as part of the Testbench.在这篇文章中,我们将了解如何从 UVC(通用验证组件)生成 Reset 信号,UVC 也称为使用 UVM 开发的 VIP(验证 IP)。本文的主要重点是 – 如何使用 UVM Phasing Mechanism 生成 Reset Assertion 和 De-Assertion 条件。除了生成重置,我们还将看到 - 如何处理UVM测试平台组件(如驱动程序、监视器、记分板和序列)内的重置处理,以及平滑重置各种定义的变量、数据结构(如队列、数组和/或临时内存元素),无论作为测试平台的一部分存在。
3) UVM Phases: 3) UVM 阶段:
Since we’re going to use UVM Phases to handle Reset generation, so at this point, lets quickly recap the UVM Phases here in brief:由于我们将使用 UVM 阶段来处理 Reset 生成,因此在这一点上,让我们简要回顾一下 UVM 阶段:
For more detailed information on UMV Phases , you may like to visit my another post i.e. UVM Phasing.有关 UMV 阶段的更多详细信息,您可能想访问我的另一篇博文,即 UVM 阶段划分。
Broadly UVM Phases are categorized into 3 categories :UVM 阶段大致分为 3 类:
- Build Phases 构建阶段
- Run Phases 运行阶段
- Clean-up Phases 清理阶段
Let’s see these categories using Figure 1 shown below:让我们使用下图 1 来查看这些类别:
Figure 1: UVM Phases (with reset phase)图 1:UVM 相位(带复位相位)
In the above Figure 1, we can see that**Run Phase** is partitioned into **12 Sub-phases** . All of these 12 Sub-phases are “ **tasks** ” in nature. It means, time can be consumed by these Sub-phases.
在上面的图 1 中,我们可以看到 Run Phase 被划分为 12 个 Sub-phases。所有这 12 个子阶段本质上都是 “任务”。这意味着,这些子阶段可以消耗时间。
Since we know that UVM foundation principle is the automated flow of execution of these **3 Phases i.e. Build, Run & Cleanup Phases ** & the proper synchronization between the Phases. There is an order of execution of different Phases which is shown in the above Figure 1 . The execution sequence is designed by the Industry Experts to cater the need of a Design to be verified. All the 12 Run Sub-phases executes in the shown order. It means once the Build Phases is over, the first Sub-phase in the Run Phase is “ Reset ” Phase. This Phase is being partitioned further into 3 Sub-phase i.e. pre_reset_phase() , reset_phase() & post_reset_phase() .
因为我们知道UVM的基础原则是这3个阶段的自动化执行流程,即构建、运行和清理阶段以及阶段之间的适当同步。不同 Phase 的执行顺序如上面的图 1 所示。执行顺序由行业专家设计,以满足要验证的设计的需求。所有 12 个 Run 子阶段都按显示的顺序执行。这意味着一旦 Build 阶段结束,Run 阶段的第一个子阶段就是 “Reset” 阶段。这个阶段被进一步划分为3个子阶段,即pre_reset_phase(),reset_phase() & post_reset_phase()。
4) Reset generation using UVM reset_phase() Phase:4) 使用 UVM reset_phase() 相位生成重置:
Lets first see the definitions of 3 UVM Reset Sub-phases :让我们首先看一下 3 个 UVM 重置子相位的定义:
pre_reset: pre_reset:
pre_reset phase starts at the same time as the run phase. Its purpose is to take care of any activity that should occur before the reset. E.g. waiting for a power signal to go active.pre_reset
阶段与 run 阶段同时开始。其目的是处理重置之前应该发生的任何活动。例如,等待电源信号激活。
reset: 重置:
As name indicates, reset phase is specially for DUT or Interface specific reset behavior. This phase would be used to generate reset to put the DUT/Interface into a default state.
顾名思义,reset phase 专门用于 DUT 或特定于 Interface 的 reset 行为。此阶段将用于生成 reset,以将 DUT/Interface 置于默认状态。
post_reset: post_reset:
This phase is intended for any activity required just after the reset phase.
此阶段适用于重置阶段之后所需的任何活动。
Since all the Run Sub-phase are to be declared as Tasks & we know that a Task can consume time in the simulation process. Hence we can utilize the reset_phase() task to generate the Reset from the UVC . Both pre_reset_phase() and post_reset_phase() are there to support the Reset process in the environment.
由于所有的运行子阶段都将被声明为任务&我们知道任务在模拟过程中可能会消耗时间。因此,我们可以利用 reset_phase() 任务从 UVC 生成 Reset。pre_reset_phase() 和 post_reset_phase() 都用于支持环境中的 Reset 过程。
Lets see below a piece of UVM code to comprehend it more clearly:
让我们看看下面的一段 UVM 代码,以便更清楚地理解它:
Driver Code: 驱动程序代码:
/// Driver Definition
class my_driver extends uvm_driver #(my_transaction);
`uvm_component_utils(my_driver)
...
...
/// Pre-reset Phase Task
task pre_reset_phase (uvm_phase phase);
phase.raise_objection(this);
dut_vi.reset = 1'b1;
#1;
phase.drop_objection(this);
endtask: pre_reset_phase
/// Reset Phase Task, reset is Active LOW
task reset_phase(uvm_phase phase);
phase.raise_objection(this);
dut_vi.reset = 1'b0;
#13;
dut_vi.reset = 1'b1;
phase.drop_objection(this);
endtask: reset_phase
endclass: my_driver
From the above UVM Driver code inside the reset_phase (), its evident that Reset signal (i.e. dut_vi.reset ) will be driven LOW (Active LOW) to assert the Reset and after some time (i.e. 13ns ) the Reset signal is driven HIGH to de-assert the Reset and DUT will be out of reset at this point of time.
从上述 reset_phase() 内的 UVM 驱动程序代码可以明显看出,Reset 信号(即 dut_vi.reset)将被驱动为低电平(低电平有效)以置位 Reset,一段时间后(即 13ns)Reset 信号被驱动为高电平以取消置位 Reset,DUT 将在此时退出 reset。
Note: “ dut_vi ” is the Virtual Interface declaration made inside the Driver .
注意:“dut_vi”是在 Driver 内部进行的虚拟接口声明。
5) Multiple Reset generation using UVM Phasing:5) 使用 UVM Phasing 生成多重重置:
We’ve seen above how to generate the Reset after the power is ON. There is a Test scenario where we may want to reset the DUT after the 1st Sequence is over & run the same or different Sequence to test DUT behavior without getting it power down. So basically a new Reset is triggered without coming out of the UVM Phases.
我们在上面已经看到了如何在电源打开后生成 Reset。在一种测试场景中,我们可能希望在第一个序列结束后重置DUT,并运行相同或不同的序列来测试DUT的行为,而不会使其断电。所以基本上一个新的 Reset 是在不退出 UVM 阶段的情况下触发的。
Following UVM code inside the “Test” can be helpful to achieve this:
在 “Test” 中遵循 UVM 代码可能有助于实现此目的:
/// Test Definition
class my_test extends uvm_test;
`uvm_component_utils(my_test)
...
...
/// phase_ready_to_end function
function void phase_ready_to_end(uvm_phase phase);
super.phase_ready_to_end(phase);
if(phase.get_imp() == uvm_shutdown_phase::get()) begin
if (run_count <= `no_of_runs) begin
phase.jump(uvm_pre_reset_phase::get());
run_count++;
end
end
endfunction
endclass: my_test
We know in UVM, the Test ending mechanism is via Raise Objections and Drop Objections . So the indication of finishing a Sequence is that all the Raised Objections are Dropped and the Objection counter value will be zero at this point. Now phase_ready_to_end () function defined above comes into action. phase_ready_to_end () is called whenever the total objection count for the current phase decrements to 0 .我们知道在 UVM 中,测试结束机制是通过 Raise Objections 和 Drop Objections。
因此,完成 Sequence 的指示是所有 Raised Objections 都被丢弃,此时 Objection counter 值将为零。现在,上面定义的 phase_ready_to_end() 函数开始生效。每当当前阶段的总异议计数减少到 0 时,就会调用 phase_ready_to_end()。
From the above code, its clear that once the phase is shutdown_phase (which is last Sub-phase out of the 12 Run Sub-phases) & there is no pending Objection, phase_ready_to_end is activated and make a JUMP to the pre_reset_phase() . From there on, the whole cycle is repeated. This way, the whole process is re-started again & a new RESET is generated.
从上面的代码中可以清楚地看出,一旦阶段shutdown_phase(这是12个运行子阶段中的最后一个子阶段)并且没有待处理的反对意见,phase_ready_to_end就会被激活并跳转到pre_reset_phase(()。从那时起,整个循环重复。这样,整个过程会再次重新启动并生成新的RESET。
This approach can be further extended to Test the scenario where Reset is triggered in-between of the Sequence execution instead of after completing the Sequence.
此方法可以进一步扩展为测试在 Reset 执行 Sequence 之间触发而不是在完成 Sequence 之后触发的场景。
6) Reset handling for different Testbench components:6) 重置不同 Testbench 组件的处理:
Once Reset is generated inside the UVM Testbench Environment, we must take care of various different Testbench component’s behavior with respect to the Reset signal. Following components ( Static or Dynamic ) needs to be prepared for Reset handling:
一旦在 UVM Testbench Environment 中生成 Reset,我们必须注意各种不同 Testbench 组件相对于 Reset 信号的行为。 需要为以下组件(静态或动态)准备重置处理:
-
Monitor 监控
-
Sequencer 音序器
-
Scoreboard 记分牌
-
Sequences 序列
-
Assertions 断言
Now, lets see what can be done to make these UVM components Reset ready:
现在,让我们看看可以做些什么来使这些 UVM 组件准备好重置:
Monitor: 监控:
Whether the UVM Agent is ACTIVE or PASSIVE , a Monitor needs to be present in both of them. Monitor’s primary job is to receive the pin-level interface signals and based on the other Control signals like “ valid_txn ” or any other it transforms the pin-level signals into Transaction Objects . So as soon as the Reset signal is asserted, Monitor should disable the process of collection data from the Interfaces.
无论 UVM Agent 是 ACTIVE 还是 PASSIVE,两者都需要存在 Monitor。Monitor 的主要工作是接收引脚级接口信号,并根据其他控制信号(如 “valid_txn” 或任何其他信号)将引脚级信号转换为交易对象。因此,一旦 Reset 信号被置位,Monitor 就应该禁用从 Interface 收集数据的过程。
Lets see how this is achieved using the UVM code for Monitor:
让我们看看如何使用 Monitor 的 UVM 代码实现这一点:
/// Monitor Defintion
class my_monitor extends uvm_monitor #(my_transaction);
`uvm_component_utils(my_monitor)
...
...
/// Run Task
task run_phase (uvm_phase phase);
forever begin
@(posedge dut_vi.reset);
fork
monitor_items();
join_none
@(negedge dut_vi.reset);
disable fork;
end
endtask: run_phase
endclass: my_monitor
Here we can see that inside the run_phase task forever loop, monitor_items () task is waiting for the** dut_vi.reset** signal positive edge (Reset de-asserted for Active LOW reset). Once the condition met, monitor_items is spawned from the fork..join_none and Monitor starts collecting the transactions. Now if there is any upcoming or intermediate Reset comes in i.e. the negedge of the dut_vi.reset (Active LOW), the fork process is disabled which stops the monitor_items task. This is exactly what we want when RESET occurs i.e. not to collect any transactions either from Input or Output ports because only valide transactions have to be passed to the Scoreboard.
在这里我们可以看到,在 run_phase 任务 forever 循环中,monitor_items() 任务正在等待 dut_vi.reset 信号正沿(Reset 为 ACTIVE LOW reset取消置低)。一旦满足条件,monitor_items就会从分叉中产生..join_none and Monitor 开始收集事务。现在,如果有任何即将到来的或中间的 Reset 出现,即 dut_vi.reset 的负数(低电平有效),则 fork 进程将被禁用,从而停止 monitor_items 任务。这正是我们在 RESET 发生时想要的,即不从 Input 或 Output 端口收集任何交易,因为只有有效的交易必须传递给 Scoreboard。
Sequencer: 音序器:
UVM Phases are very handy & automated in terms of handling different UVM components. Whenever there is UVM Phase JUMP instruction (as shown in point 5 above) it stops all the ongoing transactions and clears out the internal FIFOs which are involved to hold the running transactions on that Sequencer.
UVM Phases在处理不同的UVM组件方面非常方便且自动化。每当有 UVM Phase JUMP 指令(如上面的第 5 点所示)时,它就会停止所有正在进行的事务并清除内部 FIFOs,这些 FIFOs 涉及在该 Sequencer 上保存正在运行的事务。
Scoreboard: 记分牌:
Usually Queues , the data structure , being used inside the Scoreboards to hold the incoming stream of transactions . Once Reset occurs in the system, the declared Queues inside the Scoreboard MUST be cleared and all the existing elements needs to be flushed out. Since Scoreboard does not have direct access to the Interface and it works with UVM analysis imports and deals with transaction objects. Now again, we can utilize UVM Phases which are automated in terms of execution. So Queues can be flushed out once pre_reset_phase() occurs. It’ll be helpful in multiple RESET generation scenario.
通常 Queues,即数据结构,在 Scoreboards 中使用,以保存传入的事务流。一旦系统发生 Reset,必须清除 Scoreboard 中声明的 Queues,并且需要清除所有现有元素。由于 Scoreboard 不能直接访问 Interface,并且它与 UVM 分析一起工作,因此可以导入和处理事务对象。现在,我们可以再次利用在执行方面是自动化的 UVM 阶段。因此,一旦 pre_reset_phase() 发生,就可以刷新 Queues。在多个 RESET 生成场景中会有所帮助。
/// Scoreboard Definition
class my_scoreboard extends uvm_scoreboard;
`uvm_component_utils(my_scoreboard)
...
...
/// A Queue declaration to hold DUT I/P & O/P data
my_transaction scb_q [$];
my_transaction scb_q_o [$];
/// During reset phase Queues must be cleaned
task pre_reset_phase (uvm_phase phase);
scb_q.delete();
scb_q_o.delete();
endtask
endclass: my_scoreboard
Sequence: 序列:
Sequence is the UVM Environment dynamic component which generates Stimulus for the DUT. In terms of multiple Reset handling , definitely Sequence must be stopped once Reset is asserted and Sequence should be restarted automatically once Reset is de-asserted. UVM Phases can help us greatly to achieve what is expected out here.
Sequence 是为 DUT 生成 Stimulus 的 UVM Environment 动态组件。就多个 Reset 处理而言,一旦 Reset 被置位,Sequence 肯定必须停止,一旦 Reset 被置低,Sequence 应该自动重新启动。UVM Phases 可以极大地帮助我们实现这里的预期。
Lets see below the UVM code for the Test :
让我们看看下面的测试的 UVM 代码:
/// Test Definition
class my_test extends uvm_test;
`uvm_component_utils(my_test)
...
...
/// Main Phase Task
virtual task main_phase(uvm_phase phase);
my_sequence seq;
seq = my_sequence::type_id::create("seq");
if( !seq.randomize() )
`uvm_error("", "Randomize failed")
seq.starting_phase = phase;
phase.raise_objection(this);
seq.start( m_env.m_agnt.m_seqr );
phase.drop_objection(this);
endtask
endclass: my_test
In the above UVM Test code, Sequence is started on the Sequencer i.e. m_seqr once the main_phase is entered. So if we’re able to recycle the UVM Phasing flow, Sequence will be automatically started on the defined Sequencer.在上面的 UVM 测试代码中,Sequence 在 Sequencer 上启动,即输入 main_phase 后m_seqr。因此,如果我们能够回收 UVM Phasing 流,Sequence 将在定义的 Sequencer 上自动启动。
Assertions: 断言:
We know that Assertions are to capture the live status of signals weather its Immediate or Concurrent Assertions. Assertions are most commonly used as** Interface Protocol Checkers** & are placed inside the Interfaces or Monitors . Once Reset appears, we might want to kill the running Assertions. This can be achieved by adding following code:
我们知道 Assertions 是为了捕获信号的实时状态,无论是 Immediate 还是 Concurrent Assertions。断言最常用作接口协议检查器,并放置在接口或监视器内。一旦 Reset 出现,我们可能想要终止正在运行的 Assertion。这可以通过添加以下代码来实现:
/// Assertion 1: grant0 & grant1 should NOT be asserted together
assert property (@(posedge clk)
disable iff (~reset) !(grant0 & grant1));
In the above code, once Reset appears (Active LOW), this Assertion/Property will be disabled and will not check the required condition. It will avoid flashing** false errors** during the RESET period.
在上面的代码中,一旦出现 Reset (低电平有效),此 Assertion/Property 将被禁用,并且不会检查所需的条件。它将避免在 RESET 期间闪烁错误。
本文转自: