In SystemVerilog testbench generator class - 如何生成无限长的数据流
In SystemVerilog testbench generator class - how to generate infinitely long data stream
在我能在互联网上找到的所有 SystemVerilog 测试平台中,生成器 class 总是生成固定数量的样本并将它们发送到邮箱。驱动程序读取邮箱并通过操作接口信号生成适当的序列
一个这样的生成器,取自 [1](第 1.3 章,第 4 段)并简化为要点,例如:
class generator;
rand transaction trans;
mailbox gen2driv;
int repeat_count;
function new(mailbox gen2driv);
this.gen2driv = gen2driv;
endfunction
task main();
repeat(repeat_count) begin
trans = new();
if( !trans.randomize() ) $fatal("Gen:: trans randomization failed");
gen2driv.put(trans);
end
endtask
endclass
这个生成repeat_count
个样本并发送到邮箱。
然而,在某些情况下,用户想要生成无限数据流,因为测试平台模拟不会因缺少输入数据而终止,而是会因验证发生在未来某处未知时间的情况。
扩展上述示例以将 repeat(repeat_count) begin
替换为 forever begin
将不起作用。模拟器在尝试将无限数量的样本放入邮箱时在循环中冻结。由于 main
任务的执行是一个阻塞动作,驱动程序的信号发生器永远不会被执行,整个模拟停滞。
所以我的问题是:如何正确定义一个可以发送无限数据流的生成器class?
我正在寻找类似于 pythonic yield
和生成器函数的行为。然而,这需要驱动程序和生成器之间进行一些通信。那么这样的生成器模型应该不是很适合SV吧?
[1] https://verificationguide.com/systemverilog-examples/systemverilog-testbench-example-01
您要问的正是 UVM sequence/driver 机制的工作原理。在驱动程序准备好并要求驱动一个项目之前,生成器不会进行任何随机化。
但是您可以简单地通过构造边界为 1 的邮箱来接近 UVM 的作用。然后主循环中的 put(trans)
阻塞,直到驱动程序执行 get()
.那么邮箱里总会有一笔交易等待下一个驱动周期。
您可以在主任务的某处添加等待语句,例如 wait(gen2driv.num()<pause_threshold);
。这将阻止生成器添加更多事务,直到驱动程序有机会使用它。
task main();
forever begin
wait(gen2driv.num()<pause_threshold);
trans = new();
if( !trans.randomize() ) $fatal("Gen:: trans randomization failed");
gen2driv.put(trans);
end
endtask
在我能在互联网上找到的所有 SystemVerilog 测试平台中,生成器 class 总是生成固定数量的样本并将它们发送到邮箱。驱动程序读取邮箱并通过操作接口信号生成适当的序列
一个这样的生成器,取自 [1](第 1.3 章,第 4 段)并简化为要点,例如:
class generator;
rand transaction trans;
mailbox gen2driv;
int repeat_count;
function new(mailbox gen2driv);
this.gen2driv = gen2driv;
endfunction
task main();
repeat(repeat_count) begin
trans = new();
if( !trans.randomize() ) $fatal("Gen:: trans randomization failed");
gen2driv.put(trans);
end
endtask
endclass
这个生成repeat_count
个样本并发送到邮箱。
然而,在某些情况下,用户想要生成无限数据流,因为测试平台模拟不会因缺少输入数据而终止,而是会因验证发生在未来某处未知时间的情况。
扩展上述示例以将 repeat(repeat_count) begin
替换为 forever begin
将不起作用。模拟器在尝试将无限数量的样本放入邮箱时在循环中冻结。由于 main
任务的执行是一个阻塞动作,驱动程序的信号发生器永远不会被执行,整个模拟停滞。
所以我的问题是:如何正确定义一个可以发送无限数据流的生成器class?
我正在寻找类似于 pythonic yield
和生成器函数的行为。然而,这需要驱动程序和生成器之间进行一些通信。那么这样的生成器模型应该不是很适合SV吧?
[1] https://verificationguide.com/systemverilog-examples/systemverilog-testbench-example-01
您要问的正是 UVM sequence/driver 机制的工作原理。在驱动程序准备好并要求驱动一个项目之前,生成器不会进行任何随机化。
但是您可以简单地通过构造边界为 1 的邮箱来接近 UVM 的作用。然后主循环中的 put(trans)
阻塞,直到驱动程序执行 get()
.那么邮箱里总会有一笔交易等待下一个驱动周期。
您可以在主任务的某处添加等待语句,例如 wait(gen2driv.num()<pause_threshold);
。这将阻止生成器添加更多事务,直到驱动程序有机会使用它。
task main();
forever begin
wait(gen2driv.num()<pause_threshold);
trans = new();
if( !trans.randomize() ) $fatal("Gen:: trans randomization failed");
gen2driv.put(trans);
end
endtask