Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Industrial programming >> Verilog

Instanciações do módulo Verilog


Como vimos em um artigo anterior, projetos maiores e complexos são construídos integrando vários módulos de forma hierárquica. Os módulos podem ser instanciados dentro de outros módulos e portas dessas instâncias pode ser conectado com outros sinais dentro do módulo pai.

Essas conexões de porta podem ser feitas por meio de uma lista ordenada ou por nome.

Conexão de porta por lista ordenada


Um método de fazer a conexão entre as expressões de porta listadas em uma instanciação de módulo com os sinais dentro do módulo pai é pela lista ordenada .

meudesign é um module instanciado com o nome d0 em outro módulo chamado tb_top. As portas são conectadas em uma determinada ordem que é determinada pela posição daquela porta na lista de portas da declaração do módulo. Por exemplo, b no testbench está conectado a y do projeto simplesmente porque ambos estão na segunda posição na lista de portas.
  
  
	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

  

A ordem das portas no módulo de projeto deve ser conhecida para uma conexão correta.

Isso é muito inconveniente porque a ordem pode mudar se uma nova porta for adicionada à lista ou quando o número de portas no design for muito grande.

Conexão de porta por nome


Uma maneira melhor de conectar portas é vinculando explicitamente as portas em ambos os lados usando o nome da porta .

O ponto . indica que o nome da porta após o ponto pertence ao design. O nome do sinal ao qual a porta de projeto deve ser conectada é fornecido entre parênteses ( ) .
  
  
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

  

Recomenda-se codificar cada conexão de porta em uma linha separada para que qualquer mensagem de erro de compilação aponte corretamente para o número da linha em que o erro ocorreu. Isso é muito mais fácil de depurar e resolver em comparação com não saber qual porta criou o erro se todas estivessem na mesma linha.

Como essas conexões são feitas pelo nome, a ordem em que aparecem é irrelevante. Conexões de porta de instância de módulo múltiplo não são permitidas.
  
  
	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

  

Portas desconectadas/flutuantes


As portas que não estão conectadas a nenhum fio no módulo de instanciação terão um valor de alta impedância.
  
  
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

  

Exemplo


Vamos pegar o exemplo do registrador de deslocamento que vimos antes e deixar algumas portas desconectadas.
  
  
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

  

Observe que as saídas das instâncias u1 e u2 são deixadas desconectadas no esquema RTL obtido após a síntese. Como a entrada d para as instâncias u2 e u3 agora estão conectadas a redes que não estão sendo acionadas por nada, ela é aterrada.

Nas simulações, essas portas desconectadas serão indicadas como alta impedância ('hZ) normalmente mostrada em formas de onda como uma linha laranja alinhada verticalmente no meio.

Todas as declarações de porta são declaradas implicitamente como wire e, portanto, a direção da porta é suficiente nesse caso. No entanto, output portas que precisam armazenar valores devem ser declaradas como reg tipo de dados e pode ser usado em um bloco procedural como always e initial só.

Portas do tipo input ou inout não pode ser declarado como reg porque eles estão sendo acionados de fora continuamente e não devem armazenar valores, mas sim refletir as mudanças nos sinais externos o mais rápido possível. É perfeitamente legal conectar duas portas com tamanhos de vetor variados, mas aquela com tamanho de vetor menor prevalecerá e os bits restantes da outra porta com largura maior serão ignorados.
  
  

	// 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. Tutorial Verilog
  2. Concatenação Verilog
  3. Verilog - Em uma casca de noz
  4. Atribuições Verilog
  5. Verilog Blocking &Non-Blocking
  6. Funções Verilog
  7. Tarefa Verilog
  8. Escopo de Referência Hierárquica Verilog
  9. Gerador de Relógio Verilog
  10. Funções matemáticas Verilog