我想在我的顶级测试平台中创建一个时钟,其周期可以从测试中控制.我所做的是将句点设置为uvm_config_db并将其恢复到测试平台中.我必须输入#1以确保构建阶段已完成,否则get返回错误的值:
module testbench_top;
int clk_period;
bit clk = 0;
initial begin
#1;
void'(uvm_config_db #(int) ::get(null, "uvm_test_top.env", "clk_period", clk_period));
// Create clk
forever begin
#(clk_period/2) clk = !clk;
end
end
Run Code Online (Sandbox Code Playgroud)
我被#1烦恼了.有没有更好的方法来检查配置是否已设置?我可以以某种方式阻止直到start_of_simulation_phase?
这个问题不是UVM特定的,但我正在研究的例子是UVM相关的.我在我的UVM环境中有一系列代理,我想在所有这些代理上并行启动一个序列.
如果我这样做:
foreach (env.agt[i])
begin
seq.start(env.agt[i].sqr);
end
Run Code Online (Sandbox Code Playgroud)
,序列seq
首先执行env.agt[0].sqr
.一旦结束,它就会执行env.agt[1].sqr
,依此类推.
我想实现一个foreach-fork语句,以便seq
在所有agt[i]
顺控程序上并行执行.
无论我如何订购fork-join和foreach,我都无法实现这一目标.能帮我解决并行序列启动行为吗?
谢谢.
更新以澄清我试图解决的问题:下面的代码结构的结果与上面没有fork-join完全相同.
foreach (env.agt[i])
fork
seq.start(env.agt[i].sqr);
join
fork
foreach (env.agt[i])
seq.start(env.agt[i].sqr);
join
// As per example in § 9.3.2 of IEEE SystemVerilog 2012 standard
for (int i=0; i<`CONST; ++i)
begin
fork
automatic int var_i = i;
seq.start(env.agt[var_i].sqr);
join
end
您能否帮助了解以下功能和明显区别:
我在互联网上搜索过,有一些解释,例如:
但我仍然觉得需要更多解释。有人可以帮忙吗。
如何从源代码中检测模拟中使用的时间刻度精度?考虑我有一个配置参数(cfg_delay_i),由用户以时间单位给出的一些延迟值作为fs。如果用户给出1000,我的代码在进一步执行之前必须等待1000fs 或 1ps。
#(cfg_delay_i * 1fs );//will wait only if timescale is 1ps/1fs
do_something();
Run Code Online (Sandbox Code Playgroud)
如果时间刻度精度为1fs,则不会有任何问题,但如果精度高于该精度,则不会等待,它将作为0 delay工作。所以我想编写一个代码来确定用户使用的时间刻度并相应地给出延迟。我预期的伪代码如下所示,
if(timeprecision == 1fs )#(cfg_delay_i * 1fs ) ;
else if(timeprecision == 1ps )#(cfg_delay_i/1000 * 1ps ) ;
Run Code Online (Sandbox Code Playgroud)
请帮助我确定内部时间刻度单位和精度的逻辑。
有没有一种简单的方法可以将自定义函数存储到UVM_ERROR
宏而不需要操作UVM库?(即,无论何时在环境中的任何地方调用UVM错误,我都希望我的函数与它一起被调用.)
我想知道是否有可能以某种方式弄清楚是否错误地在UVM驱动程序内部开发人员写入DUT输出信号而不是输入信号.我试过这个,没有编译/运行时错误消息.示例在这里(尝试在我的机器上的Incisive中完成,代码稍后上传):
http://www.edaplayground.com/x/386
'some_signal'上的赋值模拟DUT输出(连续驱动程序).每当我尝试从类中驱动'some_signal'表示信号被多次驱动时,我会预料到运行时错误,但是类驱动程序"获胜"并更新信号.
前段时间,当我刚刚开始做SV时,我玩modports.我会在modport中声明一些信号作为输入,但我注意到驱动它们仍然是合法的.之后我不再使用它们了.显然这是众所周知的,正如这篇文章所说:https://verificationacademy.com/forums/systemverilog/modports-sv
我最近从同事那里继承了一些在类中使用modport的代码.我做了以下示例来说明该代码正在做什么:
http://www.edaplayground.com/x/2W_
我尝试在两个类中使用modport,但ModelSim抱怨不应该在分层路径中使用modport.敏锐的代码没有问题,也没有发出任何警告.ModelSim错误以及2012年标准中的引用"为了限制模块内的接口访问,存在在接口内声明了方向的modport列表." 有点暗示modport并不是真的打算在课堂上使用.
有人可以确认modports不是去这里的方法吗?此外,有没有人知道这些错误(从类驱动DUT输出)是否可以以任何方式被捕获?
我对 SystemVerilog 中的竞争条件有疑问,尤其是 UVM 中。在标准情况下,我们拥有多个驱动程序,它们在同一时钟前端驱动我们的待测试器件,在记分板中生成一些函数调用。这些调用是同时进行的,并且它们检查/修改黄金参考模型中的一些共享变量是现实的。如果这些操作通过非阻塞分配来完成,则不会有问题,但通过阻塞分配可能会出现竞争条件。克服这个问题的最佳方法是什么?不在类中实现黄金参考模型?提前致谢
记分板的伪代码示例可以是:
function void write_A(input TrA A);
if(GRF.b >= 100 && A.a==1)
GRF.c = 1;
endfunction
function void write_B(input TrB B);
GRF.b+=B.b;
endfunction
Run Code Online (Sandbox Code Playgroud)
当然结果取决于这两个函数的执行顺序,这是未知的。可以通过某种同步机制来解决,但是如果有许多写入并行函数,事情就会变得更加困难。使用非阻塞分配将使情况变得更加清晰和简单......也许解决方案可以是让 GRF 的所有成员都是静态的?
uvm_event
SystemVerilog 的优势是什么event
?有人能用小伪代码解释一下吗?
通常情况下,我们的UVM模拟会因签名而失败,我们最终会调试到未连接的分析端口.
有没有办法检查前面的分析端口是否连接run_phase
?
是否可以将type
参数传递给函数,以便create_eclass*
只能通过将类类型参数传递给函数来编写一次函数?
class bclass;
virtual function void print();
$display("Base Class");
endfunction
endclass
class eclass1 extends bclass;
function void print();
$display("Extended Class1");
endfunction
endclass
class eclass2 extends bclass;
function void print();
$display("Extended Class2");
endfunction
endclass
program Test ;
bclass q[$];
function create_eclass1();
bclass b;
eclass1 e;
e=new();
$cast(b,e);
q.push_back(e);
endfunction
function create_eclass2();
bclass b;
eclass2 e;
e=new();
$cast(b,e);
q.push_back(e);
endfunction
initial
begin
create_eclass1();
create_eclass2();
foreach(q[i]) q[i].print();
end
endprogram
Run Code Online (Sandbox Code Playgroud)