Étape 15 : VM 3.3 : comment instancier un Module
Dans le module précédent, j’ai mentionné similitudes entre instanciation modules en Verilog et l’appel de fonctions en C/C++.Regardons comment nous instancierait un module en Verilog.
Voici le module avec que nous allons travailler :
« calendrier 1ns / 1ps
(srlatch) module
d’entrée S,
R d’entrée,
sortie Q
);
fil Q_int, Qn_int ;
assigner Q_int = ~ (S & Qn_int) ;
assigner Qn_int = ~ (R-Q_int) ;
affecter à Q = Q_int ;
endmodule
Par maintenant qu’il ne devrait pas y avoir n’importe quel Verilog dans ce module vous ne pouvait pas expliquer.
Alors disons que nous avons voulu faire un circuit avec deux SR-loquets (peu importe comment absurde ce circuit est en réalité), chacune avec un interrupteur pour leur opération "set" et un bouton reset partagée. La sortie de chaque verrou est une LED.
Avec ces spécifications à l’esprit, nous allons faire définition du module haut de la page. Rappelez-vous, les déclarations de module supérieur contiendra seulement les entrées et sorties qui vont et viennent du monde réel.
« calendrier 1ns / 1ps
Défi : Ré-écrire cette déclaration de module à l’aide d’autobus
module (haut de la page
switch0 d’entrée,
switch1 d’entrée,
btn0 d’entrée,
sortie led0,
led1 sortie
);
endmodule
Formidable ! Maintenant nous devons ajouter deux SR-verrous de notre circuit. Comment ferions-nous cela ?
Ne dites pas « Hard coder le comportement des deux SR-verrous et affecter leurs entrées et sorties respectivement. » On instanciera deux instances d’un SR-verrou. Voici comment notre module supérieur s’occupera de l’instanciation :
« calendrier 1ns / 1ps
module (haut de la page
switch0 d’entrée,
switch1 d’entrée,
btn0 d’entrée,
sortie led0,
led1 sortie
);
(srlatch) sr0
. S(switch0),
. R(btn0),
. Q(led0)
);
(sr1) srlatch
. S(Switch1),
. R(btn0),
. Q(LED1)
);
endmodule
Alors que reste-t-il à faire ? Rien ; absolument rien (en supposant que vous avez déjà un fichier UCF prêt). Pourquoi?
La raison réside dans l’instanciation du module. Prenons regarder de plus près un.
(srlatch) sr0
. S(switch0),
. R(btn0),
. Q(led0)
);
La première ligne : srlatch sr0 (
Il s’agit d’une ligne très importante dont vous devez mémoriser la forme. Vient d’abord srlatch. C’est le nom du module base que nous sommes instanciation. sr0 est le nom de l’instance. La parenthèse s’ouvre l’instanciation. Chaque instanciation commencera comme ça ; "< module à instancier >< nom de l’instance >(".
Il y a certains cas moins fréquents où l’instanciation est légèrement différent, mais même alors ce formulaire sera toujours présent.
Les trois lignes :
. S(switch0),
. R(btn0),
. Q(led0)
Jetez un oeil à la srlatch les noms de port module et ensuite revenir sur ces trois lignes. Il s’agit, de manière détournée, similaire à la façon dont nous appeler une fonction en C/C++ ; C’est où nous passons les paramètres.
La différence est qu’en Verilog, nous passons les deux entrées au module de sorties et au module. Autrement dit, nous disons cette instance spécifique du module d'où viennent ses entrées et où nous voulons que les sorties d’aller.
Une autre façon de regarder, c’est que nous passons le module d’un ensemble d’entrées / sorties, chacun dont la valeur est continuellement mis à jour ou l’autre de l’intérieur du module (sorties) ou à l’extérieur du module (entrées).
Nous allons décomposer la déclaration : . S(switch0)
Chaque instanciation de module aura une série d’instructions similaires à cette déclaration un, un par entrées/sorties. Le ". S"fait référence à l’entrée de S dans le module srlatch, et la (switch0) se réfère à switch0 d’entrée situé dans le haut module. Voir un modèle ?
. < nom du port dans le module instancié > (< nom du port dans le module actuel >)
Ce concept est également semblable à l’appel des fonctions dans d’autres langages de programmation tels que C/C++ ; dans l’appel de fonction nous transmettre des valeurs (que nous connaissons par le nom de la variable) dans la fonction. Nous appelons cette une chose valeur, par exemple, principale, mais dans la fonction on parle de quelque chose de différent. Dans cet exemple de Verilog, nous avons une entrée dans le module supérieur appelé "swtich0", et nous voulons que la valeur de "S" de «sr0» égal à quelque « switch0 » est.
Comme je l’ai mentionné précédemment, vous avez besoin d’une instruction d’initialisation de port par port dans le module vous êtes instanciation, mais si vous êtes instanciation d’un module qui a, disons, un bus [7:0] entrée appelée « T », vous n’avez pas besoin de faire des 8 déclarations comme ". T[0](Input[0]) ". Vous pouvez passer bus tout en se référant aux noms seulement, donc vous pouvez passer « Input » en "T"en déclarant". T(Input) ". N’oubliez pas cependant que les dimensions des autobus doivent correspondre vers le haut (c'est-à-dire vous ne pouvez pas passer un bus 5 port dans un module qui a un bus 3 port).
En outre, les types de port doivent correspondre vers le haut. Vous ne pouvez transmettre une entrée pour une entrée et une sortie (ou d’un fil ; plus tard) pour une sortie.
Instructions d’initialisation de port distinct avec une seule virgule. Bon style de codage dicte que chaque ligne contient uniquement une instanciation. De là, vous devriez être capable de comprendre ces trois lignes de code.
Fermer l’instanciation avec une parenthèse et un point-virgule.
Après que l’instanciation est faite avec succès, les sorties du module instancié, en substance, seront accessibles dans le module en cours. Vous pouvez ensuite acheminer ces sorties jusqu’aux ports de haut niveau ou même les entrées des autres modules instanciés.
Avant de terminer cette discussion, nous allons résumer comment initier un module (n’oubliez pas que « module courant » désigne le module qui fait l’instanciation) :
< nom du module >< (nom d’instance >
. < nom du port dans le module à instancier > (< nom de port/fil module en cours >),
... < répétition ci-dessus autant de fois que nécessaire >...
. < nom du port dans le module à instancier > (< nom du port/fil module en cours >)
);