通常情况下,我们的UVM模拟会因签名而失败,我们最终会调试到未连接的分析端口.
有没有办法检查前面的分析端口是否连接run_phase
?
我的芯片中有一个小块的UVM测试平台.在这里有一个带有驱动程序的代理,可以在虚拟接口上驱动数据,如下所示:
interface my_if (input bit clk);
logic [3:0] opcode;
// Clocking block for the driver
clocking drvClk @(posedge clk);
output opcode;
endclocking
// Clocking block for the monitor
clocking monClk @(posedge clk);
input opcode;
endclocking
endinterface
Run Code Online (Sandbox Code Playgroud)
我在我的驱动程序中使用此接口,如下所示:
class my_driver extends uvm_driver #(my_tr);
my_if vif;
...
virtual task run_phase(uvm_phase phase);
super.run_phase(phase);
forever begin
seq_item_port.get_next_item(req);
// Drive the transaction onto the interface
// and wait for next clock
vif.opcode <= req.opcode;
@(vif.drvClk);
seq_item_port.item_done();
end
endtask
endclass
Run Code Online (Sandbox Code Playgroud)
据我所知,这是推荐的做事方式,效果很好.当我将此代理集成到更高级别的测试平台时,就会出现问题.在这种情况下,代理现在是被动的,并且不构建驱动程序.我将操作码值分配给接口,以便监视器可以观察它.这是我的顶级线束的片段:
module my_top();
bit clk = …
Run Code Online (Sandbox Code Playgroud) 我有一个用RAL建模的大型寄存器映射,我想随机化一些寄存器.如果我想单独约束寄存器那么这很简单:
reg_model.register_a.randomize() with {value > 5;}
reg_model.register_b.randomize() with {value < 2;}
reg_model.update(status);
Run Code Online (Sandbox Code Playgroud)
但是,如果我想要写两个值之间的关系,我想我必须在整个寄存器模型中添加一个约束:
reg_model.randomize() with {register_a.value > register_b.value;}
reg_model.register_a.update(status);
reg_model.register_b.update(status);
Run Code Online (Sandbox Code Playgroud)
这里的问题是模型中的其他254个寄存器也将被随机化.我可以只更新我想要随机化的两个寄存器,但镜像将与硬件不匹配.如果我有后门访问工作,我可以刷新镜像,但我没有,我当然不想通过前门读回254寄存器.
有没有办法随机化这两个寄存器但仍然有约束求解器维持它们之间的关系?
我有一个简单的序列
regmodel.REGx.write (...)
Run Code Online (Sandbox Code Playgroud)
让我们考虑一下我在 regmodel viz 下有 8 个寄存器。REG0, REG1, REG2,....,REG7 我想通过 number 作为测试加参数,比如 +NUM=4
使用 $sformat 或 $psprintf,我可以创建具有正确寄存器名称的字符串变量,例如
if ($value$plusargs ("NUM=%0d", num))
$display ("Testcase passed %0d num", num);
else
num = 0;
$sformat (regName, "REG%0d", num);
Run Code Online (Sandbox Code Playgroud)
现在我有 regName 但我不能使用以下内容:
regmodel.regName.write (...)
Run Code Online (Sandbox Code Playgroud)
regName 是字符串类型,regmodel 没有任何寄存器名称 regName,还有其他方法可以实现吗?我正在查看 get_name、get_full_name 但在这种情况下这些无济于事。
现在我可以有 if - else 8 次或 case 语句,但是对于大量寄存器来说真的很不方便。
我有一个实现的奴隶模型uvm_agent
.通过"奴隶"我的意思是它不能自己发起交易.事务始终由另一方(主DUT)启动.所以它是一种被动代理(虽然它仍然能够传输回复数据包).
当从设备检测到来自DUT的数据包时,它将自动(基于其协议)与另一个数据包进行响应/回复.从属代理有一个监听器来监听DUT的启动转移.并且由于它能够传输数据包,因此从属代理也有一个驱动程序来发送应答数据包.
+------------+ master initiate transfer +------------------------+
| Master DUT | ------------------------> | UVM Agent - slave mode |
| | | Monitor |
| | | Driver Sequencer |
+------------+ +------------------------+
+------------+ +------------------------+
| Master DUT | | UVM Agent - slave mode |
| | slave auto reply | Monitor |
| | <------------------------- | Driver Sequencer |
+------------+ +------------------------+
Run Code Online (Sandbox Code Playgroud)
我的问题是它如何发送回复数据包?直接来自它的司机?因为以uvm方式,驱动程序项始终来自正在执行来自用户测试级别的序列的顺控程序.但现在在这种情况下,没有序列 - 只有来自监视器的检测到的数据包.
我的第一个想法是,我需要提供一些反馈monitor
,sequencer
并在那里实现我的协议功能.
或者我应该直接将数据包传递monitor
给driver
,并让它处理它并发送回复?如果是这样,我该怎么做?有没有更好的方法?
我正在学习UVM教程的基础知识.我读到的任何地方总是从事务对象扩展uvm_sequence_item
而不是uvm_transaction
因为uvm_sequence_item
有事务ID等其他功能.如果是这样的话,为什么uvm_transaction
类甚至在UVM类层次结构中呢?
uvm_transaction
除了uvm_sequence_item
延伸之外,谁在使用?
是因为遗产吗?
我试图在systemverilog中按名称获取一个uvm寄存器字段.我想使用正则表达式,以便我可以使用字段名称的模式.这是我的注册字段:
YY_XXX_2_N
ZZ_BBB_3_N
UU_AAA_8_N
MM_CCC_4_N
YY_WWW_9_N
Run Code Online (Sandbox Code Playgroud)
正如您所看到的所有寄存器字段都以_N结尾,我使用以下代码来获取寄存器字段:
field=env.my_regmap.get_field_by_name("_N$");
Run Code Online (Sandbox Code Playgroud)
所以我希望这段代码得到一个与提供的模式匹配的寄存器字段.使用上面的代码,我收到以下错误:
reporter [RegModel] Unable to locate field '_N$' in block 'my_regmap'
Run Code Online (Sandbox Code Playgroud)
我想知道在这种情况下是否有办法使用正则表达式.
谢谢!
对于使用`uvm_field_queue_int
实用宏的UVM 对象,调用时 UVM 不会打印出整个队列my_object.print()
# -----------------------------------------
# Name Type Size Value
# -----------------------------------------
# my_object my_object - @443
# data_q da(integral) 16 -
# [0] integral 32 'h203f922b
# [1] integral 32 'he4b3cd56
# [2] integral 32 'hd7477801
# [3] integral 32 'h3a55c481
# [4] integral 32 'h2abf98c4
# ... ... ... ...
# [11] integral 32 'hac0d672b
# [12] integral 32 'h3ba2cb5d
# [13] integral 32 'hbe924197
# [14] integral 32 'h3cc6d490
# [15] integral 32 …
Run Code Online (Sandbox Code Playgroud) 我有一个 uvm_sequence 随机化启用位“feature_en”。根据是否启用此位,我想启用/禁用我的记分板。我使用 config_db 来设置变量,并使用 field_macros 自动将其获取到记分板中。
我的问题是,在记分牌中,我想用“feature_en”保护 run_phase 中的代码。但是,该序列在测试的 run_phase 中运行,因此记分板的 run_phase 首先运行,从而保留 feature_en 默认值,并且不会获取序列中设置的值。
我尝试使用wait(feature_en != -1)(我已将其设置为 int),但我意识到 feature_en 不会在记分牌中再次采样。
有没有办法在记分牌中动态更新feature_en?或者还有其他方法可以做到这一点吗?
我如何控制某些组件的详细程度,以便我只能将详细程度设置为少数组件?
假设,例如在验证特定功能时,涉及测试、几组组件/序列/对象/接口等。我想将只有这些的冗长设置为UVM_HIGH
. 我不想设置要设置的全局严重性,UVM_HIGH
因为可能会出现许多不相关的调试消息,这可能会增加日志大小。
这样做的更清洁方法是什么?可以使用额外的 commandline-plusarg 来触发它。基本上,要求是特定功能验证所涉及的测试/组件/序列/对象/接口应采用全局严重性或特定于功能的严重性,具体取决于哪个更高。
请注意,不能使用内置的报告方法,uvm_component
因为uvm_info
语句可以在uvm_object
扩展类和接口中。