web-dev-qa-db-fra.com

Utilisation d'une boucle générer avec pour dans verilog

J'essaie de comprendre pourquoi nous utilisons générer dans Verilog avec une boucle for.

En utilisant une génération et une boucle ensemble:

reg [3:0] temp;
genvar i;
generate
for (i = 0; i < 3 ; i = i + 1) begin: 
    always @(posedge sysclk) begin
        temp[i] <= 1'b0;
    end
end
endgenerate

Utilisant seulement pour la boucle:

reg [3:0] temp;
genvar i;
always @(posedge sysclk) begin
  for (i = 0; i < 3 ; i = i + 1) begin: 
    temp[i] <= 1'b0;
    end
end

Je pense que les deux extraits produiraient le même résultat, à savoir temp [0] à temp [10] égal à 0. Quelle est la différence/l'avantage que nous voyons en utilisant une instruction generate dans ce cas?

6
CDN

En général, la principale différence entre la boucle generate pour et la boucle régulière régulière est que la boucle génère pour génère une instance pour chaque itération. Cela signifie que dans votre exemple, il y aura toujours 3 blocs (par opposition à 1 bloc dans le cas d'une boucle normale).

Un bon exemple de code que Requiert Générer pour est:

module A();
..
endmodule;

module B();
parameter NUM_OF_A_MODULES = 2; // should be overriden from higher hierarchy
genvar i;
for (i=0 i<NUM_OF_A_MODULES; i=i+1) {
  A A_inst();
}
endmodule;

Dans cet exemple, un habitué de ne peut pas créer NUM_OF_A_MODULES instances.

Dans votre exemple, vous pouvez obtenir le résultat requis dans les deux sens. (tant que vous corrigez quelques bugs mineurs :))

4
Razko

Dans l'exemple sans generate, i devrait être un genvar pas integer. Sinon, les deux sont valides selon la version de IEEE Std 1364 prise en charge par votre jeu d’outils. La construction generate a été ajoutée dans IEEE Std 1364-2001, où les mots clés generate/endgenerate sont explicitement requis. Dans IEEE Std 1364-2005, cette option est devenue facultative, la seule condition étant que si generate est utilisé, il doit correspondre à endgenerate.

Lorsque vous utilisez IEEE Std 1364-2005 ou SystemVerilog (IEEE Std 1800), la préférence de style de codage entre déclaration implicite et déclaration explicite est importante. Explicit a l'avantage d'être une comparabilité en arrière.


Les blocs de génération sont utiles lorsque vous modifiez la structure physique du module puis via des paramètres. Par exemple, choisir Negedge ou Posedge Clock et en activer seulement un:

if ( param_use_pos == 1) begin : use_pos
  always @(posedge sysclk) begin
    ...
  end
end
else begin : use_neg
  always @(negedge sysclk) begin
     ...
  end
end

Si vous ne modifiez pas la structure physique, il est généralement préférable d'utiliser les boucles for et les instructions if-else à l'intérieur du bloc always. Les deux approches peuvent synthétiser la même chose, mais lors de l'exécution d'une simulation RTL, l'approche par blocs non générés simule généralement plus rapidement. En effet, les simulateurs peuvent normalement traiter une seule opération à N bits plus rapidement que les opérations à 1 bit. Encore une fois la synthèse est le même résultat

// faster :: 1 always block, simulator can optimize the for loop
always @(posedge sysclk) begin 
  for (i = 0; i < 3 ; i = i + 1) begin
    temp[i] <= 1'b0;
  end
end

// slower :: creates 4 always blocks, harder for the simulator to optimize
genvar i;
generate // optional if > *-2001
for (i = 0; i < 3 ; i = i + 1) begin 
    always @(posedge sysclk) begin
        temp[i] <= 1'b0;
    end
end
endgenerate // match generate 
2
Greg