我想获取uvm_sequencer的run_phase中的事务,以检查事务是否跨越4KB边界。如果它们跨越4KB边界,我想将该事务拆分为多个事务,然后将其发送给驱动程序。当从驱动程序收到响应时,所有拆分事务响应应该合并回原始事务并返回到生成原始事务的序列。有没有办法做到这一点? uvm_sequencer是否适合做这项工作?任何帮助将不胜感激。
都铎的解决方案确实有效。我在他的代码(translation_sequence)中添加了一些编辑,如下所示:
up_sequencer.get_next_item(req);
$cast(up_trans, req.clone());
// do the splitting.
start_item(up_trans);
finish_item(up_trans);
up_sequencer.item_done();
get_response(rsp);
rsp.set_sequence_id(req.get_sequence_id());
up_sequencer.put_response(rsp);
答案 0 :(得分:2)
您无法在音序器中执行此操作,因为发送项目分两步执行:start_item(...)
和finish_item(...)
。如果它只是一种方法,你可以在那里完成。
IMO的方法是实施分层方案。您的上层是您开始序列的那一层,您不关心交易的长度。您的第二层是最大长度为4K的层。交易流程为:
你的序列 - >上序列器 - >翻译序列 - >总线音序器 - >驱动器
这意味着在您的代理中,您需要两个顺控程序,其中只有一个连接到驱动程序。翻译序列可能如下所示:
class translation_sequence extends uvm_sequence #(some_trans);
uvm_sequencer #(some_trans) up_sequencer;
task body();
while (1) begin
some_trans up_trans;
up_sequencer.get_next_item(up_trans);
if (up_trans.size <= 4096) begin
`uvm_info("SPLIT", "No need to split", UVM_LOW);
start_item(up_trans);
finish_item(up_trans);
end
else begin
// implement the splitting
int unsigned size = up_trans.size;
while (1) begin
req = new();
req.size = size > 4096 ? 4096 : size;
start_item(req);
finish_item(req);
if (size < 4096)
break;
else
size -= 4096;
end
end
up_sequencer.item_done();
end
endtask
endclass
请注意,它有一个指向上层音序器的指针,它从中获取项目并表示它们已完成。在代理中,您需要启动此序列,同时为其提供指向上层序列的指针:
class some_agent extends uvm_agent;
//...
// start the translation sequence
task run_phase(uvm_phase phase);
translation_sequence seq = new();
seq.up_sequencer = sequencer;
seq.start(bus_sequencer);
endtask
endclass
如果您想了解有关分层的更多信息,请查看Verification Horizons上的这篇文章。