Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> Verilog

Instanciations de modules Verilog

Comme nous l'avons vu dans un article précédent, les conceptions plus grandes et complexes sont construites en intégrant plusieurs modules de manière hiérarchique. Les modules peuvent être instanciés dans d'autres modules et ports de ces instances peut être connecté à d'autres signaux à l'intérieur du module parent.

Ces connexions de port peuvent se faire via une liste ordonnée ou par nom.

Connexion des ports par liste ordonnée

Une méthode pour établir la connexion entre les expressions de port répertoriées dans une instanciation de module avec les signaux à l'intérieur du module parent est par la liste ordonnée .

mondesign est un module instancié avec le nom d0 dans un autre module appelé tb_top. Les ports sont connectés dans un certain ordre qui est déterminé par la position de ce port dans la liste des ports de la déclaration du module. Par exemple, b dans le testbench est connecté à y de la conception simplement parce que les deux sont à la deuxième position dans la liste des ports.

  
  
	module mydesign ( input  x, y, z,     // x is at position 1, y at 2, x at 3 and
	                  output o);          // o is at position 4
	                  
	endmodule

	module tb_top;
		wire [1:0]  a;
		wire        b, c;
		
		mydesign d0  (a[0], b, a[1], c);  // a[0] is at position 1 so it is automatically connected to x
		                                  // b is at position 2 so it is automatically connected to y
		                                  // a[1] is at position 3 so it is connected to z
		                                  // c is at position 4, and hence connection is with o
	endmodule

  

L'ordre des ports dans le module de conception doit être connu pour une connexion correcte.

Ceci est très gênant car l'ordre peut changer si un nouveau port est ajouté à la liste ou lorsque le nombre de ports dans la conception est très important.

Connexion de port par nom

Une meilleure façon de connecter les ports consiste à lier explicitement les ports des deux côtés à l'aide de leur nom de port .

Le point . indique que le nom du port suivant le point appartient à la conception. Le nom du signal auquel le port de conception doit être connecté est donné ensuite entre parenthèses ( ) .

  
  
module design_top;
	wire [1:0]  a;
	wire        b, c;
	
	mydesign d0  ( .x (a[0]),    // signal "x" in mydesign should be connected to "a[0]" in this module (design_top)
	               .y (b),       // signal "y" in mydesign should be connected to "b" in this module (design_top)
	               .z (a[1]), 
	               .o (c));
endmodule

  

Il est recommandé de coder chaque connexion de port dans une ligne distincte afin que tout message d'erreur de compilation pointe correctement vers le numéro de ligne où l'erreur s'est produite. C'est beaucoup plus facile à déboguer et à résoudre que de ne pas savoir quel port a créé l'erreur s'ils avaient tous été sur la même ligne.

Étant donné que ces connexions sont établies par leur nom, l'ordre dans lequel elles apparaissent n'a pas d'importance. Les connexions de plusieurs ports d'instance de module ne sont pas autorisées.

  
  
	module design_top;
		mydesign d0 ( .x (a[0]),
		              .z (a[1]),     // z at second position is okay because of explicit connection
		              .y (a[1]),
		              .x (b),        // illegal - x is already connected to a[0]
		              .o (c));
	endmodule

  

Ports non connectés/flottants

Les ports qui ne sont connectés à aucun fil dans le module d'instanciation auront une valeur de haute impédance.

  
  
module design_top;
	mydesign d0   (              // x is an input and not connected, hence a[0] will be Z
	              .y (a[1]),
	              .z (a[1]),
	              .o ());        // o has valid value in mydesign but since
	                             // it is not connected to "c" in design_top, c will be Z
endmodule

  

Exemple

Prenons l'exemple du registre à décalage que nous avions vu auparavant et laissons certains ports non connectés.

  
  
module shift_reg (   input   d,
                    input    clk,
                    input   rstn,
                    output   q);
 
  wire [2:0] q_net;
  
  dff u0 (.d(d),         .clk(clk), .rstn(rstn), .q(q_net[0]));
  dff u1 (.d(q_net[0]), .clk(clk), .rstn(rstn), .q()); 						// Output q is left floating
  dff u2 (.d(q_net[1]), .clk(clk), .rstn(rstn), .q()); 						// Output q is left floating
  dff u3 (.d(q_net[2]), .clk(clk), .rstn(rstn), .q(q));
 
endmodule

  

Notez que les sorties des instances u1 et u2 ne sont pas connectées dans le schéma RTL obtenu après synthèse. Étant donné que l'entrée d des instances u2 et u3 est maintenant connectée à des réseaux qui ne sont pilotés par rien, elle est mise à la terre.

Dans les simulations, ces ports non connectés seront désignés comme étant à haute impédance ('hZ), généralement affichés dans les formes d'onde sous la forme d'une ligne orange alignée verticalement au milieu.

Toutes les déclarations de port sont implicitement déclarées comme wire et donc la direction du port est suffisante dans ce cas. Cependant output les ports qui ont besoin de stocker des valeurs doivent être déclarés comme reg type de données et peut être utilisé dans un bloc procédural comme always et initial uniquement.

Ports de type input ou inout ne peut pas être déclaré comme reg car ils sont alimentés de l'extérieur en permanence et ne doivent pas stocker de valeurs, mais plutôt refléter les changements dans les signaux externes dès que possible. Il est parfaitement légal de connecter deux ports avec des tailles de vecteur différentes, mais celui avec une taille de vecteur inférieure prévaudra et les bits restants de l'autre port avec une largeur supérieure seront ignorés.

  
  

	// Case #1 : Inputs are by default implicitly declared as type "wire"
	module des0_1	(input wire clk ...); 		// wire need not be specified here
	module des0_2 	(input clk, ...); 			// By default clk is of type wire
		
	// Case #2 : Inputs cannot be of type reg
	module des1 (input reg clk, ...); 		// Illegal: inputs cannot be of type reg
	
	// Case #3: Take two modules here with varying port widths
	module des2 (output [3:0] data, ...);	// A module declaration with 4-bit vector as output
	module des3 (input [7:0] data, ...); 	// A module declaration with 8-bit vector as input
	
	module top ( ... );
		wire [7:0] net;
		des2  u0 ( .data(net) ... ); 		// Upper 4-bits of net are undriven
		des3  u1 ( .data(net) ... ); 		
	endmodule
	
	// Case #4 : Outputs cannot be connected to reg in parent module
	module top_0 ( ... );
		reg [3:0] data_reg;
		
		des2 ( .data(data) ...); 	// Illegal: data output port is connected to a reg type signal "data_reg"
	endmodule
		

  

Verilog

  1. Tutoriel Verilog
  2. Concaténation Verilog
  3. Verilog - Dans une coquille de noix
  4. Affectations Verilog
  5. Verilog bloquant et non bloquant
  6. Fonctions Verilog
  7. Tâche Verilog
  8. Portée de référence hiérarchique Verilog
  9. Générateur d'horloge Verilog