Buscar

Slides Verilog

Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original

Verilog HDL
Wagner L. A. de Oliveira
Motivação
Elementos de processamento mais utilizados
Obs.: de forma geral, a depender da aplicação e do hardware utilizado
Fluxo de Projeto Básico 
Projeto em
Nível de Sistema
Projeto
Lógico
Projeto
Físico
Fluxo de Projeto Básico 
Front-End
Back-End
Verilog HDL
Estrutura Geral
Hierarquia de módulos
Módulo representa um componente do sistema
interface
descrição funcional
estrutural
dataflow
comportamental
Módulo não pode ser inserido em outro módulo
necessário uso de instanciação
pode fazer parte do mesmo arquivo
Estilos de Implementação
Verilog permite 3 estilos de implementação
Estrutural
Dataflow
Comportamental
Estilos de Implementação
Verilog permite 3 estilos de implementação
Estrutural
circuito especificado através da instanciação de componentes já existentes (pré-definidos na linguagem ou criados pelo usuário), os quais são conectados por sinais internos
Dataflow
Comportamental
Estilos de Implementação
Verilog permite 3 estilos de implementação
Estrutural
Dataflow
circuito especificado através de expressões lógicas e aritméticas, as quais transformam conjuntos de entradas em saídas
Comportamental
Estilos de Implementação
Verilog permite 3 estilos de implementação
Estrutural
Dataflow
Comportamental
circuito especificado através do comportamento pretendido, ao estilo de linguagens de programação
Sinais: Formas de Atribuição
Dentro de blocos procedurais initial
atribuição bloqueante
quando associada a um atraso, segura a execução da sentença seguinte
=
atribuição não bloqueante
execução paralela, independente do uso de atrasos
<=
Sinais: Formas de Atribuição
Dentro de blocos procedurais always
atribuição usada em blocos combinacionais (isto é, sem sinal de clock na lista de sensibilidade)
IMPORTANTE: a execução é sequencial
=
atribuição usada em blocos sequenciais 
	(isto é, com sinal de clock na lista de sensibilidade)
IMPORTANTE: a execução é paralela
<=
Sinais: Formas de Atribuição
Fora de blocos procedurais
atribuição contínua, para circuitos combinacionais
assign sinal =
NÃO SINTETIZÁVEL para classe register
exemplos
	assign saida = (habilita) ? data_in : 1'bz; // condicional
 	assign saida = data_in;	 // não condicional
anula atribuição contínua
NÃO SINTETIZÁVEL
deassign sinal
Sinais: Tipos de Dados
Duas classes de tipos de dados
Sinais: Tipos de Dados
Classe Net: usados para interconexão
wire, tri
wor, trior
wand, triand
tri0, tri1
supply0, supply1 (somente para rails em netlists)
trireg
Sinais: Tipos de Dados
Classe Net: drive strength / charge strength
Strength
Valor
supply
7
strong
6
pull
5
large
4
weak
3
medium
2
small
1
highz
0
Sinais: Tipos de Dados
Classe Net: exemplos
...
wor a;
wire b, c;
...
assign a = b;
assign a = c;
...
Sinais: Tipos de Dados
Classe Net: exemplos
...
tri a;
wire b, c;
...
assign a = b;
assign a = c;
...
Sinais: Tipos de Dados
Classe Net: exemplos
...
trireg (large) [3:0] # (2, 5, 9) capacitor;
wire [3:0] b, c;
...
assign capacitor = (b) ? c : 4'bz;
...
Sinais: Tipos de Dados
Classe Net: exemplos
Sinais: Tipos de Dados
Classe Register: usados para armazenamento
reg
integer
real 	(NÃO SINTETIZÁVEL)
time 	(NÃO SINTETIZÁVEL)
realtime 	(NÃO SINTETIZÁVEL)
Sinais: Operadores
Portas: Tipos de Dados
Pertencentes às duas classes básicas, seguindo algumas restrições
Primitivas: Verilog
Portas de múltiplas saídas
Ex.: buf (saida1, saida2, saida3, entrada)
Primitivas: Verilog
Portas de múltiplas entradas
Ex.: xor (saida, entrada1, entrada2, entrada3)
Primitivas: Verilog
Portas tristate
Ex.: bufif1 (saida, entrada, controle)
Primitivas: Definidas pelo Usuário
UDP
 User Defined Primitive
 NÃO SINTETIZÁVEL
