Jutilise le langage Verilog et Zedboard comme tableau cible.
Pour autant que je sache , la boucle for peut être synthétisée, et loutil de synthèse traduit la boucle for comme une séquence dinstructions dupliquées comme le déroulement de la boucle.
Par exemple,
for ( i = 0; i < 4; i=i+1) begin mem[i] = i; end will be translated to mem[0] = 0; mem[1] = 1; mem[2] = 2; mem[3] = 3;
Par conséquent, pour autant que je sache, la boucle for peut être utilisée si la ressource est disponible pour déduire les portes multiples mais identiques.
Cependant, il semble que le generate dans Verilog peut être utilisé, non seulement pour impliquer les multiples instances, mais aussi les multiples instructions identiques à la boucle for.
Je comprends que la génération ne peut impliquer que les multiples instances du module et la boucle for ne peut pas être utilisée dans ce but.
Alors, quelle est la différence entre la boucle generate + for et la boucle juste pour? Je pense que les deux fonctionnent comme le déroulement de la boucle. Y a-t-il une différence notable? Sil ny a pas de différence, quel est le style de codage préférable pour induire le déroulement en boucle?
Commentaires
- Pour plus de clarté, il ' s: Jimplique, vous en déduisez. par exemple. vous impliquez une RAM dans Verilog / VHDL, le logiciel de synthèse déduit cette RAM de votre Verilog / VHDL. Erreur très courante, qui vaut la peine dêtre apprise.
Réponse
Les boucles for Verilog sont parfaitement synthétisables sous certaines conditions:
- Vous pouvez utiliser nimporte quelle instruction procédurale dans une boucle (par exemple if-else).
- Le nombre de boucles doit être prédéterminé .
- Lexpression de limitation doit être une comparaison entre la variable de boucle et une constante ou un paramètre.
- Laffectation de létape doit incrémenter la valeur de la boucle dune quantité constante.
- Vous pouvez attribuer une valeur différente à la même variable dans chaque boucle (par exemple, calculer un index à partir de la variable de boucle).
- À des fins de synthèse, la boucle est évaluée en temps zéro – cest-à-dire que si vous essayez de créer un compteur, vous ne verrez que la valeur finale.
Ces mêmes règles sappliquent que vous utilisiez une boucle for dans un bloc procédural, ou dans un bloc de génération.
Lorsque cela est fait dans un bloc de procédure, initial
et always
, vous pouvez utiliser un for boucle pour changer les éléments dun tableau (exactement comme votre exemple), ou vous pouvez changer la même valeur plusieurs fois, par exemple:
for (idx = 0; idx < 4; idx=idx+1) begin a = a + b[idx]; c = c + 2; //You can change more than one variable in a for loop end
Dans cet exemple, le matériel résultant sera une chaîne dadditionneurs, additionnant les valeurs de quatre indices de tableau.
Lessentiel est que vous ne pouvez pas créer de nouvelles variables ou modules dans une boucle for procédurale. Cette règle sapplique aux blocs procéduraux en général, pas seulement pour les boucles (cest-à-dire que vous ne pouvez « t déclarer une variable dans un bloc procédural).
Par contre, les blocs Generate permettent la création de variables et linstanciation de modules. Cela signifie que dans un bloc generate, vous pouvez utiliser une boucle generate for pour inférer des modules. Cest à peu près la seule différence.
Pour générer des boucles for, vous devez utiliser un genvar
comme variable de boucle (cest-à-dire la valeur que vous utilisez pour compter dans chaque boucle). Vous devez également donner un nom à la boucle for:
for (loopVal = 0; loopVal < 4; loopVal = loopVal + 1) begin : loopName
Ce nom est précédé de tout matériel que vous instanciez dans la boucle. Donc, si vous créez une instance appelée bob
, la boucle ci-dessus créerait des instances:
loopName[0]|bob loopName[1]|bob loopName[2]|bob loopName[3]|bob
Cela entraîne plusieurs des instances avec des noms uniques.
Les boucles for générées et procédurales effectueront un déroulement de boucle comme vous le dites. La différence réside simplement dans la manière dont vous pouvez les utiliser. La procédure peut être utilisée dans les blocs procéduraux (par exemple pour initialiser une mémoire). Generate ne peut être utilisé que pour générer des blocs.
Ils sont à la fois utiles et préférés. On ne peut « pas remplacer lautre.
Commentaires
- une autre façon de penser à generate est comme une sorte de pré-processeur, votre compilateur verilog ' exécute ' des choses dans générer des blocs au point où ' instancie le bloc contenant le génère – ils ne se produisent ' quau moment de lexécution (contrairement aux boucles procédurales)
- @Taniwha boucles procédurales don ' ne sexécutent pas non plus au moment de lexécution. Ils sont déroulés par le compilateur. Tout se résume à du matériel à la fin. Aussi ne ' t confondre le préprocesseur avec des instructions de génération, ils ne le sont pas le même concept – Verilog a un préprocesseur comprenant des instructions de type if-else.
- @TomCarpenter Japprécie une excellente réponse. Je pourrais comprendre tous vos points sauf la boucle generate for.Il semble que begin: quelque chose devrait être ajouté juste avant la boucle for, mais ne peut pas comprendre comment cela fonctionne dans linstanciation de modules. Le loopName est-il une variable ou juste une chaîne? Et comment ils peuvent être indexés de [1] à [4].
- @JaeHyukLee
loopName
est juste du texte, comme un nom dinstance ou un nom de signal. Cela peut être tout ce que vous voulez. - @TomCarpenter – cela dépend du compilateur – si vous ' compilez des portes oui elles sont déroulées, si vous ' recompiler le code pour la simulation plus probablement pas (avertissement, jai ' avoir écrit un compilateur Verilog)