在UVM中,Sequence生成的激励(Transaction)通过以下协作流程发送到Driver并最终驱动到DUT,其核心机制如下:
+---------------+ +---------------+ +------------+ +-----+
| Sequence | → | Sequencer | → | Driver | → | DUT |
+---------------+ +---------------+ +------------+ +-----+生成事务(Transaction) 管理事务队列与仲裁 拉取并处理事务 实际驱动信号
2. 激励发送的详细步骤
步骤1:Sequence生成事务
-
Sequence通过
uvm_do
宏或手动调用start_item
/finish_item
生成事务。 -
class my_sequence extends uvm_sequence #(my_transaction);task body();my_transaction tx;repeat(10) begintx = my_transaction::type_id::create("tx");start_item(tx); // 请求发送权限assert(tx.randomize());// 随机化事务finish_item(tx); // 将事务提交给Sequencerendendtask endclass
步骤2:Sequencer管理事务队列
事务缓存:finish_item()
将事务放入Sequencer的请求队列。
仲裁机制:Sequencer根据配置的仲裁算法(如优先级、公平性)选择下一个发送的事务。
-
Driver在
run_phase
中循环调用get_next_item
从Sequencer获取事务。
步骤3:Driver拉取事务
-
Driver在
run_phase
中循环调用get_next_item
从Sequencer获取事务。
-
class my_driver extends uvm_driver #(my_transaction);virtual task run_phase(uvm_phase phase);forever beginmy_transaction req;seq_item_port.get_next_item(req); // 阻塞获取事务drive_to_dut(req); // 驱动到DUTseq_item_port.item_done(); // 通知事务完成endendtask endclass
get_next_item
的作用:-
功能:从Sequencer的请求队列中阻塞获取下一个事务。
-
关键行为:
-
阻塞等待:若Sequencer的队列为空,Driver会在此处挂起,直到Sequence产生新事务。
-
获取事务对象:返回的
req
是uvm_sequence_item
类型,通常需要转换为具体的Transaction类型。
-
-
-
-
item_done
的作用 -
功能:通知Sequencer当前事务已处理完毕,允许Sequencer释放资源并继续后续操作。
-
关键行为:
-
同步握手:解除Sequence中
finish_item()
的阻塞,使Sequence能继续发送下一个事务。 -
可选响应传递:通过参数返回响应数据(如读操作结果)
-
-
Sequence与Driver的交互
+-------------------+ +-------------------+ +-------------------+
| Sequence | | Sequencer | | Driver |
+-------------------+ +-------------------+ +-------------------+
| start_item(req) | --> | 将req放入队列 | <-- | get_next_item(req)|
| | | | | |
| finish_item(req) | <-- | 等待item_done() | --(阻塞)-+ |
| | | | | 处理req并驱动DUT |
| | | | | item_done() |
+-------------------+ +-------------------+ +-------------------+
步骤4:事务完成确认
-
Driver调用
item_done()
通知Sequencer事务处理完毕,触发以下行为:-
释放Sequence阻塞:解除
finish_item()
的阻塞,允许Sequence继续发送下一个事务。 -
响应传递(可选):若需要返回响应数据(如读取DUT结果),可通过
item_done(rsp)
传递。
-
3. 关键交互机制
(1) 阻塞握手协议
-
start_item()
:请求发送权限,若Sequencer未授权则阻塞。 -
finish_item()
:将事务提交到Sequencer队列,等待Driver处理完成(item_done
)后解除阻塞。
(2) 事务生命周期
Sequence生成事务 → Sequencer缓存 → Driver拉取 → 驱动到DUT → 确认完成 → Sequence继续
4. 多Sequence并发场景
当多个Sequence同时向同一个Sequencer发送事务时:
-
Sequencer仲裁:通过
set_arbitration
方法设置仲裁策略(如UVM_SEQ_ARB_FIFO
、UVM_SEQ_ARB_PRIORITY
)。 -
优先级控制:可通过
set_priority
调整Sequence优先级。
5. 示例:完整交互流程
// 场景:一个Sequence发送3个事务
// ----------------------------
// Sequence代码
class test_sequence extends uvm_sequence #(my_transaction);task body();for (int i=0; i<3; i++) beginmy_transaction tx;tx = my_transaction::type_id::create("tx");start_item(tx);tx.data = i;finish_item(tx); // 阻塞直到Driver调用item_done()endendtask
endclass// Driver代码
class my_driver extends uvm_driver #(my_transaction);task run_phase(uvm_phase phase);forever beginmy_transaction req;seq_item_port.get_next_item(req); // 阻塞直到事务到达$display("Driving transaction: data=%0d", req.data);#10ns; // 模拟驱动时序seq_item_port.item_done(); // 解除finish_item阻塞endendtask
endclass