Incrémentation d'une variable de compteur en verilog: combinatoire ou séquentielle
Je me suis mise en œuvre d'un FSM contrôleur pour un circuit du chemin de données. Le contrôleur incrémente un compteur interne. Quand j'ai simulé le programme ci-dessous, le compteur n'a jamais été mis à jour.
reg[3:0] counter;
//incrementing counter in combinational block
counter = counter + 4'b1;
Cependant, sur la création d'une variable supplémentaire, counter_next, comme décrit dans Verilog Meilleures Pratiques - Incrémentation d'une variable et en incrémentant le compteur seulement dans le bloc séquentiel, le compteur est incrémenté.
reg[3:0] counter, counter_next;
//sequential block
always @(posedge clk)
counter <= counter_next;
//combinational block
counter_next = counter + 4'b1;
Pourquoi ne pas le compteur incrémentée dans le cas précédent? Rien de ce que je suis absent?
OriginalL'auteur iab | 2012-12-29
Vous devez vous connecter pour publier un commentaire.
Ok. Je suis en supposant que vous avez laissé un peu de code de votre premier exemple depuis qui ne devrait même pas compiler. Cependant, je pense que je peux élucider la question pour vous de toute façon.
Dans un bloc qui ressemble à ceci:
il y a deux problèmes.
1) compteur n'est jamais initialisée. Tous les 'reg' type de variables sont X au début de la simulation temps donc, l'ajout de 1 à X est X.
2) C'est ce qui est considéré comme une combinatoire de la boucle. Le bloc est sensible aux changements dans le "compteur" de sorte que même en supposant que le "compteur" est initialisé à 0 le simulateur serait en boucle toujours la mise à jour de "compteur" et du temps de simulation ne sera jamais à l'avance. c'est à dire
Si vous avez été de mettre un $affichage de la déclaration de là, on pouvait voir cette boucle se produise. Sinon, il va apparaître que le simulateur est accroché et pas de vagues.
La raison pour le 2ème exemple fonctionne, c'est que vous avez un flip-flop de briser la combinatoire de la boucle. À chaque front d'horloge "compteur" est mis à jour avec la valeur actuelle de 'counter_next'. Puis la combinatoire bloc s'exécute une fois (et une seule fois) pour calculer la nouvelle version de "counter_next'.
Vous êtes toujours en manque d'une phase d'initialisation de "compteur" à travers une réinitialisation de la clause ou de la déclaration initiale donc, pour l'exhaustivité.
Je n'ai pas l'expérience de tout "en boucle" dans ma simulation d'ailleurs. La variable "compteur" n'a même jamais été mis à jour. C'était juste fixé à 0. Une boucle serait peu probable que je compare la valeur de "compteur" à l'encontre de la constante.
Juste assez. Je ne suis pas sûr de ce que d'une comparaison, d'ailleurs a à faire avec elle. Je n'ai pas facilement accès à un simulateur pour le moment de confirmer l' (simulateur) boucle de comportement, mais le fait demeure que la combinatoire de la boucle est le problème avec votre premier exemple. Il est dit en substance "ce jeu de fils représente X et X+1 simultanément" Il n'existe pas de réalisation de matériel qui peut faire cela. Rappelez-vous que Verilog est pas de la programmation impérative. Vous êtes décrivant le matériel ici.
+1 pour l'utilisation du mot 'élucider'
compteur = compteur + 4'b1; dans une combinatoire de déclaration est une boucle. Probablement jamais mis à jour en raison de la sensibilité de la liste jamais déclenché. Ce serait parfait: toujours @(posedge clk) compteur <= compteur + 4'b1;
OriginalL'auteur Brian Magnuson