system-verilog - 系统verilog中的任务延迟
问题描述
我正在尝试在另一个任务中调用 4 个任务,如下所示:
task execute();
logic [0:3] req1, port_select;
logic [0:3] req2;
logic [0:3] req3;
logic [0:3] req4;
logic [0:31] data11, data21;
logic [0:31] data12, data22;
logic [0:31] data13, data23;
logic [0:31] data14, data24;
bfm.reset_task();
//drive multiple ports
//repeat(1)
//begin: random_stimulus
port_select = generate_combination();
repeat(1)
begin: per_combination_iteration
//port1
req1 = port_select[0]? generate_command() : 0;
data11 = generate_data();
data21 = generate_data();
//bfm.drive_ip_port1(req,data1,data2);
//port2
req2 = port_select[1]? generate_command() : 0;
data12 = generate_data();
data22 = generate_data();
//bfm.drive_ip_port2(req,data1,data2);
//port3
req3 = port_select[2]? generate_command() : 0;
data13 = generate_data();
data23 = generate_data();
//bfm.drive_ip_port3(req,data1,data2);
//port4
req4 = port_select[3]? generate_command() : 0;
data14 = generate_data();
data24 = generate_data();
//bfm.drive_ip_port4(req,data1,data2);
fork
bfm.drive_ip_port1(req1,data11,data21);
bfm.drive_ip_port2(req2,data12,data22);
bfm.drive_ip_port3(req3,data13,data23);
bfm.drive_ip_port4(req4,data14,data24);
join
end: per_combination_iteration
//end: random_stimulus
$stop;
endtask: execute
我的drive_ip_port
功能之一如下:
//driving port2
task drive_ip_port2(input logic [0:3] req2, input logic [0:31] data1_port2, data2_port2);
req2_cmd_in = req2; //req2 command
req2_data_in = data1_port2; //req2 first operand
#200;
req2_cmd_in = 0;
req2_data_in = data2_port2; //req2 second operand
#1000;
endtask: drive_ip_port2
这就是我想要实现的目标:我希望执行任务随机驱动 4 个端口。在第一个时钟上,我希望他们发送命令和数据。然后在下一个时钟,命令应该是 0,只需要发送数据。
这是我尝试过的:如我的代码所示,我已经编写了上面的代码。这段代码背后的想法是,由于任务可以处理时间延迟,我可以调用一次任务并传递数据和命令,让任务处理所有工作。
我遇到的问题:在第一个时钟周期之后,我有 #200 的延迟(等于我的时钟)。此后,该线应变为 0,对于#1000 应保持为 0。但是,我永远不会在命令中获得值 0。看起来该命令再次被此任务驱动。我尝试过使用局部变量,使用监视功能,使用断点,但仍然无法调试它。任何人都可以提出什么问题吗?
解决方案
我不知道为什么req2_cmd_in
不设置为零。也许在其他地方有一个压倒一切的任务,比如另一个任务中的错字。(尝试只调用一项任务,看看它会做什么。)
我确实知道,如果您想在某个时钟或时钟之后发生某些事情,请等待该时钟,不要使用延迟。最安全的也是确保您从时钟沿的确定点开始。因此我更喜欢在我的测试平台代码中使用这样的:
task drive_ip_port2(input logic [0:3] req2,
input logic [0:31] data1_port2, data2_port2);
// Use this or make sure you call the task at a
// determined point from the clock
@ (posedge clk) ;
// Signals here change as if they come from a clocked register
req2_cmd_in <= req2; //req2 command
req2_data_in <= data1_port2; //req2 first operand
@ (posedge clk) ;
req2_cmd_in <= 0; // No command
req2_data_in <= data2_port2; // only req2 second operand
repeat (4) // 4 or 5 depends on if you wait for clock at top
@ (posedge clk) ;
endtask: drive_ip_port2
推荐阅读
- ios - 视图属性不会出现在情节提要中
- unity3d - Unity3D 包缓存错误(?)
- salesforce - Salesforce 如何更改 pageBlockTable 的颜色
- mysql - 将表限制为在其中一列中具有特定值的记录数量
- r - R / Twitter Live Streaming:错误:流过早断开连接
- c# - 从另一个类 C# 中的线程控制 UI 表单元素
- node.js - 在 expressjs 服务器和 vuejs 客户端之间使用快速会话
- mysql - 优化“COUNT(DISTINCT col) WHERE othercol = ?” 为了速度
- r - 包 RCurl 无法通过 sp_execute_external_script 连接到 URL
- java - 当服务器关闭时,Java Socket 不会引发异常