2016-02-17 1 views
-1

J'exécute un code écrit par quelqu'un d'autre, et cela fonctionne, mais je ne comprends pas ce qui se passe!SystemVerilog Tâche à l'intérieur de la fourche

initial begin: running_test 

     fork 
      task1(); 
      task2(); 
     join 
     task3(); 

end: running_test 

Quand je suis par le débogueur dans la simulation, je vois que lorsque Task1() frappe une déclaration d'horloge, le débogueur saute à task2(), et une fois task2() frappe de même une déclaration d'horloge, alors le débogueur saute à task3() !!!!!

Et c'est là que je suis confus, parce que tâche2() est une longue tâche, alors pourquoi se déplace-t-elle (jointures) à tâche3() avant de le terminer.

Et quand je continue d'exécuter le débogueur, je vois constamment que le débogueur continue de sauter entre task1(), task2() et task3() !!!! Cela va complètement à l'encontre de ma compréhension de Fork/Join. Je m'attendais à voir que le débogueur ne passera pas à task3(), à moins qu'il ne soit fait avec task1() et task2(), mais apparemment chaque fois qu'il frappe une instruction d'horloge (à l'intérieur de l'une des tâches), à une tâche différente !!!

Quelqu'un peut-il expliquer ce qui se passe?

+1

comprennent un extrait de –

+1

Task1 et task2 Avez-vous des 'fork..join_none' ou quelque chose comme ça dans' Task1() 'et' task2() '? Comme la tâche 1 et la tâche sont simultanées, le simulateur va sauter d'un côté à l'autre. Veuillez inclure task1 et task2 dans le code. – sharvil111

+0

Faites attention à 'join'. assurez-vous que ce n'est pas 'join_any' ou' join_none' Et la seule façon pour que task3 puisse être exécutée à plusieurs reprises est s'il y a une boucle que vous ne montrez pas ou qu'il y a plusieurs instances du module contenant le bloc initial. –

Répondre

0

Il doit y avoir une sorte de fork...join_none ou fork...join_any dans le task2 & task3

S'il y a une join_none ou join_any dans le task2 & TASK3, alors simulateur fraient le fil des deux tâches, et quitter la tâche. Alors, à son tour, quittera fork...join et évaluera task3 en premier.

C'est un exemple de code, qui vous aidera à comprendre mon explication:

// code votre banc d'essai ici // ou parcourir des exemples

module top(); 
    bit clk; 

    always #5 clk = ~clk; 

    initial 
    begin 
     fork 
     task1(); 
     task2(); 
     join 
     task3(); 
    end 

    task task1(); 
    fork 
     begin 
     @(posedge clk); 
     $display("@%0t : In Task1", $time); 
     end 
    join_none 
    endtask 

    task task2(); 
    fork 
     begin 
     @(negedge clk); 
     $display("@%0t : In Task2", $time); 
     end 
    join_none 
    endtask 

    task task3(); 
    $display("@%0t : In Task3", $time); 
    endtask 
endmodule 

et la sortie du code ci-dessus est écrit au dessous de. Notez que dans cette sortie, l'instruction d'affichage task3 a été imprimée avant la tâche 1, la tâche 2 est terminée.

// Output 
@0 : In Task3 
@5 : In Task1 
@10 : In Task2 
1

J'ai vu votre question pour un scénario pour ce cas ci-dessus qui est expliqué par vous est possible. Selon moi dans un cas où task2 ou task1 appelé en interne task1 alors c'est possible. Je fournis également le code pour cela.

class A; 

    task task1; 
    #10 $display("@ time = %t Here is first task\n",$realtime); 
    endtask 

    task task2; 
    #15 $display("@ time = %t Here is second task\n",$realtime); 
    task3; 
    #10 $display("@ time = %t Here is second task\n",$realtime); 
    endtask 

    task task3; 
    #5 $display("@ time = %t Here is third task\n",$realtime); 
    endtask 

endclass 


program mailbox; 
    mailbox m1; 
    A a1; 

    initial 
    begin 
     a1 = new; 
     m1 = new; 


     fork 
     a1.task1; 
     a1.task2; 
    join 
    a1.task3; 


end 

FinProgramme