Dois tipos
Combinacionais
Sequenciais
somente para primitivas sequenciais
Estilo Comportamental
Blocos procedurais
always 
pode representar hardware COMBINACIONAL ou SEQUENCIAL
execução contínua, de acordo com
lista de sensibilidade
alteração de sinais
detecção de bordas
atrasos (NÃO SINTETIZÁVEIS)
initial
execução única, no início da simulação
NÃO SINTETIZÁVEL 
always 
		begin
			#5 clk = ~clk;
		end
always sem lista de sensibilidade
	(NÃO SINTETIZÁVEL)
always @ (a or b or sel)
		begin
		 	if (sel == 0)
		 	 	y = a;
			else
			 	y = b;
		end
always: lista sensível a quaisquer alterações
module contador (clock, reset, enable, counter_out);
	input clock, reset, enable;
	output [3:0] counter_out;
	reg [3:0] counter_out;
	
	always @ (posedge clock) // para borda de descida: negedge
		begin
		 	if (reset == 1'b1) 
	 	 	 	counter_out <= #1 4'b0000;
		 	else 
				if (enable == 1'b1)
		 	 	 	counter_out <= #1 counter_out + 1;
		end
endmodule
always: lista sensível à borda
module contador (clock, reset, enable, counter_out);
	input clock, reset, enable;
	...	
	always @ (posedge clock)
		begin
			...
		end
	initial 
		begin
			clock = 1;
			reset = 0;
			enable = 0;
		end
endmodule
initial
Estilo Comportamental
Estruturas de controle
if - else
case
while 		(*)
repeat 		(**)
for 		(**)
* sintetizável se contiver @(posedge clock) ou @(negedge clock) ou disable
** sintetizável para controle constante (valor pré-determinado)
if - else
if (enable == 1'b1)
		begin
			data = 10; 
			address = 16'hFAFA; 
			wr_enable = 1'b1; 
		end
else 
		begin
			wr_enable = 1'b0;
			data = 32'b0;
			address = address + 1;
		end
case
case ({seletor1, seletor0})
		2’b00 : saida = entrada0;
		2’b01 : saida = entrada1;
		2’b10 : saida = entrada2;
		2’b11 : saida = entrada3;
		default : saida = 1’bX;
endcase
while
module counter (clk,rst,enable,count);
	input clk, rst, enable; output [3:0] count; reg [3:0] count;
	
	always @ (posedge clk or posedge rst)
		if (rst) 
			count <= 0;
		else 
			begin : COUNT
				while (enable) 
					begin
		 	 			count <= count + 1;
			 	 		disable COUNT;
			 	 	end
			end
endmodule
for
for (i = 0; i < 16; i = i +1) 
begin
		$display ("Valor atual de i é %d" , i);
end
repeat
repeat (16)
begin
		$display ("Valor atual de i é %d" , i);
	 	i = i + 1;
end
Subprogramas: Tasks
Subprogramas: Tasks
Regras de uso
locais de definição de uma task
dentro do módulo no qual ela é utilizada
em um arquivo separado, o qual deverá ser incluído no arquivo que instancia a task, com o uso de uma cláusula `include
task pode incluir cláusulas temporais
posedge / negedge / # / wait
task pode ter qualquer número de entradas e saídas
variáveis declaradas dentro de uma task são locais a task
a ordem de declaração dentro da task define a ordem de passagem de argumentos
Subprogramas: Tasks
Regras de uso
task pode usar variáveis globais
task pode chamar outra task ou function
task pode ser usada para modelar tanto lógica combinacional quanto sequencial
task deve ser chamada diretamente em uma sentença
não pode ser acionada dentro de uma expressão
Subprogramas: Tasks
Exemplo: chamada de task
module Converte_Temp(C1, C2, F1, F2);
input [7:0] C1, C2;
output reg [7:0] F1, F2;
	always @(C1)
		Celsius_Fahrenheit(C1, F1);
	always @(C2)
		Celsius_Fahrenheit(C2, F2);
	task Celsius_Fahrenheit;
	input [7:0] Celsius;
	output [7:0] Fahrenheit;
			Fahrenheit = (9/5) * Celsius + 32;
	endtask
endmodule
Subprogramas: Functions
Subprogramas: Functions
Regras de uso
locais de definição de uma function
dentro do módulo no qual ela é utilizada
em um arquivo separado, o qual deverá ser incluído no arquivo que instancia a function, com o uso de uma cláusula `include
function não pode incluir
cláusulas temporais
posedge / negedge / # / wait
em termos de simulação, functions têm tempo zero de atraso
function pode ter qualquer número de entradas e somente uma saída
variáveis declaradas dentro de uma function são locais a function
a ordem de declaração dentro da function define a ordem de passagem de argumentos
Subprogramas: Functions
Regras de uso
function pode usar variáveis globais
function pode chamar outra function
não pode chamar uma task
function pode ser usada para modelar somente lógica combinacional
não pode modelar lógica sequencial
function deve ser chamada a partir de uma expressão
Subprogramas: Functions
Exemplo: chamada de function
module teste_funcao(a, b, c, d, e, f);
input a, b, c, d, e ;
output f;
	assign f = (xisto (a,b,c,d)) ? e :0;
	function xisto;
	input k, l, m, n;
		begin
			xisto = (k || l) && (m || n);
		end
	endfunction
endmodule
Parâmetros
Definem constantes
 declarados junto às portas do módulo
Parâmetros
Definem constantes
 declarados junto às portas do módulo
Usos
tamanho de objetos
controle de laços
especificação de atrasos
nomes de estados
Exemplos do uso de parâmetros
module counter (clk,rst,enable,count, clk_out);
 parameter BusWidth = 4, contador = 48, atraso = 20;
 input clk, rst, enable; 
 output clk_out;
 output [BusWidth-1:0] count; 
 reg [BusWidth-1:0] count;
 ...	
	assign #atraso clk_out = clk; 
 ...	
	for (i = 0; i < contador; i = i +1) 
 ...	
endmodule
	
Exemplos do uso de parâmetros
module adder (a, b, c);
 parameter WIDTH = 4;
 input [WIDTH-1:0] a, b;
 output [WIDTH:0] c;
 ...
endmodule
module multiplier (x, y, z);
 input [3:0] x, y;
 output [4:0] z;
 wire [4:0] fio1, fio2, fio3;
 wire [5:0] fio4, fio5, fio6; 
 ...
 adder somador1 ( .a(fio2), .b(fio3), .c(fio6) );
 defparam somador1.WIDTH = 5; // (NÃO SINTETIZÁVEL)
endmodule
Atrasos (NÃO SINTETIZÁVEIS)
Antes das etapas de implementação física, não há informações sobre os atrasos reais do circuito
Contudo, pode-se modelar atrasos ideais para diferentes partes do circuito, objetivando-se estabelecer os tempos máximos de atraso permitidos
 uso de operadores de atraso
Atrasos (NÃO SINTETIZÁVEIS)
Operadores de atraso (#) são especificados em unidades de tempo
Para definir tal unidade de tempo, utiliza-se uma diretiva de compilação
`timescale <unidade_tempo> / <precisão>
ambos valores deverão ser 1, 10 ou 100, acompanhados da unidade correspondente (s, ms, us, ns, ps, fs)
<unidade_tempo> é o valor usado nos operadores de atraso (#)
<precisão> é o arredondamento utilizado pelo simulador
Exemplo: `timescale 10 us / 100 ns
Atrasos (NÃO SINTETIZÁVEIS)
Dois tipos de operadores de atraso
assignment delay
atraso precede execução da atribuição
	#5 x = y + z;
Atrasos (NÃO SINTETIZÁVEIS)
Dois tipos de operadores de atraso
assignment delay
atraso precede execução da atribuição
	#5 x = y + z;
intra-assignment delay
lado direito da atribuição é calculado tão logo a sentença entra em execução, mas resultado somente é atribuído após o atraso
	x = #5 y + z;
Atrasos (NÃO SINTETIZÁVEIS)
Dois tipos de operadores de atraso
assignment delay
atraso precede execução da atribuição
	#5 x = y + z;
intra-assignment delay
lado direito da atribuição é calculado tão logo a sentença entra em execução, mas resultado somente é atribuído após o atraso
	x = #5 y + z;
Ambos podem ser combinados
	#5 x = #5 y + z;
Atrasos (NÃO SINTETIZÁVEIS)
Diferentes formas de modelar atrasos
Controle de Eventos
Operador @
detecta evento sobre o sinal à sua direita, permitindo a execução da sentença seguinte
exemplos
@ (CLK) Q = D;
@ (posedge CLK) Q = D;
@ (negedge CLK) Q = D; 
Controle de Eventos
Sentença wait
suspende a execução da sentença associada (se existir), até que a condição especificada seja verdadeira
NÃO SINTETIZÁVEL
exemplos
wait (enable); 
wait (enable) #7 x = y + z; 
Estrutura fork-join
Em descrições comportamentais, há duas formas para agrupar sentenças em um bloco
begin - end
execução sequencial das sentenças entre begin e end
fork - join
execução paralela das sentenças entre fork e join
Estrutura fork-join
Estrutura fork-join assemelha-se a um conjunto de atribuições não bloqueantes
fork - join usa assignments delays
atribuições não bloqueantes usam intra-assignments delays
NÃO SINTETIZÁVEL
bloco sequencial com atribuições bloqueantes
reg [7:0] RegX;
initial
	begin
		# 50 RegX = 8‘h01; 	// 50
		# 50 RegX = 8‘h02;	// 100
		# 50 RegX = 8‘h03;	// 150
		# 50 RegX = 8‘h04;	// 200
	end
bloco sequencial com atribuições não bloqueantes
reg [7:0] RegX;
initial
	begin
		RegX <= # 50 	8‘h01;	// 50
		RegX <= # 100 	8‘h02;	// 100
		RegX <= # 150	8‘h03;	// 150
		RegX <= # 200	8‘h04;	// 200
	end
bloco concorrente
reg [7:0] RegX;
initial
	fork
		# 50 	RegX = 8‘h01;	// 50
		# 100 	RegX = 8‘h02;	// 100
		# 150 	RegX = 8‘h03;	// 150
		# 200 	RegX = 8‘h04;	// 200
	join
Máquina de Estados Finita
Exemplo: máquina de venda de chocolates
Máquina made in USA
Aceita somente moedas de 5, 10 e 20 cents (em fendas apropriadas)
Libera barra de chocolate ao atingir 45 cents
Não retorna troco
Máquina de Estados Finita
Máquina de Estados Finita
Exemplo: máquina de venda de chocolates
Máquina de Estados Finita
Exemplo: máquina de venda de chocolates
Máquina de Estados Finita
Exemplo: máquina de venda de chocolates
Máquina de Estados Finita
Exemplo: máquina de venda de chocolates
Máquina de Estados Finita
Exemplo: máquina de venda de chocolates
Máquina de Estados Finita
Exemplo: máquina de venda de chocolates
Boas Práticas de Codificação
Código mais claro para leitura
divisão do código em módulos e funções significativos
nomes significativos para variáveis e portas
uso de identação
uso de parâmetros
uso de comentários
uso de assigns simples
Boas Práticas de Codificação
Em blocos always @ (*)
todo reg deve ter um valor para todos os ramos condicionais
caso contrário, será gerado um latch
para garantir isso, faça uma atribuição default para cada reg, antes dos construtores if e case 
Boas Práticas de Codificação
Atente para o uso adequado de atribuições bloqueantes e não bloqueantes
Boas Práticas de Codificação
Atente para o uso adequado de atribuições bloqueantes e não bloqueantes
Boas Práticas de Codificação
Não misture atribuições bloqueantes com não bloqueantes em blocos always @
use tantos blocos quanto julgar necessário
lembre-se de que rodam em paralelo
Boas Práticas de Codificação
Evite usar RESET assíncrono
a não ser que seu chefe mandou 
neste caso, certifique-se que não violará restrições de tempo (setup / hold)
Boas Práticas de Codificação
Não crie loops combinacionais
suponha o contador sequencial abaixo
a
y
Boas Práticas de Codificação
Não crie loops combinacionais
Boas Práticas de Codificação
Não use múltiplos assign para um mesmo wire, sem uma condição
a função de resolução retornará sempre lógico 0
Boas Práticas de Codificação
Em resumo
faça código legível e comentado
não gere latches
não misture atribuições bloqueantes com não bloqueantes no mesmo bloco
RESET assíncrono é perigoso
não crie loops combinacionais (loops infinitos)
não faça atribuições múltiplas sobre um mesmo wire, sem uma condição
Para saber mais
ASIC World
	www.asic-world.com/verilog
Verilog Online Help
	verilog.renerta.com/source/vrg00000.htm
Fundamentals of Digital Logic with Verilog Design
Stephen D. Brown, Zvonko G. Vranesic 2008
Verilog for Digital Design
	Frank Vahid, Roman Lysecky
	2007

Teste o Premium para desbloquear

Aproveite todos os benefícios por 3 dias sem pagar! 😉
Já tem cadastro?

Outros materiais

Outros materiais