verilog - 程序块如何控制这段代码中的时钟输出?
问题描述
这是一个简单的 SV 程序(我知道仲裁器要复杂得多,请原谅我将其命名为一个),但我不知道该线路如何repeat(4) @ar.cb;
控制整个时钟。如果我注释掉该行,即使我已将其放在顶部模块内的“始终”块中,时钟也会停止。我无法理解这是如何工作的。
testbench.sv
interface arb_if(input bit clk);
logic [1:0] request;
logic [1:0] grant;
logic reset;
clocking cb @(posedge clk);
output request;
input grant;
endclocking
modport DUT(input request,clk,reset,output grant);
modport TB(clocking cb,output reset); endinterface
program automatic test(arb_if.TB ar);
initial begin
ar.reset <= 1;
ar.cb.request<=$urandom;
$display("[%0t]Request is sent",$time);
repeat(4) @ar.cb;
$display("[%0t]Grant=%0d",$time,ar.cb.grant);
end endprogram
module top;
bit clk;
always #5 clk=~clk;
arb_if arb(clk);
test tb(arb);
arbit a1(arb,clk); endmodule
design.sv
module arbit(arb_if.DUT arbiter,input bit clk); always @(posedge clk)
if(arbiter.reset==0)
arbiter.grant<=2'bxx;
else
#1 arbiter.grant<=arbiter.request;
endmodule
在设计中,即使我使用阻塞分配,直到下一个周期才会分配授权(除非我给#1
,在这种情况下,它会在延迟之后)。
我正在努力理解同步电路时序。如果有人可以为我解决这个问题,那将是一个很大的帮助。
没有#1
:
与#1
:
解决方案
program
终止模拟。
来自 IEEE Std 1800-2017,第24.3 节程序构造:
当一个程序中的所有初始过程都已结束时,该程序应立即终止该程序中初始过程的所有后代线程。如果在至少一个程序块中至少有一个初始过程,则整个模拟将通过隐式调用 $finish 系统任务立即终止,所有线程及其所有后代线程都源自所有程序中的所有初始过程已经结束。
使用该repeat
语句,模拟在时间 35 结束。它等待 4 个上升沿clk
,然后隐式调用$finish
。
如果没有该repeat
语句,模拟将在时间 0 结束。它不会等待任何clk
边,然后隐式调用$finish
.
推荐阅读
- python - py 命令不起作用,但 python 命令在 cmd 中工作
- javascript - 尝试从我的 api 获取数据时获得 [object object] 响应
- php - 用自制软件更新 php 会导致并发症
- python - 如何使用python中的两列计算进程的总长度,直到它发生变化?
- powershell - PSWindowsUpdate 在域管理员时在远程机器上被拒绝访问
- git - git serverside hook - 用于检查 Java 代码格式的预接收或更新 - 如何使用它?
- javascript - 不包括 node_modules 的 Glob 文件模式
- swiftui - SwiftUI:QuickLook 在 iPad 设备中无法正常工作
- typescript - 从泛型类型推断返回类型?
- api - 请求完成后访问 DI 对象。ASP.NET 核心 2.1