Manual Verilog
Manual Verilog
Autores
Histórico de revisões
23/01/2025 V1.0 Versão inicial
2
Tópicos
• Introdução à Álgebra Booleana
• Introdução a Mintermos, Maxtermos e Mapas de Karnaugh
• Introdução às Ferramentas e Servidor
• Verilog – Introdução à Linguagem
• Verilog – Tipos de Dados
• Verilog – Operadores
• Verilog – Declarações Processuais
• Verilog – Declarações Blocking e Non-blocking
• Verilog – Reset Síncrono e Assíncrono
• Verilog – Estilos de Código
• Verilog – Descrição RTL
• Verilog – Descrição Comportamental
• Verilog – Descrição Estrutural
• Verilog – Primitivas do Verilog e Primitivas Definidas por Usuário
• Verilog – Codificação para Síntese e Simulação
3
Página em branco.
4
Aula 0
Introdução à Álgebra Booleana
Definição
• Álgebra Booleana é um
sistema matemático dedutivo
que lida com variáveis lógicas
e operações baseadas em
dois valores possíveis: 0
(falso) e 1 (verdadeiro).
George Boole
(1815 - 1864)
• Foi desenvolvida por George
Boole no século XIX e serve
como base teórica para a
lógica digital e os circuitos
lógicos utilizados em
computadores e dispositivos
digitais.
6
Postulados
• Os postulados de um sistema matemático formam as
suposições básicas a partir das quais é possível deduzir as
regras, os teoremas e as propriedades do sistema. Os
postulados mais comuns usados para formular várias
estruturas algébricas são os seguintes:
1) Fechamento
2) Lei Associativa
3) Lei Comutativa
4) Elemento Identidade
5) Elemento Inverso
6) Lei Distributiva
7
Fechamento
• Um conjunto S é fechado em
relação a um operador binário se,
para cada par de elementos de S, o
operador binário especifica uma
regra para obter um elemento
único de S. Por exemplo, o
conjunto dos números naturais
N={1,2,3,4,…} é fechado em
relação ao operador binário + pelas
regras da adição aritmética, pois,
para quaisquer a, b ∈ N, existe um
único c ∈ N tal que a + b = c.
8
Lei Associativa
Os operadores binários * e + em um conjunto S são ditos
serem associativos sempre que:
9
Lei Comutativa
Um operador binário * em um conjunto S é dito ser
comutativo sempre que:
x*y=y*x
x=4 4*5=5*4
y=5
20 = 20
10
Elemento Identidade
Um conjunto S possui um elemento identidade em relação a
uma operação binária * se existir um elemento e ∈ S que
satisfaça a propriedade:
e * x = x * e = x para todo valor de x ∈ S
11
Inverso
Um conjunto S, com um elemento identidade em relação a
uma operação binária *, possui inversos se, para cada x ∈ S,
existir um elemento y ∈ S tal que:
x*y=e
12
Lei Distributiva
Se * e ⋅ são dois operadores binários em um conjunto S, dizemos
que * é distributivo sobre ⋅ se, para todos os x, y, z ∈ S:
Exemplo: Considere x = 2, y = 3 e z = 4:
2 ⋅ (3 + 4) = (2 ⋅ 3) + (2 ⋅ 4)
x=2
y=3
2⋅7= 6+8
z=4
14 = 14
13
Álgebra Booleana de Dois
Valores
A álgebra booleana de dois valores usa o conjunto B = {0, 1},
com os operadores binários OR (+), AND (⋅) e NOT (x’). As
tabelas abaixo mostram as regras de cada operador:
14
Álgebra Booleana de Dois
Valores
1) Fechamento:
A estrutura é fechada para os operadores + e ⋅, pois o resultado
de qualquer operação é sempre 0 ou 1, ambos pertencentes ao
conjunto B.
2) Elementos Identidade:
• Das tabelas da verdade, observamos os seguintes elementos
identidade:
(a) Para “+”: 0, pois 0 + x = x + 0 = x;
(b) Para “⋅”: 1, pois 1 ⋅ x = x ⋅ 1 = x;
• Isso confirma os elementos identidade conforme o Postulado
2.
3) Leis Comutativas:
As tabelas do slide anterior mostram que x + y = y + x e
x ⋅ y = y ⋅ x, demonstrando a comutatividade dos operadores.
15
Álgebra Booleana de Dois
Valores
x y z y+z 4) Leis Distributivas:
x . (y+z) x.y x.z (x.y) + (x.z)
0 0 0 0 0 0 0 0
1 0 0 0 0
A tabela da verdade
0 0 1
0 1 0 1 0 0 0 0
confirma que os resultados
1 0
de x ⋅ (y + z) e (x ⋅ y) + (x ⋅ z)
0 1 1 0 0 0
0 0
são sempre iguais.
1 0 0 0 0 0
1 0 1 1 1 0 1 1
1 1 0 1 1 1 0 1
1 1 1 1 1 1 1 1
16
Álgebra Booleana de Dois
Valores
5) Complemento
O Postulado 1 trata das propriedades do Complemento e
afirma que:
• x + x’ = 1
• x⋅x=0
(a) Para x + x′ = 1
• 0 + 0′ = 0 + 1 = 1
• 1 + 1′ = 1 + 0 = 1
Assim, verificamos que o Postulado 1
é verdadeiro para os valores de x e x’.
(b) x ⋅ x′ = 0
• 0 ⋅ 0′ = 0 ⋅ 1 = 0
• 1 ⋅ 1′ = 1 ⋅ 0 = 0
17
Álgebra Booleana de Dois
Valores
6) Estrutura binária
O Postulado 6 define a estrutura binária da Álgebra Booleana,
que possui dois elementos distintos, representados por 0
(falso) e 1 (verdadeiro) e esses elementos são diferentes entre
si:
1≠0
18
Postulados e Teoremas
Postulados e Teoremas da (a) (b)
Álgebra Booleana
Postulado 2 x+0=x x⋅1=x
Postulado 5 x + x’ = 1 x ⋅ x’ = 0
Teorema 1 x+x=x x⋅x=x
Teorema 2 x+1=1 x⋅0=0
Teorema 3, Involução (x’)’ = x
Postulado 3, Comutativo x+y=y+x x⋅y = y⋅x
Teorema 4, Associativo x + (y + z) = (x + y) + z x(y⋅z) = (x⋅y)z
Postulado 4, Distributivo x(y + z) = xy + xz x + yz = (x + y)(x + z)
Teorema 5, DeMorgan (x + y)’ = x’y’ (xy)’ = x’ + y’
Teorema 6, Absorção x + xy = x x(x + y) = x
19
Postulados e Teoremas
Teorema 1 (a): Prova de x + x = x
Declaração Justificativa
x + x = (x + x) ⋅ 1
Postulado 2 (b)
= (x + x)(x + x’)
5 (a)
= x + xx’
4 (b)
=x+0
5 (b)
=x
2 (a)
20
Postulados e Teoremas
Teorema 1 (b): Prova de x ⋅ x = x
Declaração Justificativa
x ⋅ x = xx + 0
Postulado 2 (a)
= xx + xx’
5 (b)
= x(x + x’)
4 (b)
=x⋅1
5 (a)
=x
2 (b)
21
Postulados e Teoremas
Teorema 2 (a): Prova de x + 1 = 1
Declaração Justificativa
x + 1 = 1 ⋅ (x + 1)
Postulado 2 (a)
= (x + x’) (x + 1)
5 (b)
= x + x’ ⋅ 1
4 (b)
= x + x’
5 (a)
Teorema 2 (b): x ⋅ 0 ==
0 por
1 dualidade
2 (b)
22
Postulados e Teoremas
Teorema 3: Prova de (x’)’ = x
x x’ (x’)’
Base: A partir do Postulado 5,
0 1 0
temos:
1 0 1
x + x’ = 1 e x ⋅ x’ = 0
23
Postulados e Teoremas
Teorema 6 (a): Prova de x + xy = x
Declaração Justificativa
x + xy = x⋅1 + xy
Postulado 2 (b)
= x(1 + y)
4 (a)
= x(y + 1)
3 (a)
= x⋅1
2 (a)
Teorema 6 (b): x(x + y)== xx por dualidade.
2 (b)
24
Funções Booleanas
Definição:
• A Álgebra Booleana lida com variáveis binárias e operações
lógicas.
Componentes de uma Função Booleana:
• Uma função booleana é descrita por uma expressão algébrica
com:
Variáveis binárias (x, y, z);
Constantes (0 e 1);
Operadores lógicos (AND, OR, NOT, etc).
Comportamento:
• Para um valor dado das variáveis binárias, a função retorna 0
ou 1.
F(x,y) = x⋅y + x′
25
Exemplo: Funções Booleanas
F1 = x + y'z
• Uma Função Booleana descreve
uma relação lógica entre as
variáveis binárias, determinando
sua saída com base nos valores
binários atribuídos às entradas.
x y z F1
• Representação com a Tabela da
0 0 0 0
Verdade:
0 0 1 1
• A Tabela da Verdade mostra todas
as combinações possíveis de 0 1 0 0
entrada e saída correspondente.
0 1 1 0
• O número de linhas da tabela da
1 0 0 1
verdade é 2n, onde n é o número
de variáveis. 1 0 1 1
• Exemplo: Para F1 = x + y'z, há 8 1 1 0 1
combinações possíveis (n = 3). 1 1 1 1
26
Exemplo: Funções Booleanas
(a)
F2 = x’y’z + x’yz +
xy’ (a)
F2 = x’z (y’ + y) +
xy’1
27
Simplificando Funções
1) x(x’ + y) = xx’ + xy = 0 + xy = xy
29
Complemento de Função
Booleanas
• Os teoremas de DeMorgan, para qualquer número de variáveis,
seguem a mesma lógica dos casos com duas variáveis.
• Eles podem ser derivados por substituições sucessivas,
semelhantes ao método usado nas derivações anteriores.
Para soma (+):
(A + B + C + D + ... + F)’ = A’B’C’D’...F’
O complemento de uma soma de variáveis resulta no produto dos
complementos das variáveis.
30
Exemplo: Cálculo do Complemento de
Funções Booleanas
31
Página em branco.
32
Aula 1
Introdução à Álgebra Booleana
(cont.)
Relatório Prático
• Nesta aula, iremos aplicar os conceitos estudados sobre
Álgebra Booleana em exercícios práticos, presentes no
arquivo Relatórios Práticos – SD112 atividade A-001.
• O aluno deverá fazer todos os exercícios e enviar os arquivos
da resolução assinados com seu nome completo para o e-
mail [email protected];
• Assunto do e-mail: Relatório SD112 – Atividade A-001.
34
Instruções
• Para utilização da plataforma Draw.IO, deve-se habilitar as
formas para circuitos elétricos, que incluem portas lógicas,
de acordo com as imagens a seguir:
1) 2)
35
Página em branco.
36
Aula 2
Introdução à Mintermos,
Maxtermos e Mapas de
Karnaugh
Mintermo/Maxtermo
• São duas formas padrões para expressar as funções
booleanas.
38
Mintermo
• Com duas variáveis binárias são possíveis 4
combinações (22 = 4).
A B
39
Mintermo
• Esses 4 termos são chamados de mintermos ou
produto padrão.
• Mintermo é composto por duas ou mais variáveis,
ou o seu complemento, aplicadas através de uma
porta AND.
• Para funções de n variáveis
tem-se 2n mintermos,
designados por mj, onde o A B
subscrito j representa o
decimal equivalente ao
número binário que
representa o mintermo.
40
Mintermo
Tabela da verdade ilustrando os mintermos com funções com 3 variáveis.
A B C Mintermo Designação
0 0 0 m0
0 0 1 m1
0 1 0 m2
0 1 1 m3
1 0 0 m4
1 0 1 m5
1 1 0 m6
1 1 1 m7
41
Maxtermo
42
Maxtermo
Tabela da verdade ilustrando os maxtermos com funções com 3 variáveis.
A B C Maxtermo Designação
0 0 0 M0
0 0 1 M1
0 1 0 M2
0 1 1 M3
1 0 0 M4
1 0 1 M5
1 1 0 M6
1 1 1 M7
43
Mintermo/maxtermo
Toda expressão booleana pode ser representada como uma
soma de mintermos ou como um produto de maxtermos.
Exemplo 01: Expressar X(A,B,C) e Y(A,B,C) em termos de soma
de mintermos:
A B C X Y
0 0 0 0 0 1
1 0 0 1 1 1
2 0 1 0 1 0
3 0 1 1 0 0
4 1 0 0 0 1
5 1 0 1 1 1
6 1 1 0 1 0
7 1 1 1 0 1
44
Mintermo/maxtermo
Toda expressão booleana pode ser representada como uma
soma de mintermos ou como um produto de maxtermos.
Exemplo 02: Expressar X(A,B,C) e Y(A,B,C) em termos de
produto de maxtermos:
A B C X Y
0 0 0 0 0 1
1 0 0 1 1 1
2 0 1 0 1 0
3 0 1 1 0 0
4 1 0 0 0 1
5 1 0 1 1 1
6 1 1 0 1 0
7 1 1 1 0 1
45
Mintermo/maxtermo
• Cada maxtermo é o complemento do seu
correspondente mintermo e vice-versa.
Exemplo 03:
• Prove que
46
Mintermo/maxtermo
Exemplo 04:
• Prove que
47
Propriedades dos Mintermos e
Maxtermos
1. Qualquer função booleana pode ser expressa
através da soma de mintermos.
2. Qualquer função booleana pode ser expressa
através do produto de maxtermos.
Uma função booleana pode ser obtida da Tabela da Verdade
atribuindo-se um mintermo para cada combinação de
variáveis que produz lógica 1 e então unindo todos os termos
através do operador OR.
3. Quando uma função booleana está representada
na forma de soma de mintermos ou produto de
maxtermos a função está representada na forma
canônica.
48
Mintermo/maxtermo
Exemplo 05: Expressar as funções D e B através da soma de
mintermos. Entradas Saídas
X Y Z D B
0 0 0 0 0
0 0 1 1 1
0 1 0 1 1
0 1 1 0 1
1 0 0 1 0
1 0 1 0 0
1 1 0 0 0
1 1 1 1 1
49
Mintermo/maxtermo
Exemplo 06: Expressar as funções D e B através do produto de
maxtermos. Entradas Saídas
X Y Z D B
0 0 0 0 0
0 0 1 1 1
0 1 0 1 1
0 1 1 0 1
1 0 0 1 0
1 0 1 0 0
1 1 0 0 0
1 1 1 1 1
50
Mintermo/Maxtermo
• Muitas funções booleanas são compostas por termos que
não contém todas as variáveis.
• Contudo, é possível expressar a função através da soma de
produtos.
(Teoria do Complemento)
51
Mapa de Karnaugh
• O Mapa de Karnaugh (K-map) é um método
utilizado para simplificação de expressões
da Álgebra Booleana.
• Foi desenvolvido por Maurice Karnaugh em
1953, sendo um aperfeiçoamento do Mapa Maurice Karnaugh
de Veitch, este desenvolvido por Edward (1924-2022)
Veitch em 1952. K-map
K-map K-map (4 variáveis)
(2 variáveis) (3 variáveis)
AB
A AB 00 01 11 10
0 1 00 01 11 10
00 0 0 0 0
0 0 1 0 0 0 0 0
B C 01 0 1 1 0
1 0 1 1 0 1 1 0 CD 11 1 1 1 1
10 1 1 0 1
52
Mapa de Karnaugh
• O Mapa de Karnaugh é um método para reduzir uma
expressão booleana na sua forma mais simples.
• Contém as mesmas informações contidas na Tabela da
Verdade, entretanto permite que o projetista identifique os
termos que podem ser simplificados.
• Cada linha da Tabela da Verdade representa uma célula no
Mapa de Karnaugh.
• O princípio do Mapa de Karnaugh é o Teorema do
Complemento:
• Termos que diferem em um único bit podem ser
simplificados, eliminando a variável que assume o valor "1"
em um dos termos e o valor "0" no outro termo.
• Código Gray.
53
Mapa de Karnaugh para Duas Variáveis
A
0 1 v1 A=0 e B=0
0 v1 v3 ou v1 v3 v2 A=0 e B=1
B 1 v2 v4 v2 v4 v3 A=1 e B=0
v4 A=1 e B=0
A A A
X 0 1 Y 0 1 0 1
Z
0 1 0 1 0 1
B B 1 1 B
1 1 1 1 1
54
Mapa de Karnaugh para Duas Variáveis
A A A A
0 1 0 1 0 1 0 1
0 1 0 0 1 0
B 1 B 1 1 B B
1 1 1
A A A A
0 1 0 1 0 1 0 1
0 1 0 1 0 1 1 0
B 1 1 B 1 1 B B
1 1 1 1
55
Mapa de Karnaugh para Duas Variáveis
A
X 0 1
0 1 1
B 1
A
Y 0 1
0 1 1
B 1 1
A A A
Z 0 1 Z 0 1 Z 0 1
0 1 1 0 1 1 0 1 1
B 1 1 1
B 1 1 1 B 1 1 1
56
Mapa de Karnaugh para Três
Variáveis
AB • A sequência dos termos é
00 01 11 10 importante para que o Mapa
0 de Karnaugh possa ser
C 1 utilizado corretamente.
AB AB AB
00 01 11 10 00 01 11 10 00 01 11 10
0 1 0 1 0 1
C C C
1 1 1 1 1 1
AB
00 01 11 10
0 1
C
1 1
57
Mapa de Karnaugh para Três
Variáveis
AB AB AB
00 01 11 10 00 01 11 10 00 01 11 10
0 1 1 0 1 1 0 1 1
C C C
1 1 1
AB
00 01 11 10
0 1 1
C
1
58
Mapa de Karnaugh para Três
Variáveis
AB AB AB
00 01 11 10 00 01 11 10 00 01 11 10
0 0 0
C C C
1 1 1 1 1 1 1 1 1
AB
00 01 11 10
0
C
1 1 1
59
Mapa de Karnaugh para Três
Variáveis AB
AB AB
00 01 11 10 00 01 11 10 00 01 11 10
0 1 1 0 1 1 0 1 1
C C C
1 1 1 1 1 1 1 1 1
AB
00 01 11 10
0 1 1
C
1 1 1
AB AB
00 01 11 10 00 01 11 10
0 1 1 1 1 0 1 1 1 1
C C
1 1
60
Mapa de Karnaugh para Três
Variáveis
AB
00 01 11 10
0 1 1 1 1
C
1 1 1
AB
00 01 11 10
0 1 1
C
1 1 1
AB
00 01 11 10
0 1 1 1
C
1 1 1
61
Mapa de Karnaugh para Três
Variáveis AB
00 01 11 10
(3 variáveis / 18 literais)
0 1 1 1
C
1 1 1 1
Algumas possibilidades de agrupamentos*:
AB AB AB
00 01 11 10 00 01 11 10 00 01 11 10
0 1 1 1 0 1 1 1 0 1 1 1
C C C
1 1 1 1 1 1 1 1 1 1 1 1
EXPRESSÕES BOOLEANAS
EQUIVALENTES EXPRESSÃO BOOLEANA MÍNIMA
(possuem o mesmo resultado lógico) (a mais reduzida: menor quantidade de literais e
menor quantidade de variáveis)
*Existem outros agrupamentos possíveis, mas que também não são mínimos.
62
Mapa de Karnaugh para Quatro Variáveis
AB
00 01 11 10
00 A B C D A BC D
01 D D
CD 11
10
63
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 1 00 1
01 01
CD 11 CD 11
10 10
AB AB
00 01 11 10 00 01 11 10
00 1 00 1
01 01
CD 11 CD 11
10 10
64
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 00
01 1 01 1
CD 11 CD 11
10 10
AB AB
00 01 11 10 00 01 11 10
00 00
01 1 01 1
CD 11 CD 11
10 10
65
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 00
01 01
CD 11 1 CD 11 1
10 10
AB AB
00 01 11 10 00 01 11 10
00 00
01 01
CD 11 1 CD 11 1
10 10
66
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 00
01 01
CD 11 CD 11
10 1 10 1
AB AB
00 01 11 10 00 01 11 10
00 00
01 01
CD 11 CD 11
10 1 10 1
67
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 1 1 00 1 1
01 01
CD 11 CD 11
10 10
AB AB
00 01 11 10 00 01 11 10
00 1 1 00 1 1
01 01
CD 11 CD 11
10 10
68
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 00
01 1 1 01 1 1
CD 11 CD 11
10 10
AB AB
00 01 11 10 00 01 11 10
00 00
01 1 1 01 1 1
CD 11 CD 11
10 10
69
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 00
01 01
CD 11 1 1 CD 11 1 1
10 10
AB AB
00 01 11 10 00 01 11 10
00 00
01 01
CD 11 1 1 CD 11 1 1
10 10
70
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 00
01 01
CD 11 CD 11
10 1 1 10 1 1
AB AB
00 01 11 10 00 01 11 10
00 00
01 01
CD 11 CD 11
10 1 1 10 1 1
71
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 1 00
01 1 01 1
CD 11 CD 11 1
10 10
AB AB
00 01 11 10 00 01 11 10
00 00 1
01 01
CD 11 1 CD 11
10 1 10 1
72
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 1 00
01 1 01 1
CD 11 CD 11 1
10 10
AB AB
00 01 11 10 00 01 11 10
00 00 1
01 01
CD 11 1 CD 11
10 1 10 1
73
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 1 00
01 1 01 1
CD 11 CD 11 1
10 10
AB AB
00 01 11 10 00 01 11 10
00 00 1
01 01
CD 11 1 CD 11
10 1 10 1
74
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 1 00
01 1 01 1
CD 11 CD 11 1
10 10
AB AB
00 01 11 10 00 01 11 10
00 00 1
01 01
CD 11 1 CD 11
10 1 10 1
75
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 1 1 00 1 1
01 1 1 01 1 1
CD 11 CD 11
10 10
AB AB
00 01 11 10 00 01 11 10
00 1 1 00 1 1
01 1 1 01 1 1
CD 11 CD 11
10 10
76
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 00
01 1 1 01 1 1
CD 11 1 1 CD 11 1 1
10 10
AB AB
00 01 11 10 00 01 11 10
00 00
01 1 1 01 1 1
CD 11 1 1 CD 11 1 1
10 10
77
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 00
01 01
CD 11 1 1 CD 11 1 1
10 1 1 10 1 1
AB AB
00 01 11 10 00 01 11 10
00 00
01 01
CD 11 1 1 CD 11 1 1
10 1 1 10 1 1
78
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 1 1 00 1 1
01 01
CD 11 CD 11
10 1 1 10 1 1
AB AB
00 01 11 10 00 01 11 10
00 1 1 00 1 1
01 01
CD 11 CD 11
10 1 1 10 1 1
79
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 1 1 1 1 00
01 01 1 1 1 1
CD 11 CD 11
10 10
AB AB
00 01 11 10 00 01 11 10
00 00
01 01
CD 11 1 1 1 1 CD 11
10 10 1 1 1 1
80
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 1 00 1
01 1 01 1
CD 11 1 CD 11 1
10 1 10 1
AB AB
00 01 11 10 00 01 11 10
00 1 00 1
01 1 01 1
CD 11 1 CD 11 1
10 1 10 1
81
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 1 1 1 1 00
01 1 1 1 1 01 1 1 1 1
CD 11 CD 11 1 1 1 1
10 10
AB AB
00 01 11 10 00 01 11 10
00 00 1 1 1 1
01 01
CD 11 1 1 1 1 CD 11
10 1 1 1 1 10 1 1 1 1
82
Mapa de Karnaugh para Quatro Variáveis
AB AB
00 01 11 10 00 01 11 10
00 1 1 00 1 1
01 1 1 01 1 1
CD 11 1 1 CD 11 1 1
10 1 1 10 1 1
AB AB
00 01 11 10 00 01 11 10
00 1 1 00 1 1
01 1 1 01 1 1
CD 11 1 1 CD 11 1 1
10 1 1 10 1 1
83
Mapa de Karnaugh para Quatro Variáveis
AB
00 01 11 10
00 1
01 1 1
CD 11 1 1
10 1
AB
00 01 11 10
00 1 1 1
01
CD 11 1 1
10 1 1 1 1
84
Mapa de Karnaugh para Cinco
Variáveis
85
Mapa de Karnaugh para Seis
Variáveis
86
Mapa de Karnaugh com Condições
Irrelevantes
• Condições irrelevantes são situações de entrada na
qual a saída pode assumir 0 ou 1 de forma
indiferente.
• Essa condição ocorre, principalmente, devido à
impossibilidade prática de a situação de entrada
acontecer.
• Para utilizá-la em Mapas de Karnaugh, devemos,
para cada condição irrelevante, adotar o valor (0
ou 1) que permita um melhor agrupamento,
visando uma simplificação mais eficiente.
87
Mapa de Karnaugh com Condições
Irrelevantes
A B C S AB
0 0 0 X 00 01 11 10
0 0 1 1 0 X 1 1 1
0 1 0 1 C 1 0 0 0 0
0 1 1 1
1 0 0 0 𝐒 =𝐂
1 0 1 0
1 1 0 0 • O símbolo (X) indica uma condição em que a
1 1 1 0 saída pode assumir 0 ou 1 de forma
indiferente.
• Para fins de simplificação, é recomendado
atribuir X = 1, pois essa escolha permite
formar um agrupamento de uma quadra, em
vez de dois pares (caso X = 0), resultando em
uma expressão de saída mais simplificada.
88
Aula 3
Introdução à Mintermos,
Maxtermos e Mapas de
Karnaugh (cont.)
Relatório Prático
• Nesta aula, iremos aplicar os conceitos estudados
sobre Mintermos, Maxtermos e Mapas de Karnaugh em
exercícios práticos, presentes no arquivo Relatórios Práticos
– SD112 atividade A-002.
• O aluno deverá fazer todos os exercícios e enviar os arquivos
da resolução assinados com seu nome completo para o e-
mail [email protected];
• Assunto do e-mail: Relatório SD112 – Atividade A-002.
90
Aula 4
Introdução às Ferramentas e
Servidor
92
Aula 5
Verilog - Introdução à
Linguagem
O que é Verilog?
• Verilog não é uma
linguagem de software.
• Verilog é uma HDL
(hardware description
language).
• Uma linguagem de
programação com
estruturas especiais
para modelar
hardware.
94
Benefícios de Utilizar HDLs
• HDL é escrito em texto ASCII comum.
• Permite desenvolver o projeto de forma rápida e
gerenciar modificações facilmente.
• Permite projetar em um nível de abstração mais alto.
• Facilita avaliar diferentes opções de design.
• Permite identificar problemas mais cedo no ciclo de
projeto.
• A descrição é independente da implementação.
• A escolha da tecnologia de implementação pode ser
postergada.
• Torna mais simples realizar alterações arquiteturais e
funcionais.
• Facilita a adaptação do design para projetos futuros.
95
Níveis de Abstração
Behavioral
(comportamental)
- algorítimico
Register
Transfer Síntese
Level (RTL) Lógica
Verilog
Gate Level
(nível de portas) Layout
- netlist Place
&
Route
Físico
- silício
- polígonos
96
Níveis de Abstração: Trade-
offs
Simulação/entrada
Menos detalhado
mais rápida Behavioral (comportamental)
- algorítimico
Register
Transfer
Level (RTL)
Físico
- silício
Simulação/entrada - polígonos Mais detalhado
mais lenta
97
Níveis de Abstração
Alto Nível
Estrutural (Structural)
Comportamental
(Behavioral)
RTL
Nível de transistor
Baixo Nível
98
Níveis de Abstração: Exemplo
MUX
Comportamental
Estrutural
if sel == '0'
then
RTL out = IN1
else
out = IN2
case(sel)
'0': out = IN1
'1': out = IN2
99
Simulação Tradicional
• Aplica-se estímulos de baixo nível, proprietários e não
portáveis (ou seja, sinais específicos que não são facilmente
transferidos para outros sistemas ou ferramentas).
• Observa-se os resultados na exibição de formas de onda.
• Verifica-se manualmente se a funcionalidade e o tempo do
circuito estão corretos).
• Agora, vamos comparar isso com o uso de Verilog...
100
Simulação baseada em
Verilog
• Testbench de alto nível em
Verilog.
• Testbench escrito em
estilo comportamental.
• Interage-se com o design.
• Design escrito em
estilo RTL.
• Pode-se verificar
automaticamente a
funcionalidade do design.
• Portável entre ferramentas.
101
Estrutura Básica
• Começa com a palavra-chave module module_name
(port_list);
module e termina com a Declarações de porta
palavra-chave endmodule.
• Espaços em branco são Declarações de tipos de dados
utilizados para legibilidade.
Funcionalidade do circuito
• O ponto e vírgula é utilizado
para finalizar instruções. Especificações de tempo
• //: utilizado para comentar
endmodule
uma única linha.
Importante!
• /* */: utilizado para comentar O Verilog é case sensitive para
múltiplas linhas. identificadores
As palavras-chave são sempre
escritas com letra minúscula
102
Declaração de Portas
• Os módulos se comunicam através
de portas. module mult_acc
(out, ina, inb, clk,
• Declaração de portas: aclr);
103
Representando Hierarquia
Criação de hierarquia por:
• Instanciação de módulo(s).
• Conexão das portas do
módulo a portas ou nets
locais.
104
Instanciação de Módulos
Formato:
• <component_name> <instance_name> (port
list);
• <component name>
• O nome do módulo que será instanciado.
• <instance name>
• Nome da instância. Deve ser único dentro do módulo
superior.
• (port_list)
• Mapeamento explícito de portas (nome da porta no
módulo original conectado a um sinal ou variável no
módulo superior).
105
Conexão de Portas Nomeadas (Named Port
Connection)
• Especifica-se explicitamente
qual porta da instância está
mapeada para qual
porta/conexão local.
Dica:
Use conexão de
module fulladd (input a, b, cin, output sum, carry);
portas nomeadas
wire n_sum, n_carry1, n_carry2; para conectar
hierarquias
halfadd U1
(.a(a), .b(b), .sum(n_sum), .carry(n_carry1));
...
endmodule wire n_carry1
module halfadd (a, b, sum, do módulo
carry); fulladd mapeado
output sum, carry; para a saída carry
input a, b; do módulo
... halfadd
endmodule
106
Conexão de Portas Ordenadas (Ordered Port
Connection)
• Mapeia-se portas/conexões
locais para as portas de
instância por posição na
ordem que as portas são
declaradas.
module fulladd (input a, b, cin, output sum, carry);
input a do
wire n_sum, n_carry1, n_carry2; fulladd mapeada
halfadd U1 (a, b, n_sum, n_carry1);
para a input a do
... halfadd
input b do
endmodule fulladd mapeada
para a input b do
module halfadd (a, b, sum, halfadd
carry); Cuidado!
output sum, carry; Menos legível e mais propensa a
input a, b; erros do que a conexão de portas
... nomeadas
endmodule
107
Revisão
1. O que é Verilog e para que ele é utilizado?
2. Qual é o bloco básico de construção de um design em Verilog?
3. O que significa instanciar um módulo em Verilog?
4. Qual a diferença entre conexão ordenada e conexão nomeada
ao instanciar um módulo?
5. O que é um testbench e por que ele é importante?
6. Escreva o código para instanciar o seguinte módulo:
108
Relatório Prático
• Nesta aula, iremos aplicar os conceitos estudados
sobre Verilog - Introdução à Linguagem em exercícios
práticos, presentes no arquivo Relatórios Práticos – SD112
atividade A-004.
• O aluno deverá fazer todos os exercícios e enviar os arquivos
da resolução assinados com seu nome completo para o e-
mail [email protected];
• Assunto do e-mail: Relatório SD112 – Atividade A-004.
109
Página em branco.
110
Aula 6
Verilog – Tipos de Dados
O Sistema de Lógica de 4 Valores do
Verilog
Zero, baixo (low), falso, baixo lógico Um, alto (high), verdadeiro, alto
(logic low), terra (ground), VSS, negativo lógico (logic high), VDD, VCC, positivo
112
High-Z (Alta Impedância)
• Representa um estado de alta impedância no circuito.
• O circuito comporta-se como se estivesse desconectado,
sem conduzir corrente elétrica.
• Usado em barramentos de três estados (tri-state buses)
para evitar conflitos de sinal.
Quando ocorre?
• Drivers desativados: Quando todos os drivers do
barramento estão desligados.
• Portas não conectadas: Dados ou portas que não
possuem conexão física.
113
Conceito de Tipo de Dados
• Ao declarar uma variável, é necessário reg op;
especificar seu tipo. Caso a variável
tenha mais de um bit, também é Tipo reg Nome(s) da variável
preciso definir sua largura. module mux
(
• Exemplo: as portas de um módulo, por input a, b,
padrão, são fios (wire) de um único input sel,
bit. output reg op
);
• É possível especificar o tipo e a
always @(a or b or
largura, conforme necessário. sel)
• Existem regras que determinam o uso if (sel == 1)
op = a;
dos tipos de dados: else
op = b;
• Exemplo: atribuições procedurais só
podem ser feitas para tipos de registro endmodule
(register). a 1
op
• Tipos permitidos: integer, b 0
real, reg, time, realtime. sel
114
Tipos de Dados
• Tipo de dado net: representa a interconexão física
entre estruturas.
Bloco nets Bloco nets
nets
funcional: funcional:
Mux (nets) Adder (nets)
115
Tipos de Dado Net
Tipo Definição
wire Representa um nó ou conexão
tri Representa um nó de três estados
supply0 0 lógico
supply1 1 lógico
117
Tipos de Dados Variáveis
Tipo Definição
reg Variável sem sinal de qualquer tamanho
Utilize reg signed para implementação sinalizada
integer Variável com sinal de 32 bits
real* Armazena números de ponto flutuante
time* Variável inteira de 64 bits usada para representar o tempo de simulação
realtime* Variante de real, usada para medir tempos com ponto flutuante
119
Exemplo
DUT – Design Under Test
Inout port
module top;
wire ytop;
reg atop, btop; net module dut (
input a, b,
initial output y
begin
);
atop = 1'b0;
btop = 1'b0;
end assign y = a & b;
dut U1 endmodule
(.a(atop), .y(ytop), .b(btop));
endmodule
120
Parâmetros
• Um parâmetro é um valor constante definido em um módulo para
controlar certos aspectos do seu comportamento ou
configuração.
• Largura de bits, variáveis, delays, valores iniciais etc.
• Pode ser sobrescrito para cada instância individual.
• Os parâmetros do módulo não podem ser modificados durante a
execução – eles não são variáveis.
Sintaxe Verilog 1995 Sintaxe Verilog 2001
module mux (a, b, sel, module mux #(parameter WIDTH =
out); 2)(
parameter WIDTH = 2; input [WIDTH-1:0] a, b;
input [WIDTH-1:0] a, input sel;
b; output [WIDTH-1:0] out;
input sel; reg [WIDTH-1:0] out;
output [WIDTH-1:0] out; );
reg [WIDTH-1:0] out; ...
... endmodule
endmodule
121
Parâmetros
• Ao instanciar o módulo mux, pode-se utilizar o valor padrão
do parâmetro (2) ou modificá-lo conforme necessário para
atender aos requisitos do design.
// Sobrescrevendo o parâmetro
mux #(8) mux8
(.a(abus), .b(bbus), .sel(sel), .out(opbus);
122
Parâmetros
Parâmetros locais:
• localparam: idêntico aos parâmetros de módulo em
todos os aspectos, exceto pelo fato de não poder ser
sobrescrito.
• Usado para constantes que nunca devem ser sobrescritas
durante a instanciação.
parameter size = 8;
localparam outsize = 16;
reg [size-1:0] dataa, datab;
reg [outsize-1:0] out
...
123
Revisão
1. Qual é a principal diferença entre o tipo de dado net e
register (variável)?
2. O que significa declarar um sinal como inout em Verilog
e quando seria útil?
3. Quais são as implicações de declarar um sinal de porta de
módulo como wire ou reg?
4. Qual a principal diferença entre um parameter e um
localparam em Verilog e quando você deve usar cada
um?
124
Aula 7
Verilog – Tipos de Dados (cont.)
Relatório Prático
• Nesta aula, iremos aplicar os conceitos estudados
sobre Verilog – Tipos de Dados em exercícios práticos,
presentes no arquivo Relatórios Práticos – SD112 atividade
A-005.
• O aluno deverá fazer todos os exercícios e enviar os arquivos
da resolução assinados com seu nome completo para o e-
mail [email protected];
• Assunto do e-mail: Relatório SD112 – Atividade A-005.
126
Aula 8
Verilog – Operadores
Sistema de Numeração
• Valores numéricos são representados
como:
<size>'<base><value>
• size: número de bits.
…
• Números sem tamanho definido reg [3:0] zbus;
possuem, por padrão, 32 bits. …
zbus = 4'b1001; //1001
• base: pode ser b (binário), o zbus = 4'o05; //0101
(octal), d (decimal) ou h zbus = 4'd14; //1110
zbus = 4'h2f; //1111
(hexadecimal).
…
4'b1001 = 4'd9 =
4'o11.
• Números sem base definida são, por
padrão, decimais.
• value: qualquer número válido na
base escolhida (mais Z ou X, se for
binário, octal ou hexadecimal). 128
Sistema de Numeração
8'b1100_0001 Binário de 8 bits
64'hff01 Hexadecimal de 64 bits
9'o17 Octal de 9 bits
12 Base e tamanho não definidos (default: decimal de 32
bits)
'h83a Hexadecimal com tamanho não definido
32'bz z de 32 bits (x e z mais à esquerda são
automaticamente estendidos)
• Usa-se _ (underscore) para melhorar a legibilidade.
• Números negativos são especificados colocando-se um sinal de
menos antes do <size>.
• Correto: -8'd3 = Número negativo de 8 bits armazenado
como complemento de 2 de 3.
• Incorreto: 4'd-2 = ERROR!
129
Extensão Automática de
Números
• A base numérica utilizada
define quantos bits cada dígito reg [7:0] a;
reg [11:0] b;
representa: initial
• Um bit (binário) begin
// 0 passing contents of
• Três bits (octal) a
a = 8'h11; // 00010001
• Quatro bits (hexadecimal) a = 8'b11; // 00000011
a = 8'd11; // 00001011
• Se o bit mais significativo for a = 8'h01; // 00000001
um X ou Z, esse valor será a = 8'h10; // 00010000
estendido à esquerda para a = 0; // 00000000
pelo menos 32 bits.
// z padding contents of
• Verilog-2001: estende até b
a largura da expressão. b = 12'hzzz; //
zzzzzzzzzzzz
b = 12'hz; //
zzzzzzzzzzzz
b = 12'h0z; //
00000000zzzz
130
b = 12'hz0; //
Vetores
• Um vetor é um net ou reg com uma largura de dois ou mais bits.
• A largura é especificada ao declarar a variável:
[left position : right position]
• A convenção é utilizar [msb:lsb], e.g., [3:0].
module mux4 (
input wire [3:0] a, b, Vetor wire de 4 bits
input wire sel,
output reg [3:0] op
);
Vetor reg de 4 bits
always @ (a or b or sel)
if (sel == 1)
op = a;
else
op = b;
endmodule
131
Atribuição de Vetores e Ordem de Bits
• Os elementos de um vetor podem ser acessados
pela posição.
input [3:0] inp; reg [3:0] ibus;
output [3:0] reg [3:0] obus;
outp;
assign outp = obus = ibus;
inp;
outp[3 inp[3] obus[3 ibus[3
]
outp[2 inp[2] ]
obus[2 ]
ibus[2
]
outp[1 inp[1] ]
obus[1 ]
ibus[1
]
outp[0 inp[0] ]
obus[0 ]
ibus[0
] ] ]
132
Atribuição de Vetores e Ordem de Bits
assign outp[3] =
inp[0];
outp[3 inp[3]
]
outp[2 inp[2]
]
outp[1 inp[1]
]
outp[0 inp[0]
]
• Os elementos são acessados com base em sua posição, e
não pelo número do elemento — utilize o vetor de acordo
com a forma como ele foi declarado.
133
Atribuição de Vetores e
Largura de Bit
• As larguras dos vetores não precisam coincidir em uma atribuição.
• Se o vetor de origem for maior que o vetor de destino, ele
será truncado. Isso significa que os bits mais significativos
(MSB) do vetor de origem serão descartados para que o
tamanho do vetor de origem se ajuste ao tamanho do vetor
de destino.
• Se o vetor de origem for menor que o vetor de destino, o
vetor de destino será preenchido com 0 a partir dos bits
mais significativos (MSB) até atingir o tamanho necessário.
• Isso pode resultar em um comportamento indesejado, portanto, é
uma boa prática de codificação garantir que as larguras dos
vetores de destino e origem coincidam.
• Pode-se utilizar fatias (slices) e o operador de concatenação { }
para ajustar as larguras dos vetores de maneira mais flexível.
134
Atribuição de Vetores e
Largura de Bit
reg [3:0] zbus; // Vetor de 4
bits
reg [5:0] widebus; // Vetor de 6
bits
zbus = widebus =
widebus; zbus;
widebus[5 widebus[5 0
]
widebus[4 ]
widebus[4 0
zbus[3 ]
widebus[3 ]
widebus[3 zbus[3]
]
zbus[2 ]
widebus[2 ]
widebus[2 zbus[2]
]
zbus[1 ]
widebus[1 ]
widebus[1 zbus[1]
]
zbus[0 ]
widebus[0 ]
widebus[0 zbus[0]
] ] ]
slice concatenation
zbus = widebus = {2'b00,
widebus[3:0]; zbus};
135
Operadores Aritméticos
Símbolo do Operador Funcionalidade module arithops;
// Constantes locais Verilog-2001
+ Adicionar, positivo
localparam integer CONST_INT = -3
- Subtrair, negativo CONST_5 = 5;
localparam [3:0] rega = 3,
* Multiplicar regb = 4'b1010,
regc = 14;
/ Dividir
integer val;
% Módulo reg [3:0] num;
** Expoente initial
begin
• integer é com sinal. val = CONST_5 * CONST_INT; // -
15
• reg é sem sinal . val = (CONST_INT + 5)/2; // 1
• Verilog-2001 – pode-se val = CONST_5/CONST_INT; // -
1
declarar um reg com sinal. num = rega + regb; //
• Verilog-2001 – pode-se 1101
num = rega + 1; //
converter um valor com 0100
sinal e sem sinal utilizando 1101
num = CONST_INT; //
endmodule 136
Operadores Bit a Bit (Bit-wise)
Símbolo do Operador Funcionalidade
module bitwise;
~ NOT (bit a bit) reg [3:0] rega, regb, regc;
& AND (bit a bit) reg [3:0] num;
val = ^CONST_B; // 0
val = ~|
CONST_A; // 0
val = 139
~&CONST_A; // 1
Operadores de Deslocamento
Símbolo do Operador Funcionalidade module shift ();
reg [7:0] rega =
<< Deslocamento lógico 8'b10011001;
para a esquerda reg [7:0] regb;
>> Deslocamento lógico
para a direita initial
<<< Deslocamento aritmético begin
para a esquerda regb = rega << 1;
// 00110010
>>> Deslocamento aritmético regb = rega >> 1;
para a direita // 01001100
regb = rega << -1;
// 00000000
end -1 é 2**32-1
endmodule
• Realizam deslocamentos de bits para a esquerda ou direita.
• Deslocamentos para a esquerda (lógico ou aritmético): posições vazias preenchidas com 0.
• Deslocamentos para a direita:
• Lógico: posições vazias preenchidas com 0
• Aritmético (sem sinal): posições vazias preenchidas com 0
• Aritmético (com sinal): posição vazia preenchida com o valor de sinal do bit valor do
MSB.
• Os bits deslocados são perdidos.
140
Operadores Relacionais
module relationals;
Símbolo do Operador Funcionalidade
reg [3:0] rega, regb,
> Maior que regc;
reg val;
< Menor que
>= Maior ou igual initial
begin
<= Menor ou igual
rega = 4'b0011;
regb = 4'b1010;
• Utilizados para comparar valores. regc = 4'b0x10;
• O resultado é: val = regc > rega;
• 1'b1 se a condição for // val = x
verdadeira; val = regb < rega;
// val = 0
• 1'b0 se a condição for falsa; val = regb >= rega;
• 1'bx se a condição não puder // val = 1
val = regb > regc;
ser resolvida. // val = x
end
endmodule
141
Operadores de Igualdade
Símbolo do Operador Funcionalidade
module equalities ();
== Igualdade reg [3:0] rega, regb, regc;
reg val;
!= Desigualdade
=== Igualdade estrita initial
begin
!== Desigualdade estrita rega = 4'b0011;
regb = 4'b1010;
• Utilizados para comparar valores. regc = 4'b1x10;
module concatenation;
reg [7:0] rega, regb, regc, regd, new;
... reg [3:0] nib1, nib2;
wire out3;
reg out1, out2; initial
begin
rega = 8'b00000011;
always @ (a or b or sel) regb = 8'b00000100;
out1 = sel ? a : b; regc = 8'b00011000;
regd = 8'b11100000;
always @ (a or b or sel) new = {regd[6:5], regc[4:3],
if (sel) regb[3:0]};
out2 = a; // new = 8'b11_11_0100
else new = {2'b11, regb[7:5], rega[4:3],
1'b1};
out2 = b; // new = 8'b11_000_00_1
new = {regd[4:0], regd[7:5]};
assign out3 = sel ? a : // rotate regd right 3 places
b; // new = 8'b00000_111
{nib1, nib2} = rega;
... //nib1 = 4'0000, nib2 = 4'0011
end
endmodule
143
Outros Operadores
Símbolo do Operador Funcionalidade
{ { } } Replicar
module replicate ();
reg rega;
reg [1:0] regb;
• A replicação permite que reg [3:0] regc;
reg [7:0] bus;
você reproduza uma variável initial
begin
dimensionada um número rega = 1'b1;
regb = 2'b11;
determinado de vezes. regc = 4'b1001;
144
Prioridade de Operadores
Tipos de Operadores Símbolos
Alta
Concatenação/Replicação { } { { } }
Inversão (Lógica/Bit a Bit/Aritmética) ! ~ + -
Exponencial **
Aritmética * / %
+ - (binária)
Deslocamento << >> <<< >>>
145
Revisão
1. Quantos bits tem o resultado de uma operação lógica &&?
2. Reescreva a seguinte instrução utilizando um número
hexadecimal: aval = 8'b11010011
3. O que é necessário garantir ao replicar valores com o
operador de replicação?
4. Dado o seguinte código "regx = 4'b0101;", qual é
o valor de "bus = { 2{regx[3:1], {3{1'b0,
regx[0]}}} };"?
5. Se regb for definido como um número assinado de 4 bits
conforme abaixo, forneça o código para uma divisão
aritmética binária por dois. Dica: o bit de sinal (ou bit mais
significativo) deve permanecer intacto.
reg [3:0] regb;
146
Aula 9
Verilog – Operadores (cont.)
Relatório Prático
• Nesta aula, iremos aplicar os conceitos estudados
sobre Verilog – Operadores em exercícios práticos,
presentes no arquivo Relatórios Práticos – SD112 atividade
A-006.
• O aluno deverá fazer todos os exercícios e enviar os arquivos
da resolução assinados com seu nome completo para o e-
mail [email protected];
• Assunto do e-mail: Relatório SD112 – Atividade A-006.
148
Aula 10
Verilog – Declarações Processuais
e Contínuas
Declarações Contínuas (Continuous
Assignment)
Modela o comportamento de lógica
combinacional utilizando expressões
e operadores. /*implicit continuous assignment*/
wire [15:0] adder_out = mult_out +
1. O lado esquerdo da expressão out;
(left-hand side – LHS) deve ser é equivalente a
um dado do tipo net.
wire [15:0] adder_out;
2. Sempre ativo: quando um dos assign adder_out = mult_out +
operandos do lado direito da out
expressão (right-hand side –
RHS) muda, a expressão é
avaliada e o net LHS é
atualizado imediatamente.
3. O RHS pode ser net, register ou
funções. assign #5 adder_out = mult_out +
4. Valores de delay podem ser out
atribuídos para modelar
atrasos de portas lógicas.
150
Declarações Processuais (Procedural
Assignments)
…
Existem dois tipos de blocos reg a, b, zor, zand;
processuais
initial
• always: executa begin
a = 1'b1;
repetidamente ao longo da b = 1'b0; Verilog-2001:
simulação, sendo acionado end
Lista de eventos
por uma mudança no valor de always @* com operador
qualquer variável na lista de begin "coringa"
eventos. if (a | b)
zor = 1'b1;
• initial: executa apenas else
zor = 1'b0;
uma vez no início da
simulação. if (a & b)
zand = 1'b1;
• É necessário agrupar várias else
Blocos initial
instruções dentro de um bloco zand = 1'b0;
não são
end
usando begin...end. ... sintetizáveis.
151
Declarações Processuais (Procedural
Assignments)
• Atribuições feitas dentro
de blocos processuais module fulladder (
são chamadas de input a, b, cin,
output reg [1:0] out
atribuições processuais );
(procedural
reg sum, carry;
assignments).
always @(a, b, cin)
begin
• Todas as variáveis no sum = a ^ b ^ cin;
carry = (a & b) | cin & (a ^
lado esquerdo (LHS) b);
devem ser do tipo de out = {carry, sum};
end
dado register (por
exemplo, reg). endmodule
152
Lista de Eventos (Event List)
Lista de eventos construída
• Um evento é qualquer transição utilizando o operador or
dos sinais especificados. always @(a or b or sel)
if (sel == 1)
• O processo é reiniciado quando um op = a;
else
evento na lista de eventos ocorre. op = b;
• O Verilog-2001 adicionou os Lista de eventos construída
operadores vírgula e "coringa". utilizando o operador ','
always @(a, b, sel)
• O operador "coringa" adiciona if (sel == 1)
todos os sinais que entram no op = a;
else
bloco e em qualquer função op = b;
chamada a partir do bloco. Lista de eventos construída
• Nota: Parênteses são opcionais utilizando o coringa '*'
always @(*)
para expressões de evento if (sel == 1)
compostas por um único token. op = a;
else
op = b;
153
Tipos de Processo
Processo Combinacional
• Sensível a todas as entradas utilizadas na lógica combinacional.
A lista de eventos inclui
always @(a, b, sel)
todas as entradas
always @*
usadas na lógica
combinacional.
154
Blocos Processuais no Verilog
module design;
wire nsela;
// continuous statements
…
endmodule
155
Comando if
module if_example (
• if é um comando input [3:0] a, b, c, d,
condicional. );
output reg [3:0] y
• A condição é uma
always @(a or b or c or d)
expressão booleana. if (d == 4'b0000)
y = a;
• Cada condição do if else if (d <= 4'b0101)
é testada em y = b;
else
sequência. y = c;
• O primeiro teste válido endmodule
executa aquele ramo.
Estrutura de
• As condições podem se hardware inferida
sobrepor.
If sintetiza
em estruturas
de mux
156
Sintaxe do Comando If
if (CONDITION) begin • Comandos if únicos executam
// procedural instruções processuais apenas se
statements a condição for verdadeira...
end
if (CONDITION) begin
• ...adicione um else incondicional
// procedural para executar instruções
statements processuais quando a condição do
end
else begin
if for falsa...
// procedural • ...adicione else if para testar
statements
end outras condições caso a primeira
if (CONDITION) begin seja falsa.
// procedural
statements • O else final é opcional e pode
end ser usado para indicar uma
else if (CONDITION) begin operação padrão.
// procedural
statements • Use begin e end para delimitar
end
else begin
múltiplas instruções processuais.
// procedural
statements 157
Comando case
• case é um comando
condicional de múltiplas vias. module case_example (
input [3:0] a, b, c,
• A expressão do case é d,
avaliada e comparada com output reg [3:0] y
cada item em sequência. );
159
Comandos casex e casez
• casex trata x, ? e z casex (encoder)
4'b1xxx : high_lvl = 3;
como "don't cares" ao 4'b01xx : high_lvl = 2;
4'b001x : high_lvl = 1;
invés de valores lógicos. 4'b0001 : high_lvl = 0;
default : high_lvl = 0;
endcase
Se encoder = 4'b1z0x,
então high_lvl = 3
casez (encoder)
• casez trata ambos z e ? 4'b1??? : high_lvl
4'b01?? : high_lvl
=
=
3;
2;
como "don't cares". 4'b001? : high_lvl
4'b0001 : high_lvl
=
=
1;
0;
default : high_lvl = 0;
endcase
Se encoder = 4'b1z0x,
então high_lvl = 3
160
Comando case Alternativo
module finscase (
input [3:0] a, b, c, • Um case item também
d, pode ser uma expressão.
input x, y,
output reg [3:0] op • É possível usar case para
);
verificar os valores de
always @* várias variáveis ao mesmo
case (1'b1) tempo.
x : op = a;
y : op = b; • Os itens são priorizados de
(c==d) : op = c;
default : op = d;
acordo com a ordem.
endcase
endmodule
161
Comandos em Loop: for
• O for é iterado no loop por um número especificado
de vezes.
• A variável de loop deve ser declarada.
• Quando o loop é executado:
• A variável de loop é inicializada.
• A(s) instrução(ões) do loop é(são) executada(s).
• A operação do loop é realizada.
• Quando a condição for falsa, o loop é encerrado.
162
Comandos em Loop: for
module parity (
input wire [3:0] a,
output reg odd
);
integer i;
reg tmp;
always @ a
begin // Expansão do loop for
tmp = 0; tmp = 0 ^ a[0]; // =
for (i = 0; i <= 3; i = i + a[0]
1) tmp = tmp ^ a[1];
tmp = tmp ^ a[i]; tmp = tmp ^ a[2];
odd = tmp; tmp = tmp ^ a[3];
end
O padrão de síntese
endmodule oferece suporte a loops
com limites constantes.
163
Comandos em Loop: repeat
module multiplier ( • O loop repeat executa
input [3:0] op_a, op_b,
output reg [7:0] result um bloco de declarações
); processuais um número
reg [7:0] shift_opa;
determinado de vezes,
reg [3:0] shift_opb; conforme especificado
always @(op_a, op_b)
pelo valor ou expressão
begin entre parênteses.
result = 0;
shift_opa = op_a; // Zero extend • Se uma variável isolada
left for usada na expressão
shift_opb = op_b;
repeat (4) de um loop repeat, o
begin valor da variável dita o
if (shift_opb[0])
result = result + shift_opa;
número de vezes que o
shift_opa = shift_opa << 1; \\ loop será executado.
left
shift_opb = shift_opb >> 1; \\ repeat (count)
right
end // executa o número
end de vezes = valor de
count 164
endmodule
Comandos em Loop: while
... • O loop while executa
while (count < 10) um bloco de declarações
begin
// statements procedurais enquanto
count = count + 1; sua expressão for
end verdadeira (ou diferente
... de zero). Se a expressão
... for inicialmente falsa, as
reg [7:0] tempreg; declarações não são
reg [3:0] count;
...
executadas.
// Count the ones in tempreg • Se uma variável isolada
count = 0;
while (tempreg) // tempreg = 8 for usada na expressão
begin de um loop while, o
if (tempreg[0]) tamanho da variável
count = count + 1;
tempreg = tempreg >> 1; // Shift determina o número de
right vezes que o loop será
end executado.
...
165
Sintaxe dos Comandos em
Loop
Comandos em Loop: // Variável de loop deve ser
declarada
• O loop for requer a declaração for (initial; condition;
de uma variável de loop. inc_dec)
begin
• O loop while continua // statements
enquanto a condição for end
while (condition)
verdadeira. begin
// statements
• O loop repeat itera o número end
de vezes definido pela expressão.
• O loop forever executa repeat (expression)
begin
indefinidamente. // statements
O padrão de síntese não end
suporta forever, repeat
e while. Use-os apenas em forever
testbenches e modelos de begin
simulação. // statements
end
166
Revisão
1. Se mais de uma condição de uma instrução
if...else for verdadeira, qual condição tem
prioridade?
2. As instruções if, case e for são contínuas ou
processuais?
3. Codifique a seguinte lógica condicional:
167
Página em branco.
168
Aula 11
Verilog – Declarações Processuais
e Contínuas (cont.)
Relatório Prático
• Nesta aula, iremos aplicar os conceitos estudados
sobre Verilog – Declarações Processuais e Contínuas em
exercícios práticos, presentes no arquivo Relatórios Práticos
– SD112 atividade A-007.
• O aluno deverá fazer todos os exercícios e enviar os arquivos
da resolução assinados com seu nome completo para o e-
mail [email protected];
• Assunto do e-mail: Relatório SD112 – Atividade A-007.
170
Aula 12
Verilog – Declarações Blocking
e Non-Blocking
Tipos de Atribuições
Processuais
• Declaração blocking (=): É executada imediatamente, ou seja, o
valor é atribuído à variável antes que as instruções seguintes
sejam processadas. É geralmente usada em blocos
combinacionais e segue uma execução sequencial, onde cada
linha deve ser concluída antes da próxima ser executada.
Assumindo inicialmente a = 1 e b = 2
173
Ciclo de Simulação
module sim_ex(
input a,
output reg m, y, w
);
always @(a or m)
begin:P1
m <= a;
y <= m;
end
always @(m)
begin: P2
w <= m;
• Assuma que a, m, y e end
w são todos 1'b0. endmodule
• a muda de valor de 1'b0
a : 0
para 1'b1. Valores das
m : 0
variáveis no
y : 0
começo:
w : 0
174
Ciclo de Simulação
module sim_ex(
input a,
output reg m, y, w
);
always @(a or m)
begin:P1
m <= a;
y <= m;
end
always @(m)
begin: P2
w <= m;
• a foi atualizado de 1'b0 para 1'b1. end
• O processo P1 é executado.
endmodule
• Atualização de m agendada.
• Nenhuma alteração no valor de y. Valores das
a : 1
m : 0
variáveis no
y : 0
começo:
w : 0
175
Ciclo de Simulação
module sim_ex(
input a,
output reg m, y, w
);
always @(a or m)
begin:P1
m <= a;
y <= m;
end
always @(m)
begin: P2
w <= m;
• m muda de valor para 1'b1. end
• O processo P1 é colocado na
endmodule
lista de agendamento.
• O processo P2 é colocado na a : 1
Valores das m : 1
lista de agendamento. variáveis depois y : 0
de um delta: w : 0
176
Ciclo de Simulação
module sim_ex(
input a,
output reg m, y, w
);
always @(a or m)
begin:P1
m <= a;
y <= m;
end
always @(m)
begin: P2
• Os processos P1 e P2 são w <= m;
end
executados (em ordem aleatória).
• Atualizações para y e w são endmodule
agendadas. a : 1
Valores das
• Nenhuma mudança no valor de m. m : 1
variáveis depois y : 0
de um delta: w : 0
177
Ciclo de Simulação
module sim_ex(
input a,
output reg m, y, w
);
always @(a or m)
begin:P1
m <= a;
y <= m;
end
always @(m)
begin: P2
• Y e w são atualizados para 1'b1. w <= m;
end
• Não há mais processos para
serem executados. endmodule
a : 1
Valores das m : 1
variáveis depois y : 1
de dois deltas: w : 1
178
Ciclo de Simulação: Resumo
a : 0
Valores das
m : 0
variáveis no module sim_ex(
y : 0 input a,
começo:
w : 0 output reg m, y, w
);
Lista de Eventos das Agendamento Valores das
Variáveis de Processos Variáveis
always @(a or m)
a <= 1 P1 a : 1 begin:P1
m : 0 m <= a;
y : 0 y <= m;
w : 0 end
179
Ciclo Delta e Tempo de
Simulação
• Vários ciclos delta ocorrem em cada ponto no tempo de
simulação.
• É possível especificar o tempo de execução dentro dos
blocos processuais utilizando três tipos de controle de
tempo:
• Controle de tempo sensível à borda (edge): @
• Atrasos simples: #
• Controle de tempo sensível ao nível: wait
O padrão de síntese
não suporta wait.
180
Declarações Blocking vs. Non-blocking
always @(posedge clk) always @(posedge clk)
begin begin
x = next_x; x <= next_x;
end end
Mesmo
comportamento
Comportamento
diferente
181
Declaração Blocking em Processos
Sequenciais
Declarações do tipo blocking podem levar a
“race conditions” quando: initial
begin
• Múltiplos processos são acionados pelo avar = 1'b1;
mesmo evento, de forma que... bvar = 1'b1;
end
• Um processo pode ler uma variável que
outro processo “simultaneamente” escreve. always @(posedge
clock)
Exemplo: bvar = avar + 1'b1
• Ambos os processos são executados na
always @(posedge
borda positiva do clock.
clock)
• Declarações blocking para bvar e cvar são cvar = bvar;
concluídas imediatamente após a execução
das instruções. Importante!
Os processos podem
• Mas qual instrução será executada primeiro?
ser executados em
• O valor de cvar depende de qual qualquer ordem.
procedimento é executado primeiro.
182
Declaração Non-blocking em Processos
Sequenciais
• Declarações non-blocking
evitam "race conditions".
• Exemplo: initial
begin
• Ambos os processos são avar = 1'b1;
bvar = 1'b1;
executados na borda positiva end
do clock. always @(posedge
• As atribuições para bvar e clock)bvar <= avar + 1'b1
cvar são agendadas.
always @(posedge
• A atribuição para cvar clock)
cvar <= bvar;
utiliza o valor de bvar antes
da borda de subida do clock.
183
Código Dependente da
Posição
• Declarações blocking em processos sequenciais podem
resultar em códigos dependentes de posição.
always @(posedge always @(posedge
clk) clk)
begin begin
b = a; d = c;
c = b; c = b;
d = c; b = a;
end end
184
Lógica Combinacional
always @(a or b) always @(a or b or m or n)
begin begin: P1
m = a; m <= a;
n = b; n <= b;
p = m + n; p <= m + n;
end end
• As declarações non-blocking
podem ser ineficientes para lógica
combinacional. Lista de Eventos Agendamento
de Variáveis de processos
• Especificamente, quando a lógica
contém comportamento serial ou a <= 1 P1
variáveis intermediárias: b <= 2
• Variáveis intermediárias m <= 1 P1
precisam ser adicionadas à lista n <= 2
de eventos. p <= 3
• O procedimento levará vários
ciclos delta para atingir o
“estado estável”.
185
Regra Prática
186
Revisão
1. Qual é a principal diferença entre atribuições
blocking e non-blocking?
2. Onde você deve usar atribuições non-blocking?
3. Onde você deve usar atribuições blocking?
187
Página em branco.
188
Aula 13
Verilog – Declarações Blocking e
Non-Blocking (cont.)
Relatório Prático
• Nesta aula, iremos aplicar os conceitos estudados
sobre Verilog – Declarações Blocking e Non-blocking em
exercícios práticos, presentes no arquivo Relatórios Práticos
– SD112 atividade A-008.
• O aluno deverá fazer todos os exercícios e enviar os arquivos
da resolução assinados com seu nome completo para o e-
mail [email protected];
• Assunto do e-mail: Relatório SD112 – Atividade A-008.
190
Aula 14
Verilog – Reset síncrono e
assíncrono
Reset Síncrono
• O reset síncrono (synchronous module synchronous_reset_test
reset) é um tipo de reset que é (
acionado por um sinal de clock. Ou input clk, reset,
seja, o reset ocorre apenas em uma in1,
borda específica do clock (borda de output reg out1
subida ou de descida). );
192
Reset Síncrono
Vantagens:
• Circuito completamente síncrono: O reset é acionado e
propagado de forma controlada em relação ao clock, garantindo
que todos os elementos do circuito sejam inicializados de forma
sincronizada.
• Menor chance de comportamento indesejado, como glitches ou
condições de corrida, pois o reset é controlado pelo clock.
• Mais fácil de prever o comportamento do circuito.
Desvantagens:
• Pode exigir mais lógica e recursos, pois precisa ser sincronizado
com o clock.
• O sinal de reset precisa ser estendido, caso não seja longo o
suficiente para ser capturado pela borda ativa do clock.
• A resposta ao reset é retardada em uma borda de clock, o que
pode ser uma limitação em sistemas de alta velocidade.
193
Reset Assíncrono
194
Reset Assíncrono
Vantagens:
• Resposta mais rápida ao reset, pois não depende
do clock. O sistema é resetado imediatamente
quando o sinal de reset é ativado.
• Útil em situações onde a inicialização rápida do
sistema é necessária, como em sistemas de
recuperação de falhas.
Desvantagens:
• Pode causar problemas de sincronização, como
glitches e condições de corrida.
• Pode ser mais difícil de prever e controlar,
especialmente em sistemas complexos.
195
Reset Síncrono vs. Assíncrono
Síncrono Assíncrono
module dff_sync ( module dff_sync (
input d, clk, sclr, input d, clk, aclr,
spre output reg q
output reg q );
);
always @(posedge clk,
always @(posedge clk) posedge aclr)
begin begin
if (sclr) if (aclr)
q <= 1'b0; q <= 1'b0;
else if (spre) else
q <= 1'b1; q <= d;
else end
q <= d;
end endmodule
endmodule
196
Reset Síncrono vs. Assíncrono
• O reset síncrono é preferido quando a precisão e a
previsibilidade são cruciais, como em sistemas de
alta frequência.
• O reset assíncrono pode ser útil em situações onde
o tempo de resposta rápido é mais importante que
a sincronização precisa.
• Em alguns sistemas, pode ser tentador usar tanto
resets síncronos quanto assíncronos. No entanto,
isso exige cuidados extras para evitar conflitos e
problemas de sincronização.
197
Revisão
1. Quais são as diferenças entre reset síncrono e
assíncrono?
2. Quais são as vantagens do reset síncrono?
3. Quais são as vantagens do reset assíncrono?
4. Explique com suas palavras a diferença da
implementação, em nível de código, de um reset
síncrono e assíncrono.
198
Relatório Prático
• Nesta aula, iremos aplicar os conceitos estudados
sobre Verilog – Reset Síncrono e Assíncrono em exercícios
práticos, presentes no arquivo Relatórios Práticos – SD112
atividade A-009.
• O aluno deverá fazer todos os exercícios e enviar os arquivos
da resolução assinados com seu nome completo para o e-
mail [email protected];
• Assunto do e-mail: Relatório SD112 – Atividade A-009.
199
Página em branco.
200
Aula 15
Verilog – Estilos de Códigos
Boas Práticas de
Implementação
Comentários em Verilog
1. Linha única:
Representados com “//”.
Qualquer texto à direita de // é ignorado pelo compilador.
Exemplo:
// Este é um comentário de linha única
input a, b; // Comentário ao final da linha de
código
2. Bloco:
Representados com “/* */”:
Permitem comentários em várias linhas, mas não podem ser
alinhados.
Exemplo:
/* Este é um comentário
que ocupa várias linhas
*/
202
Boas Práticas de
Implementação
Objetivo dos comentários
1. Ajudar no entendimento do código, especialmente para
leitores futuros.
2. Melhorar a comunicação entre desnvolvedores.
3. Esclarecer intenções em partes mais complexas do
código.
Evite comentários óbvios ou desnecessários, como:
// Multiplica a e b e atribui
a c
c = a * b;
204
Boas Práticas de
Implementação
Espaçamento e Organização
2. Indentação e quebra de linhas:
always @ (a or
b)
if (a > b)
op = a;
else
op = b;
205
Boas Práticas de
Implementação
Regras de Nomes de Identificadores
• Identificadores podem conter caracteres alfanuméricos
(a–z, A–Z, 0–9), incluindo o símbolo do dólar $ e o
sublinhado _.
• Exemplos válidos:
• unit_32, structural, bus_16_bits, a$b.
206
Boas Práticas de
Implementação
Case Sensitive
• O Verilog diferencia entre maiúsculas e minúsculas (case
sensitive).
207
Boas Práticas de
Implementação
• Exemplos inválidos:
• unit@32, 16_bit_bus.
• Não há um limite estrito para o comprimento do nome,
mas ferramentas específicas podem restringir esse
tamanho.
208
Boas Práticas de
Implementação
Palavras-chave
• Palavras-chave em Verilog devem ser em minúsculas e não
podem ser usadas como identificadores. (ex.: module,
wire).
209
Boas Práticas de
Implementação
Identificadores Escapados (Escape Identifiers)
• Permitem o uso de caracteres especiais ou nomes não
convencionais.
• Exemplos:
• \unit@32, \16-bit-bus.
210
Boas Práticas de
Implementação
Recomendações
• Evitar o uso de palavras-chave como identificadores, mesmo
que tecnicamente permitido.
211
Boas Práticas de
Implementação
Compatibilidade e Ferramentas
• Identificadores escapados são úteis para lidar com
bibliotecas que exigem formatos específicos de nomes (ex.:
nomes de células de tecnologia que especificam o número
de entradas como 2nand, 4or).
Recomendações
• Para a maioria dos casos, use identificadores convencionais.
• Identificadores escapados devem ser a última alternativa,
sendo aplicáveis apenas em cenários de compatibilidade
técnica.
212
Boas Práticas de
Implementação
Latches
• Um latch é um elemento de memória simples que armazena
o estado de um sinal. Ele é transparente, ou seja, enquanto
o enable está ativo, o latch continua atualizando seu estado
com base no sinal de entrada. Quando o enable é
desativado, o latch mantém o último valor da entrada.
213
Boas Práticas de
Implementação
Evitando latches indesejados
• Falta de uma condição “else” em blocos combinacionais:
Quando uma variável não recebe valor para todas as condições
possíveis, um latch é inferido para armazenar o valor da variável
até que uma nova condição seja atendida.
Errado:
always @ (*) begin
if (enable)
out = data; // Não há valor definido para 'out' quando
enable = 0
end
Correto:
always @ (*) begin
out = 0; // Valor
padrão
if (enable)
out = data;
end
214
Boas Práticas de
Implementação
Evitando latches indesejados
Uso inadequado de lógica combinacional para memória: Descrever
memória sem utilizar flip-flops pode levar à criação de latches. No
exemplo abaixo, memory[address] depende de write_enable,
mas não há clock, o que faz com que a ferramenta infira um latch. Uma
boa prática é a utilização de um bloco sensível ao clock para descrever a
memória.
Errado:
always @ (*) begin
if (write_enable)
memory[address] = data; // Latch será inferido para
'memory[address]'
end
Correto:
always @ (posedge clk) begin
if (write_enable)
memory[address] <=
data;
end
215
Boas Práticas de
Implementação
Evitando latches indesejados
Lógica de seleção parcial (case incompleto): Ao usar um bloco “case”
sem cobrir todas as possibilidades, um latch será gerado para armazenar o
valor anterior. Uma boa prática é lidar com todas as condições possíveis,
incluindo o default.
always @ (*) begin
case (sel)
2'b00: out = a;
Errado: 2'b01: out = b;
// Outros valores de 'sel' não são
especificados
endcase
end
always @ (*) begin
case (sel)
2'b00: out = a;
Correto: 2'b01: out = b;
default: out = 0; // Valor padrão
endcase
end
216
Revisão
1. Qual a diferença entre a utilização de comentários com
“//” e “/* */” ?
2. Qual é o impacto da má organização no entendimento do
código?
3. Como garantir que um bloco case não gere latches
indesejados?
4. Por que é importante lembrar que Verilog é case
sensitive?
217
Relatório Prático
• Nesta aula, iremos aplicar os conceitos estudados
sobre Verilog – Estilos de Código em exercícios práticos,
presentes no arquivo Relatórios Práticos – SD112 atividade
A-010.
• O aluno deverá fazer todos os exercícios e enviar os arquivos
da resolução assinados com seu nome completo para o e-
mail [email protected];
• Assunto do e-mail: Relatório SD112 – Atividade A-010.
218
Aula 16
Verilog - Descrição RTL
Níveis de Abstração
MUX
Comportamental
RTL (Register Transfer Estrutural
if sel == '0'
Level) then
out = IN1
else
out = IN2
case(sel)
'0': out = IN1
'1': out = IN2
220
Descrição RTL
• Descrição RTL, ou Register-Transfer Level, é um
nível de abstração onde os circuitos são descritos
em termos de registros e fluxo de dados entre eles.
• A descrição especifica como os dados são
transferidos de um registrador para outro, como
são processados e como os sinais de controle são
gerados para controlar o fluxo de dados e as
operações dentro do circuito.
221
Descrição RTL
• A imagem abaixo destaca o papel central da Descrição RTL
no processo de design de circuitos digitais, conectando a
abstração comportamental à implementação física do
hardware.
222
Por que o código é RTL?
1. Descrição em Termos de Operações em Portas e Sinais:
• O código descreve operações lógicas e conexões entre sinais, caracterizando o
nível RTL ao detalhar a lógica sem descer ao nível de transistores ou portas
básicas.
2. Uso de Operações Combinatórias:
module or_nand_1 (
• As operações or e nand são utilizadas input enable, x1, x2, x3,
para determinar os sinais intermediários x4,
(w1, w2, w3) e a saída (y), output logic y
);
caracterizando a lógica combinatória
logic w1, w2, w3;
típica de RTL, sem referências ao nível
estrutural do hardware. or (w1, x1, x2);
3. Abstração RTL: or (w2, x3, x4);
or (w3, x3, x4); //
• Não é puramente comportamental, pois Redundante
define explicitamente as portas e sinais nand (y, w1, w2, w3,
usados, nem estrutural, já que utiliza enable);
operadores lógicos em vez de instanciar endmodule
componentes ou portas físicas
diretamente.
223
Descrição RTL
module mux_2x1_rtl1(
• Exemplo MUX 2x1: input in1, in2, select,
output out
);
wire n_select, and1, and2;
224
Descrição RTL
• Exemplo:
module combinational_circuit (
input A, B, C, // Entradas do circuito
output S // Saída do circuito
);
// Operações intermediárias
assign and_out = A & B; // Porta AND entre A e B
assign not_c = ~C; // Inversão do sinal C
assign not_and_out = ~and_out; // Inversão da saída da porta AND
assign or_out1 = not_and_out | not_c; // Porta OR entre ~AND e ~C
assign not_or_out1 = ~or_out1; // Inversão da saída da porta OR1
assign not_b = ~B; // Inversão do sinal B
assign or_out2 = not_or_out1 | not_b; // Porta OR entre o resultado anterior e
~B
// Saída final
assign S = ~(or_out2);
endmodule
225
Revisão
1. O que é o RTL (Register Transfer Level) em
Verilog?
2. Quais são os três principais níveis de abstração
usados na descrição de circuitos?
3. Qual é o papel dos blocos assign na descrição
RTL?
4. No exemplo do MUX 2x1, como o seletor (select)
determina a saída (out)?
226
Relatório Prático
• Nesta aula, iremos aplicar os conceitos estudados
sobre Verilog – Descrição RTL em exercícios práticos,
presentes no arquivo Relatórios Práticos – SD112 atividade
A-011.
• O aluno deverá fazer todos os exercícios e enviar os arquivos
da resolução assinados com seu nome completo para o e-
mail [email protected];
• Assunto do e-mail: Relatório SD112 – Atividade A-011.
227
Página em branco.
228
Aula 17
Verilog - Descrição
Comportamental
Descrição Comportamental
• É uma forma de representar circuitos digitais descrevendo
sua funcionalidade (função e algoritmo), sem detalhar
como o hardware realiza essas operações.
• Essa descrição está focada em “o que fazer” e não em
“como fazer”.
230
Descrição Comportamental
• A descrição comportamental é amplamente utilizada nas
fases iniciais do desenvolvimento para:
• Simular o comportamento funcional do design.
• Validar a lógica do circuito antes de detalhar a
implementação.
• Possui alta abstração e flexibilidade, facilitando ajustes
rápidos na lógica.
• Permite a criação de testbenches simples e rápidas para
verificar o comportamento funcional.
always @(*)
begin
if (sel)
out =
in2;
else
out =
in1;
end
231
Descrição Comportamental
Vantagens para simulações:
1. Detecção precoce de erros
Identificação de problemas na lógica sem precisar
construir o hardware completo.
2. Prototipagem rápida
Permite testar ideias de design rapidamente.
3. Custo reduzido
Minimiza retrabalhos ao detectar falhas antes da
implementação física.
232
Descrição Comportamental
Exemplo: Multiplexador 2 para 1
module mux_2x1_behavioural1(
input in1, in2, select,
output out
);
assign out = select ? in2 :
in1;
endmodule
233
Descrição Comportamental
Exemplo: Multiplexador 2 para 1
module mux_2x1_behavioural2(
input in1, in2, select,
output out
);
reg muxout;
always @(*) begin
if (select)
// Se select for 1, saída recebe
in2
muxout <= in2;
else
// Se select for 0, saída recebe
in1
muxout <= in1;
end
assign out = muxout;
endmodule
234
Descrição Comportamental
Exemplo: Multiplexador 2 para 1
module mux_2x1_behavioural3(
input in1, in2, select,
output out
);
reg muxout;
always @(*) begin
case (select)
// Se select = 0, saída recebe
in1
1'b0 = muxout <= in1;
// Se select = 1, saída recebe
in2
1'b1 = muxout <= in2;
default = muxout <= 0;
endcase
end
assign out = muxout;
endmodule
235
Descrição Comportamental
Exemplo: Contador de 4 bits com Incremento
module counter_4bit (
input clk, // Clock
input reset, // Reset
output reg [3:0] count // Saída do
contador
);
always @(posedge clk or posedge reset)
begin
if (reset) begin
// Reseta o contador
count <= 4'b0000;
end else begin
// Incrementa o contador
count <= count + 1;
end
end
endmodule
236
Descrição Comportamental
Exemplo: Unidade Lógica e
Aritmética (ALU) Simples
module alu (
input [3:0] a, b, //Entrada de 4 bits
input [1:0] sel, // Sinal de seleção
input reg [3:0] result // Resultado
);
always @(*) begin
case (sel)
2'b00: result = a + b; // Soma
2'b01: result = a – b; //
Subtração
2'b10: result = a & b; // AND bit-
a-bit
2'b11: result = a | b; // OR bit-
a-bit
default: result = 4'b0000 // Valor
padrão
endcase
end 237
Descrição Comportamental
Exemplo: Registro de Deslocamento (Shift Register)
module shift_register (
input clk, // Clock
input reset, // Reset
input shift_in, // Bit de entrada
output reg [3:0] q // Saída do registro
);
always @(posedge clk or posedge reset) begin
if (reset) begin
q <= 4'0000 // Reseta o registro
end else begin
q <= {q[2:0], shift_in}; // Desloca os bits para a
direita
end
end
endmodule
238
Revisão
1. O que caracteriza uma descrição comportamental em
Verilog?
2. Quais são as principais vantagens da descrição
comportamental durante a simulação de circuitos?
3. Qual é a diferença entre descrição comportamental e a
descrição RTL?
4. O que acontece no código do contador de 4 bits quando o
sinal de reset é acionado?
239
Relatório Prático
• Nesta aula, iremos aplicar os conceitos estudados
sobre Verilog – Descrição Comportamental em exercícios
práticos, presentes no arquivo Relatórios Práticos – SD112
atividade A-012.
• O aluno deverá fazer todos os exercícios e enviar os arquivos
da resolução assinados com seu nome completo para o e-
mail [email protected];
• Assunto do e-mail: Relatório SD112 – Atividade A-012.
240
Aula 18
Verilog - Descrição Estrutural
Descrição Estrutural
Definição
• A modelagem estrutural descreve o circuito ao especificar
explicitamente as conexões entre componentes pré-definidos.
• Similar ao diagrama esquemático, mas descrito textualmente.
• Baseia-se na instância de componentes como módulos definidos
anteriormente.
242
Descrição Estrutural
243
Descrição Estrutural
Exemplo: Crossbar Switch
module mux_2x1_rtl1(
input in1, in2, select,
output out
);
wire n_select, and1, and2;
endmodule
244
Descrição Estrutural
Exemplo: Full Adder
245
Descrição Estrutural
module Add_half (sum, c_out, a, b);
Exemplo: Full Adder input a, b;
output sum, c_out;
246
Descrição Estrutural
Exemplo: 4-bit
Adder
247
Descrição Estrutural
Exemplo: 4-bit Adder
module four_bit_adder (a, b, cin, s, cout);
input [3:0] a, b; // Entradas de 4 bits
input cin; // Carry-in (entrada de transporte)
output [3:0] s; // Saída de 4 bits (soma)
output cout; // Carry-out (transporte final)
wire [2:0] cy; // Barramento de transporte intermediário
endmodule
248
Descrição Mista
Exemplo: MultiplicadorAcumulador (MAC)
module mult_acc (outZ, inA, inB, clk, clr);
input [7:0] inA, inB; // Entradas de 8 bits
input clk, clr; // Entradas de clock e reset
output [15:0] outZ; // Saída acumulada de 16 bits
249
Revisão
1. O que caracteriza a descrição estrutural em Verilog?
2. Cite um exemplo de módulo estrutural e descreva sua
funcionalidade.
3. Qual é a função do “Crossbar Switch”? Como ele utiliza
instâncias de outros módulos?
4. Quais são os módulos básicos que compõem um “Full
Adder” em Verilog? Como eles interagem entre si?
5. Quais são as vantagens de usar a descrição estrutural em
sistemas complexos?
250
Relatório Prático
• Nesta aula, iremos aplicar os conceitos estudados
sobre Verilog – Descrição Estrutural em exercícios práticos,
presentes no arquivo Relatórios Práticos – SD112 atividade
A-013.
• O aluno deverá fazer todos os exercícios e enviar os arquivos
da resolução assinados com seu nome completo para o e-
mail [email protected];
• Assunto do e-mail: Relatório SD112 – Atividade A-013.
251
Página em branco.
252
Aula 19
Verilog – Primitivas do Verilog e
Primitivas Definias por Usuário
O que são primitivas?
• Primitivas em Verilog são construções básicas utilizadas
como macros para representar o comportamento de
hardware em um nível mais próximo do físico.
• Elas modelam componentes lógicos simples, como portas
lógicas combinacionais e elementos sequenciais.
254
Primitivas Predefinidas vs Definidas pelo
Usuário (UDP)
• Primitivas Predefinidas (Built-in) são fornecidas como parte
da linguagem Verilog e não podem ser modificadas. São 26
primitivas utilizadas para modelar portas lógicas e
transistores.
255
Primitivas Predefinidas
Lista de tipos e primitivas da linguagem Verilog.
256
Primitivas Predefinidas
Tabela verdade para gates lógicos.
257
Primitivas Predefinidas
Tabela verdade para buffers e inversores.
258
Primitivas Predefinidas
Tabela verdade para transistores.
259
Pinos Primitivos são
Expansíveis
• Saídas são sempre definidas à esquerda, seguidas por dados
de entrada e controle mais à direita. Uma primitiva pode ter
múltiplas entradas, mas uma única saída.
260
Declaração de primitivas
• Gates: and, nand, or, nor, xor, xnor, buf, not
Estas primitivas servem para modelar portas lógicas
convencionais ou buffers. Suportam o assignment de drive
strength, delay, range e portas.
gate (drive_strength) #(2delays) instance_name[range] (list_of_ports);
261
Declaração de primitivas
• Gates: and, nand, or, nor, xor, xnor, buf, not
Estas primitivas servem para modelar portas lógicas
convencionais ou buffers. Suportam o assignment de drive
strength, delay, range e portas.
gate (drive_strength) #(2delays) instance_name[range] (list_of_ports);
262
Declaração de primitivas
• Transistores MOS de chaveamento: nmos, pmos, rnmos,
rpmos, cmos, rcmos,
Estas primitivas permitem modelar portas lógicas e circuitos a
nível de transistor. São extremamente úteis para um modelo de
simulação mais complexo, permitindo avaliar codinções de
corrida e outras mais a fundo. Possuem condução unidirecional.
gate #(3delays) instance_name[range] (list_of_ports);
263
Declaração de primitivas
• Resistores de pull-up e pull-down: pullup, pulldown
Utilizados para modelar o drive de um sinal para valor lógico 1
(pull-up) ou 0 (pull-down).
pullup (pullup_strength) instance_name[range] (list_of_ports);
pulldown (pulldown_strength) instance_name[range] (list_of_ports);
264
Declaração de primitivas
• Opcionalmente pode-se omitir o nome da instância:
and (out, in1, in2, in3, in4); // Instância sem
nome
buf b1 (out1, out2, in); // Instância com
nome
• Especificar as saídas antes das entradas. As saídas SEMPRE são
declaradas antes das entradas no código Verilog.
265
Primitivas Definidas pelo Usuário (UDPs)
• As Primitivas Definidas pelo Usuário (UDPs) permitem criar
primitivas personalizadas no Verilog para modelar
comportamentos lógicos específicos. Seu formato é baseado em
tabelas da verdade. São utilizadas apenas para simulação, uma
vez que não são sintetizáveis.
Pontos chaves:
✅Complementam primitivas existentes: Permitem adicionar elementos ao
conjunto padrão de primitivas do Verilog.
✅ Independentes: UDPs não instanciam outros módulos.
✅ Suportam comportamentos combinacionais e sequenciais.
✅ Definição simples: O comportamento é descrito em uma tabela da
verdade.
✅ Instanciação intuitiva: UDPs são instanciadas assim como as primitivas
built-in.
266
Características das UDPs
✅ Podem ter apenas uma saída.
✅ Podem ter de 1 a 10 entradas.
✅Todas as portas devem ser escalares e portas bidirecionais
não são permitidas.
✅ O valor lógico Z (alta impedância) não é suportado.
✅ A porta de saída deve ser listada primeiro na lista de portas.
✅ O terminal de saída do UDP pode ser inicializado com um
valor conhecido no início da simulação.
✅ UDPs não podem ser sintetizados.
267
Tabelas verdade
Símbolo Descrição Exemplo de Uso
0 Representa um nível lógico baixo 0 (zero volt ou
(LOW). nível baixo)
1 Representa um nível lógico alto 1 (tensão alta ou
(HIGH). nível alto)
X Valor indefinido ou desconhecido, X (estado incerto)
comum durante simulação quando o
estado não pode ser determinado.
? Coringa que aceita qualquer valor 0, 1 ou X
entre 0, 1 e X. Satisfaz a lógica (qualquer valor)
independente do valor.
B Representa valores binários válidos (0 0 ou 1 (binário)
ou 1). Não permite X como valor
válido.
268
Tabelas verdade
Símbolo Descrição Exemplo de Uso
- Representa sem mudança no estado de saída -
ou próximo estado.
(vw) Indica uma relação onde v pertence a {0, 1, x} v ∈ {0, 1, x} ->
e w pertence a {0, 1, x} w ∈ {0, 1, x}
* Representa qualquer combinação entre {0, 1, * : {0, 1, x} ->
x} e mapeia para {0, 1, x} {0, 1, x}
r Indica uma transição crescente (0 -> 1). r : (01)
f Indica uma transição decrescente (1 -> 0). f : (10)
p Representa uma mudança para 1 ou estado (01), (0x), (x1),
indefinido. Inclui variações de 0x, 1x, etc. (0z), (z1)
n Representa uma mudança para 0 ou estado (10), (1x), (x0),
indefinido. Inclui variações de 1x, x0, etc. (1z), (z0)
269
Primitivas Definidas pelo Usuário
(UDP)
• Primitiva que implementa
um Flip-Flop tipo D
simples:
table
// d clk : q : q+
0 (01) : ? : 0; // Armazena '0' na borda de subida
1 (01) : ? : 1; // Armazena '1' na borda de subida
? (0?) : ? : -; // Sem mudança durante borda descendente ou nível
baixo
endtable
endprimitive
270
Primitivas Definidas pelo Usuário
(UDP)
• Um latch SR sensível ao nível
com entradas Set e Reset:
table
// s r : q : q+
0 0 : ? : -; // Sem mudança
1 0 : ? : 1; // Set ativo
0 1 : ? : 0; // Reset ativo
1 1 : ? : x; // Estado indefinido
endtable
endprimitive
271
Primitivas Definidas pelo Usuário
(UDP)
• Um Multiplexador 2:1:
table
// a b s : o
0 ? 1 : 0;
1 ? 1 : 1;
? 0 0 : 0;
? 1 0 : 1;
0 0 x : 0;
1 1 x : 1;
endtable
endprimitive
272
Primitivas Definidas pelo Usuário
(UDP)
• Um Flip-Flop com primitive u_ff_p_cl (q, clk, data,
clr);
Clear Síncrono: input clk, data, clr;
output q;
reg q;
table
// clk data clr próximo estado
r ? 1 : ? : 0;
r 0 ? : ? : 0;
r 1 0 : ? : 1;
// Reduz pessimismo
p 0 ? : 0 : -;
p 1 0 : 0 : -;
p 1 0 : 1 : -;
274
Primitivas Sequenciais
primitive dff(q, clk, data);
output q; reg q;
input clk, data;
table
// clk data q new-q
(01) 0 : ? : 0; // Travar em 0
(01) 1 : ? : 1; // Travar em 1
(0x) 1 : 1 : 1; // Manter quando d e q são
ambos 1
(0x) 0 : 0 : 0; // Manter quando d e q são
ambos 0
(?0) ? : ? : -; // Manter quando clk cai
(??) ? : ? : -; // Manter quando clk estável
endtable
CLK D Q(n+1)
endprimitive Condição
0 x Qn Sem mudança
1 x Qn Sem mudança
↓ x Qn Sem mudança
↑ 0 0 Q segue a entrada D
↑ 1 1 Q segue a entrada D
275
Primitivas em nível de
chaveamento
• Primitivas de chaveamento são modelos simples que
representam transistores como chaves digitais (ON/OFF).
• O Verilog fornece primitivas unidirecionais e bidirecionais que
podem ser utilizadas para modelar redes de chaveamento.
• Primitivas unidirecionais:
Permitem a passagem de CMOS
corrente apenas em um
sentido:
cmos, nmos, pmos,
pullup
• Primitivas bidirecionais:
Permitem a passagem de
corrente nos dois sentidos.
tran, tranif0,
tranif1
276
Primitivas em nível de
chaveamento
• Exemplo de implementação de uma porta NAND com CMOS, utilizando
primitivas de chaveamento. Esses códigos são especialmente úteis para
simular o comportamento de circuitos em um nível mais próximo do
hardware real.
module cmos_nand_gate(output Y, input A, B);
supply1 Vdd; // Alimentação positiva
supply0 GND; // Alimentação negativa
277
Primitivas em nível de
chaveamento
• Modelagem detalhada: um
esquema de modelagem mais
aprofundado, capaz de
identificar problemas elétricos
adicionais que podem surgir ao
utilizar transistores dessa forma.
• Uso atual: Circuitos geralmente
não são projetados dessa forma.
• Simulação avançada: Esses
circuitos são frequentemente
simulados com softwares
semelhantes ao SPICE, que
utilizam solucionadores de
equações diferenciais não
lineares.
278
Primitiva de Transporte
• Definição:
Primitivas de transporte são
blocos básicos em linguagens de
descrição de hardware, como
Verilog, que implementam
funções lógicas simples.
• Aplicação:
As primitivas de transporte são
amplamente usadas para
descrever operações como carry
(transporte) em somadores
binários e outras funções lógicas
em circuitos digitais.
279
Primitiva de Transporte: Exemplo e
Funcionamento
• A primitiva “carry” descreve o comportamento de um bit de transporte
em circuitos combinacionais, com base na tabela de verdade
apresentada.
primitive carry(out, a, b, c);
output out; // Sempre possui exatamente uma saída A B C Out
input a, b, c;
0 0 ? 0
// A tabela da verdade pode incluir entradas "não
importa" (?) ? 0 0 0
table
00? : 0;
? 0 0 0
?0? : 0; 1 1 ? 1
?00 : 0;
11? : 1; 1 ? 1 1
1?1 : 1;
?11 : 1; ? 1 1 1
endtable
endprimitive
280
Revisão
1. O que são primitivas em Verilog e quais são os dois tipos
principais?
2. Qual a diferença entre primitivas predefinidas e definidas
pelo usuário (UDPs)?
3. Qual é a função de uma primitiva condicional como
bufif0 e notif0?
4. Explique a diferença da primitiva sensível à borda e
sensível ao nível.
5. Qual a diferença entre primitivas unidirecionais e
bidirecionais?
6. O que caracteriza uma UDP combinacional e uma UDP
sequencial?
281
Aula 20
Verilog – Primitivas do Verilog e
Primitivas Definias por Usuário
(cont.)
Relatório Prático
• Nesta aula, iremos aplicar os conceitos estudados
sobre Verilog – Primitivas do Verilog e Primitivas Definidas
por Usuário em exercícios práticos, presentes no arquivo
Relatórios Práticos – SD112 atividade A-014.
• O aluno deverá fazer todos os exercícios e enviar os arquivos
da resolução assinados com seu nome completo para o e-
mail [email protected];
• Assunto do e-mail: Relatório SD112 – Atividade A-014.
283
Aula 21
Verilog - Codificação para
Síntese e Simulação
Fluxos Típicos de Síntese RTL e
Simulação RTL
285
Simulação
286
Síntese de circuitos
287
Simulação vs. Síntese
• Simulação
• Código executado exatamente como escrito;
• Usuário tem flexibilidade na escrita de modelos
comportamentais;
• Inicialização lógica totalmente suportada;
• Síntese
• Código é interpretado e o hardware criado;
• As ferramentas de síntese exigem uma codificação
específica para gerar a lógica correta;
• O estilo de codificação é importante para lógica rápida e
eficiente;
• As lógicas Pré & Pós- síntese devem funcionar da mesma
maneira!
288
Síntese
• Síntese é o processo de transformar uma descrição em HDL
(como Verilog ou VHDL) em um circuito físico que pode ser
implementado no hardware.
• Esse processo inclui a tradução de operações abstratas
(como transferências entre registradores e operações
aritméticas) em uma rede de portas lógicas.
• O sintetizador pega a descrição em RTL e gera uma
representação do circuito no nível de portas lógicas.
289
Síntese
• Converte código HDL (RTL) em uma netlist.
• O código HDL (descrito no nível RTL) é transformado em uma
netlist, que é uma descrição do circuito no nível de portas
lógicas e interconexões.
• Simulação Pós-Síntese: Garante que a funcionalidade
permanece alinhada.
• Ferramentas de síntese (como Vivado, Quartus ou Synopsys
Design Compiler) mapeiam a netlist gerada para a tecnologia de
destino:
Implementam para FPGA ou criam layouts físicos para ASIC.
• Objetivo da Síntese:
Criar uma representação física do design que possa ser
implementada em hardware real.
290
Síntese
291
Objetivos da Síntese
• Minimizar a área: Em termos de contagem de literais,
contagem de células, contagem de registradores, etc.
• Minimizar o consumo de energia: Em termos de atividade
de comutação em portas individuais, blocos de circuito
desativados, etc.
• Maximizar o desempenho: Em termos de frequência
máxima de clock em sistemas síncronos e taxa de
processamento para sistemas assíncronos.
• Qualquer combinação dos itens acima: Por exemplo um
problema de restrição: “minimizar a área para uma
velocidade de clock > 300 MHz”.
• Mais objetivos globais: Tamanhos físicos reais, atrasos,
posicionamento e roteamento.
292
Restrições na Síntese
• Estilo de implementação fornecido
• Implementação em dois níveis (PLA, CAMs);
• Lógica multinível;
• FPGAs.
• Requisitos de desempenho fornecidos
• Requisito mínimo de velocidade de clock;
• Latência mínima, vazão (throughput).
• Biblioteca de células fornecida:
• Conjunto de células na biblioteca padrão de células;
• Restrições de fan-out (número máximo de portas
conectadas a outra porta);
• Geradores de células.
293
Síntese RTL
294
Estruturas Sintetizáveis em
Verilog
• module • Portas
• port • and, nand, nor, or,
• parameter xor, xnor
• Tipos de dados de rede • buf, not, bufif0,
• wire, tri, tri0, tri1 bufif1, notif0, notif1
• wor, wand, trior,
triand • Primitivas definidas pelo
• supply0, supply1
usuário (UDP)
• Atribuições Blocking e Non-
• Tipos de dados variáveis
Blocking
(registros)
• reg, integer • Blocos Sequenciais
• Tasks & funções
• assign (contínuo) • Seleção de bits & partes
• always & initial blocks
295
Estruturas Sintetizáveis em Verilog
(continuação)
Estruturas Comportamentais
If-else • As ferramentas de síntese
Case podem impor certas
Loop (com restrições)
restrições sobre as
disable
Instanciação de módulos estruturas suportadas.
• Consulte a ajuda online no
Tasks de Sistema readmemb e
software Quartus® (ou na
readmemh
Diretivas do compilador: ferramenta de síntese alvo)
`define, `undef, `ifdef, para uma lista completa.
`else, `endif • O software Quartus®
`include suporta muitas estruturas
`unconnected_drive que não são compatíveis
[pull0|pull1],
com outras ferramentas de
`nounconnected_drive
`resetall síntese.
296
Estruturas Não-Sintetizáveis em
Verilog
• Estas são algumas das estruturas não suportadas pela síntese de
software Quartus®:
Tipos de dados de rede force e release (para redes e
trireg registradores)
Tipos de dados variáveis Controle de delays
time, real, realtime Eventos (intra-procedural)
Portas lógicas Evento nomeado;
rtran, tran, tranif0,
Estruturas de paralelismo (fork
tranif1,
rtranif0, rtranif1 e join)
Blocos de especificação
Chaves
cmos,
Diretivas de tempo
nmos, rcmos,
rnmos, pmos, rpmos
Maioria das tarefas de sistema
pullup e pulldown (ex.: $display)
Força de condução
assign (contínuo procedural) e
deassign
297
Operadores
• As ferramentas de síntese substituem operadores por
blocos de lógica predefinidos (pré-otimizados).
• Exemplo: divisores
• Divisores são grandes blocos de lógica.
• Cada “/” (divisão) e “%” (módulo) insere um bloco
divisor e deixa para a síntese a tarefa de otimizá-lo.
• Uma melhor otimização de recursos geralmente
envolve o uso criativo de multiplicadores ou
operações de deslocamento (shifts) para realizar
divisões.
298
Gerando Lógica de
Operadores
• As ferramentas de
síntese dividem o
código em blocos
lógicos.
• Em seguida, elas
montam, otimizam
e mapeiam para o
hardware.
299
Estruturando Procedimentos
Pergunta
Este
Este códigocódigo
pode descrever
pode
always @(posedge clk) essa lógica, ou
descrever seja,lógica,
essa é ou
begin possível
seja, é descrever
possível adescrever
// lógica nos blocos A e estrutura acima usando um
a estrutura acima usando
B único procedimento
um único procedimento
sequencial?
end
sequencial?
300
Síntese de Declarações if
module if_example (
input a, b, c,
input [3:0] ctrl,
output reg op
); Pergunta
301
A Arquitetura Inicial de Declarações
if e case
if (ctrl == 4'h0)
op = a;
else if (ctrl <= 4'h4)
op = b;
else
op = c;
case (ctrl)
0: op = Síntese
a;
0, 1, 2, 3, 4: op = b; Como isso mudaria se
default: op = c; orientássemos a ferramenta
endcase de síntese a construir os
ramos do case em paralelo?
302
Declarações de case Paralelo
• Ferramentas de síntese são capazes
de construir ramos de case
mutuamente exclusivos sem a
necessidade de uma estrutura de (* synthesis, parallel_case
*)
prioridade. case (1)
• As ferramentas de síntese podem this: op = a;
identificar automaticamente um that: op = b;
case claramente paralelo. Para default: op = c;
endcase
situações em que isso não ocorre, é
possível utilizar as seguintes opções:
• Metacomentário (ainda aceito):
// ambit synthesis case =
full
• Atributo do Verilog-2001
(padrão atual):
(* synthesis, parallel_case
*)
303
Diretivas de Síntese
• A maioria das ferramentas de síntese também aceita diretivas
de síntese como metacomentários.
• Metacomentários são comentários em Verilog, ignorados pela
simulação, mas significativos para outras ferramentas.
• Seu efeito é idêntico ao do atributo de síntese padrão.
304
Síntese de Declarações casex
• As declarações casex e casez
always @(pri_in)
permitem que você especifique casex (pri_in)
posições de bits como "não 4'b1???: op = 3;
importa" (don’t-care). 4'b01??: op = 2;
• A ferramenta de síntese 4'b001?: op = 1;
interpreta essas declarações 4'b0001: op = 0;
exatamente como interpreta a default: op = 0;
declaração case. endcase
• Por vezes, pode ser difícil end
determinar se uma declaração
always @(ctrl) begin
casex ou casez é realmente
int = 3'b000;
paralela. casex (ctrl)
3'b??1: int[0] =
Pergunta 1'b1;
3'b?1?: int[1] =
Essas declarações 1'b1;
casex são 3'b1??: int[2] =
1'b1;
paralelas? endcase
end 305
Declarações de full_case
• Lógica Combinacional: A saída é determinada // no latch
always @(ctrl or a or
a todo momento pelo estado atual das b)
entradas. Se existir uma combinação de case (ctrl)
entradas para a qual a saída não esteja 0,1: op = a;
2: op = b;
definida, a ferramenta de síntese irá acionar 3: op = 1'bx;
um latch para essa combinação. endcase
// no latch
reg [1:0] ctrl; always @(ctrl or a or b)
reg a, b, op; case (ctrl)
0,1: op = a;
// latch op when ctrl == 2: op = b;
3 default: op =
always @(ctrl or a or b) 1'bx;
case (ctrl) endcase
// no latch
0,1: op = a;
always @(ctrl or a or b)
2: op = b;
begin
endcase op = 1'bx
Síntese case (ctrl)
Atribuir o estado desconhecido ‘x’ informa à 0,1: op = a;
2: op = b;
ferramenta de síntese que você não se importa com endcase
qual será a saída para aquela combinação de entradas. end
306
O Atributo full_case
• O padrão de síntese suporta o // no latch
atributo full_case para forçar a always @(ctrl or a or b)
(* synthesis, full_case
ferramenta de síntese a assumir *)
que todos os ramos do case estão case (ctrl)
representados. 0,1: op = a;
• É equivalente a um item de 2: op = b;
endcase
correspondência default case
que atribui "não importa" (don’t-
care) a todas as saídas. // no latch
always @(ctrl or a or b)
case (ctrl)
Atenção: 0,1: op = a;
• Ele não realiza nenhuma função 2: op = b;
além daquela que um item de default: op =
1'bx;
correspondência default case endcase
já pode executar. Além disso, não
impede a inferência de latches.
307
Ainda é Possível Obter
Latches!
A ferramenta de síntese ainda
pode inferir latches para uma module select (
input wire [1:0] sel,
declaração de case marcada output reg a, b
com full_case. );
• O atributo full_case
always @(sel) begin
aplica-se apenas às a = 0; b = 0; // Evita latch para a
expressões de (* sythesis, full_case *)
case (sel)
correspondência do case. 2'b00: begin a = 0; b = 0; end
• Qualquer variável que não 2'b01: begin a = 1; b = 1; end
2'b10: begin a = 0; b = 1; end
for totalmente atribuída no 2'b11: b = 1;
bloco combinacional ainda default: begin a = 'bx; b = 'bx;
end
será armazenada em latch. endcase
• Atribuições default end
evitam a inferência de
endmodule
latches — use-as!
308
Síntese de Declarações initial
— Não!
module counter ( module counter (
input wire clk, input wire clk,
output reg [3:0] rst,
q output reg [3:0]
); q
);
initial q = 0;
always @(posedge clk)
always @(posedge clk) if (rst)
if (q == 9) q <= 4'h0;
q <= 4'h0; else if (q == 9)
else q <= 4'h0;
q <= q + 1; else
q <= q + 1;
endmodule
endmodule
Síntese
O padrão de síntese suporta a construção initial apenas para a
inicialização de dados de ROM e exige que seja acompanhada pelos
atributos logic_block ou rom_block.
309
Inferência de Registradores para
Atribuição Blocking
module blockshift (
input wire clk, ip, always @(posedge clk)
output reg op begin
); // expansão do loop do
reg [7:0] shift_reg; for
integer i; op = shift_reg[7];
shift_reg[7] =
always @(posedge clk) shift_reg[6];
begin shift_reg[6] =
op = shift_reg[7]; shift_reg[5];
for (i = 7, i > 0, i = i – 1) shift_reg[5] =
shift_reg[i] = shift_reg[4];
shift_reg[i-1]; shift_reg[4] =
shift_reg[0] = ip; shift_reg[3];
end shift_reg[3] =
endmodule shift_reg[2];
• Para uma atribuição
shift_reg[2] = do tipo
blocking, um registrador é
shift_reg[1];
Pergunta shift_reg[1]
inferido =
se a variável for lida
shift_reg[0];
Quantos registradores antes de ser escrita.
shift_reg[0] = ip;
são inferidos? end
310
Atribuição de Variável
Temporária
Variáveis atribuídas com atribuições
do tipo blocking e, posteriormente,
lidas no mesmo procedimento são module tworeg (
temporárias – a ferramenta de síntese input wire d, clk,
output reg q
não infere armazenamento para elas. );
reg rega;
always @(posedge
clk)
begin
rega = d;
q <= rega;
end
endmodule
311
Atribuição de Variável
Temporária
A ferramenta de síntese sempre
infere armazenamento para module tworeg (
input wire d, clk,
variáveis atribuídas com output reg q
atribuições do tipo nonblocking. );
reg rega;
always @(posedge
clk)
begin
rega <= d;
q <= rega;
end
endmodule
312
Inferindo Latches
module latch (
• Uma atribuição incompleta em um input data,
procedimento combinacional enable,
output reg q
infere armazenamento por meio );
de latches.
always @(enable, data)
• É dessa forma que se codifica um if (enable)
design baseado em latch, caso q = data;
module tri_state_drivers (
input en_1, en_2,
input [7:0] data_1, data_2,
output [7:0] data_bus
);
endmodule
314
Hierarquia: Registre Todas as
Saídas
315
Gerenciamento de Hierarquia
Algumas pontos a serem considerados:
• Mesclagem de lógica combinacional;
• Estratégias de otimização;
• Tamanhos sintetizáveis;
• Controle de caminhos críticos.
316
Revisão
1. Qual é a principal diferença entre a simulação e a
síntese em Verilog?
2. Cite e explique dois dos principais objetivos da
síntese.
3. Dê dois exemplos de estruturas ou construções
em Verilog que não são suportadas pelas
ferramentas de síntese.
4. O que ocorre quando há atribuições incompletas
em um bloco combinacional?
317
Aula 22
Verilog - Codificação para
Síntese e Simulação (cont.)
Simulação
• O que é?
Modela e verifica o comportamento lógico do design.
Foco na funcionalidade, sem considerar detalhes físicos.
• Por que usar?
Explora opções: Teste diferentes configurações antes da síntese.
Economiza tempo: Identifica e corrige erros no início.
Verifica a lógica: Garante a funcionalidade antes de custos
elevados.
• Exemplo
ü Multiplicação no HDL é
tratada idealmente, sem
detalhes do hardware.
• Objetivo:
ü Garantir que a lógica está
correta e funcional antes
de etapas caras.
319
Simulação
A simulação requer um ambiente específico com ferramentas e técnicas
para testar e verificar o circuito.
• Usando recursos auxiliares: Esses recursos não fazem parte do circuito
final, mas ajudam a criar cenários de teste e depuração durante a
simulação. Por exemplo:
Formas de onda Active-HDL;
Leitura de arquivos;
Instruções de impressão/logs;
• Usando código de simulação em Verilog: A simulação em Verilog utiliza
um testbench, também chamado de "test fixture".
Um testbench fornece entradas ao circuito, monitora as saídas e
valida seu comportamento.
Este código simula um ambiente funcional sem fazer parte do
circuito sintetizável.
320
Test Fixture (Testbench)
• Fornece clock: gera os sinais de clock necessários para o circuito
durante a simulação.
• Fornece vetores de teste/verifica resultados: vetores de teste e
resultados são pré-computados. Geralmente, os vetores de teste
são lidos a partir de arquivos.
• Modela o ambiente do sistema: programa complexo que simula o
ambiente externo para o circuito.
• O test fixture pode utilizar todos os recursos da linguagem: inclui
comandos como inicialização (initial), atrasos (delays), leitura/
escrita de arquivos, etc.
*DUT: Design
Under Test
321
O que é Simulação Lógica?
• Simular o comportamento de um design
lógico.
• Descrição do design lógico:
Netlist, rede.
Componentes.
Ex.: AND, OR, RAM, PENTIUM
Interconexões dos componentes.
• Modelos Lógicos:
Comportamento dos componentes.
Comportamento das interconexões.
Valores dos sinais.
• Modelos Temporais:
Comportamento dos componentes.
Comportamento das interconexões.
Atrasos dos sinais.
322
Descrição do Design Lógico
• Componentes:
Módulos, células, etc.
Primitivos (ex.: AND, OR, NOT).
Predefinidos – a partir de bibliotecas:
Comportamento funcional.
Comportamento temporal.
Compostos – definidos pelo usuário:
Sub-rede.
Hierarquia.
• Conexões de Componentes:
Fiação.
Pontos de conexão - pinos, portas,
terminais.
Pode incluir estrutura de fiação:
Fan-in, fan-out.
Parasitismo.
323
Organização do Design
• Linhas tracejadas indicam que a compilação pode verificar
a existência e a legibilidade dos arquivos de entrada, assim
como a permissão para criar arquivos de saída.
324
Simulação de um Modelo
Verilog
initial
avec = 8'h00;
always @(posedge clk)
q <= d;
always @(a or b or
sel)
if sel
y = a;
...
325
Organização da Testbench
Testbench Simples
• Apenas envia dados para o
design.
• Poucos processos envolvidos.
• Não há interação com o
design.
Testbench Sofisticado
• Modela o ambiente ao redor
do design.
• Interage com o design.
• Evolui em direção a um
modelo de sistema completo.
• Possui verificação automática
(self-checking).
326
Estímulo “Em Linha”
module inline_tb;
endmodule
327
Estímulo a Partir de Loops
Em um loop, é possível
modificar repetidamente a module loop_tb;
mesma variável de estímulo.
As vantagens incluem: reg clk;
reg [7:0] stimulus;
• Facilidade de entrada. integer i;
• Descrição compacta.
// Instância do DUT
Esse método pode ser mais // Geração de clock
adequado para estímulos que
initial begin
possuem: for (i = 0; i <= 255; i = i +
• Um período de tempo 1)
@(negedge clk) stimulus =
definido. i;
• Valores regulares. end
Importante: endmodule
É importante inserir um
controle de tempo no loop!
328
Estímulo a Partir de Arrays
• É possível pré-carregar module array_tb;
endmodule
329
Estímulo a partir de Arquivos
module file_array_tb;
endmodule
330
Estímulo Aleatório usando
$random
Números aleatórios podem ser gerados utilizando a função de
sistema $random.
Retorna um inteiro com sinal de 32 bits aleatório
• Verilog-1995: O algoritmo não é padrão nem portátil.
• Verilog-2001: O algoritmo é padrão e portátil.
É possível inicializar o gerador (seed) para produzir sequências
reproduzíveis. module random_tb;
O Verilog fornece funções de sistema que reg [3:0] avec;
permitem alterar a distribuição dos números reg [7:0] bvec;
aleatórios. ...
• $dist_chi_square initial
• $dist_erlang begin
• $dist_exponential avec =
• $dist_normal $random;
• $dist_Poisson bvec =
$random;
• $dist_t ...
• $dist_uniform end
endmodule 331
As Palavras-Chave fork e join
• As instruções incluídas dentro module forkfoin_tb;
reg [7:0] data,
de fork...join são addr;
executadas simultaneamente.
// Instância do DUT
• Cada instrução segue o initial
fork
controle de evento ou atrasos data = 8'h00;
que ela contém. #10 data =
8'h45;
• O bloco fork...join é #15 addr =
concluído quando todas as 8'hf0;
#30 data =
instruções iniciadas com fork 8'h0f;
join
são finalizadas.
Síntese endmodule
• O padrão de síntese não
suporta a construção
fork...join.
332
Bloco de Estímulo
Concorrente
Um bloco concorrente pode conter
qualquer instrução processual
(chamadas de tarefas, loops, etc).
Algumas questões importantes a module concurrent_tb;
reg [7:0] data;
serem consideradas:
• Não é possível prever a ordem // Instância do DUT
333
A palavra-chave event
• Declare um evento module event_example (
nomeado em Verilog usando input [3:0] in1, in2,
output [4:0] o1
a palavra-chave event. );
• Notifique o evento usando o
event e1; // Declara
operador de disparo evento
-> event.
always @(in1 or in2)
• Utilize o evento em um begin
o1 = in1 + in2;
controle de evento @ -> e1; // Notifica
event. evento
end
Síntese:
• O padrão de síntese não always @(e1) // Usa
evento
oferece suporte ao comando $displayb(o1);
event. endmodule
334
Usando Strings para Monitorar o
Progresso module testbench;
Exibir strings informativas pode reg [40*8:1] message;
ajudar nos esforços de depuração ao task reset;
begin
monitorar o progresso da simulação. message = "reset";
@(negedge clock);
• Defina um vetor com 8 bits para reset <= 1'b1;
cada caractere ASCII. @(negedge clock);
reset <= 1'b0;
• Atribua um literal de string ao end
endtask
vetor (preenchido ou truncado task test1;
input [3:0] a_vec,
como qualquer outro número). b_vec;
• Defina um processo acionado por output [7:0] d_vec;
begin
alterações na mensagem para message = "test one";
...
exibir a nova mensagem. end
• Visualize as mensagens com a endtask
always @(message)
ferramenta de exibição de formas $display ("%s",
message);
de onda (defina a base de exibição initial begin
para ASCII). reset;
test1(a, b, out);
end
endmodule
335
Variáveis Hierárquicas
•É possível acessar module mux (
variáveis fora do módulo input a, b, sel, clk,
output reg f
utilizando um caminho );
wire g = sel ? a : b;
hierárquico. always @(posedge clk)
• Isso é útil em f <= g;
endmodule
testbenches.
• Os caminhos podem ser module tb;
...
relativos ou absolutos. mux uut (.a, (1'b0), .b(bnet),
.sel(select), .clk(clk), .f(f));
• Este exemplo utiliza um initial
caminho relativo. begin
wait (uut.g);
• O caminho absoluto $display("mux has a logic
equivalente poderia one");
end
ser: ...
endmodule
wait (tb.uut.g);
336
Captura de Vetor
• É possível capturar os module capture_tb;
estímulos e as reg [7:0] stimulus, response;
integer stimfile, respfile;
respostas nos pinos
do DUT. // Instância do DUT
• Esses vetores podem initial
ser reproduzidos no begin
stimfile = $fopen("stimulos.txt");
DUT utilizando respfile = $fopen("results.txt");
apenas um ambiente fork
if (stimfile != 0)
de teste simplificado. forever #(period)
$fstrobeh (stimfile, "%b",
• Além disso, é possível stimulus);
fornecer esses if (respfile != 0)
#(period/2) forever #(period)
vetores de teste ao $fstrobeh (respfile, "%b",
fabricante do response);
join
dispositivo. end
endmodule
337
Reprodução de Vetores
• É possível reproduzir
vetores lidos de um
arquivo. module playback_tb;
localparam integer num_vecs = 256;
reg [7:0] data_bus;
reg [7:0] stim [0:num_vecs-1];
integer i;
// Instância do DUT
00111000
00111001 initial
begin
00111010
// Carrega estímulos
00111100
$readmemb("vec.txt", stim);
00110000 // Replay os vetores
10111000 for (i = 0; i < num_vecs; i =
... i + 1)
vec.txt #50 data_bus = stim[i];
end
endmoule
338
Gerador de Clock
• Exemplos de gerador de clock
always begin // Simples
#(period/2) clk = 0; nand #(period/2) u1 (ck, ck,
#(period/2) clk = 1; go);
end initial begin
go = 0;
initial begin // Com atraso #(period/2) go = 1;
clk = 0; end
#(period)
forever nand #(period/2) u1 (ck, ck,
#(period/2) clk = go);
~clk; initial begin
end go = 0;
#(period) go = 1;
initial begin // Irregular end
#(period + 1) clk = 1;
#(period/2 - 1) nand #(period/4, 3*period/4)
forever begin u1 (ck, ck, go);
#(period/4) clk = 0; initial begin
#(3 * period/4) clk = go = 0;
1; #(period) go = 1;
end end
end
339
Uso de Tasks
module bus_ctrl_tb;
• Usar tasks em um testbench reg [7:0] data;
encapsula operações reg data_valid;
wire data_read;
repetidas, tornando seu
task cpu_driver;
código mais eficiente. input [7:0] data_in;
begin
#30 data_valid = 1;
wait (data_read ==
1);
#20 data = data_in;
wait (data_read ==
0);
#20 data = 8'hzz;
#30 data_valid = 0;
end
endtask
// Instânciação da CPU
initial
begin
cpu_driver
(8'b0000_0000);
cpu_driver
(8'b1010_1010);
cpu_driver
340
(8'b0101_0101);
Revisão
1. O que é uma simulação em Verilog e qual é o seu
principal objetivo?
2. Quais recursos de Verilog podem ser usados em um
testbench e não são sintetizáveis?
3. Qual é a diferença entre estímulos “em linha” e estímulos
gerados por “arrays”?
4. Quais as vantagens de usar loops para gerar estímulos
durante a simulação?
5. Explique o uso das palavras-chave “fork” e “join” em
uma testbench.
341
Aula 23
Verilog - Codificação para
Síntese e Simulação (cont.)
Relatório Prático
• Nesta aula, iremos aplicar os conceitos estudados
sobre Verilog – Codificação para Síntese e Simulação em
exercícios práticos, presentes no arquivo Relatórios Práticos
– SD112 atividade A-015.
• O aluno deverá fazer todos os exercícios e enviar os arquivos
da resolução assinados com seu nome completo para o e-
mail [email protected];
• Assunto do e-mail: Relatório SD112 – Atividade A-015.
343