Задержки внутри задач в системе Verilog - PullRequest
0 голосов
/ 06 мая 2018

Я пытаюсь вызвать 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 и должен остаться 0 для # 1000. Тем не менее, я никогда не получаю значение 0 по команде. Похоже, что команда снова управляется этой задачей. Я пытался использовать локальные переменные, используя функцию наблюдения, используя точку останова, но все еще не смог отладить ее. Кто-нибудь может подсказать, что не так?

1 Ответ

0 голосов
/ 06 мая 2018

Я не знаю, почему 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
...