首页 > 解决方案 > 系统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。看起来该命令再次被此任务驱动。我尝试过使用局部变量,使用监视功能,使用断点,但仍然无法调试它。任何人都可以提出什么问题吗?

标签: system-verilog

解决方案


我不知道为什么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

推荐阅读