Étape 19 : VM 4.2 : blocage vs Non-bloquante Verilog déclarations
Il peut sembler étrange que nous basculons de discuter toujours blocs à bloquant/non-bloquant, mais c’est le moment idéal pour introduire une nouvelle notion.Lorsque nous écrire du code en C/C++, notre code est exécutée ligne par ligne dans l’ordre jusqu'à ce que le programme est dit de s’écarter de ce schéma (par exemple sauter à la ligne). Une ligne est exécutée et qu’après il finitions en cours d’exécution sont la ligne suivante exécutée. Pour la plupart des cas, on ne remarque tout retard dans les applications console simple. Mais dans la conception numérique, ce retard de l’exécution d’une seule ligne à l’autre pourrait avoir des conséquences très négatives et perceptibles. Même des retards de moins d’une nanoseconde pourraient provoquer des problèmes ; Glitches pour être exact.
Un pépin est officiellement défini comme un changement momentané et indésirable en sortie d’un circuit en raison d’une entrée dans un état transitoire et l’entrée ayant au moins deux chemins à travers le circuit sans retards équivalent porte entre les chemins d’accès.
Imaginez que vous avez deux interrupteurs (sw0 et sw1) qui ont tous deux une logique 0, et le résultat d’une seule LED a une logique un si les deux interrupteurs ont une logique 0 (LED = ~(sw0 & sw1)), parmi d’autres voulu sorties. Mais que vous sautiez sw1 à un niveau élevé de la logique. Que se passe-t-il si seulement pour une fraction de seconde que la LED est toujours une logique alors que la tension de la source de sw1 « ondule » son chemin « en aval » à travers les portes de logique dans ses divers chemins jusqu'à ce qu’il arrive à la dernière porte dans le circuit ? Il y a là une fraction de seconde où la LED est une logique un alors que théoriquement il devrait être une logique zéro ; votre circuit enfreignaient les règles de ses propres équations de logique !
Tandis que le point de ce module ne doit couvrir comment réparer les pépins dans vos instructions logiques, le point est que logique même bien formé des équations pour les circuits qui sont « glitch gratuit » peuvent potentiellement créer un pépin si vous utilisez une instruction de blocage où vous aurait dû utiliser un non-blocage déclaration et vice versa.
Comment cela se passe-t-il et pourquoi le mauvais énoncé Verilog cela provoquerait ?
Une déclaration de blocage est une affectation (il ne doit pas nécessairement utiliser le mot clé « assign ») qui utilise l’opérateur « = ». Blocage des instructions sont exécutées comme code en C/C++: séquentiellement et dans l’ordre. Une déclaration de non-bloquant est une instruction d’assignation qui utilise le "< =" opérateur. Déclarations non bloquante quand mises dans la même étendue de code avec d’autres instructions non bloquants seront exécutées simultanément.
Re lire les définitions ci-dessus, car ils sont très importants.
Une commune pensée étudiants peuvent avoir est « Verilog code est un langage de description de matériel, donc il ne devrait pas question quel genre de déclaration j’écris parce qu’il se résumer selon le même circuit physique et se comportent de la même manière. » Ce n’est pas nécessairement vrai, comme le complexe Verilog compilateur devra créer des motifs différents de transistor pour transmettre des signaux différents à différents endroits, et vous devez spécifier si cela doit arriver en même temps ou autres intervalles de temps. Il peut s’avérer plus efficace de construire un circuit avec des déclarations qui peuvent diriger des signaux à une heure convenable pour le circuit de blocage, mais souvent, il est important que deux ou plusieurs changements de production ont lieu en même temps essentiellement.
Vous voyez comment une série d’instructions blocage pourrait avoir des effets néfastes du comportement du circuit ? Déclarations de haut niveau assign bloquent parce que les déclarations sont seulement « exécutées » une fois, mais quelque chose comme un décodeur qui peut « toujours » être ré-évaluer la situation qui doit changer les sorties simultanément. Imaginez les problèmes que d’ingénieur aurait si leur sortie décodeur GS et les signaux de sortie EO changé à différents moments !
Jetez un oeil à quelques exemples simples ("si" déclarations sont couverts dans le module suivant!) :
Exemple #1
toujours @ (sw0, sw1)
commencer
Si (sw0 == 1' b1)
commencer
toutes ces sorties seront affectés leur
valeurs en même temps
sortie 1 < = 1' b0 ;
output2 < = 1' b1 ;
output3 < = 1' b0 ;
fin
fin
Exemple #2
toujours @ (sw0, sw1)
commencer
Si (sw0 == 1' b1)
commencer
la première sortie sera assignée, puis les deux suivants
on attribuera simultanément
sortie 1 = 1' b0 ;
output2 < = 1' b1 ;
output3 < = 1' b0 ;
fin
fin
Exemple #3
toujours @ (sw0, sw1)
commencer
Si (sw0 == 1' b1)
commencer
la première sortie sera assignée, puis les deux suivants seront
assigner une après l’autre
sortie 1 = 1' b0 ;
output2 = 1' b1 ;
output3 = 1' b0 ;
fin
fin
Ne jamais mettre une déclaration de blocage à l’intérieur d’un bloc de structure logique. En d’autres termes, ne jamais mettre un « = » à l’intérieur d’un bloc toujours. Même si vous changez seulement une sortie c’est mauvaise pratique d’utiliser une instruction de blocage.
Toujours utiliser une instruction de blocage lorsque vous utilisez le mot clé "affectation". Ces déclarations seront déroulera toujours en dehors de le toujours bloquer. Exemple utilisation déclarerions un reg dont la valeur vous changez à l’intérieur d’un bloc toujours, assignant un fil de sortie « = » valeur de la reg.
Astuce: vous donnera généralement un reg une valeur en utilisant le formulaire : < nom du reg >< = < valeur > ;
Astuce supplémentaire (en double): vous ne pouvez définir des valeurs d’un reg dans une toujours bloquer, aucune assignation des valeurs pour les fils de type. Vous pouvez, toutefois, plus tard assigner le fil égal à la valeur de la reg.