Módulo Verilog
Un module
es un bloque de código Verilog que implementa una cierta funcionalidad. Los módulos pueden integrarse dentro de otros módulos y un módulo de nivel superior puede comunicarse con sus módulos de nivel inferior utilizando sus puertos de entrada y salida.
Sintaxis
Un módulo debe estar encerrado dentro de module
y endmodule
palabras clave El nombre del módulo se debe dar justo después del module
También se puede declarar una palabra clave y una lista opcional de puertos. Tenga en cuenta que los puertos declarados en la lista de declaraciones de puertos no se pueden volver a declarar dentro del cuerpo del módulo.
module <name> ([port_list]);
// Contents of the module
endmodule
// A module can have an empty portlist
module name;
// Contents of the module
endmodule
Todas las declaraciones de variables, declaraciones de flujo de datos, funciones o tareas e instancias de módulos inferiores, si las hay, deben definirse dentro del module
y endmodule
palabras clave Puede haber varios módulos con diferentes nombres en el mismo archivo y se pueden definir en cualquier orden.
Ejemplo

El módulo dff representa un flip flop D que tiene tres puertos de entrada d, clk, rstn y un puerto de salida q. El contenido del módulo describe cómo debe comportarse un flip flop D para diferentes combinaciones de entradas. Aquí, la entrada d siempre se asigna a la salida q en el flanco positivo del reloj si rstn es alto porque es un reinicio bajo activo.
// Module called "dff" has 3 inputs and 1 output port
module dff ( input d,
input clk,
input rstn,
output reg q);
// Contents of the module
always @ (posedge clk) begin
if (!rstn)
q <= 0;
else
q <= d;
end
endmodule
Esquema de hardware
Este módulo se convertirá en el siguiente circuito digital durante la síntesis.

¡Tenga en cuenta que no puede tener ningún código escrito fuera de un módulo!
¿Cuál es el propósito de un módulo?
Un módulo representa una unidad de diseño que implementa ciertas características de comportamiento y se convertirá en un circuito digital durante la síntesis. Se puede dar cualquier combinación de entradas al módulo y proporcionará una salida correspondiente. Esto permite que el mismo módulo para ser reutilizado para formar módulos más grandes que implementen hardware más complejo.
Por ejemplo, el DFF que se muestra arriba se puede encadenar para formar un registro de desplazamiento.
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(q_net[1]));
dff u2 (.d(q_net[1]), .clk(clk), .rstn(rstn), .q(q_net[2]));
dff u3 (.d(q_net[2]), .clk(clk), .rstn(rstn), .q(q));
endmodule
Esquema de hardware
Tenga en cuenta que las instancias dff están conectadas entre sí con cables como se describe en el módulo Verilog RTL.

En lugar de construir a partir de bloques más pequeños para formar bloques de diseño más grandes, también se puede hacer lo contrario. Considere el desglose de un motor de GPU simple en componentes más pequeños, de modo que cada uno pueda representarse como un módulo que implementa una característica específica. El motor GPU que se muestra a continuación se puede dividir en cinco subbloques diferentes donde cada uno realiza una funcionalidad específica. La unidad de interfaz de bus obtiene datos del exterior en el diseño, que es procesado por otra unidad para extraer instrucciones. Otras unidades más adelante procesan los datos proporcionados por la unidad anterior.

Cada subbloque se puede representar como un module
con un determinado conjunto de señales de entrada y salida para la comunicación con otros módulos y cada subbloque se puede dividir en bloques más finos según sea necesario.
¿Qué son los módulos de nivel superior?
Un nivel superior módulo es aquel que contiene todos los demás módulos. Un módulo de nivel superior no se instancia dentro de ningún otro módulo.
Por ejemplo, los módulos de diseño normalmente se instancian dentro de los módulos de banco de pruebas de nivel superior para que la simulación se pueda ejecutar proporcionando estímulos de entrada. Pero, el banco de pruebas no se instancia dentro de ningún otro módulo porque es un bloque que encapsula todo lo demás y, por lo tanto, es el módulo de nivel superior .
Diseño de nivel superior
El código de diseño que se muestra a continuación tiene un módulo de nivel superior llamado diseño. Esto se debe a que contiene todos los demás submódulos necesarios para completar el diseño. Los submódulos pueden tener más submódulos anidados como mod3 dentro de mod1 y mod4 dentro de mod2. De todos modos, todos estos se incluyen en el módulo de nivel superior cuando se instancian mod1 y mod2. Así que esto hace que el diseño completo y es el módulo de nivel superior para el diseño.
//---------------------------------
// Design code
//---------------------------------
module mod3 ( [port_list] );
reg c;
// Design code
endmodule
module mod4 ( [port_list] );
wire a;
// Design code
endmodule
module mod1 ( [port_list] ); // This module called "mod1" contains two instances
wire y;
mod3 mod_inst1 ( ... ); // First instance is of module called "mod3" with name "mod_inst1"
mod3 mod_inst2 ( ... ); // Second instance is also of module "mod3" with name "mod_inst2"
endmodule
module mod2 ( [port_list] ); // This module called "mod2" contains two instances
mod4 mod_inst1 ( ... ); // First instance is of module called "mod4" with name "mod_inst1"
mod4 mod_inst2 ( ... ); // Second instance is also of module "mod4" with name "mod_inst2"
endmodule
// Top-level module
module design ( [port_list]); // From design perspective, this is the top-level module
wire _net;
mod1 mod_inst1 ( ... ); // since it contains all other modules and sub-modules
mod2 mod_inst2 ( ... );
endmodule
Nivel superior del banco de pruebas
El módulo de banco de pruebas contiene estímulos para comprobar la funcionalidad del diseño y se utiliza principalmente para la verificación funcional mediante herramientas de simulación. Por lo tanto, el diseño se instancia y se llama d0 dentro del módulo del banco de pruebas. Desde la perspectiva del simulador, testbench es el módulo de nivel superior.
//-----------------------------------------------------------
// Testbench code
// From simulation perspective, this is the top-level module
// because 'design' is instantiated within this module
//-----------------------------------------------------------
module testbench;
design d0 ( [port_list_connections] );
// Rest of the testbench code
endmodule
Nombres jerárquicos
Se forma una estructura jerárquica cuando los módulos se pueden instanciar uno dentro de otro y, por lo tanto, el módulo de nivel superior se denomina raíz. . Dado que se requiere que cada instancia de módulo inferior dentro de un módulo dado tenga diferentes nombres de identificador, no habrá ninguna ambigüedad en el acceso a las señales. Un nombre jerárquico se construye con una lista de estos identificadores separados por puntos .
para cada nivel de la jerarquía. Se puede acceder a cualquier señal dentro de cualquier módulo usando la ruta jerárquica a esa señal en particular.
// Take the example shown above in top level modules
design.mod_inst1 // Access to module instance mod_inst1
design.mod_inst1.y // Access signal "y" inside mod_inst1
design.mod_inst2.mod_inst2.a // Access signal "a" within mod4 module
testbench.d0._net; // Top level signal _net within design module accessed from testbench
Verilog