2017-08-31 6 views
0

Je veux exécuter toujours le blocage au temps zéro. Par exemple. le code ci-dessous n'exécutera pas à l'instant zéro.Toujours bloquer l'exécution au temps zéro

always @* begin 
//functional code 
end 

je me suis déplacé la liste de sensibilité à la fin afin que le code exécute à l'instant zéro,

always begin 
//funcitonal code 
@*; 
end 

Ce code exécute à l'instant zéro mais n'exécute pas du tout après le temps zéro, même s'il y a une modification des entrées utilisées à l'intérieur du bloc. Par exemple voir le code ci-dessous et sa sortie:

module AlwaysTimeZeroTest_v(); 

reg reg_A; 

initial begin 
    $display ("I'm in Initial begin block  \tTime=%f, reg_A=%b\n",$stime,reg_A); 
    #1 
    reg_A=1'bZ; 

    #1 
    reg_A=1'b1; 

    #1 
    reg_A=1'b0; 

    #1 
    reg_A=1'bZ; 

    #5 $finish; 
end 

always @* begin 
    $display ("I'm in Non-time Zero always block\tTime=%f, reg_A=%b\n",$stime,reg_A); 
end 

always begin 
    $display ("I'm in time Zero always block  \tTime=%f, reg_A=%b\n",$stime,reg_A); 
    @*; 
end 

endmodule 

Sortie:

**I'm in Initial begin block    Time=0.000000, reg_A=x 

I'm in time Zero always block   Time=0.000000, reg_A=x 

I'm in Non-time Zero always block  Time=1.000000, reg_A=z 

I'm in Non-time Zero always block  Time=2.000000, reg_A=1 

I'm in Non-time Zero always block  Time=3.000000, reg_A=0 

I'm in Non-time Zero always block  Time=4.000000, reg_A=z** 

simulation complète via finition $ (1) au moment de 9 NS + 0

Quelqu'un peut-il expliquer pourquoi seconde toujours bloc dans le code ne pas exécuter du tout après le temps zéro?

Y at-il un moyen que je peux mettre en œuvre toujours bloquer de sorte qu'il s'exécute à l'heure zéro sans utiliser le bloc initial? (quelque chose de similaire à always_comb dans SV?)

Répondre

0

Vous avez étiqueté ce système-verilog alors je vais donner la réponse par rapport à cela. Si votre utilisation actuelle est always @* et que vous ne générez pas les sorties de plusieurs blocs toujours, utilisez always_comb. Par LRM, always_comb sera exécuté au moment 0.

module AlwaysTimeZeroTest_v(); 

reg reg_A; 

initial begin 
    $display ("I'm in Initial begin block  \tTime=%f, reg_A=%b\n",$stime,reg_A); 
    #1 
    reg_A=1'bZ; 
    #1 
    reg_A=1'b1; 
    #1 
    reg_A=1'b0; 
    #1 
    reg_A=1'bZ; 
    #5 $finish; 
end 

always_comb begin 
    $display ("I'm in Non-time Zero always block\tTime=%f, reg_A=%b\n",$stime,reg_A); 
end 

always_comb begin 
    $display ("I'm in time Zero always block  \tTime=%f, reg_A=%b\n",$stime,reg_A); 
    // @*; 
end 

endmodule 
4

Beaucoup de gens ne réalisent pas que @ est un modificateur de déclaration, ne construira pas par lui-même. Il dit de retarder la déclaration qui suit jusqu'à ce qu'il y ait un événement. @(A or B) signifie attendre jusqu'à ce qu'il y ait un changement dans la valeur de A ou B (à ne pas confondre avec un changement dans le résultat de A|B). @* signifie regarder l'instruction qui suit et créer une liste de signaux de sensibilité implicite pour attendre une modification.

Dans votre premier always, l'instruction qui suit est un bloc begin/end, donc reg_A est ajouté à la liste de sensibilité. Dans votre deuxième always, l'instruction suivante est une instruction null, il n'y a donc aucune sensibilité à une modification. La seule façon de s'assurer que always @* s'exécute à l'instant zéro est de mettre une référence à la variable dans le bloc qui a un changement à l'instant 0. Ensuite, utilisez une affectation non bloquante à cette variable pour éviter tout temps 0 course conditions.

Mieux encore, utilisez alway_comb qui a été spécialement conçu pour résoudre ce problème.

+0

Merci Dave pour l'explication. Existe-t-il une alternative pour always_comb dans Verilog? – sanforyou

+0

Cela dépend de la situation qui empêche le bloc de s'exécuter à l'instant 0. Une suggestion pourrait être de s'assurer que tout ce qui est dans la liste de sensibilité est déclaré comme un fil. –