Verilog: Cómo crear una instancia de un módulo

Si tengo un módulo Verilog ‘top’ y un ‘subcomponente’ del módulo verilog, ¿cómo instanciar el subcomponente en la parte superior?

parte superior:

module top( input clk, input rst_n, input enable, input [9:0] data_rx_1, input [9:0] data_rx_2, output [9:0] data_tx_2 ); 

subcomponente:

 module subcomponent( input clk, input rst_n, input [9:0] data_rx, output [9:0] data_tx ); 

Nota
Esto fue escrito como una pregunta genérica que sigue apareciendo de vez en cuando, sigue el formato de auto-respuesta . Se recomiendan las respuestas y actualizaciones adicionales.

En general, esto está cubierto por la Sección 23.3.2 de SystemVerilog IEEE Std 1800-2012 .

La forma más simple es crear instancias en la sección principal de la parte superior, crear una instancia con nombre y cablear los puertos en orden:

 module top( input clk, input rst_n, input enable, input [9:0] data_rx_1, input [9:0] data_rx_2, output [9:0] data_tx_2 ); subcomponent subcomponent_instance_name ( clk, rst_n, data_rx_1, data_tx ); endmodule 

Esto se describe en la Sección 23.3.2.1 de SystemVerilog IEEE Std 1800-2012 .

Esto tiene algunos inconvenientes, especialmente en relación con el orden de los puertos del código del subcomponente. La refacturación simple aquí puede romper la conectividad o cambiar el comportamiento. por ejemplo, si alguien más arregla un error y reordena los puertos por alguna razón, cambiando el clk y reiniciando el orden. No habrá problemas de conectividad de su comstackdor, pero no funcionará como se esperaba.

 module subcomponent( input rst_n, input clk, ... 

Por lo tanto, se recomienda conectar usando puertos con nombre, esto también ayuda a rastrear la conectividad de los cables en el código.

 module top( input clk, input rst_n, input enable, input [9:0] data_rx_1, input [9:0] data_rx_2, output [9:0] data_tx_2 ); subcomponent subcomponent_instance_name ( .clk(clk), .rst_n(rst_n), .data_rx(data_rx_1), .data_tx(data_tx) ); endmodule 

Esto se describe en la Sección 23.3.2.2 de SystemVerilog IEEE Std 1800-2012 .

Darle a cada puerto su propia línea y sangrar correctamente aumenta la legibilidad y la calidad del código.

 subcomponent subcomponent_instance_name ( .clk ( clk ), // input .rst_n ( rst_n ), // input .data_rx ( data_rx_1 ), // input [9:0] .data_tx ( data_tx ) // output [9:0] ); 

Hasta ahora, todas las conexiones que se han realizado han reutilizado las entradas y salidas al submódulo y no se han creado cables de conectividad. ¿Qué sucede si vamos a tomar salidas de un componente a otro?

 clk_gen( .clk ( clk_sub ), // output .en ( enable ) // input subcomponent subcomponent_instance_name ( .clk ( clk_sub ), // input .rst_n ( rst_n ), // input .data_rx ( data_rx_1 ), // input [9:0] .data_tx ( data_tx ) // output [9:0] ); 

Esto funciona nominalmente como un cable para clk_sub se crea automáticamente, existe el peligro de confiar en esto. solo creará un cable de 1 bit por defecto. Un ejemplo donde esto es un problema sería para los datos:

Tenga en cuenta que el nombre de instancia para el segundo componente ha sido cambiado

 subcomponent subcomponent_instance_name ( .clk ( clk_sub ), // input .rst_n ( rst_n ), // input .data_rx ( data_rx_1 ), // input [9:0] .data_tx ( data_temp ) // output [9:0] ); subcomponent subcomponent_instance_name2 ( .clk ( clk_sub ), // input .rst_n ( rst_n ), // input .data_rx ( data_temp ), // input [9:0] .data_tx ( data_tx ) // output [9:0] ); 

El problema con el código anterior es que data_temp tiene solo 1 bit de ancho, habría una advertencia de comstackción sobre la discrepancia del ancho del puerto. El cable de conectividad debe crearse y debe especificarse un ancho. Recomendaría que todos los cables de conectividad se escriban explícitamente.

 wire [9:0] data_temp subcomponent subcomponent_instance_name ( .clk ( clk_sub ), // input .rst_n ( rst_n ), // input .data_rx ( data_rx_1 ), // input [9:0] .data_tx ( data_temp ) // output [9:0] ); subcomponent subcomponent_instance_name2 ( .clk ( clk_sub ), // input .rst_n ( rst_n ), // input .data_rx ( data_temp ), // input [9:0] .data_tx ( data_tx ) // output [9:0] ); 

Pasando a SystemVerilog, hay algunos trucos disponibles que te permiten escribir un puñado de caracteres. Creo que dificultan la legibilidad del código y pueden dificultar la búsqueda de errores.

Use .port sin corchetes para conectarse a un cable / reg del mismo nombre. Esto puede verse bien especialmente con un montón de clk y restablecimientos, pero en algunos niveles puede generar diferentes relojes o reseteos o no desea conectarse a la señal del mismo nombre, pero sí a una modificada, y esto puede provocar errores de cableado. no es obvio para el ojo.

 module top( input clk, input rst_n, input enable, input [9:0] data_rx_1, input [9:0] data_rx_2, output [9:0] data_tx_2 ); subcomponent subcomponent_instance_name ( .clk, // input **Auto connect** .rst_n, // input **Auto connect** .data_rx ( data_rx_1 ), // input [9:0] .data_tx ( data_tx ) // output [9:0] ); endmodule 

Esto se describe en la Sección 23.3.2.3 de SystemVerilog IEEE Std 1800-2012 .

Otro truco que creo que es incluso peor que el anterior es .* que conecta puertos no mencionados con señales del mismo cable. Considero que esto es bastante peligroso en el código de producción. No es obvio cuando se han agregado nuevos puertos y faltan o que pueden conectarse accidentalmente si el nuevo nombre de puerto tiene una contrapartida en el nivel de instancias, se conectan automáticamente y no se genera ninguna advertencia.

 subcomponent subcomponent_instance_name ( .*, // **Auto connect** .data_rx ( data_rx_1 ), // input [9:0] .data_tx ( data_tx ) // output [9:0] ); 

Esto se describe en la Sección 23.3.2.4 de SystemVerilog IEEE Std 1800-2012 .

Asegúrese de verificar verilog-mode y especialmente verilog-auto. http://www.veripool.org/wiki/verilog-mode/ Es un modo verilog para emacs, pero existen plugins para vi (m?) por ejemplo.

Una instanciación se puede automatizar con AUTOINST. El comentario se expande con Mx verilog-auto y luego se puede editar manualmente.

 subcomponent subcomponent_instance_name(/*AUTOINST*/); 

Expandido

 subcomponent subcomponent_instance_name (/*AUTOINST*/ //Inputs .clk, (clk) .rst_n, (rst_n) .data_rx (data_rx_1[9:0]), //Outputs .data_tx (data_tx[9:0]) ); 

Los cables implícitos se pueden automatizar con /*AUTOWIRE*/ . Verifique el enlace para más información.

    Intereting Posts