知识点:

uvm世界运转得必要条件:组件之间进行事务传送,sequence_item是道路上行驶卡车,sequence是道路,sequencer是目的地的关卡,driver是最终的目的地。sequence_item从sequence出发,经过sequencer,到达driver。

uvm_sequence_item:基于uvm_object类,可以在任何阶段创建;完成所需要的具体数据和控制要求,由于item本身的数据属性,为了充分利用UVM域声明的特性,可以把不要的数据成员通过`uvm_field_xxx宏来声明,以便日后uvm_object的基本数据方法自动实现;
uvm_sequence:基于uvm_object类,可以在任何阶段创建;sequence只负责生成item的相关内容,驱动激励时序的任务则是由driver完成的。

uvm_sequencer:将数据put给driver;
driver:负责进行处理数据;driver与sequencer之间的TLM通信采用get模式,由driver发起请求,从sequencer获得item,再由sequencer将其传给driver。所以driver是一个永动机,不用的索求item;
实现driver和sequencer的request获取和response返回端口:
item的传送:driver::seq_item_port和sequencer::seq_item_export
端口的连接:driver::seq_item_port::connect(sequencer::seq_item_export)
REQ和RSP的一致性:在自定义sequencer和driver时就表明传递的具体item类型,就不需要额外的转换了,否则在driver得到REQ在进行下一步数据处理的时候,需要动态转换将REQ转换为uvm_sequence_item的子类型才能有效的获取数据。目的是方便统一处理。
1.1 driver与squencer的改建
首先移除邮箱句柄以及句柄通信的方式,然后更改通信方式,这里使用uvm_driver::seq_Item_port的通信方式,通过get_next_item的方式获取句柄,然后等待driver消化了req的,通过item_done的方式告知sequence此次传输已经结束了,然后把rsp返回到fifo里面;移除generator,定义具有相同功能的reg_sequence和reg_sequencer:



1.2 底层sequence的提取
把各个generator中的transaction任务提取为对应的sequence,除了声明reg_sequencer类以外,还声明了reg_sequence类,内容完全是reg_generator类的内容基础上做的改变,移除了邮箱句柄,task start()替换为task body(),mcdf_base_test中的idle_reg、write_reg、read_reg都是通过调用generator来做randomize,现在改用`uvm_do_with 的方法完成随机化。send_trans的目的还是发送reg_trans,以前是通过邮箱握手的方式进行的,使用`uvm_do_with的方式也包含了创建、随机化和发送,调用get_response的函数拿回句柄。把 mcdf_base_test 中的task移到 reg_sequences中去,声明为idle_reg_sequence、write_reg_sequence、read_reg_sequence
class reg_base_sequence extends uvm_sequence #(reg_trans);
rand bit[7:0] addr = -1;
rand bit[1:0] cmd = -1;
rand bit[31:0] data = -1;
constraint cstr{
soft addr == -1;
soft cmd == -1;
soft data == -1;
}
`uvm_object_utils_begin(reg_base_sequence)
`uvm_field_int(addr, UVM_ALL_ON)
`uvm_field_int(cmd, UVM_ALL_ON)
`uvm_field_int(data, UVM_ALL_ON)
`uvm_object_utils_end
`uvm_declare_p_sequencer(reg_sequencer)
function new (string name = "reg_base_sequence");
super.new(name);
endfunction
task body();
send_trans();
endtask
// generate transaction and put into local mailbox
task send_trans();
reg_trans req, rsp;
`uvm_do_with(req, {local::addr >= 0 -> addr == local::addr;
local::cmd >= 0 -> cmd == local::cmd;
local::data >= 0 -> data == local::data;
})
`uvm_info(get_type_name(), req.sprint(), UVM_HIGH)
get_response(rsp);
`uvm_info(get_type_name(), rsp.sprint(), UVM_HIGH)
if(req.cmd == `READ)
this.data = rsp.data;
assert(rsp.rsp)
else $error("[RSPERR] %0t error response received!", $time);
endtask
function void post_randomize();
string s;
s =

本文深入探讨UVM(Universal Verification Methodology)中序列化机制的实现原理与应用技巧,包括sequence_item、sequence、sequencer及driver的角色与交互方式。通过对具体代码案例的解析,帮助读者理解如何构建高效的验证环境。
最低0.47元/天 解锁文章
417

被折叠的 条评论
为什么被折叠?



