如何指定默认时钟以解决SystemVerilog中##2延迟报错问题?
SystemVerilog使用
##延迟运算符报错的解决方法 问题详情
报错信息:
Error-[DCNS] Default clocking not specified. testbench.sv, 37; "##(2) ;". Cycle delay operator requires a default clocking to be specified for module/interface/program 'test'.
相关代码:
interface dut_if(input logic clk); logic [7:0] data; logic valid; logic ready; // Clocking block for the testbench (Driver/Monitor) default clocking cb @(posedge clk); default input #1step output #2ns; output data, valid; input ready; endclocking // Modport to restrict the testbench to using the clocking block modport TB (clocking cb); endinterface module test; logic clk; dut_if vif(.clk(clk)); initial begin clk = 0; forever #5 clk = ~clk; end initial begin // Synchronize to the clocking event @(vif.cb); // Drive signals through the clocking block vif.cb.data <= 8'hA5; vif.cb.valid <= 1; // Wait for 2 clock cycles using the cycle delay operator ##2; // Sample a signal if (vif.cb.ready) $display("DUT is ready at time %t", $time); vif.cb.valid <= 0; end initial #50 $finish; initial begin $dumpfile("dump.vcd"); $dumpvars; end endmodule
已在interface的clocking block前添加default关键字,但test模块中使用##2仍报错,改用repeat (2) @(vif.cb);可正常运行,询问如何通过##2解决问题。
解决方案
原因说明
interface内定义的default clocking仅作用于interface自身范围,而##延迟运算符是在test模块的initial块中调用的,该模块未指定自己的默认时钟块,导致编译器无法识别延迟对应的时钟沿,从而报错。
两种可行解决方式
方式1:在test模块内声明默认时钟块
在test模块中添加默认时钟块定义,直接关联到interface的时钟块:
module test; logic clk; dut_if vif(.clk(clk)); // 新增:指定test模块的默认时钟块 default clocking cb = vif.cb; // 原有代码保持不变... endmodule
添加后##2会自动使用该默认时钟块的时钟沿计数周期。
方式2:在##前明确指定时钟块
无需修改模块默认设置,直接在延迟运算符前指定要使用的时钟块:
// 将原代码中的##2;替换为 vif.cb ##2;
这种方式更直接,明确告诉编译器使用interface中的cb时钟块执行周期延迟操作。
内容的提问来源于stack exchange,提问作者Tang Y
相关产品推荐
相关产品推荐

