Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> Verilog

Instanziierungen des Verilog-Moduls

Wie wir in einem früheren Artikel gesehen haben, werden größere und komplexe Designs erstellt, indem mehrere Module hierarchisch integriert werden. Module können instanziiert werden innerhalb anderer Module und Ports dieser Instanzen kann mit anderen Signalen innerhalb des übergeordneten Moduls verbunden werden.

Diese Portverbindungen können über eine geordnete Liste oder nach Namen erfolgen.

Portverbindung nach geordneter Liste

Eine Methode, um die Verbindung zwischen den Portausdrücken, die in einer Modulinstanziierung aufgeführt sind, mit den Signalen innerhalb des übergeordneten Moduls herzustellen, ist die geordnete Liste .

meindesign ist ein module mit dem Namen d0 in einem anderen Modul namens tb_top instanziiert. Ports werden in einer bestimmten Reihenfolge verbunden, die durch die Position dieses Ports in der Portliste der Moduldeklaration bestimmt wird. Zum Beispiel ist b in der Testbench einfach mit y des Designs verbunden, weil beide an zweiter Stelle in der Liste der Ports stehen.

  
  
	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

  

Die Reihenfolge der Ports im Designmodul sollte für eine korrekte Verbindung bekannt sein.

Dies ist sehr unpraktisch, da sich die Reihenfolge ändern kann, wenn ein neuer Port zur Liste hinzugefügt wird oder wenn die Anzahl der Ports im Design sehr groß ist.

Portverbindung nach Name

Ein besserer Weg, Ports zu verbinden, besteht darin, Ports auf beiden Seiten explizit mit ihrem Portnamen zu verknüpfen .

Der Punkt . gibt an, dass der Anschlussname nach dem Punkt zum Design gehört. In Klammern ( ) steht als nächstes der Signalname, mit dem der Designport verbunden werden soll .

  
  
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

  

Es wird empfohlen, jede Portverbindung in einer separaten Zeile zu codieren, damit jede Kompilierungsfehlermeldung korrekt auf die Zeilennummer verweist, in der der Fehler aufgetreten ist. Dies ist viel einfacher zu debuggen und zu beheben als nicht zu wissen, welcher Port den Fehler verursacht hat, wenn sie alle in derselben Zeile gewesen wären.

Da diese Verbindungen namentlich hergestellt werden, ist die Reihenfolge, in der sie erscheinen, irrelevant. Mehrere Modulinstanz-Port-Verbindungen sind nicht zulässig.

  
  
	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

  

Nicht verbundene/Floating Ports

Ports, die im Instantiierungsmodul mit keinem Draht verbunden sind, haben einen hochohmigen Wert.

  
  
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

  

Beispiel

Nehmen wir das Schieberegister-Beispiel, das wir zuvor gesehen haben, und lassen einige Ports unbeschaltet.

  
  
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

  

Beachten Sie, dass die Ausgänge der Instanzen u1 und u2 in dem nach der Synthese erhaltenen RTL-Schema unverbunden bleiben. Da der Eingang d zu den Instanzen u2 und u3 nun mit Netzen verbunden ist, die von nichts angesteuert werden, ist er geerdet.

In Simulationen werden solche nicht angeschlossenen Ports als hohe Impedanz ('hZ) bezeichnet, die in Wellenformen typischerweise als orangefarbene Linie dargestellt wird, die vertikal in der Mitte ausgerichtet ist.

Alle Portdeklarationen werden implizit als wire deklariert und daher ist die Portrichtung in diesem Fall ausreichend. Jedoch output Ports, die Werte speichern müssen, sollten als reg deklariert werden Datentyp und kann in einem Prozedurblock wie always verwendet werden und initial nur.

Ports vom Typ input oder inout kann nicht als reg deklariert werden denn sie werden ständig von außen angesteuert und sollen keine Werte speichern, sondern die Änderungen der externen Signale so schnell wie möglich widerspiegeln. Es ist völlig legal, zwei Ports mit unterschiedlichen Vektorgrößen zu verbinden, aber der mit der kleineren Vektorgröße wird sich durchsetzen und die verbleibenden Bits des anderen Ports mit der größeren Breite werden ignoriert.

  
  

	// 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. Verilog-Tutorial
  2. Verilog-Verkettung
  3. Verilog - In einer Nussschale
  4. Verilog-Aufgaben
  5. Verilog-Blockierung und Nicht-Blockierung
  6. Verilog-Funktionen
  7. Verilog-Aufgabe
  8. Verilog Hierarchischer Referenzbereich
  9. Verilog-Taktgenerator
  10. Verilog Math-Funktionen