Instancias del módulo Verilog
Como vimos en un artículo anterior, los diseños más grandes y complejos se construyen integrando múltiples módulos de manera jerárquica. Los módulos pueden ser instanciados dentro de otros módulos y puertos de estas instancias se puede conectar con otras señales dentro del módulo principal.
Estas conexiones de puertos se pueden realizar a través de una lista ordenada o por nombre.
Conexión de puertos por lista ordenada
Un método para establecer la conexión entre las expresiones de puerto enumeradas en una instanciación de módulo con las señales dentro del módulo principal es mediante la lista ordenada .
midiseño es un module
instanciado con el nombre d0 en otro módulo llamado tb_top. Los puertos se conectan en un cierto orden que está determinado por la posición de ese puerto en la lista de puertos de la declaración del módulo. Por ejemplo, b en el banco de pruebas está conectado a y del diseño simplemente porque ambos están en la segunda posición en la lista de puertos.
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
Se debe conocer el orden de los puertos en el módulo de diseño para una conexión correcta.
Esto es muy inconveniente porque el orden puede cambiar si se agrega un nuevo puerto a la lista o cuando la cantidad de puertos en el diseño es muy grande.
Puerto de conexión por nombre
Una mejor manera de conectar puertos es vincular puertos explícitamente en ambos lados usando su nombre de puerto .
El punto .
indica que el nombre del puerto que sigue al punto pertenece al diseño. El nombre de la señal a la que se debe conectar el puerto de diseño se proporciona a continuación entre paréntesis ( )
.
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
Se recomienda codificar cada conexión de puerto en una línea separada para que cualquier mensaje de error de compilación apunte correctamente al número de línea donde ocurrió el error. Esto es mucho más fácil de depurar y resolver en comparación con no saber qué puerto creó el error si todos estuvieran en la misma línea.
Debido a que estas conexiones se realizan por nombre, el orden en que aparecen es irrelevante. No se permiten conexiones de puerto de instancia de módulo múltiple.
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
Puertos no conectados/flotantes
Los puertos que no están conectados a ningún cable en el módulo de creación de instancias tendrán un valor de alta impedancia.
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
Ejemplo
Tomemos el ejemplo del registro de desplazamiento que habíamos visto antes y dejemos algunos puertos sin conectar.
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
Tenga en cuenta que las salidas de las instancias u1 y u2 se dejan desconectadas en el esquema RTL obtenido después de la síntesis. Dado que la entrada d a las instancias u2 y u3 ahora está conectada a redes que no están siendo impulsadas por nada, está conectada a tierra.

En las simulaciones, dichos puertos no conectados se indicarán como de alta impedancia ('hZ), que normalmente se muestran en formas de onda como una línea naranja alineada verticalmente en el medio.

Todas las declaraciones de puerto se declaran implícitamente como wire
y, por lo tanto, la dirección del puerto es suficiente en ese caso. Sin embargo output
los puertos que necesitan almacenar valores deben declararse como reg
tipo de datos y se puede utilizar en un bloque de procedimiento como always
y initial
solo.
Puertos de tipo input
o inout
no se puede declarar como reg
porque están siendo impulsados desde el exterior continuamente y no deben almacenar valores, sino reflejar los cambios en las señales externas lo antes posible. Es perfectamente legal conectar dos puertos con diferentes tamaños de vectores, pero prevalecerá el que tenga un tamaño de vector más bajo y se ignorarán los bits restantes del otro puerto con un ancho mayor.
// 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