Specman UVM:当值写入另一个寄存器时,如何更新寄存器的值?
(在我的验证环境中,我们使用Specman UVM:当值写入另一个寄存器时,如何更新寄存器的值?,specman,uvm,e,Specman,Uvm,E,(在我的验证环境中,我们使用vr_adpackage。)。我尝试实施下一步: 当数据写入其中一个寄存器(timer\u load)时,应使用相同的数据更新另一个寄存器(timer\u bgload) 我在《UVM用户指南》中找到了下一个示例: // Attaching the target register file to the broadcasted register extend ex_c_bus_env { post_generate() is also { xc
vr_ad
package。)。我尝试实施下一步:
当数据写入其中一个寄存器(timer\u load
)时,应使用相同的数据更新另一个寄存器(timer\u bgload
)
我在《UVM用户指南》中找到了下一个示例:
// Attaching the target register file to the broadcasted register
extend ex_c_bus_env {
post_generate() is also {
xcore_regs.vr_ad_rx_data.attach(xbus_regs);
};
};
// Implement the broadcast:
// When writing to register VR_AD_RX_DATA in XCORE vr_ad_reg_file,
// propagate the value to the VR_AD_XBUS_DATA register in ACTIVE_XBUS.
extend ACTIVE_XBUS vr_ad_reg_file {
indirect_access( direction : vr_ad_rw_t, ad_item : vr_ad_base) is {
if ad_item is a VR_AD_RX_DATA vr_ad_reg (d) {
vr_ad_xbus_data.write_reg_val(d.get_cur_value());
};
};
};
*** Error: No such variable 'timer_bgload'
at line 17 in @timer_reg_db
timer_bgload.write_reg_val(d.get_cur_value());
我的寄存器:
reg_def TIMER_LOAD_0 TIMER 20'h00010 {
reg_fld timer_load : uint (bits : 32) : RW : 0xffff;
};
reg_def TIMER_BGLOAD_0 TIMER 20'h00014 {
reg_fld timer_bgload : uint (bits : 32) : RW : 0xffff;
};
reg_def TIMER_BGLOAD_1 TIMER 20'h00028 {
reg_fld timer_bgload : uint (bits : 32) : RW : 0xffff;
//another reg with the same instance name
};
我的代码用于在将数据写入tiemr\u load
后更新计时器加载
寄存器:
extend TIMER vr_ad_reg_file {
indirect_access( direction : vr_ad_rw_t, ad_item : vr_ad_base) is {
if ad_item is a TIMER_LOAD_0 vr_ad_reg (d) {
timer_bgload.write_reg_val(d.get_cur_value());
};
};
};
unit timer_env_u like any_env {
post_generate() is also {
timer_regs.timer_load_0.attach(timer_regs.timer_bgload_0.timer_bgload);
};
};
我得到一个编译错误:
// Attaching the target register file to the broadcasted register
extend ex_c_bus_env {
post_generate() is also {
xcore_regs.vr_ad_rx_data.attach(xbus_regs);
};
};
// Implement the broadcast:
// When writing to register VR_AD_RX_DATA in XCORE vr_ad_reg_file,
// propagate the value to the VR_AD_XBUS_DATA register in ACTIVE_XBUS.
extend ACTIVE_XBUS vr_ad_reg_file {
indirect_access( direction : vr_ad_rw_t, ad_item : vr_ad_base) is {
if ad_item is a VR_AD_RX_DATA vr_ad_reg (d) {
vr_ad_xbus_data.write_reg_val(d.get_cur_value());
};
};
};
*** Error: No such variable 'timer_bgload'
at line 17 in @timer_reg_db
timer_bgload.write_reg_val(d.get_cur_value());
我真的非常感谢您的帮助。我会用
post\u access
实现它,比如:
extend TIMER_LOAD_0 TIMER vr_ad_reg {
post_access(operation : vr_ad_rw_t) is {
if operation == WRITE {
var rgf := get_access_path()[0].as_a(TIMER vr_ad_reg_file);
rgf.timer_bgload_0.timer_bgload = timer_load;
};
};
};
注意,它可能在第一次击中时不起作用。如果不是,我会逐步构建它,从“空”代码开始,如下所示:
extend TIMER_LOAD_0 TIMER vr_ad_reg {
post_access(operation : vr_ad_rw_t) is {
print me, operation;
};
};
在
print
语句中设置断点,打开数据浏览器,查看我们在那里得到的字段的确切名称,尝试从Specman CLI访问它们—当它工作时—将其重新编码。您可以将定时器加载
寄存器直接连接到定时器加载
寄存器,并在那里实现间接访问(…)
:
// attach the regs
extend TIMER vr_ad_reg_file {
post_generate() is also {
timer_load_0.attach(timer_bgload_0);
};
};
// implement indirect_access()
extend TIMER_BGLOAD_0 vr_ad_reg {
indirect_access(direction : vr_ad_rw_t, ad_item : vr_ad_base) is {
if direction == WRITE and ad_item is a TIMER_LOAD_0 vr_ad_reg (d) {
write_reg_val(d.get_cur_value());
};
};
};
我不知道Cadence示例为什么要花很长的时间将寄存器文件附加到间接寄存器
此外,如果您有多个TIMER\u LOAD/BGLOAD寄存器(看起来可能有2个),那么最好先定义类型:
// define register types without instantiation in reg_file
reg_def TIMER_LOAD {
reg_fld timer_load : uint (bits : 32) : RW : 0xffff;
};
reg_def TIMER_BGLOAD {
reg_fld timer_bgload : uint (bits : 32) : RW : 0xffff;
};
定义类型后,可以根据需要在寄存器文件中手动实例化它们。请看一下手册,这里有一个示例向您详细说明了如何操作
这意味着在
TIMER\u BGLOAD
子类型中实现间接访问(…)
方法就足够了(仅一次),而不是两次(对于TIMER\u BGLOAD\u 0
和TIMER\u BGLOAD\u 1
)。TIMER\u BGLOAD仅存在于TIMER\u BGLOAD\u 0
和TIMER\u BGLOAD\u 1
(它们不是同一个字段!)您不能从计时器vr_ad_reg_文件中访问它们
这也是我过去使用后期访问(…)
的方式,但是间接访问(…)
是专门为这种事情设计的。