我试图在另一个任务中调用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。看起来该命令再次受此任务驱动。我尝试使用局部变量,使用watch功能,使用断点但仍然无法调试它。任何人都可以提出错误的建议吗?
答案 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