uvm sequencer和driver通信

uvm driver从sequencer FIFO中获取request类型的sequence item(REQ), 类似握手协议, 返回一个response类型的(RSP)。如下图所示:

本篇主要介绍在driver中使用get_next_item的方法。

这种情况下, driver获取sequence item主要是通过seq_item_port, 比如下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class my_driver extends uvm_driver #(my_data);
`uvm_component_utils (my_driver)

virtual task run_phase(uvm_phase phase);
super.run_phase(phase);

// 1. This task will get an item from the sequencer using get_next_item()
`uvm_info ("DRIVER", $sformatf ("Waiting for data from sequencer"), UVM_MEDIUM)
seq_item_port.get_next_item(req);

// 2. For simplicity, lets just assume the driver drives the received packet
// during this time and consumes 20ns to complete driving the transaction
`uvm_info ("DRIVER", $sformatf ("Start driving tx addr=0x%0h data=0x%0h", req.addr, req.data), UVM_MEDIUM)
#20;

// 3. After driver has finished the transaction, it has to let the sequencer know
// by calling item_done()
`uvm_info ("DRIVER", $sformatf ("Finish driving tx addr=0x%0h data=0x%0h", req.addr, req.data), UVM_MEDIUM)
seq_item_port.item_done();
endtask

一旦driver完成驱动interface上的信号, 就可以用item_done的方法通知sequencer。

那么sequencer又是如何获取sequence item的呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class my_sequence extends uvm_sequence;
`uvm_object_utils (my_sequence)


virtual task body();
// 1. Create an item the connected sequencer can accept
my_data tx = my_data::type_id::create("tx");
`uvm_info ("SEQ", $sformatf("About to call start_item"), UVM_MEDIUM)

// 2. Call the start_item() task which will send this object to the driver
start_item(tx);
`uvm_info ("SEQ", $sformatf("start_item() fn call done"), UVM_MEDIUM)

// 3. Because the class handle passed to the driver points to the same object, we
// can do late randomization
tx.randomize();
`uvm_info ("SEQ", $sformatf("tx randomized with addr=0x%0h data=0x%0h", tx.addr, tx.data), UVM_MEDIUM)

// 4. Call finish_item method so that the sequence waits until the driver lets the
// sequencer know that this item has finished
finish_item(tx);
`uvm_info ("SEQ", $sformatf("finish_item() fn call done"), UVM_MEDIUM)
endtask
endclass