Você está na página 1de 61

UNIVERSIDADE FEDERAL DA PARAÍBA

CENTRO DE CIÊNCIAS E TECNOLOGIA


DEPARTAMENTO DE ENGENHARIA ELÉTRICA
DISCIPLINA: ARQUITETURA DE SISTEMAS DIGITAIS

Projeto de Sistemas Digitais na Atualidade

Alexandre Scaico

Campina Grande
Dezembro/2000
Projeto de Sistemas Digitais na Atualidade pág. 2

SUMÁRIO

1. INTRODUÇÃO...........................................................................................................................5
2. A LÓGICA PROGRAMÁVEL...................................................................................................7
2.1 - O que é a Lógica Programável? ...........................................................................................7
2.2 - Memórias PROM .................................................................................................................7
2.3 - Os Dispositivos Lógicos Programáveis (PLD) ....................................................................9
2.4 - Arranjos Lógicos Programáveis.........................................................................................10
2.4.1 - PLA..............................................................................................................................10
2.4.2 - PAL..............................................................................................................................11
2.5 - Arranjos de Portas Programáveis (Programmable Gate Array).........................................11
2.5.1 - CPLD (Complex PLD) ................................................................................................12
2.5.2 - FPGA (Field Programmable Gate Array)....................................................................13
2.6 - Considerações finais ..........................................................................................................14
2.7 - Bibliografia ........................................................................................................................15
3. AS LINGUAGENS DE DESCRIÇÃO DE HARDWARE.......................................................16
3.1 - Evolução dos sistemas digitais...........................................................................................16
3.2 - Surgimento das HDL’s ......................................................................................................16
3.3 - Fluxo Típico em um Projeto ..............................................................................................17
3.4 - Importância das HDL’s......................................................................................................18
3.5 - Tendências em HDL’s .......................................................................................................19
3.6 - Bibliografia ........................................................................................................................19
4. VERILOG HDL ........................................................................................................................20
4.1 - O que é Verilog? ................................................................................................................20
4.2 - Por que usar o Verilog HDL? ............................................................................................20
4.3 - Popularidade do Verilog HDL ...........................................................................................21
4.4 - Aplicações do Verilog e outras linguagens HDL ..............................................................21
4.5 - Limitações do Verilog........................................................................................................21
4.6 - Níveis de abstração ............................................................................................................22
4.7 - Nível comportamental x RTL ............................................................................................22
4.8 - Conceitos principais da linguagem ....................................................................................23
4.9 - Metodologias de projeto ....................................................................................................24
4.10 - Estrutura dos módulos......................................................................................................24
4.11 - Projeto hierárquico...........................................................................................................26
4.12 - Instâncias..........................................................................................................................26
4.13 - Representando hierarquia.................................................................................................27
A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 3

4.14 - Componentes de uma simulação......................................................................................28


4.15 - Nomes hierárquicos .........................................................................................................29
4.16 - Exemplos de módulos ......................................................................................................30
4.16.1 - Meio somador ............................................................................................................30
4.16.2 - Somador completo.....................................................................................................30
4.17 - Conceitos básicos.............................................................................................................31
4.18 - Convenções léxicas..........................................................................................................32
4.18.1 - Espaços em branco ....................................................................................................32
4.18.2 - Comentários...............................................................................................................32
4.18.3 - Operadores.................................................................................................................32
4.18.4 - Especificações de números ........................................................................................32
4.18.5 - Strings........................................................................................................................33
4.18.6 – Identificadores e palavras-chave...............................................................................33
4.19 - Tipos de dados .................................................................................................................33
4.19.1 - Definição de valores ..................................................................................................33
4.19.2 - Nets............................................................................................................................34
4.19.3 - Registradores .............................................................................................................34
4.19.4 - Vetores.......................................................................................................................34
4.19.5 - Registros de tipos de dados integer, real e time ........................................................34
4.19.6 - Arrays ........................................................................................................................35
4.19.7 - Memórias ...................................................................................................................35
4.19.8 - Parâmetros .................................................................................................................35
4.19.9 - Strings........................................................................................................................35
4.20 - Módulos ...........................................................................................................................35
4.21 - Portas................................................................................................................................37
4.21.1 - Lista de portas............................................................................................................37
4.21.2 - Declarações de portas ................................................................................................37
4.21.3 - Regras de conexões de portas ....................................................................................38
4.21.4 - Conectando portas a sinais externos..........................................................................39
4.22 - Exemplos de estruturas de módulos.................................................................................40
4.22.1 - Nível de portas lógicas ..............................................................................................40
4.22.2 - Nível de fluxo de dados (RTL)..................................................................................41
4.22.3 - Nível comportamental ...............................................................................................41
4.23 - Bibliografia ......................................................................................................................42
5. O VERILOG E A FERRAMENTA DE SÍNTESE LÓGICA DA ALTERA ...........................43
5. 1 - Considerações iniciais.......................................................................................................43
A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 4

5.2 - Tipos de operadores ...........................................................................................................43


5.2.1 - Operadores aritméticos ................................................................................................44
5.2.2 - Operadores lógicos ......................................................................................................44
5.2.3 - Operadores relacionais ................................................................................................45
5.2.4 - Operadores de igualdade .............................................................................................45
5.2.5 - Operadores Bitwise......................................................................................................45
5.2.6 - Operadores de Redução ...............................................................................................45
5.2.7 - Operadores de deslocamento .......................................................................................46
5.2.8 - Operador de concatenação...........................................................................................46
5.2.9 - Operador de replicação................................................................................................46
5.2.10 - Operador Condicional................................................................................................46
5.3 - Definição de constantes .....................................................................................................47
5.4 - Estruturas if-else e case......................................................................................................47
5.4.1 - Estrutura if-else............................................................................................................47
5.4.2 - Estrutura case...............................................................................................................48
5.4.3 - Outras estruturas ..........................................................................................................48
5.5 - Controle de Eventos...........................................................................................................48
5.6 - Lógica Combinacional .......................................................................................................49
5.6.1 - Atribuições contínuas ..................................................................................................49
5.6.2 - Construções always .....................................................................................................49
5.7 - Lógica seqüencial...............................................................................................................50
5.7.1 – Implementando registradores......................................................................................50
5.7.2 - Implementando contadores..........................................................................................51
5.8 - Bibliografia ........................................................................................................................52
6. A PLACA FPGA E A FERRAMENTA MAX+PLUS II .........................................................53
6. 1 - Considerações iniciais.......................................................................................................53
6.2 – A placa de desenvolvimento .............................................................................................53
6.3 – A ferramenta de síntese lógica Max+Plus II .....................................................................55
6.3.1 – Utilizando o Max+Plus II............................................................................................57
6.4 – Realização dos testes na placa...........................................................................................61
6.5 – Bibliografia........................................................................................................................61

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 5

1. INTRODUÇÃO

Para muito de nós, a realização de um projeto de um sistema digital consiste em


determinarmos a função lógica que o sistema que queremos projetar deve apresentar como
resposta aos estímulos recebidos, e então construirmos um circuito lógico complexo que execute
essa função a partir de circuitos lógicos simples (portas OR, AND, XOR, Flip-flops, contadores,
registradores, etc.).

Mas, devido a complexidade dos sistemas atuais, esse tipo de projeto está se tornando
inviável devido a vários problemas que o projeto a nível de portas lógicas acarreta, tais como:

- Alto número de CI’s contendo os circuitos lógicos (portas lógicas) simples necessários;
- Atraso global do sistema alto devido a contribuição individual dos atrasos de cada porta
lógica individualmente;
- Alto custo do projeto;
- Necessidade de um grande layout físico para acomodar todos os componentes;
- Alto consumo do sistema;
- Possíveis erros de conexão e/ou mau contatos (confiabilidade do sistema);
- Possíveis indisponibilidades dos circuitos necessários no mercado, acarretando em atraso na
finalização dos projetos;
- Necessidade de protótipos para testes, que acarreta em mais gastos.

Junte a isso a evolução tecnológica que vem ocorrendo nos últimos 35 anos. Com a
evolução, ocorreu um aumento na capacidade de processamento dos sistemas, e isso acarretou
uma maior complexidade dos sistemas a serem projetados (e com isso um maior número de
portas lógicas necessárias ao projeto). E também gerou uma maior escala de integração dos CI’s,
que é a VLSI (Integração em Altíssima Escala).

Então, com a inviabilidade de se efetuar os projetos digitais da maneira convencional


(com portas lógicas), pesquisas foram implementadas a fim de se obter uma forma alternativa
mais viável de se efetuar os projetos em dispositivos que contivessem milhares de portas lógicas
internamente, e que essas portas pudessem ser programadas de acordo com a necessidade do
projeto a fim de implementar a função desejada (ao invés de ter que interligar uma quantidade
considerável de CI’s contendo portas lógicas, se usaria esse novo dispositivo). Esses estudos
geraram a chamada lógica programável.

Com a lógica programável surgiram vários novos dispositivos passíveis de serem


programados pelo projetista (seja enviando o projeto para a produtora dos dispositivos efetuar a
programação ou programando-o o próprio projetista). E, com esses dispositivos surgiu a
necessidade de uma nova forma de se projetar, pois as formas tradicionais de projetos baseados
em tabelas da verdade, em softwares de projeto lógico a partir de portas lógicas (o Eletronic
Workbech é um exemplo), entre outros, já não eram mais viável.

Dentre as novas técnicas que surgiram, a que despontou como a mais promissora é a
“descrição de hardware”. Nesta modalidade de projeto, o projetista, com o auxílio do
computador, descreve o hardware a ser projetado (o seu sistema digital) utilizando uma HDL
(Hardware Description Language – Linguagem de Descrição de Hardware). Uma HDL é muito
parecida com uma linguagem de programação de alto nível, como C ou Pascal. O projeto
utilizando HDL se torna parecido com a programação, uma vez que o projetista inicialmente não
A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 6

se preocupa com a tecnologia que vai ser utilizada na implementação do projeto, e sim com a
funcionalidade lógica do projeto.

Após a descrição ser feita, existem várias ferramentas de simulação para testar a
funcionalidade do projeto antes de sua implementação. E isto é importante porque reduz
drasticamente o tempo de testes, uma vez que não é necessária a construção de protótipos e que,
na ocorrência de um erro ou mudança no projeto, é muito simples se modificar a descrição do
sistema em HDL.

Ao término da etapa de teste é então escolhido o dispositivo que mais se adapte ao


projeto (número de portas, tempo de resposta, etc.) e então utilizamos um software de síntese
lógica, disponibilizado pelo fabricante do dispositivo, para convertermos a nossa descrição em
HDL para um arquivo que contenha os dados necessários para a programação do dispositivo. E.
uma vez realizada a programação, o dispositivo está pronto para ser utilizado.

Deve-se ressaltar que existem dispositivos programáveis que só podem ser programados
uma única vez (que são os que o projetista envia a descrição para o fabricante programar), e os
que podem ser reprogramados de acordo com a necessidade (que são os programáveis pelo
projetista).

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 7

2. A LÓGICA PROGRAMÁVEL

2.1 - O que é a Lógica Programável?

Os componentes da lógica programável são dispositivos que possuem em sua lógica


interna centenas (ou milhares) de portas lógicas, flip-flops e registradores; que são interligados
internamente. Essas interconexões são os pontos programáveis da lógica. Podemos então
programar essas conexões para permanecerem fechadas ou abertas, de acordo com a necessidade
do projeto.

Essas interconexões podem ser entendidas como fusíveis, que de acordo com a
necessidade do projeto podem ou não ser queimados (desfazendo ou não a conexão entre portas
lógicas). Essa “queima” é realizada pelo projetista, utilizando um software de programação do
dispositivo.

Existem vários tipos de dispositivos lógicos programável (PLD – Programmable Logic


Devices), como os mostrados abaixo:

- PLA
- PAL
- Dispositivos Lógicos Programáveis Complexos (CPLD)
- Arranjo de Portas Programáveis em Campo (FPGA)

Podemos também considerar as memórias PROM como dispositivos de lógica programáveis


se elas forem utilizadas para implementar funções lógicas.

2.2 - Memórias PROM

O conceito de programação de hardware (sistemas digitais) se materializou com a


necessidade de se construir unidades de memória, cujo conteúdo fixo, não era perdido ao se
desligar o sistema. Esta necessidade foi resolvida com a criação das memórias ROM, que
vinham de fábrica com o seu conteúdo já determinado. Com a evolução surgiram as memórias
PROM (ROM programável), cuja programação ocorria pela “queima” dos fusíveis internos
(interconexões entre as portas lógicas básicas que compõem a PROM).

Temos na figura a seguir o modelo de um PROM. Ela internamente nada mais é que uma
estrutura AND-OR, com a matriz AND fixa e a matriz OR programável. Então, podemos ver a
matriz AND da PROM como um decodificador completo de endereços que pode ser programado
a partir da matriz OR. Ao ser produzida, a PROM vem com todas as conexões internas. Para
programá-la devemos aplicar níveis de tensão apropriados a fim de manter ou não a conexão de
cada entrada de cada porta OR (“queimar” ou não os fusíveis internos). Só que uma vez feita a
programação, ela não pode ser desfeita. Com a evolução, sugiram novos tipos de ROMs que
solucionaram essa limitação das PROMs, que são as EPROMs apagáveis por radiação
ultravioleta, e as PROMs apagáveis eletricamente (EEPROM).

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 8

Fig.01 – Memória PROM de 8 x 2 bits

Então, podemos ver a PROM não apenas como uma memória apenas de leitura, mas
também como um circuito combinatório genérico de n entradas e m saídas, cuja função lógica
executada pode ser facilmente programável, como mostra a figura abaixo.

Fig. 02 – PROM vista como um circuito combinatório

Mas o uso de PROMs como dispositivos programáveis apresentam algumas


desvantagens, como por exemplo:

- A memória não aproveita as vantagens das técnicas de minimização porque implementam


diretamente a tabela da verdade;
A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 9

- Quando um sistema possui menos saída que o comprimento da palavra da memória, temos
porções de memória que não são utilizadas totalmente.

Por isso, os pesquisadores se empenharam em produzir dispositivos melhores que as


memórias para implementar projetos lógicos, esses componentes são chamados de Dispositivos
Lógicos Programáveis (PLD – Programmable Logic Devices).

2.3 - Os Dispositivos Lógicos Programáveis (PLD)

Dispositivos Lógicos Programáveis são dispositivos (circuitos integrados) configuráveis


pelo usuário usados para implementar uma grande variedade de funções lógicas, tanto
seqüenciais como combinacionais. PLDs podem implementar qualquer expressão booleana ou
função construída a partir de estruturas lógicas. Sua programação é efetuada pelo usuário
utilizando uma ferramenta computacional de síntese lógica fornecida pelo fabricante do
dispositivo.

Podemos ter PLDs com pontos internos de programação permanentes ou reprogramáveis.


Os pontos de programação são os “fusíveis” (conexões) que interconectam os elementos internos
do PLD. É através da queima ou não desses “fusíveis” que programamos o dispositivo.

Devido a complexidade da estrutura interna dos PLDs, podemos dividi-los em duas


categorias, como mostra a figura abaixo. E, em cada categoria temos os dispositivos mais
representativos.

PLD

Arranjos Arranjos
Lógicos de Portas
Programáveis Programáveis

PAL PLA FPGA CPLD

Fig. 03 – Divisão dos PLDs

É importante destacar que esses componentes têm o objetivo central de oferecer a


versatilidade, o baixo custo, a confiabilidade e a velocidade da microeletrônica em estruturas
menos rígidas que as tradicionais. E, para que esses dispositivos sejam utilizáveis de maneira
simples, os fabricantes oferecem programas de computador que, a partir de descrições
simplificadas do circuito que se deseja projetar (em HDL), consegue-se gerar rapidamente a
programação correta do dispositivo. Ressaltando-se que esses softwares, além de gerar o
conteúdo a ser gravado (programado) no componente, oferecem recursos de simulação
(verificação), documenta completamente o projeto e, ainda, gera roteiros de testes.

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 10

2.4 - Arranjos Lógicos Programáveis

Os dispositivos que são arranjos lógicos programáveis possuem uma estrutura interna
semelhante baseadas na estrutura interna AND-OR das PROMs. A estrutura consiste de um
número de entradas ligadas a número de portas AND. As saídas das portas AND são conectadas
as entradas de um número de portas OR, cujas saídas são as saídas do dispositivo. Nestes
dispositivos podemos ter tanto as duas matrizes de portas programáveis, quanto apenas a matriz
de portas AND programáveis. E isso gerou dois tipos de dispositivos: as PLAs e as PALs. Estes
dispositivos, assim como as PROMs, só podem se programados um única vez.

2.4.1 - PLA

A estrutura de uma PLA é muito semelhante a de uma PROM. Só que ela possui uma
menor quantidade de portas AND (não formando um decodificador completo), e possuindo tanto
a matriz de portas AND quanto a matriz de portas OR programáveis. Temos a seguir a estrutura
típica de uma PLA.

Fig. 04 – Estrutura típica de uma PLA

Possuindo as duas matrizes de portas programáveis, as PLAs possibilitam que o projetista


implemente termos minimizados (que não utilizam todas as entradas), como mostra o diagrama
simplificado abaixo (note que cada linha de entrada das portas AND representam todas as
entradas disponíveis na portas, estando apenas em notação simplificada).

Fig 05 – Implementação de uma função lógica usando PLA


A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 11

2.4.2 - PAL

Com o uso da PLA’s foram verificadas que existiam situações em que a flexibilidade da
matriz OR programável era desnecessária, o que não justificava o uso da PLAs. Além disso, a
existência das duas matrizes (AND e OR) programáveis acarretava uma grande propagação de
atraso entre a entrada e a saída do dispositivo (além de uma maior custo do dispositivo).

Por causa disso foi-se criado um dispositivo baseado no PLA só que mais simples, que é
o PAL. O PAL se assemelha ao PLA, tendo apenas a matriz de portas AND programável (a de
portas OR é fixa). Temos a seguir a estrutura interna simplificada de uma PAL.

Fig. 06 – Estrutura típica de uma PAL

Essa estrutura básica da PAL pode ser varia da em quatro alternativas básicas:

- Combinatório;
- Entrada/Saída Programada;
- Saídas com registradores e realimentação;
- Saídas com porta XOR.

O PAL mais simples, o combinatório, tem as saídas iguais as somas de produtos, sem
realimentação (o PAL da figura anterior). Os PALs mais complexos realimentam a saída de volta
para a entrada, permitindo que a saída seja também uma entrada. Outra característica de PALs
mais complexos e a existência de registradores na saída, que fornecem aos PALs a possibilidade
de sintetizar circuitos seqüenciais síncronos. Um tipo de PAL bem complexo é o que dispõe de
circuitos de saída que incorporam a porta XOR. Tais dispositivos são normalmente chamados de
aritméticos porque são sempre necessários quando se quer sintetizar unidades aritméticas.

2.5 - Arranjos de Portas Programáveis (Programmable Gate Array)

Os arranjos de portas programáveis são estruturas mais genéricas e versáteis que as


baseadas na estrutura típica de um PROM (PAL, PAL ou a própria PROM). Nestas estruturas
existem recursos de configuração e interligação mais genéricos que aqueles apresentados pelo
rígido esquema baseado na estrutura AND-OR. Os fabricantes destes tipos de dispositivos
garantem que com seu uso se consegue um fator de utilização de 80 a 90%, enquanto que com
PALs, tipicamente, utiliza-se apenas cerca de 15% de seus componentes.

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 12

Inicialmente, assim como as PROMs, estes componentes só eram passíveis de uma única
programação. Mas, com o desenvolvimento das técnicas de fabricação, surgiram as versões
programáveis em campo (que podiam ser reprogramadas de acordo com as necessidades do
projetista), dentre as quais podemos destacar os FPGAs e os CPLDs.

Devemos salientar que com o surgimento das versões programáveis em campo, as


versões programadas na fábrica não deixaram de existir. Pois componentes programáveis em
fábrica são sempre mais confiáveis, dispensam as etapas de programação e, dependendo do
volume, são mais baratos. Devido a esses fatores é que os fabricantes oferecem versões
programáveis em fábrica para os dispositivos programáveis em campo que dispõem. A idéia é
que sempre que se necessitar de componentes para elevadas quantidades, utiliza-se o
componente programável em campo para a construção dos protótipos, e uma vez terminado o
projeto e assegurado que se disponha da programação correta do dispositivo, o fabricante poderá
fornece-lo em versões programáveis de fábrica.

2.5.1 - CPLD (Complex PLD)

De uma maneira genérica os CPLDs (ou EPLDs – Erasable Programmable Logic Device)
podem ser vistos como dispositivos que agregam em sua estrutura vários PLDs (PLA ou PAL)
interligados por conexões programáveis, como ilustra a figura a seguir.

PLD PLD

Entradas Saídas

PLD PLD

Conexões Programáveis

Fig. 07 – Visão genérica de um CPLD

Na realidade, sua estrutura interna é formada por centenas de macrocélulas programáveis,


interligadas por conexões também programáveis (cada PLD da figura anterior seria, na verdade,
uma macrocélula). Cada macrocélula é composta por uma matriz AND-OR (com a matriz AND
programável e a OR fixa, como nos PALs) para implementar as funções lógicas combinacionais,
cujas saídas ativam módulos de entrada/saída (compostos por flip-flops e realimentações com
funções e interligações programáveis). Os pinos de E/S podem ser configurados como apenas
saída, apenas entrada, ou entrada/saída.

Os CPLDs são programáveis em campo, e podem ser reprogramados quantas vezes seja
necessário.

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 13

2.5.2 - FPGA (Field Programmable Gate Array)

Os FPGAs (Field Programmable Gate Arrays – Arranjo de Portas Programáveis em


Campo), em comparação com os PLDs, possuem uma arquitetura mais flexível baseada no
conceito de blocos lógicos. Um bloco lógico (BL) consiste de um certo número de portas lógicas
capazes de implementar uma grande variedade de funções lógicas dependendo de sua
programação, e pode ou não conter registradores. Temos em detalhe, na figura abaixo, a
estrutura interna de um BL típico do fabricante Xilinx, que consiste em dois registradores, um
número de multiplexadores e uma unidade de função combinatória (para implementar as funções
lógicas).

Fig 08 – Estrutura de um Bloco Lógico da Xilinx

Tipicamente, os blocos lógicos de um FPGA são idênticos, e cada bloco pode ser
programado individualmente para realizar um pedaço da lógica do projeto (decompondo a
função lógica geral do projeto em funções menores que serão implementadas pelos blocos
lógicos). A complexidade de um bloco lógico pode variar (não se limita a estrutura típica
mostrada acima) consideravelmente entre diferentes FPGAs, indo desde um bloco de
“granularidade fina” implementando uma ou duas funções lógicas de duas ou quatro variáveis,
até blocos de “granularidade grossa” implementando diversas funções lógicas de quatro a dez
variáveis.

Cada FPGA contém um grande número de blocos lógicos, tipicamente entre 50 e 250, e
algumas vezes mais. Cada bloco lógico é conectado aos outros blocos lógicos e aos pinos de E/S
por interconexões programáveis. Temos a seguir alguns exemplos de arquiteturas de FPGAs no
que diz respeito ao blocos lógicos e as interconexões programáveis.

Fig 09 – Exemplos de arquitetura de FPGAs com respeitos as interconexões entre blocos lógicos

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 14

Podemos entender as interconexões programáveis como um conjunto de fios e um


conjunto de chaves programáveis entre esses fios. As chaves são programadas para conectar ou
desconectar segmentos de fio, de forma a prover os caminhos de comunicação desejados. A
figura a seguir mostra um exemplo.

Fig. 10 – Exemplo de conexão entre Blocos Lógicos

2.6 - Considerações finais

Como já foi dito, para efetuarmos um projeto utilizando os dispositivos explicados,


necessitamos de uma nova técnica de projeto e de um software que permita realizar a
programação (software de síntese lógica).

Para o caso da programação, cada dispositivo possui o seu próprio software (de síntese
lógica) que é fornecido pelo fabricante. Resta, então, aprender uma nova técnica de projeto. E,
como também já foi mencionado, a técnica mais promissora nos dias atuais é a “descrição de
hardware”. Pois, além das linguagens de descrição de hardware estarem amplamente difundidas
e serem de fácil aprendizado (já que se parecem com uma linguagem de programação de alto
nível), os softwares de síntese lógica (que programam os dispositivos) aceitam o projeto em
linguagem de descrição de hardware para fazerem a programação dos dispositivos. E, dentre as
linguagens de descrição de hardware, a mais promissora nos dias atuais é o Verilog HDL.

Devemos salientar também que, para o usuário final, FPGA e CPLD podem ser vistas
como o mesmo tipo de estrutura. A única diferença está na sua estrutura interna, mas o seu
resultado final é o mesmo. O fato é que um dos grandes fabricantes, a Xilinx usa o nome FPGA,
enquanto outro grande fabricante, a Altera, usa o nome CPLD. Tanto faz usar uma ou a outra
(embora os fabricantes tentem mostrar que a sua estrutura interna é sempre melhor), que se
obtém o mesmo resultado. Na prática, tanto os FPGAs quanto os CPLDs são conhecidos como
FPGAs.

Existe atualmente uma nova tecnologia que permite usarmos um conceito chamado
“cache lógica” com FPGAs. A cache lógica é um meio mais barato de se implementar lógica
mais eficientemente. As funções ativas da aplicação que está sendo executada pelo FPGA podem
ser reconfiguradas durante a execução, enquanto funções inativas são armazenadas em uma
memória mais barata (um EPROM, por exemplo). Quando uma nova função é necessária, ela é
buscada na memória e escrita sobre as antigas. Ou seja, as funções vão sendo buscadas a medida
que são necessárias como em uma cache de computador. Essa técnica foi desenvolvida pela
A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 15

ATMEL Corporation e, segundo a ATMEL, com isso conseguimos um aumento muito grande da
utilização do FPGA, pois estudos seus mostram que em um FPGA de 10000 com uma função
que o utiliza por completo, apenas 2000 são utilizadas ao mesmo tempo. Então, utilizando essa
tecnologia para fazer a cache das outras 8000 portas podemos implementar essa mesma função
com um FPGA de 2000 portas (bem mais barato).

Finalizando, é interessante saber que os dispositivos reprogramáveis não existem apenas


na área digital. Existem circuitos reconfiguráveis analógicos, os FPAAs (Field Programmable
Analog Arrays); e os mistos (que misturam estruturam analógicas e digitais), os FPMAs (Field
Programmable Mixed Arrays).

2.7 - Bibliografia

1. FREGNI, Edson e SARAIVA, Antonio M. “Engenharia do Projeto Lógico Digital” Ed.


Edgard Blûcher LTDA, São Paulo, SP, 1995.

2. SEALS, R. C. & WHAPSHOTT, G. F. “Programmable Logic – PLDs and FPGAs”. Ed.


McGraw-Hill, USA, 1997.

3. DEWEY, Allen M. “Analysis and Design of Digital Systems with VHDL”. Ed. ITP, Boston,
MA, USA, 1997.

4. WESTE, Neil H. E. & ESHRAGHIAN, Kamran. “Principles of CMOS VLSI Design – A


System Perspective”. 2a Edition, Ed. Addison Wesley, Santa Clara, CA, USA, 1993.

5. “Altera Data Book”. Altera Corporation, 1996.

6. “Implement Cache Logic with FPGAs”. Aplication Note, Atmel Corporation, 1999.

7. “Programmable Logic Devices”. (www.eeng.dcu.ie/~scaifer/csh/pld/pld.html}

8. “FPGA Page”. (www.ele.auckland.ac.nz/students/chengms/fpga.htm)

9. “FPGA Research at University of Toronto”. (www.eecg.toronto.edu\EECG\RESEARCH\FPGA.html)

10. “FIPSOC: Field Programmable System on a Chip Family”. (www.sida.es\ftpsoc.htm)

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 16

3. AS LINGUAGENS DE DESCRIÇÃO DE HARDWARE

3.1 - Evolução dos sistemas digitais

O projeto de sistemas digitais têm se desenvolvido rapidamente nos últimos 35 anos. Os


circuitos digitais mais simples eram desenvolvidos com válvulas e transistores. Posteriormente
foram criados os circuitos integrados, quando passou-se a existir uma maior preocupação com os
espaços físicos ocupados por circuitos mais complexos. Os primeiros chips de circuitos
integrados foram os chips SSI (Integração em Pequena Escala) onde um pequeno número de
portas lógicas dividiam o mesmo espaço.

Com o começo da sofisticação tecnológica, os projetistas desenvolveram circuitos com


cerca de 100 portas (ou 100 transistores) em um mesmo chip. Esses chips foram chamados chips
MSI (Integração em Média Escala). Com o surgimento do LSI (Integração em Larga Escala), os
projetistas poderiam colocar milhares de portas em um único chip.

Neste ponto, os projetos começaram a ficar muito complexos, e os projetistas acharam


necessário automatizar todos os processos envolvidos nos projetos. E dessa forma, as técnicas de
CAD (Projetos Auxiliados por Computador) começaram a ser desenvolvidas. Os projetistas de
chip passaram a usar circuitos e técnicas de simulação lógica para verificar a funcionalidade de
blocos de construção da ordem de 100 transistores (ou portas lógicas). Até esta data, os circuitos
ainda eram testados sobre breadboards (protoboards) e o layout era feito no papel ou pelo
controle manual de um computador gráfico.

Com o surgimento da Tecnologia VLSI (Integração em Altíssima Escala), os projetistas


passaram a projetar chips com mais de 100.000 transistores. Devido a complexidade desses
circuitos já não era possível verificar o funcionamento desses circuitos sobre breadboard.
Técnicas de auxílio por computador começaram a ficar indispensáveis na verificação e no
projeto de circuitos digitais VLSI. Programas de computador para fazer automaticamente a
divisão do espaço disponível e rotinas de layout de circuitos também começaram a se difundir.
Os projetistas estavam agora construindo circuitos digitais ao nível de porta sobre terminais
gráficos. Eles construíam pequenos blocos e então formavam blocos em um nível arquitetural
mais alto a partir dos blocos mais simples. Esse processo continuaria até que se tivesse
construído todo o circuito. Simuladores lógicos eram então usados para verificar a
funcionalidade desses circuitos antes da fabricação do chip. Como os projetos foram ficando
mais e mais complexos, os simuladores lógicos assumiram um importante papel nos processos
do projeto.

3.2 - Surgimento das HDL’s

Ao longo do tempo, linguagens de programação (tais como FORTRAN, Pascal e C)


foram desenvolvidas para descrever programas de computador. Também no campo de projetos
digitais, os projetistas começavam a vislumbrar a necessidade de uma linguagem específica para
descrever circuitos digitais. Surgiram, então, as Linguagens de Descrição de Hardware (HDLs).
As HDLs podem descrever um sistema digital em vários níveis. Por exemplo, uma HDL pode
descrever o layout dos fios, resistores e transistores sobre um chip de circuito integrado, ou seja,
descrever o nível de layout. Ou ela pode descrever as portas lógicas e flip-flops em um sistema
digital, ou seja, o nível de portas lógicas. Em um nível mais alto ela descreve os registradores e
A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 17

os vetores de transferência de informação entre os registradores. Este é chamado de nível de


transferência entre registradores (RTL). Existe ainda o nível comportamental, em que se
descreve apenas a funcionalidade do projeto sem se preocupar com detalhes de implementação.

Ao contrário das linguagens seqüenciais (Pascal, FORTRAN, C, etc.), as HDL’s permitiram


aos projetistas modelarem os processos concorrentes encontrados nos elementos de Hardware.
Entre essas linguagens as que se tornaram mais populares foram a Verilog HDL e a VHDL.

A Verilog HDL foi introduzida em 1985 pela Gateway Design System Corporation. Até
maio de 1990, com a formação da Open Verilog International (OVI), a Verilog HDL era uma
linguagem de propriedade da Cadence Design Systems, conglomerado que tinha o controle da
Gateway Design System Corporation.

A VHDL foi desenvolvida em 1983 pelo departamento de defesa americano (DOD)


através de um programa chamado Very High Speed Integrated Circuits (VHSIC). Apesar de
difícil de aprender, VHDL passou a ser um padrão aceito pelo IEEE em 1987.

Atualmente ambos os padrões, Verilog e VHDL são amplamente aceitos pelos projetistas de
sistemas digitais.

3.3 - Fluxo Típico em um Projeto

Um típico diagrama de fluxo de projetos de circuitos VLSI IC é mostrado na figura


abaixo.
Especificações do Projeto

Descrições de procedimento

Descrições RTL (HDL)

Verificação Funcional de Testes

Síntese Lógica

Net List -- Nível-porta

Verificação lógica e teste

Plano de Fundo Automático

Layout físico

Verificação de layout

Implementação

Fig. 11 - Diagrama de fluxo típico de um projeto de um sistema digital

O diagrama de fluxo acima é tipicamente usado para projetos que usam HDL’s. Em
qualquer projeto, as especificações são definidas primeiro. As especificações descrevem de
A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 18

forma abstrata a funcionalidade, interface, e toda a arquitetura do circuito digital a ser projetado.
Neste ponto o projetista não precisa saber como implementar o circuito. A descrição de
funcionamento é então criada para analisar o projeto em temos da funcionalidade, performance,
submissão aos padrões e outras características de alto-nível. As descrições de funcionamento são
manualmente convertidas para as descrições RTL em uma HDL. O projetista tem que descrever
o fluxo de dados desejado no circuito digital. Deste ponto em diante, o processo é feito com o
auxílio de ferramentas de CAD (Computer-Aided Design).

As ferramentas de síntese lógica convertem a descrição RTL em uma descrição à nível de


portas lógicas. O nível de portas lógicas é uma descrição do circuito em termos de portas e
conexões entre elas. O nível de porta é a entrada para a ferramenta de rotas e distribuição física
dos elementos, a qual cria o layout. O layout é verificado e então o chip é fabricado.

A maior parte do tempo gasto no projeto de um circuito digital é concentrado na


otimização manual da descrição RTL do circuito. Depois da descrição RTL concluída,
ferramentas de CAD são usadas para assistir o projeto nos demais processos. Diminuindo-se o
tempo gasto no nível RTL pode-se reduzir o tempo de projeto de anos para poucos meses. É
também possível fazer mais interações no projeto em um curto período de tempo.

Com essa finalidade, ferramentas de síntese comportamental tem começado a surgir


recentemente. Essas ferramentas podem criar descrições RTL a partir da descrição da
funcionalidade do circuito (nível comportamental). Com o amadurecimento dessas ferramentas,
os projetos de circuitos digitais estão se tornarão similares à programação em alto-nível de
computadores. Os projetistas simplesmente implementarão o algoritmo com a HDL em um nível
muito abstrato. As ferramentas de CAD ajudarão os projetistas a converterem as descrições de
procedimento em um chip de circuito integrado.

É importante notar que apesar das ferramentas de CAD conseguirem automatizar os


processos e reduzirem o tempo de projeto, os projetistas serão ainda as pessoas que controlarão a
performance dessas ferramentas. Além disso, se usadas impropriamente, essas ferramentas de
CAD produzirão projetos ineficientes. Então torna-se necessário o uso de projetistas que
entendam as nuances das metodologias de projeto, usando as ferramentas de CAD para obter um
projeto otimizado.

3.4 - Importância das HDL’s

As HDL’s levam muita vantagem em relação aos projetos baseados apenas em esquemas
tradicionais.

• Os projetos podem ser descritos em um nível muito abstrato pelo uso de HDL’s.
Projetistas podem escrever suas descrições sem escolha prévia de uma tecnologia
específica de fabricação. Ferramentas de síntese lógica podem automaticamente
converter os projetos para qualquer tecnologia de fabricação. Se uma nova tecnologia
surgir, os projetistas não necessitam reprojetar seus circuitos. Eles simplesmente entram
com as descrições RTL e/ou comportamental na ferramenta de síntese lógica (desde que a
ferramenta suporte o nível de descrição usado) e ela então cria uma nova organização ao
nível de porta, usando a nova tecnologia de fabricação. A síntese lógica otimiza o circuito
na área e no tempo de processamento, adequando-o a nova tecnologia.
• Através da descrição em HDL’s, a verificação funcional do projeto pode ser feita
facilmente durante as etapas de projeto. Desde que projetistas trabalham em um nível
A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 19

mais alto de abstração (RTL ou comportamental), eles podem otimizar e modificar suas
descrições até que seja alcançada a funcionalidade desejada. A maior parte dos bugs do
projeto são eliminados nesse ponto. Isso causa uma redução significativa no tempo gasto
no projeto.

• Projetos com HDL’s são análogos a programas de computador. Uma descrição textual
com comentários é uma forma fácil de desenvolver circuitos e retirar seus problemas.
Eles também fornecem uma concisa representação do projeto comparado com os
esquemas elétricos tradicionais. Esses esquemas tradicionais são altamente
incompreensíveis para projetos muito complexos.

HDLs são certamente uma tendência no futuro. Com o rápido aumento da complexidade
dos circuitos digitais e com a sofisticação das ferramentas de CAD, HDLs provavelmente se
tornarão o único método de projeto de grandes sistemas.

3.5 - Tendências em HDL’s

A velocidade e complexibilidade dos circuitos digitais têm crescido rapidamente. Os


projetistas têm projetado em níveis cada vez mais altos de abstração, se preocupando apenas com
a funcionalidade dos circuitos e deixando os detalhes de implementação a cargo das ferramentas
de CAD. Essas ferramentas por sua vez vem se tornando sofisticadas o suficientemente para
fazerem implementações próximas do ótimo.

Certamente a tendência atual é projetar em HDL em um nível alto de abstração (RTL ou


comportamental) e empregar as ferramentas de síntese lógica para criar os nível de portas a partir
do nível projetado.

A síntese de funcionalidade surgiu recentemente. Com o melhoramento dessas


ferramentas, os projetistas irão conseguir projetar diretamente em algoritmos o comportamento
do circuito e então usar ferramentas de CAD para fazer a tradução e otimização nas demais fases
do projeto. A modelagem do comportamento dos circuitos será usada mais e mais com o
amadurecimento da síntese de funcionalidade.

Técnicas de “verificação formal” também vêm aparecendo no horizonte. A verificação


formal aplica técnicas de matemática formal para verificar a precisão das descrições em HDL e
estabelecer equivalência entre o nível RTL (e/ou comportamental) e o nível de portas. Contudo a
necessidade de descrever um projeto em HDL não irá desaparecer.

Para circuitos de alta velocidade como microprocessadores, o nível de portas provido


pelas ferramentas de síntese lógica não é ótimo. Nestes casos os projetistas misturam as
descrições em nível de portas com as descrições em níveis mais abstratos para conseguir
resultados melhores. Esta prática vai contra o paradigma de se projetar em alto-nível, mas
mesmo assim, é muito utilizada pelos projetistas devido a ineficiência das ferramentas de CAD
para esses circuitos de tempo crítico.

3.6 - Bibliografia

01. PALNIKTAR, Salmir. Verilog HDL – A Guide to Digital Design and Synthesis, Sun Soft
Press, California, EUA, 1996.
A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 20

4. VERILOG HDL

4.1 - O que é Verilog?

O Verilog é uma das duas maiores HDL (Hardware Description Language – Linguagem
de Descrição de Hardware) usadas pelos projetista de hardware na industria e mo meio
acadêmico (a outra é o VHDL). Ela é usada para descrever o comportamento e a estrutura de
uma parte de um hardware (ou ele todo), e é muito parecido com uma linguagem de
programação de alto nível (C, para ser mais preciso).

O Verilog foi desenvolvido entre 1984 e 1985 por Philip Moorby que necessitava de um
meio simples, intuitivo e efetivo de descrever circuitos digitais para modelagem, simulação e
análise. Em 1985 a linguagem se tornou propriedade da Gateway Design System Corporation,
que posteriormente foi adquirida pela Cadence Design Systems Inc., que desenvolveu a
linguagem. Até maio de 1990, quando foi criada a Open Verilog International (OVI), o Verilog
era uma linguagem proprietária da Cadence. Com o OVI a Cadence se sentiu motivada a abrir a
linguagem para domínio público com a expectativa que com isso aumentasse rapidamente a
aceitação da linguagem, e com isso a procura por suas ferramentas de desenvolvimento para
Verilog.

O padrão atual da linguagem Verilog é o IEEE1364 de dezembro de 1995.

4.2 - Por que usar o Verilog HDL?

Os sistemas digitais atuais são muito complexos. Em seus níveis de maior detalhamento,
verificamos que eles consistem de milhões de elementos (transistores ou portas lógicas). Então,
para sistemas digitais grandes, o projeto a nível de portas lógicas está morto. Por muitas décadas,
esquemas lógicos serviram como a linguagem para projetos digitais. Porém hoje em dia a
complexidade do hardware cresceu para um degrau no qual os esquemas lógicos não são mais
usuais e mostram apenas uma teia de conexões e não a funcionalidade do projeto. Desde 1970,
engenheiros de computação e engenheiros elétricos tem usado as HDL’s, das quais as
proeminentes são o Verilog e o VHDL. Porém o Verilog é usado pela maioria dos
desenvolvedores, dentre os quais os projetistas de empresas como a Sun Microsistems, Apple
Computer e Motorola.

A linguagem Verilog provê ao projetista digital a possibilidade de descrever um sistema


digital em uma grande faixa de níveis de abstração, e, ao mesmo tempo, provê acesso a
ferramentas de projeto por computador no auxílio ao projeto.

O Verilog permite expressar o projeto em termos de estruturas comportamentais,


deixando os detalhes da implementação para um estágio posterior do projeto. Uma representação
abstrata ajuda o projetista a explorar alternativas de arquiteturas através de simulações e detectar
falhas no projeto antes de começar um maior detalhamento do projeto.

Após terminar os testes com o projeto em Verilog em um nível comportamental, existem


ferramentas computacionais que compilam descrições em Verilog para uma descrição das
máscaras de um CI VLSI, e então enviar essa descrição para uma fábrica de CI para o mesmo ser
criado. Pode-se ainda converter uma descrição em Verilog em uma descrição para programar um
A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 21

FPGA (ou um ASIC, ou um PLD), onde o mesmo é testado e o projeto é aperfeiçoado para
depois ser enviado para uma fábrica de CI.

4.3 - Popularidade do Verilog HDL

O Verilog tem se tornado uma linguagem de descrição de hardware padrão por oferecer
características muito úteis aos projetistas digitais. Dentre as quais podemos destacar:

• O Verilog é uma HDL de propósito geral que é fácil de aprender e usar. Sua sintaxe é
similar a da linguagem de programação C. Projetistas com experiência de programação
em C vão achar fácil aprender Verilog.
• O Verilog permite que diferentes níveis de abstração sejam misturados em um mesmo
modelo. Então, pode-se definir uma parte do hardware em termos de portas lógicas, outra
em termos comportamentais, etc.
• As ferramentas de síntese lógica mais populares suportam o Verilog. Isto torna o Verilog
a linguagem de escolha dos projetistas.

4.4 - Aplicações do Verilog e outras linguagens HDL

As linguagens de descrição de hardware encontraram a sua principal aplicação em


Dispositivos Lógicos Programáveis (PLD – Programmable Logic Devices) em vários níveis de
complexidade, desde PLD’s simples até PLD’s complexos (CPLD – Complex PLD), e também
nos FPGA’s (Field Programmable Gate Array).

PLD’s são, de maneira simplificada, matrizes programáveis de estruturas de soma de


produtos (AND-OR). São utilizados em circuitos onde não é exigida muita flexibilidade nem
muita lógica seqüencial. Já os FPGA’s são dispositivos mais complexos, que consistem em
vários blocos lógicos em que o projeto é realizado. Essa divisão em blocos e a composição dos
mesmos varia de forma radical de fabricante para fabricante, não sendo aqui possível uma
explicação genérica deste dispositivo.

No caso específico do Verilog, temos que inicialmente (meio dos anos 80) ele era usado
para o projeto de ASIC´s (usando ferramentas de síntese para automaticamente criar e otimizar a
implementação). Atualmente, o Verilog também é usado (como já foi mencionando) nas áreas de
FPGA’s e PLD’s (que são sua aplicação principal).

Existem hoje em dia várias linguagens de descrição de hardware sendo utilizadas


atualmente. As mais populares são a Abel, Palasm e Cupl (usadas para projetos de dispositivos
com baixa complexidade), e a Verilog e VHDL (para grandes CPLD’s e FPGA’s).

4.5 - Limitações do Verilog

O Verilog é uma linguagem para projeto de sistemas digitais. Até o presente momento ele
não suporta trabalhar com sistemas e sinais analógicos.

O IEEE 1364 define apenas a linguagem Verilog e sua sintaxe, porém ele não descreve os
diferentes estilos do Verilog e quando usá-los.

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 22

Cada ferramenta de síntese suporta uma partição da linguagem Verilog (definida pelo
fabricante da ferramenta) e não toda a linguagem. Com isso a vezes é necessário se adequar
(alterar) o seu código (descrição em Verilog) para se usar determinada ferramenta de síntese.

4.6 - Níveis de abstração

Como já foi mencionado, uma descrição de um sistema digital em Verilog pode ser feita
em vários níveis de abstração, que são os diferentes estilos de escrita em Verilog. A abstração
define o nível de detalhamento necessário ao projeto, especificado por uma dada descrição
desejada. Esses níveis de abstração são:

1. Nível de Layout: É o nível mais baixo de abstração. O projeto neste nível é implementado em
termos de chaves, nós de armazenamentos, e das interconexões entre eles. Este nível
especifica as informações sobre o layout atual do projeto na pastilha de silício, e pode
também especificar informações detalhadas sobre temporização e possíveis efeitos
analógicos.

2. Nível de portas lógicas: Em seguida ao nível de layout vem o nível de portas lógicas. Aqui o
projeto é descrito como uma rede de portas lógicas e registradores, e das interconexões entre
os mesmos. Projetar neste nível é similar a descrever um projeto em termos de diagrama
lógico de portas lógicas. Já o layout e os efeitos analógicos são ignorados. No entanto, o
projeto contém informações sobre a função, a arquitetura, a tecnologia e a temporização.

3. Nível de Transferência de registros (RTL – Register Transfer Level): É também conhecido


como nível de fluxo de dados. Nesse nível usamos um estilo estrito do Verilog que define
cada registrador do projeto, e a lógica entre eles (o projeto especifica o fluxo dos dados).
Aqui, o projetista está preocupado em como os dados fluem entre os registradores. O projeto
contém informações sobre a arquitetura, mas não contém detalhes sobre a tecnologia.

4. Nível Comportamental: Este é o nível mais alto de abstração. Aqui descrevemos a função do
projeto sem especificar a arquitetura ou os registradores. O projeto pode ser implementado
em termos do algoritmo do projeto desejado sem detalhes da implementação de hardware.
Projetar neste nível é similar a programar em C.

4.7 - Nível comportamental x RTL

Como mostrado, existem quatro estilos distintos no Verilog. Os níveis de layout e de


portas lógicas não são adequados para sistemas com um número considerável de elementos,
sendo mais utilizados os níveis RTL e comportamental.

Vamos ver os casos os casos em que um desses níveis (RTL e comportamental) é mais
adequado que o outro:

• A razão para o RTL ser tão importante é que a maioria das ferramentas de síntese que
existem hoje requer que o código esteja escrito em RTL. E nesse nível o projetista ainda
mantém controle sobre a arquitetura dos registradores do projeto.
• Por outro lado, as ferramentas de síntese comportamental geram automaticamente
arquiteturas de portas lógicas e de registradores direto de uma descrição comportamental

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 23

em Verilog. Existem poucas ferramentas desse tipo e elas tendem a ser baseadas em
VHDL.
• Geralmente você precisa descrever seu projeto de FPGA ou PLD em RTL para usar as
ferramentas de síntese disponíveis.
• O nível comportamental é usado para criar estruturas de estímulos, para modelar partes
padrão do projeto, ou para criar especificações simuláveis do seu sistema.

Atualmente, as descrições são feitas utilizando conjuntamente os níveis RTL e


comportamental para dar maior flexibilidade ao projetista. E pra isso os fabricante já dispõem de
ferramentas de síntese lógica que suporta esses dois níveis de descrição (e também o de portas
lógicas, se for necessário).

4.8 - Conceitos principais da linguagem

1. Concorrência
Como o Verilog nos permite descrever hardware, ele também tem que ser capaz de descrever
atividades que estão ocorrendo em paralelo (atividades concorrentes).

A
B
S
C
D
Fig. 12 – Concorrência

2. Estrutura
Uma característica muito importante do Verilog é a capacidade de descrever estrutura ou
hierarquia. Descrições de estrutura podem ser misturadas com descrições de comportamento.
Também é possível ter apenas a descrição estrutural do projeto em Verilog ( que são as
netlists do Verilog).

A SUM
B U1 U2
Cin U1 CARRY

Fig. 13 – Estrutura hierárquica

3. Declarações de procedimentos
Uma descrição em Verilog pode também conter declarações que executam um após o outro
em seqüência como uma linguagem de software tradicional com C ou Pascal. Isso é
conhecido como declarações de procedimento.

4. Tempo
O Verilog nos permite modelar o conceito de tempo, que claramente é uma parte muito
importante da descrição de um sistema eletrônico.

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 24

4.9 - Metodologias de projeto

Existem 2 tipos básicos de metodologias para projetos digitais: metodologia de projeto


“top-down” e a metodologia de projeto “botton-up”.

Na metodologia “top-down” nós definimos o bloco de nível superior do projeto e


identificamos os sub-blocos necessários para construir o bloco de nível superior. Subdividimos
então os sub-blocos até chegarmos em células básicas (blocos que não podem ser subdivididos),
como mostra a figura abaixo.

BS

SB SB SB SB

CB CB CB CB CB CB CB CB

Fig. 14 – Metodologia top-down

Na metodologia “bottom-up” nós primeiro identificamos os blocos que possuímos e a


partir deles construímos blocos maiores até chegarmos no bloco de nível superior, como mostra a
figura abaixo.

BS

SB SB SB SB

CB CB CB CB CB CB CB CB

Fig. 15 – Metodologia bottom-up

Usualmente usamos uma combinação dessas 2 metodologias. Especificamos o bloco de


nível superior e vamos dividindo-o ao mesmo tempo em que identificamos os blocos que já
possuímos e vamos agrupando-os para formar blocos maiores.

4.10 - Estrutura dos módulos

Agora vamos começar a ver como estruturamos o código em Verilog para fazer a
representação de um projeto. Um projeto é formado a partir da construção de blocos, e no
Verilog cada bloco é chamado de módulo. O módulo é o equivalente a um símbolo em um
projeto baseado em esquema elétrico.

A primeira coisa que temos que fazer quando desenvolvemos um bloco é dar a ele um
nome único. Em seguida temos que definir as interfaces desse projeto e especificar quais são
A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 25

entradas, saídas ou portas bidirecionais. Nós temos que incluir informações sobre a
funcionalidade que é implementada pelo bloco.

Nós podemos ainda ter a necessidade de incluir blocos de nível inferior no projeto. Para
isso temos que definir quais são esses blocos e como eles são interconectados. A esse processo
dá-se o nome de hierarquia.

O bloco abaixo sintetiza tudo o que foi enunciado.

BlocoA
Entrada 1 Saída 1
Bloco X
Entrada 2 Saída 2
f Bloco Y

Fig. 16 – Estrutura de um módulo

O módulo pode ser um elemento ou uma coleção de blocos de projeto de nível inferior.
Tipicamente, os elementos são agrupados em módulos para prover uma funcionalidade comum
que é usada em várias partes do projeto. Um modulo provê a funcionalidade necessária para o
bloco de nível superior através de sua interface de portas (entradas e saídas), mas esconde a
implementação interna. Isto permite ao projetista modificar o conteúdo de um módulo sem afetar
o resto do projeto.

Um modulo é declarado pela keyword module e seu término com a keyword endmodule.
Todo módulo deve conter um identificador para o módulo (seu nome), o module_name,
acompanhado de uma descrição das entradas e saídas do módulo, o module_terminal_list. Deve
conter também a definição de quem é entrada/saída e a descrição de sua funcionalidade, o
module_internals.

module<module_name>
.
.
.
<module_internals>
.
.
.
endmodule

O Verilog é uma linguagem tanto estrutural quanto comportamental. O conteúdo de cada


módulo, como já foi explicado, pode ser definido em 4 níveis de abstração, dependendo da
necessidade do projeto. O módulo se comporta identicamente com o ambiente externo
independente do nível de abstração no qual é descrito (o conteúdo do módulo é invisível para o
ambiente). Então, podemos mudar o nível de abstração que descreve o módulo sem a
necessidade de mudanças no ambiente.

O Verilog permite ao projetista misturar e casar os 4 níveis de abstração em um mesmo


projeto. Se um projeto contém 4 módulos, o Verilog permite que cada modulo seja escrito em
um nível de abstração diferente.
A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 26

Quanto mais alto o nível de abstração, mais flexível e independente da tecnologia é o


projeto. Quanto mais baixo o nível de abstração (aproximando do nível de layout), mais
dependente da tecnologia e inflexível se torna o projeto. Considere a analogia com a
programação em C e em Assembly. É fácil programar em uma linguagem de alto nível como o
C, e o programa pode ser facilmente portado para qualquer máquina. No entanto, se o programa
é em assembly, ele é escrito para uma máquina específica e não é facilmente portável para outra
máquina.

4.11 - Projeto hierárquico

A hierarquia de um projeto descreve a forma na qual ele é dividido em sub-blocos


recursivamente até eventualmente chegarmos a um nível de célula básica. É importante entender
hierarquia para se entender os conceito de projeto hierárquico.

Bloco A

Bloco X Bloco Y Bloco Z

Bloco D Bloco B Bloco D Bloco E Bloco B Bloco C

Fig. 17 – Projeto hierárquico

Acima temos o diagrama que mostra os sub-blocos que formam o bloco A e a sua
hierarquia dentro do bloco.

As vantagens que obtemos ao fazer uso da hierarquia são:

• Ao dividir o projeto em partes menores se torna mais fácil encontrar e depurar erros, já que o
projetista irá lidar com pedaços menores de código.
• Pedaços da lógica (sub-blocos) podem ser identificados e reusados em outras partes do
projeto apenas instanciando ("chamando") o sub-bloco quando necessário.
• Um projeto em blocos pode ser distribuído entre vários projetistas.

4.12 - Instâncias

Um módulo é um modelo, a partir do qual você pode criar objetos. Quando um módulo é
chamado, o Verilog cria um objeto único a partir do modelo. Cada objeto tem seu próprio nome,
variáveis, parâmetros e interfaces de E/S. O processo de criar um objeto a partir de um módulo
modelo é chamado instanciação, e os objetos são chamados de instâncias. No exemplo abaixo
(contador de 4 bits) o bloco de nível superior cria 4 instâncias do flip-flop T (T_FF) modelo, que
por sua vez instância um D_FF e uma porta inversora. Observe que cada instância deve possuir
um nome único.

Atente para o fato de que no Verilog é ilegal cascatear módulos (um dentro do outro), só
é permitido instanciar.

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 27

Contador
q0 q1 q2 q3
de 4 bits

q q q q
clock T_FF T_FF T_FF T_FF
tff 0 tff 0 tff 0 tff 0

reset

Fig. 18 – Contador de 4 bits

d
q
clock D_FF

reset

Fig. 19 – Flip-flop D

Temos a seguir a descrição em Verilog.

module ripple_carry_ counter(q, clk, reset);

output [3,0] q;
input clk, reset;

T_FF tff0(q(0), clk, reset); // 1ª instância do T_FF


T_FF tff1(q(1), q(0), reset); // 2ª instância do T_FF
T_FF tff2(q(2), q(1), reset); // 3ª instância do T_FF
T_FF tff3(q(3), q(2), reset); // 4ª instância do T_FF

endmodule

module T_FF(q, clk, reset);

output q;
input clk, reset;
wire d;

D_FF dff0(q, d, clk, reset); // instância de D_FF


not n1(d, q) // a porta inversora é uma porta básica do Verilog

endmodule

4.13 - Representando hierarquia

A hierarquia é representada pela instanciação. Instanciando blocos de níveis inferiores


(sub-blocos) nós podemos usar sua funcionalidade, mas não precisamos descrever sua

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 28

funcionalidade neste nível. Podemos descrever o módulo de nível inferior em qualquer outro
lugar.

No entanto isso significa que o módulo pode ter dois tipos de nomes: nomes de referência
e nomes de instância. Para não gerar confusão vamos ver um exemplo de um somador completo
feito a partir de dois meio somadores. Isso nós dá dois níveis de hierarquia.

somador completo

meio somador meio somador


Fig. 20 – Estrutura hierárquica de um somador completo

Neste caso, o bloco meio somador, com nome de referência HALF_ADD é instanciado
duas vezes. Então precisamos de dois nomes de instância U1 e U2 para distinguí-los.

FULL ADD
A SUM
HALF_ADD HALF_ADD
B U1 U2

Cin
OR CARRY

Nomes de instância

Fig. 21 – Instâncias em um somador completo

Tipicamente você vai instanciar o nível mais alto do seu projeto em um módulo de
estímulo (que serve para testar a funcionalidade do projeto), que então passará a ser o seu bloco
de nível superior.

4.14 - Componentes de uma simulação

Uma vez que um projeto ou parte dele é completado, é uma boa prática testá-lo. A
funcionalidade do bloco projetado pode ser testada aplicando-se estímulos e checando os
resultados. Nós chamamos o bloco que faz isso de módulo de estímulo. É uma boa prática
manter o projeto e módulo de estímulo em arquivos separado e identificar os dois como fazendo
parte de um mesmo projeto maior.

Dois estilos de aplicação de estímulos são possíveis. No primeiro estilo o módulo de estímulo
instancia o módulo do projeto e mando e recebe sinais do mesmo (o bloco de estímulo não
possui nem entradas nem saídas).

No segundo estilo, os blocos de estímulo e projeto são instanciados em um módulo de teste


(novo bloco de nível superior). O bloco de estímulo então interage com o projeto através de suas
interfaces.

Temos a seguir um esquema ilustrativo desses dois estilos de simulação.

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 29

Bloco de estímulo Bloco de teste


(estímulos)

módulo módulo

módulo projetado de do

estímulo projeto

(resultados)

Fig. 22 – Estilos de simulação

4.15 - Nomes hierárquicos

Como foi visto o Verilog suporta uma metodologia de projeto hierárquico. Cada instância
de um módulo é definida com um identificador (seu nome de instância). Cada identificador em
particular tem uma posição única na hierarquia do projeto. Um nome hierárquico é uma lista de
identificadores separados por pontos para cada nível de hierarquia. Então, cada identificador
pode ser endereçado de qualquer lugar do projeto simplesmente especificando o nome
hierárquico correspondente desse identificador.

O módulo de nível superior é chamado de módulo raiz porque ele não é instanciado em
nenhum lugar do projeto. Ele é o ponto de partida. Normalmente o módulo de nível superior é
um módulo de estímulo (para testar o projeto).

Para identificar o nome único de um identificador, comece do módulo de nível superior e


trace o caminho através do projeto hierárquico até o identificador desejado. Para ficar mais claro
esse processo, vamos considerar o exemplo abaixo, já visto anteriormente.

ESTÍMULO

FULL ADD
L1
A SUM
HALF_ADD HALF_ADD
B U1 U2 L3

Cin
L2 OR CARRY

Fig. 23 – Módulo de estímulo do somador completo

Para essa simulação, o módulo ESTÍMULO é o módulo de nível superior. Como ele não é
instanciado em parte alguma, ele é o módulo raiz. Os identificadores definidos nesse módulo são
A, B, Cin, SUM e CARRY. Módulo raiz instancia U1 (com o identificadores a, b, L1 e L2) e U2
(com os identificadores (L1, cin, sum L3), que são módulos do tipo HALF_ADD e uma porta
básica OR (com os identificadores L2, L3, cr). Como a porta OR é um bloco básico do Verilog e
só é usado uma vez não é necessário instanciá-la. A partir dai podemos identificar os nomes
hierárquicos, que são:

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 30

ESTÍMULO ESTÍMULO.FULL_ADD.HALF_ADD.U1
ESTÍMULO.FULL_ADD ESTÍMULO.FULL_ADD.HALF_ADD.U2
ESTÍMULO.FULL_ADD.A ESTÍMULO.FULL_ADD.HALF_ADD.U1.A
ESTÍMULO.FULL_ADD.B ESTÍMULO.FULL_ADD.HALF_ADD.U1.B
ESTÍMULO.FULL_ADD.Cin ESTÍMULO.FULL_ADD.HALF_ADD.U1.L1
ESTÍMULO.FULL_ADD.SUM ESTÍMULO.FULL_ADD.HALF_ADD.U2.L1
ESTÍMULO.FULL_ADD.CARRY ESTÍMULO.FULL_ADD.OR.CARRY

A partir dai você pode identificar os outros nomes hierárquicos.

4.16 - Exemplos de módulos

Vamos agora mostrar 2 exemplos simples de módulos para mostrar de uma forma geral
como uma descrição é feita no Verilog.

4.16.1 - Meio somador

HALF ADD
A SUM
XOR

B AND CARRY

Fig. 24 – Estrutura de um meio somador

A palavra chave module define o começo de cada descrição de módulo e é seguida pela lista
de portas. Após a lista de portas vem a declaração das portas. Cada porta é declarada com
entrada, saída ou entrada/saída. Você pode especificar portas como barramento declarando que a
porta tem um comprimento nas declarações de entrada ou saída.

Finalizando descrevemos o comportamento do módulo. Neste caso temos duas atribuições de


sinais: o resultado de "A xor B" é atribuído para a saída SUM, e o resultado de "A and B" e
atribuído para a saída CARRY.

A seguir temos o código em Verilog para esse módulo.

module HALF_ADD(A, B, SUM, CARRY);


output SUM, CARRY;
input A, B;
assign SUM=A^B;
assing CARRY=A&B;
endmodule

4.16.2 - Somador completo

Agora, para demonstrar o uso de hierarquia vamos ver o código de um somador


completo, incorporando dois dos meios somadores projetados no exemplo anterior.

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 31

FULL ADD
I1
A SUM
HALF_ADD HALF_ADD
B U1 U2 I3

Cin
I2 OR CARRY

Fig. 25 – Estrutura do somador completo

O nome do módulo e lista de portas são seguidos das declarações locais. Nosso
FULL_ADD contém os sinais I1, I2 e I3 que são locais ao projeto (não são nem entradas nem
saídas). Sinais locais são declarados no seu respectivo módulo, após a declaração das portas.

Em seguida vem a instanciação dos 2 meio somadores (U1 e U2). E, como parte da
instanciação, temos que definir as conexões aos terminais dos meio somadores (na mesma
seqüência definida no módulo HALF_ADD). As conexões aos módulos HALF_ADD são feitas
pela posição: a primeira porta listada no HALF_ADD (porta A) é conectada a primeira porta
listada na instanciação do HALF_ADD no módulo FULL_ADD (porta A), e assim por diante.

Nós ainda temos uma pequena seção de código que descreve a função OR que é requeria
pelo somador completo. E, finalmente declaramos o fim da descrição do módulo. Note que o
conteúdo do meio somador não é definido neste nível (é apenas instanciado).

A seguir temos o código em Verilog para esse módulo.

module FULL_ADD(A, B, Cin, SUM, CARRY);


output SUM, CARRY;
input A, B, Cin;
wire I1, I2, I3;
HALF_ADD U1(A,B, I1, I2);
HALF_ADD U2(I1, Cin, SUM, I3);
assign CARRY=I2 | I3;
endmodule

4.17 - Conceitos básicos

Para se fazer uma descrição em Verilog é necessário ter conhecimentos das várias partes que
compõem a descrição (como estruturar um módulo, como definir entradas e saídas, as
convenções léxicas usadas, os tipos de dados aceitos pela linguagem, etc.), ou seja, dos conceitos
básicos inerente ao Verilog.

Nos itens a seguir teremos uma visão geral acerca desses conceitos para com isso
proporcionar uma motivação para um posterior estudo mais aprofundado da linguagem. Atente
ao fato de que os conceitos estruturais inerentes ao Verilog que serão apresentados a seguir estão
apenas dando uma visão geral para que você possa começar a dar os primeiros passos em
Verilog, e não para que você saia já programando (o quer requer um estudo bem mais detalhado
e dedicado).

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 32

4.18 - Convenções léxicas

As convenções léxicas básicas usadas pelo Verilog são similares as usadas na linguagem C.
O Verilog possui muitos marcadores. Marcas podem ser comentários, delimitadores, números,
strings, identificadores, e palavras-chaves. O Verilog é uma linguagem case sensitive, isto é, ela
diferencia as letras maiúsculas das minúsculas. E, todas as palavras-chaves devem ser escritas
em minúsculas.

4.18.1 - Espaços em branco

Espaços em branco (\b), tabulações (\t) e novas linhas (\n) compreendem o espaço em
branco. Os espaços em brancos são ignorados pelo Verilog, exceto quando estão separando
marcas. Os espaços em branco não são ignorados em strings.

4.18.2 - Comentários

Como na linguagem C, os comentários de uma linha começam com “//”. Comentários de


múltiplas linhas começam com “/*” e terminam com “*/”.

4.18.3 - Operadores

O Verilog aceita três tipos de operadores: unário, binário e ternário. Operadores unários
precedem o operando. Os operadores binários aparecem entre os operandos. Os operadores
ternários possuem dois operadores separados que separam três operandos.

a = ~ b // ~ é um operador unário. b é o operando


a = b && c // && é um operador binário. b e c são operandos
a = b ? c : d // ?: é um operador ternário. b, c e d são os operandos.

4.18.4 - Especificações de números

- Números com comprimento definido:


São representados como: <comprimento>’<base numérica><número>

- Números sem comprimento definido:


São representados como: ‘<base numérica><número>
Os números sem a definição da <base numérica> são entendidos como decimal.

- Valores X e Z:
O x denota um número desconhecido, e o z denota alta impedância.
Um x ou um z definem 4 bits para um número hexadecimal, 3 bits para um número octal
e 2 bits para um número binário. Se o bit mais significativo é um 0, x ou z, e você não
define os bits restantes, os bits mais significativos restantes são automaticamente
preenchido, respectivamente, com 0, x ou z. Se o bit mais significativo for um 1, o
restante será preenchido com 0.

- Números negativos:
São definidos colocando-se um sinal “-“ antes do <comprimento> do número.

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 33

- Caracteres “_” e “?”:


O “_” é usado para facilitar a leitura do número (usamos para separar o número), já que
não tem efeito algum sobre o mesmo (exceto se for colocado antes do número). A “?” é
uma alternativa para o z (alta impedância) no contexto dos números.

Temos a seguir exemplos de especificações de números.

4’b1111 // Número binário de 4 bits


12’habc // Número hexadecimal de 12 bits
16’d255 // Número decimal de 16 bits
23456 // Número decimal sem comprimento definido
‘hc3 // Número hexadecimal sem comprimento definido
12’h13x // Nº hexa de 12 bits (4 bits menos significativos desconhecidos)
6’hx // Nº hex a de 6 bits (todos desconhecidos)
32’bz // Nº binário de 32 bits (todos em alta impedância)
-6’d3 // Nº negativo de 6 bits armazenado em complemento de dois
12’b1111_0000_1010 // Uso de _ para facilitar a leitura do número
4’b10?? // Equivalente a 4’b10zz

4.18.5 - Strings

Uma string é uma seqüência de caracteres delimitados por aspas. A restrição é que uma
string deve ser de apenas uma linha.

4.18.6 – Identificadores e palavras-chave

Palavras-chave são identificadores especiais reservados para definir as estruturas da


linguagem. As palavras-chave devem estar em minúsculas. Procure conhecer as palavras-chaves
em algum livro ou tutorial sobre o Verilog.

Identificadores são nomes dados a objetos para que os mesmos possam ser referenciados no
projeto. Identificadores podem conter caracteres alfanuméricos, “_” e $, porém não podem
iniciar pelo “&” ou por um número.

4.19 - Tipos de dados

4.19.1 - Definição de valores

O Verilog suporta 4 valores e oito pesos para modelar a funcionalidade de sistemas reais.
Temos abaixo esses 4 valores e a definição dos pesos.

Nível de Valor Condição em circuitos digitais


0 Zero lógico, condição falsa
1 Um lógico, condição verdadeira
x Valor desconhecido
z Alta impedância, estado flutuante

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 34

Nível de peso Tipo Degrau


suplly Transmissão Maior prioridade
strong Transmissão
pull Transmissão
large Armazenamento
weak Transmissão
medium Armazenamento
small Armazenamento
highz Alta impedância Menor prioridade

Se tivermos um sinal pull e um sinal weak ao mesmo tempo em um fio, o valor do pull irá se
sobressair sobre o weak (esse pensamento vale para todos os níveis). Se os sinais são de pesos
iguais o resultado é um valor desconhecido.

4.19.2 - Nets

Nets representam conexões entre elementos digitais. Seriam as interconexões entre os


elementos (os fios). Nets são declaradas pela palavra-chave wire. O valor padrão de um net é z.

4.19.3 - Registradores

Os registradores representam elementos de armazenagem de dados. Eles retém o valor até


que um novo valor seja escrito neles. Não confunda o termo registrador do Verilog com os
registradores reais. No Verilog o termo registrador se refere a uma variável que pode armazenar
valor.

Os registradores são definidos pela palavra-chave reg (reg reset, é um exemplo de definição
de um registrador).

4.19.4 - Vetores

Nets ou registradores podem ser declarados como vetores (de comprimento de múltiplos
bits). Se o número de bits não é especificado o Verilog toma como padrão 1.

wire [7:0] bus // Barramento de 8 bits


reg [0:40] sum // Variável reg de 41 bits

Note que o bit da esquerda (não importa a definição do vetor) é o bit mais significativo.

4.19.5 - Registros de tipos de dados integer, real e time

Integer: é um registro de tipos de dados de propósito geral usado para manipular quantidades.
São declarados pela palavra-chave integer.

Real: número reais constantes e registros de tipos de dados real são declarados pela palavra-
chave real. Podem ser especificados em notação decimal ou científica. Ele não deve conter
uma declaração de comprimento. Seu valor padrão é 0.

Time: simulações no Verilog terminam com seus respectivos tempos de simulação. O time é
usado para armazenar tempo de simulação. É declarado pela palavra-chave time.

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 35

4.19.6 - Arrays

Arrays são permitidos para reg, integer, time e vetores (não são permitidos para variáveis
reais). É importante não confundir array com vetor. Um vetor é um elemento de n-bits de
comprimento, enquanto um array é composto de n elementos de 1-bit ou n-bits de comprimento.
Temos abaixo alguns exemplos.

integer count[0:7] // Array de 8 variáveis count


reg [4:0] port_id [0:7] // Array de oito port_id, cada port_id com 4 bits

4.19.7 - Memórias

As memórias no Verilog são simples arrays de registros (como no segundo item do exemplo
anterior).

4.19.8 - Parâmetros

Usamos a palavra-chave parameter para definir constantes. Os parâmetros não podem ser
usados como variáveis.

4.19.9 - Strings

Strings devem ser armazenadas em variáveis do tipo reg. O comprimento do registrador deve
ser suficiente para acomodar toda a string.

4.20 - Módulos

Vamos agora analisar o conteúdo de um módulo. Um módulo no Verilog consiste de várias


partes distintas, como mostrado abaixo.

Nome do módulo
Lista de portas, declarações das portas (se existirem portas)
Parâmetros (opcional)

Declarações de wires, Declarações de fluxo de dados


regs e outras variáveis (assign)

Instanciação de módulos Blocos always e initial. Todas declarações


de nível inferior comportamentais vão nesses blocos

Funções e tarefas

Declaração endmodule

Fig. 26 – Conteúdo de um módulo

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 36

A definição de um módulo sempre inicia com a palavra-chave module. O nome do módulo,


lista de portas, declarações das portas e o opcional parâmetros devem vir primeiro na definição
do módulo. Lista de portas e declarações de portas estão presentes apenas se o módulo contiver
portas para interagir com o ambiente externo. Os cinco componentes pertencente ao módulo são:
declarações de variáveis, declarações de fluxo de dados, instanciação de módulos de níveis
inferiores, blocos comportamentais, e funções e tarefas. Estes componentes podem estar em
qualquer ordem e em qualquer lugar na definição do módulo. A declaração endmodule deve
sempre vir por último na definição do módulo. Todos os componentes exceto module, nome de
módulo e endmodule são opcionais é podem ser misturados e casados de acordo com a
necessidade do projeto. O Verilog permite que vários módulos sejam definidos em um mesmo
arquivo. Estes módulos podem vir em qualquer ordem no arquivo.

Para entender os componentes de um módulo mostrados acima, vamos considerar um


exemplo simples de um latch SR, confirme a figura a seguir.

Sbar
(set) Q

Rbar Qbar
(reset)

Fig. 27 – Latch RS

O latch SR tem S e R como portas de entrada e Q e Qbar como portas de saída. O latch SR e
seu bloco de estímulo podem ser modelados conforme o código abaixo.

module SR_latch(Q, Qbar, Sbar, Rbar);


output Q, Qbar;
input Sbar, Rbar;
nand n1(Q, Sbar, Qbar); // Instanciação da porta nand
nand n2(Qbar, Rbar, Q);
endmodule

module estimulo;
wire q, qbar;
reg set, reset;
SR_latch m1(q, qbar, ~set, ~reset);

initial
begin
$monitor($time “set = %b, reset = %b, q = %b\n”, set, reset, q);
set = 0; reset = 0;
#5 reset = 1;
#5 reset = 0;
# 5 set = 1;
end

endmodule

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 37

Perceba as seguintes características sobre os módulos definidos acima.

• Na definição do latch SR, perceba que todos os componentes descritos na figura acima estão
presentes no módulo. Nós não temos declarações de variáveis, declarações de fluxo de
dados, ou blocos comportamentais (always ou initial).
• No entanto, o bloco de estímulo contém declarações nome de módulo, wire, reg, e
declarações de variáveis, instanciação de módulos de nível inferior, bloco de
comportamento (initial) e endmodule, mas não contém lista de portas, declaração de portas,
e declarações de fluxo de dados (assign).
• Então, todas as partes exceto module, nome do módulo, e endmodule são opcionais e podem
ser misturados e casados de acordo com as necessidades do projeto.

4.21 - Portas

As portas provêm a interface pela qual o módulo se comunica com o ambiente. Por exemplo,
os pinos de E/S de um CI são as suas portas. O ambiente interage com o módulo através das
portas. O conteúdo do módulo não é visível para o ambiente. Isto provê uma flexibilidade muito
poderosa ao projetista. O conteúdo do módulo pode ser mudado sem afetar o ambiente desde que
a interface não seja modificada. Portas são também chamadas de terminais.

4.21.1 - Lista de portas

A definição de um módulo contém uma opcional lista de portas. Se o módulo não troca
sinais com o ambiente, não há portas na lista. Considere um somador completo de 4 bits
instanciado em um módulo de estímulo, conforme a figura abaixo.

estimulo

a somador sum
completo
b (4 bits)
c-in fulladd4 c-out

Fig. 28 – Somador completo de 4 bits

Note que o módulo estimulo é o bloco de nível superior. O módulo fulladd4 tem como
portas de entrada a, b e cin e como portas de saída sum e carry. Então, fulladd4 se comunica com
meio externo. Já o módulo estimulo não necessita de se comunicar com o ambiente, ele apenas se
comunica com fulladd4, então não necessita de um lista de portas. Temos abaixo um exemplo da
declaração desses módulos e de suas listas de portas.

module fulladd4(sum, c_out, a, b, c_in); // módulo com uma lista de portas


module estimulo; // módulo sem lista de portas (não contém portas)

4.21.2 - Declarações de portas

Todas as portas na lista de portas devem ser declaradas no módulo. As portas podem ser
declaradas como input (porta de entrada), output (porta de saída) ou inout (porta bidirecional).
Veja a seguir a declaração das portas do fulladd4.
A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 38

module fulladd4(sum, c_out, a, b, c_in)


output [3:0] sum;
output c_out;
input [3:0] a, b;
input c_in;
...
<module internals>
...
endmodule

Note que todas as declarações de portas são implicitamente declaradas como wire no
Verilog. Então, se uma porta deve ser declarada como wire, é suficiente declará-la como output,
input ou inout. As portas input e inout são normalmente declaradas como wire. No entanto, se a
porta output deve armazenar algum valor, ela deve ser declarada como reg. Portas input e inout
não podem ser declaradas como reg porque as variáveis reg armazenam valores e esses tipos de
portas apenas refletem as mudanças dos sinais externos a que são conectadas.

4.21.3 - Regras de conexões de portas

Podemos visualizar uma porta como consistindo de duas unidades, uma interna ao módulo e
outra externa ao mesmo. As unidades internas e externas são conectadas. Existem regras que
governam a conexão de portas quando módulos são instanciados em outros módulos. O Verilog
funcionará de maneira anômala se essas regras forem violadas. Essas regras estão ilustradas na
figura abaixo.
net

net inout

input output

reg ou net net reg ou net net

Fig. 29 – Regra de conexão de portas

- Input:
Internamente, portas do tipo input devem sempre ser do tipo net. Externamente, elas
podem ser conectadas as variáveis reg ou net.

- Output:
Internamente, portas output podem ser do tipo reg ou net. Externamente, elas devem ser
sempre conectadas com nets.

- Inout:
Internamente devem ser sempre do tipo net. Externamente, inouts devem sempre ser
conectadas as nets.

- Portas desconectadas:
O Verilog permite que deixemos portas desconectadas. Você pode deixar uma porta
desconectada instanciando um módulo como é mostrado abaixo.

Fulladd4 fa0(SUM, , A, B, C_IN); // A porta de saída c está desconectada


A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 39

4.21.4 - Conectando portas a sinais externos

Existem dois métodos de se fazer conexões entre sinais especificados na instanciação do


módulo e as portas na definição do módulo. Os dois métodos não podem ser misturados.

- Conectando por lista ordenada:

Conectar por lista ordenada é o método mais intuitivo para a maioria dos iniciantes. Os
sinais a serem conectados devem aparecer na instanciação do módulo na mesma ordem que
as portas na lista de portas da definição do módulo. Vamos considerar o módulo fulladd4
como exemplo (já explorado anteriormente). Para conectar sinais do módulo estimulo por
uma lista ordenada devemos usar um código como o mostrado abaixo. Note que os sinais
externos SUM, C_OUT, A, B, e C_IN aparecem exatamente na mesma ordem que as portas
sum, c_out, a, b, e c_in na definição do módulo fulladd4.

module estimulo;
reg [3:0] A, B; // Declaração das variáveis de conexão
reg C_IN;
wire [3:0] SUM;
wire C_OUT;
fulladd4 fa_orden(SUM, C_OUT, A, B, C_IN); // Instanciação de fulladd4
...
<estímulos>
...
endmodule

module fulladd4(sum, c_out, a, b, c_in);


output [3:0] sum;
output c_out;
input [3:0] a, b;
input c_in;
...
<module internals>
...
endmodule

- Conectando portas por nome:

Para grandes projetos onde os módulos têm, por exemplo, 50 portas ou mais, lembrar a
ordem das portas na definição do módulo é impraticável e bastante factível ao erro. O
Verilog, então, também provê a capacibilidade de se conectar sinais externos a portas
usando os nomes hierárquicos das portas. Temos abaixo um exemplo para o fulladd4. Note
que você pode especificar as conexões das portas em qualquer ordem desde que o nome da
porta na definição do módulo corresponda corretamente ao sinal externo.

Fulladd4 fa_nome(.c_out(C_OUT), .sum(SUM), .b(B), .c_in(C_IN), .a(A));

Note que apenas as portas que serão conectadas a sinais externos devem ser especificadas
na conexão de portas por nome. Por exemplo, se a porta c_out não é conectada a sinal
algum, a instanciação de fulladd4 será de seguinte maneira:

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 40

Fulladd4 fa_nome(.sum(SUM), .b(B), .c_in(C_IN), .a(A));

Outra vantagem de se conectar portas por nome é que enquanto o nome da porta não é
mudado, a ordem da portas na lista de portas de um módulo pode ser rearranjada se causar
mudanças nas conexões das portas nos módulos instanciados.

4.22 - Exemplos de estruturas de módulos

Vamos terminar essa introdução do Verilog com alguns exemplos de estruturas de módulos.
Usaremos como exemplo um multiplexador 4 para 1, descrevendo-o em três níveis de abstração
(portas lógicas, RTL e comportamental) para que você perceba os diferentes estilos de escrita de
módulos.

4.22.1 - Nível de portas lógicas

Temos abaixo o diagrama lógico do MUX 4x1.

In0 Y0
NotSel1
Sel1
In1 Y1
NotSel0
Sel0
Out
In2 Y2

In3 Y3

Fig. 30 – Diagrama lógico do MUX 4x1

E, a seguir, a sua descrição em Verilog no nível de portas lógicas.

Module mux4x1(Out, In0, In1, In2, In3, Sel1, Sel0);

output out;
input In0, In1, In2, In3, Sel0, Sel1;

wire NotSel0, Not Sel1;


wire Y0, Y1, Y2, Y3;

not (NotSel0, Sel0);


not (NotSel1, Sel1);
and (Y0, In0, NotSel1, NotSel0);
and (Y1, In1, NotSel1, Sel0);
and (Y2, In2, Sel1, NotSel0);
and (Y3, In3, Sel1, Sel0);
or (Out, Y0, Y1, Y2, Y3);

endmodule

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 41

4.22.2 - Nível de fluxo de dados (RTL)

In0 and
lógico

In1
and
lógico
or Out
In2 lógico
and
lógico

In3 and
lógico

not not
lógico lógico

Sel1

Sel0
Fig. 31 – Diagrama de fluxo de dados do MUX 4x1

module mux4x1(Out, In0, In1, In2, In3, Sel1, Sel0);

output Out;
input In0, In1, In2, In3, Sel0, Sel1;

assign Out = (~Sel1 & ~Sel0 & In0) | (~Sel1 & Sel0 & In1) | (Sel1 & ~Sel0 &In2)
| (Sel1 & Sel0 & In3)

endmodule

4.22.3 - Nível comportamental


In0

In1
Out
In2

In3

Sel1 Sel0

Fig. 32 – Diagrama lógico do MUX 4x1

module mux4x1(Out, In0, In1, In2, In3, Sel1, Sel0);

output Out;
input In0, In1, In2, In3, Sel0, Sel1;
reg Out;
always @(Sel1 or Sel0 or In0 or In1 or In2 or In3)
begin
A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 42

case ([Sel1, Sel0})


2’b00 : Out = In0;
2’b01 : Out = In1;
2’b10 : Out = In2;
2’b11 : Out = In3;
default : Out = 1’bx;
endcase
end

endmodule

4.23 - Bibliografia

01. PALNIKTAR, Salmir. Verilog HDL – A Guide to Digital Design and Synthesis, Sun Soft
Press, California, EUA, 1996.

02. HYDE, Daniel C. CSCI 320 Computer Architecture Handbook of Verilog HDL. Bucknell
University, Lewisburg, PA, 1997. (http://www.eg.bucknell.edu/~cs320/1995-fall/verilog-manual.html)

03. Masterclass Multimedia Verilog Tutorial, Esperan (http://www.esperan.com/index2.htm)

04. Evita Verilog Tutorial, Aldec (http://www.aldec.com/pages/Downloads.htm)

05. Verilog-HDL Introductory Course . (http://www.vol.webnexus.com/index.html)

06. A Hardware Designer’s Guide to Verilog, Doulos (http://www.doulos.co.uk/hdgv/index.htm)

07. BLAIR, Gerard M. Online Verilog manual, University of Edinburgh


(http://www.ee.ed.ac.uk/~gerard/Teach/Verilog/manual/index.html)

08. PELLERIN, David. Introduction to VHDL – for synthesis and simulation, Accolade Desing
Automation Inc. (www.acc_eda.com\h_intro.htm)

09. Masterclass Multimedia Verilog Tutorial, Esperan (http://www.esperan.com/index2.htm)

10. Evita VHDL Tutorial, Aldec (http://www.aldec.com/pages/Downloads.htm)

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 43

5. O VERILOG E A FERRAMENTA DE SÍNTESE LÓGICA DA ALTERA

5. 1 - Considerações iniciais

Como já foi mencionado, cada ferramenta de síntese lógica suporta apenas uma partição
do Verilog (e não toda a linguagem). A ferramenta lógica que vamos utilizar não é uma exceção,
ela também só trabalha com uma partição do Verilog. E é isto que nós vamos abordar neste
capítulo.

Essa ferramenta permite que a descrição seja feita misturando-se os níveis RTL e
comportamental. Vamos então estudar a partição do Verilog RTL e comportamental suportada
pela ferramenta.

Na verdade, não vamos aqui abordar toda a partição do Verilog e as funcionalidades que
a ferramenta suporta, pois isto tornaria este capítulo muito extenso e tedioso. Vamos aqui
abordar basicamente o que é necessário para se iniciar com projetos usando Verilog.

Vamos estudar quais são os tipos de operadores que o Verilog suporta e quais são as
operações que esses operadores realizam; como definir constantes; a estrutura de controle de
eventos; as estruturas if-else, case e for; e veremos como implementar lógica combinacional,
como também lógica seqüencial.

5.2 - Tipos de operadores

Os operadores suportados pelo Verilog são dos tipos: aritméticos, lógicos, relacionais, de
igualdade, bitwise, de redução, de deslocamento, de concatenação, e condicional. Muitos desses
operadores são parecidos com os da linguagem C. Cada operador (como nas linguagens de
programação) possui um símbolo que o representa. Temos a seguir uma tabela com a lista
completa dos operadores e seus símbolos, agrupados por tipo.

Tipo de Operador Símbolo do Operador Operação Realizada Número de


Operandos
Aritmético * Multiplicação Dois
/ Divisão Dois
+ Adição Dois
- Subtração Dois
% Módulo Dois
Lógico ! NOT lógico Um
&& AND lógico Dois
|| OR lógico Dois
Relacional > Maior que Dois
< Menor que Dois
>= Maior ou igual que Dois
<= Menor ou igual que Dois
Igualdade == Igualdade Dois
!= Desigualdade Dois
=== Igualdade Case Dois
!== Desigualdade Case Dois
A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 44

Bitwise ~ NOT Um
& AND Dois
| OR Dois
^ XOR Dois
^ ~ ou ~ ^ XNOR Dois
Redução & AND redutor Um
~& NAND redutor Um
| OR redutor Um
~| NOR redutor Um
^ XOR redutor Um
^ ~ ou ~ ^ XNOR redutor Um
Deslocamento >> Deslocamento a direita Dois
<< Deslocamento a Dois
esquerda
Concatenação { } Concatenação Qualquer número
Replicação {{ }} Replicação Qualquer número
Condicional ?: Condicional três

5.2.1 - Operadores aritméticos

Os operadores aritméticos podem ser binários ou unários. Os operadores binários são


aqueles que operam sobre dois operandos: multiplicação (*), divisão (/), adição (+), subtração(-)
e módulo (%). Temos a seguir alguns exemplos.

// A = 4’b0011, B = 4’b0100, C = 6, D = 4
A * B // Multiplica A por B e resultam em 4’b1100
C / D // Divide C por D, truncando a parte fracionária
A + B // Soma A com B, resultando em 4’b0111
B – A // Subtrai A de B, resultando em 4’b0001
C % D // Resulta no resto da divisão de C por D, que é 2

Observe que se um dos operando conter um bit do tipo x, o resultado da operação será x
(não dá pra precisar o valor se um dos operandos não tem um valor preciso). Observe também
que o resultado da operação módulo tem sempre o mesmo sinal do primeiro operando da
operação (Se C fosse –6 o resultado seria –2; e se C fosse positivo e D negativo o resultado teria
sinal positivo).

Os operadores + e – também são usados como operadores unários. Eles são utilizados
para definir o sinal de um operando (por convenção, os operandos sem sinal são considerados
positivos). E, o Verilog representa internamente os números negativos em complemento de 2.

Uma ressalva aqui é que embora tenhamos explicado os operadores / e %, os mesmos não
são suportados pela ferramenta de síntese lógica da Altera (Max+Plus II).

5.2.2 - Operadores lógicos

Os operadores lógicos realizam uma função lógica em dois operados (no caso de NOT é
utilizado apenas um operando) e retornam como resultado um O (falso) ou um 1 (verdadeiro) de
acordo com a função lógica que foi executada. Qualquer operando diferente de zero é
considerado como sendo um 1 lógico. Temos a seguir alguns exemplos.

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 45

// A = 3, B = 0
A && B // Realiza um AND lógico entre A (1 lógico) e B (0 lógico) resultando em 0
A || B // OR lógico entre A e B, resultando em 1
!A // Negação lógica de A, resultando em 0
!B // Negação lógica de B, resultando em 1

5.2.3 - Operadores relacionais

Os operadores relacionais comparam dois operandos e retornam um 1 se a comparação


for verdadeira e um 0 se for falsa. Os operadores relacionais são: maior que (>), menor que (<),
maior ou igual a (>=) e menor ou igual a (<=). Observe alguns exemplos.

// A = 4, B = 3, X = 4’ b1010, Y = 4’ b1101
A <= B // Resulta em 0
A > B // Resulta em 1
Y >= X // Resulta em 1

5.2.4 - Operadores de igualdade

Comparam 2 operadores bit a bit, retornando um 0 (falso) ou um 1 (verdadeiro), de


acordo com o resultado da comparação. Se os operando são de comprimento diferentes, o menor
é preenchido com zeros. A tabela a seguir lista esses operadores.

Expressão Descrição Valores lógicos possíveis


A==B A igual a B, o resultado é do tipo x se A ou B 0, 1, x
contiverem bits do tipo x
A!=B A diferente de B, o resultado é do tipo x se A ou 0, 1, x
B contiverem bits do tipo x
A===B A igual a B incluindo os bits x e z 0, 1
A!==B A diferente de B incluindo os bits x e z 0, 1

Os Operadores de igualdade === e !==, embora mostrados acima, não são suportados
pelo Max+Plus II.

5.2.5 - Operadores Bitwise

Esses são os conhecidos operadores da eletrônica digital. Eles realizam a operação bit a
bit em dois operandos (ou em um se for o operador NOT). Eles pegam cada bit de um operando
e realizam a operação com o bit correspondente do outro operando (se os operando forem de
comprimento diferentes, o menor é preenchido por zeros). Temos a seguir alguns exemplos.

// X = 4’b1010, Y = 4’b1101
~X // Negação de X, resultando em 4’b0101
X & Y // And entre X e Y, resultando em 4’b1000
X | Y // Or entre X e Y, resultando em 4’b1111

5.2.6 - Operadores de Redução

Esses operandos realizam operações da lógica digital em apenas um operando. Como


podemos ver nos exemplos a seguir.

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 46

// X = 4’b1010
&X // Equivalente a 1 & 0 & 1 & 0, resultando em 1’b0
|X // Equivalente a 1 | 0 | 1 | 0, resultando em 1’b1
^X // Equivalente a 1 ^ 0 ^ 1 ^ 0, resultando em 1’b0

5.2.7 - Operadores de deslocamento

Esses operadores deslocam os bits de um operando para a direita ou esquerda um número


especificado de bits, como é mostrado a seguir.

// X = 4’b1100
Y = X >> 1; // Y é igual a X deslocado de um bit para a direita. Y = 4’b0110
Y = X << 1; // Y é igual a X deslocado de um bit para a esquerda. Y = 4’b1000
Y = X << 2; // Y é igual a X deslocado de dois bits para a esquerda. Y = 4’b0000

Observe que quando os bits são deslocados, os lugares vazios são preenchidos por zeros.
E, temos que os operadores de deslocamentos só são sintetizáveis pelo Max+Plus II se o
operador da direita (número de bits a ser deslocado) for um valor constante.

5.2.8 - Operador de concatenação

Esse operador permite concatenar múltiplos operandos, como é mostrado a seguir.

// A = 1’b1, B = 2’b00, C = 2’b10, D =3’b110


Y = {B, C} // Resulta na concatenação de B e C. Então Y = 4’b0010
Y = {A, B, C, D, 3’b001} // Resulta em Y = 11’b10010110001
Y = {A, B[0], C[1]} // Resultam em Y = 3’b101

5.2.9 - Operador de replicação

Esse operador permite fazer uma concatenação de um mesmo número várias vezes de
forma mais simples que com o operador de concatenação, como é mostrado a seguir.

// A = 1’b1, B = 2’b00
Y = {4{A}} // Resulta em Y = 4’b1111
Y = {4{A}, 2{B}} // Resultam em Y = 8’b11110000

5.2.10 - Operador Condicional

O operador condicional (?:) tem a seguinte estrutura:

variável = expressão_condicional ? expressão_verdadeira : expressão_falsa

O que temos é que ao executar essa linha de código, primeiro é verificado a expressão
condicional, se ela for verdadeira a variável terá como resultado a primeira expressão após a
interrogação (expressão_verdadeira), e caso contrário o resultado será a segunda expressão após
a interrogação (expressão_falsa). Observe os exemplo abaixo.

assign out = control ? In1 : In2;


assign val = (A = = 3) ? x : y;

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 47

No primeiro exemplo, primeiro há o teste da variável control. Se control = 1 então out


terá o valor de In1 (o assign é o operador de atribuição contínua, que será explicado mais a frente
neste capítulo), se control = 0 out terá o valor de In2. Observe que a expressão condicional só
tem como resultado 0 (falso) ou 1 (verdadeiro); com isso, ao se usar uma variável como
expressão condicional, temos que assegurar que essa variável só tenha como valores 0 ou1. No
segundo exemplo há o teste que verifica o valor da variável A, se A for igual 3 a expressão
condicional é verdadeira (retorna 1) e val tem seu valor igual a x; se A for diferente de 3 a
expressão condicional é falsa (retorna 0) e val tem seu valor igual a y.

5.3 - Definição de constantes

Para se definir constantes no Verilog utilizamos o operador `define, como é mostrado nos
exemplos abaixo.

`define A = 3;
`define regA = 1110;

Como podemos ver, no primeiro caso definimos uma constante do tipo int de valor 3,
sempre que A for usado na descrição em Verilog estaremos na realidade usando o inteiro 3
(como na liguagem C). e, no segundo exemplo, definimos uma constante do tipo reg de
comprimento 4 e valor 1110.

5.4 - Estruturas if-else e case

5.4.1 - Estrutura if-else

A estrutura if-else no Verilog é muito parecida com a da linguagem de programação C.


Sua sintaxe é mostrada abaixo.

if (<condição>)
begin
<linhas de código caso a expressão seja verdadeira>
end
else
begin
<linhas de código caso a expressão seja falsa>
end

Caso só tenhamos uma linha de código a ser executada após o if ou o else, não
necessitamos de usar as keywords begin e end. Caso só desejemos que alguma ação seja
executada apenas no caso da condição ser verdadeira, omitimos o else. E, pode-se aninhar vários
if-else. Abaixo temos alguns exemplos.

if (!lock) buffer = data

if (control == 0) y = x + z;
else if (control == 1) y = x – z;
else if (control == 2) y = x * z;

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 48

if(regA = regB)
begin
regC = regA + regC;
regB = regC;
end
else regC = regA;

No primeiro caso, se a variável lock for igual a zero (a ! indica negação) a variável buffer
ficará com o mesmo valor da variável data. Pois quando usamos apenas a variável como
condição em um if (if incompleto) estamos na verdade testando o valor da mesma, se é um zero
lógico ou um lógico, e indicando uma ação a ser tomada.

5.4.2 - Estrutura case

A estrutura case é usada quando temos uma variável que pode assumir vários valores e
desejamos que uma ação seja efetuada para cada um desses valores. Esse efeito também se
consegue utilizando estruturas if-else aninhadas, só que com case fica mais claro de se visualizar
as relações. Tome como exemplo o último exemplo do item anterior.

case (control)
0 : y = x + z;
1: y = x – z;
2: y = x * z;
endcase

5.4.3 - Outras estruturas

Existem ainda outras estruturas usadas para se implementar laços (for, while e repeat).
Essas estruturas são suportadas pela ferramenta de síntese lógica da Altera, mas não serão
abordadas neste documento. Se necessário se reporte a bibliografia para encontrar explicações
sobre essas estruturas e sua sintaxe.

5.5 - Controle de Eventos

No Verilog podemos fazer com que a ocorrência de eventos (funções, por exemplo) fique
sujeita a mudanças de variáveis conhecidas cujos valores variam entre 0 e 1. Essas mudanças
podem ser a mudança de estado dessa variável escolhida (mudança de 0 para 1 ou 1 para 0), a
subida de nível (variação de 0 para 1), ou então descida do mesmo (variação de 1 para 0). Esse
controle é conseguido usando o operador @ (que significa mudança de nível). Se usarmos
apenas o @ temos que o evento sob controle é evoluído sempre que a variável de controle mude
de estado; se usarmos em conjunto a palavra reservada posedge, estamos indicando que o evento
só ocorre quando ocorrer uma subida de nível da variável (mudança de 0 para 1); e, se usarmos
negedge, estamos indicando que o evento só ocorre quando ocorrer uma descida de nível. Temos
abaixo alguns exemplos hipotéticos.

always @ (d) X = X +1 // Sempre que d mudar de nível X é incrementado

always @ (negedge d) X = Y // Sempre que d for a zero X recebe o valor de Y

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 49

always @ (posedge d)
begin // Sempre que d subir para 1, as operações entre o begin e o
X = X + 1; // end são efetuadas
Y = 2 * X;
end

5.6 - Lógica Combinacional

A lógica combinacional é aquela em que as saídas em um dado instante de tempo são


função apenas das entradas neste instante de tempo (ex: decodificadores, multiplexadores, etc.).
A lógica combinacional é implementada pelo Verilog utilizando atribuições contínuas, ou
construções do tipo always que descrevem um comportamento puramente combinatório, isto é,
que não dependem de gatilhamento de relógio (clock).

5.6.1 - Atribuições contínuas

O operador de atribuição contínua atribui valores a variáveis do tipo net (wire). Seu
comportamento é como se fosse criada uma conexão direta entre a variável que está recebendo a
atribuição e a função ou variável que está sendo atribuída. Fisicamente é como pegar um sinal é
ligar diretamente a um ponto por meio de um fio.

Abaixo temos um exemplo do uso desse tipo de construção na criação de uma porta AND
e de conexão entre dois nós do projeto. Observe que as atribuições são executadas em paralelo
(aliás, todas as construções, exceto quando indicadas, no Verilog são executadas paralelamente).

module exemplo(a, b, c, d);


input a, b, e;
output c, d;

assign c = a & b;
assign d = e;

endmodule

Como podemos observar, temos três entradas e duas saídas nesse módulo. Temos que
uma função AND e executada com as entrada a e b e seu valor é então atribuído continuamente a
saída c (quer dizer que a saída c terá sempre o valor do AND ocorrido entre as entradas a e b).
Temos também que a saída d terá valor igual a entrada e (é como se ligássemos um foi entre
esses dois pontos no circuito).

5.6.2 - Construções always

Uma construção always em conjunto com um controle de eventos pode ser usada para
implementar lógica combinacional se sua construção tem as seguintes propriedades:

- O controle de eventos para essa construção não pode ser sensível à mudanças de nível
do clock do sistema (se existir um clock).
- O controle de eventos para a construção é sensível para todas as possíveis mudanças
na saída dessa construção.

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 50

- A construção always provê uma saída para cada mudança ou combinação de


mudanças das variáveis que estão sendo monitoradas pelo controle de eventos.

Para exemplificar vamos tomar um módulo simples que conta o número de bits 1 em uma
variável do tipo reg.

module proc(d, q)
input [2:0] d;
output [1:0] q;
integer num_bits;

always @ (d)
begin
integer i;
num_bits = 0;
for (i = 0; i < 3; i = i + 1)
if (d[i] == 1) num_bits = num_bits + 1;
end
assign q = num_bits;

endmodule

Como podemos ver, sempre que a variável d mudar ser valor (always @ (d)) teremos um
laço de comparação para saber quantos dos seus bits são iguais a 1, e esse resultado e
armazenado na variável q.

5.7 - Lógica seqüencial

A lógica seqüencial é aquela em que as saídas em um dado instante de tempo são função
das entradas nesse instante de tempo e nos tempos anteriores (ex: registradores, contadores,
latches, etc). A lógica seqüencial é implementada com construções always.

5.7.1 – Implementando registradores

A ferramenta de síntese lógica da Altera (Max+Plus II) permite que sejam criados
registradores com qualquer combinação dos sinais Clear, Preset, Load e Clock síncrono. Os
registradores são criados utilizando construções always. E, para criarmos registradores temos que
observar duas restrições:

- O sinal de clock só pode ser usado no controle de eventos (não pode ser usado em
nenhuma outra parte da construção always).
- Devemos usar variáveis do tipo reg para implementar os registradores (já que as
mesmas armazenam seu estado anterior).

Temos abaixo três exemplo que servem como base para a construção de registradores.

module reg1(d, clock, q1)


input d, clk;
output q1;
reg q1;
A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 51

always @ (posedge clock)


q1 = d;
endmodule

module reg2(d, clock, clear, q2)


input d, clock, clear;
output q2;
reg q2;
always @ (posedge clock or posedge clear)
begin
if (clear) q2 = 0;
else q3 = d;
end
endmodule

module reg3(d, clock, preset, q3)


input d, clock, load;
output q3;
reg q3;
always @ (negedge clock or negedge preset)
if (!preset) q3 = 1;
else q3 = d;
end
endmodule

No primeiro exemplo temos um registrador sensível a subida do clock (clock mudando de


nível 0 para 1 faz com que d seja armazenado em q1). No segundo exemplo temo um registrador
sensível a subida do clock e com uma entrada clear assíncrona (sempre que clear for igual ao
nível lógico 1 o registrador é resetado, e se o clear é igual ao nível lógico0 o registrador se
comporta como no exemplo anterior). E, no terceiro exemplo temos um registrador sensível a
descida do clock e com um preset assíncrono (observe que o preset é ativado no nível lógico 0).
Atente para o fato de que no controle de eventos e na definição da função a ser executada os
sinais de controle assíncronos devem estar definidos para uma mesma mudança de nível (por
isso é que no terceiro exemplo como o preset é ativo em 0, foi necessário usar o operador ! para
inverter seu valor de controle e o mesmo ficar em consonância com seu valor no controle de
eventos).

5.7.2 - Implementando contadores

A implementação de contadores é muito parecida com a implementação de registradores,


como pode ser observado nos exemplos abaixo.

module cont1(clock, enable, c1)


input clock, enable;
output c1;
reg c1;
always @ (posedge clock)
begin
if (enable) c1 = c1 + 1:
end
endmodule

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 52

module cont2(clock, clear, enable, c2)


input clock, clear, enable;
output c2;
reg c2;
always @ (posedge clock)
begin
if (!clear) c2 = 0;
else if (enable) c2 = c2 + 1;
end
endmodule
module c3(clock, up_down, c3)
input clock, up_down;
output c3;
reg c3;
integer direcao;
always @ (posedge clock)
begin
if (up_down) direcao = 1;
else (direcao = -1;
c3 = c3 + direcao;
end
endmodule

No primeiro exemplo temos um contador sensível a subida do clock e com um sinal


enable assíncrono (sempre que o clock mudar de 0 para 1 e o enable for igual a 1 o contador é
incrementado). No segundo exemplo temos um contador sensível a subida do clock e com um
sinal clear assíncrono. E, no terceiro exemplo temos um contador que contém um sinal
(up_down) que controla se o contador deve ser incrementado ou decrementado a cada subida do
clock.

5.8 - Bibliografia

01. Ajuda on-line da ferramenta de síntese lógica Max+Plus II, da Altera Corp.

02. PALNIKTAR, Salmir. Verilog HDL – A Guide to Digital Design and Synthesis, Sun Soft
Press, California, EUA, 1996.

03. HYDE, Daniel C. CSCI 320 Computer Architecture Handbook of Verilog HDL. Bucknell
University, Lewisburg, PA, 1997. (http://www.eg.bucknell.edu/~cs320/1995-fall/verilog-
manual.html)

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 53

6. A PLACA FPGA E A FERRAMENTA MAX+PLUS II

6. 1 - Considerações iniciais

Neste último capítulo do texto vamos dar uma visão geral acerca da placa de
desenvolvimento de projetos digitais com auxílio de um FPGA, mostrando sua configuração
física, características, limitações e restrições de uso.

Vamos var também os passos necessários para se utilizar a ferramenta de síntese lógica
Max+Plus II para, a partir de uma descrição de seu projeto digital em Verilog, se programar a
placa e realizar os testes com a mesma.

6.2 – A placa de desenvolvimento

Para a realização dos experimentos nós utilizaremos as placas desenvolvidas pelo


professor Elmar Uwe Kurt Melcher do DEE. São placas que contém um FPGA (na verdade um
CPLD da Altera) e toda sua interface definida, para uso em projeto de sistemas digitais. Por
serem placas que já possuem a interface do FPGA definida, é necessário que se atente para as
características e limitações inerentes. Ao se falar interface, queremos dizer o meio pelo qual o
FPGA se comunica com o mundo exterior (que no caso serão através de chaves de entrada e leds
de saída).

Então, não necessitamos nos preocupar com a montagem física do projeto, e sim apenas
com a descrição e como a descrição fará uso das interfaces e do próprio FPGA. Temos a seguir a
visão superior e inferior da placa.

Fig. 33 - Visão superior da placa


A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 54

Fig. 34 - Visão inferior da placa

Como podemos observar, temos na visão inferior o FPGA, que é o núcleo da placa, pois
todo o resto da placa é composta basicamente da interface ao FPGA (seja para programação ou
para testes) e do circuito de clock.

Observando a placa na visão superior vemos que a mesma é composta de um cabo


paralelo para ser ligado ao computador, por onde a programação da placa será transferida do
computador ao FPGA. Logo após esse cabo, na entrada da placa, temos um CI buffer que serve
para regenerar o sinal recebido do computador.

Temos 67 leds, que são utilizados como portas de saída do FPGA para se observar os
dados de saída. Junto a esses leds vemos vários CIs, que na verdade são drivers de corrente para
os leds, para garantir a corrente necessária para o leds funcionarem, uma vez que a corrente de
saída do FPGA é muito baixa. A numeração dos leds é dada a partir da primeira fileira inferior
de leds, começando pela direita com o led 0 até o 15, na segunda fileira do led 16 até 31, até a
última fileira que termina no led 63. Os três leds mais inferiores são os leds 64, 65 e 66.

Temos também 4 conjuntos de 8 chaves de duas posições, que são utilizadas como
entradas para o FPGA. A numeração dessas chaves é da direita para a esquerda a partir de 0 a 31.
E, existe também uma chave seletora de 10 posições, que é utilizada para se aumentar a
capacidade de entradas e saídas do sistema (associando, por exemplo, que determinado conjunto
de leds mostra a saída de um registrador se a chave seletora estiver na posição 1, e a saída de um
somador se a chave seletora estiver na posição 2).

Existe ainda uma chave bipolar (abaixo da chave seletora) que é utilizada para se gerar o
clock manual. E, para se gerar o clock existe na placa um oscilador que gera um clock de 5kHz
ou 0,5kHz, de acordo com uma seleção na placa (que está associada a um arquivo Verilog de
geração de clock, que será abordado mais adiante).

Finalizando, a esquerda da placa existem dois módulos de memória RAM.

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 55

6.3 – A ferramenta de síntese lógica Max+Plus II

Para se utilizar a placa, é necessário primeiro programá-la. E para isso é necessário uma
ferramenta de síntese lógica fornecida pelo fabricante do dispositivo escolhido para o projeto. No
nosso caso a ferramenta é o Max+Plus II da Altera. Essa ferramenta além de programar a placa,
permite a depuração de erros na descrição Verilog, a simulação do projeto, entre outras
funcionalidades. Para o nosso caso veremos apenas como compilar e depurar erros na descrição
Verilog e como programar a placa.

Para trabalharmos com o Max+Plus II teremos que dispor de 3 arquivos, um com a


descrição Verilog do projeto (arquivo com extensão .v), um com a descrição da interface da
placa ( arquivo com extensão .acf) e um com a descrição da geração do clock (peacclk.v).

O arquivo .acf é muito importantes, pois é nele que definimos qual é o dispositivo que
será utilizado (para a ferramenta poder programá-lo) e quais foram as definições de portas do
FPGA. Quer dizer, ao fazermos uma descrição em Verilog, definimos as interfaces do módulo
que criamos, essas interfaces tem que ser atribuídas as portas físicas do FPGA para que o mesmo
possa “saber” que variável corresponde a cada porta física (pino do CI). Então, o arquivo .acf
tem que ter o mesmo nome da arquivo .v para que na hora da programação da placa as portas de
entrada e saída do FPGA sejam atribuídas as variáveis definidas como interfaces do projeto.

O arquivo .v contém a descrição Verilog do sistema projetado. Como estamos usando


uma placa já construída, temos uma limitação no projeto, pois só podemos utilizar as interfaces
já definidas para essa placa (uma vez que já existem as conexões físicas permanentes na placa).
Com isso, nós não desenvolveremos o projeto todo, e sim apenas a funcionalidade do mesmo, ou
seja, utilizaremos um arquivo .v que já vem com a definição das interfaces e projetaremos apenas
a função do sistema. E, utilizaremos a interfaces que já virão definidas. O arquivo .v que será
trabalhado será como o mostrado a seguir.

module PC(led, swi, onda, bip, Amem, Dmem, OE, WE, clock);
output [66:0] led;
input [31:1] swi;
input [8:0] onda;
input [1:0] bip;
output [13:0] Amem;
inout [15:0] Dmem;
output OE, WE;
input clock;

wire [66:0] led;


wire [31:1] sw = ~swi;

`include "peacclk.v"

//----- inicio da função ------

//----- fim da função -----

assign led [55:48] = 0;


assign led [47:0] = 0;
assign led [63:56] = 0;
assign led [66:65] = 0;

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 56

wire OE = 1 ;
wire WE = 1 ;
wire [15:0] Dmem = 0;
wire [13:0] Amem = 0;

endmodule

Só será trabalhado a parte entre início da função e fim da função, que é onde você
escreverá a sua descrição Verilog. E usará também a parte de atribuição aos leds que vem após o
fim da função para definir as saídas do sistema. Temos a seguir um exemplo simples.

module reg_Out(led, swi, onda, bip, Amem, Dmem, OE, WE, clock);
output [66:0] led;
input [31:1] swi;
input [8:0] onda;
input [1:0] bip;
output [13:0] Amem;
inout [15:0] Dmem;
output OE, WE;
input clock;

wire [66:0] led;


wire [31:1] sw = ~swi;

`include "peacclk.v"

//----- inicio da função ------

reg [7:0] Out;


wire load;

assign load = sw[7];

always @ (posedge clk)


begin
if (!load)
Out = sw[15:8];
end

//----- fim da função -----

assign led [55:48] = Out;


assign led [47:0] = 0;
assign led [63:56] = 0;
assign led [66:65] = 0;

wire OE = 1 ;
wire WE = 1 ;
wire [15:0] Dmem = 0;
wire [13:0] Amem = 0;

endmodule

Como pode ser observado, foram definidas duas variáveis internas, um que armazena
valor (Out, com 8 bits de comprimento) e outra que não armazena (load). Utilizamos então as
variáveis de interface de entrada sw[15:8] que já foi definida para definir as entradas do sistema.
Temos a função (que é um registrador síncrono simples), e utilizamos as variáveis de interface
de saída led[55:48] para definirmos as saídas do sistema.
A

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 57

Observe que temos a inclusão de um arquivo chamado peacclk.v que é o arquivo que gera
o clock. Esse arquivo permite a criação de um clock automático ou manual. Devido ao uso desse
arquivo temos algumas restrições no uso da placa. Não devemos utilizar a chaves de entrada de 0
a 3, pois são as chaves que controlam o clock (deixe as três em nível baixo para trabalhar com o
clock manual). E, não podemos utilizar o led 64, que é o led que mostra o valor do clock no
instante atual.

Resumindo, teremos três arquivos para trabalhar, um com extensão .v, um com extensão
.acf e o peacclk.v. Desses três, o único que trabalharemos é o .v, o qual descreveremos a função
de nosso projeto. Atente para o fato de que o arquivo .v, o nome do módulo dentro do arquivo .v,
o arquivo .acf e a definição do chip dentro do arquivo .acf tem que ter o mesmo nome. Você não
pode mudar isso. E, o arquivo .v só pode ter esse único módulo (que é uma restrição da
ferramenta). E esses três arquivos tem que estar dentro do mesmo diretório.

O arquivo .v pode ser editado em qualquer editor de texto, uma vez que ele é um arquivo
texto com a extensão mudada pra .v. E, o arquivo .v pode ser editado dentro do próprio
Max+Plus II.

6.3.1 – Utilizando o Max+Plus II

Para se utilizar o Max+Plus II devemos primeiro iniciar o aplicativo. Ao fazer isso


chegamos em uma tela cinza. Devemos então abrir o arquivo .v (menu File, comando Open) com
a descrição do projeto. Com isso abriremos uma caixa de diálogo onde escolheremos o arquivo a
ser aberto, como mostra a figura abaixo.

Fig. 35 - Janela Abrir Arquivo

Com o arquivo .v aberto, temos que em seguida informar ao aplicativo que esse é o
arquivo que queremos trabalhar. Isso é feito acionando o menu File, em seguida Project,
comando Set Project to Current File, como mostra a figura a seguir.

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 58

Fig. 36 - Atribuição do projeto ao arquivo corrente

Em seguida devemos compilar esse arquivo. É durante a compilação que a ferramenta


verifica se existem erros na descrição. Os erros podem ser de sintaxe, de atribuição de portas, de
atribuição de variáveis, etc. Se ocorrer um erro, será mostrado o tipo de erro (é uma mensagem
que é um tanto confusa), a linha de código onde se encontra o erro e a compilação para. Você
deve então corrigir o erro e compilar novamente o projeto.

Para se compilar o projeto você deve acionar o menu File, em seguida Project e
selecionar a opção Save & Compile. A figura abaixo ilustra isto.

Fig. 37 – Janela de Compilação

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 59

Atente para o fato de que uma compilação bem sucedida não garante um projeto correto
em relação a função desejada, e sim garante um projeto correto em relação ao Verilog. Isso
porque você pode usar um operador errado em relação a sua função que não indica nenhum tipo
de erro lógico e sim um erro funcional, quer dizer, uma função será realizada mas não será a
desejada.

Durante a compilação é que é feita a conversão da descrição em um nível mais alto de


abstração para um nível inferior (normalmente o nível de portas lógicas) para a placa ser
programada.

Uma vez compilado o projeto, devemos passar para a parte de programação da placa.
Observe que a placa deve estar conectada ao computador para se efetuar a programação. Para
isso devemos primeiro entrar no modo de programação, através do menu Max+plus II, comando
Programmer, como é mostrado na figura a seguir.

Fig. 38 - Janela de Programação

Com isso é aberta a janela de programação. Mas, antes de programar a placa


necessitamos criar um arquivo de extensão .jcf que é o arquivo de programação da placa. Para
isso acionamos o menu JTAG, comando Multi-Device Jtag Chain Setup. Será então aberta uma
janela onde iremos criar o arquivo .jcf. Essa janela é mostrada abaixo.

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 60

Fig. 39 - Janela para criar o arquivo .jcf

Aqui você deve clicar no botão Select Programming File, e com isso é aberta uma janela
na qual você irá selecionar o arquivo com extensão .sof cujo nome é igual a seu arquivo .v. Você
retornará a janela anterior e então deve clicar no botão Add (observe que o único arquivo que
deve estar presente na caixa de texto maior é o que você acabou de adicionar, e caso exista
algum outro, selecione-o e clique em delete). Salve o arquivo clicando em Save Jcf. O nome do
arquivo .jcf deve ser igual ao do .v. e ser salvo de preferência no mesmo diretório. Em seguida
saia dessa janela clicando em OK. Observe que o nome do arquivo .jcf agora aparece na janela
Programmer.

Fig. 40 - Criação do arquivo jcf

Alexandre Scaico Dezembro/2000


Projeto de Sistemas Digitais na Atualidade pág. 61

Para um mesmo projeto só é necessário criar o arquivo .jcf uma única vez. Se você voltar
para a parte de edição e compilação, ou se sair do programa e abrí-lo novamente, você precisa
apenas restaurar o arquivo .jcf, através do menu JTAG, comando Restore jcf. E, é uma boa
medida de precaução restaurar o arquivo .jcf logo após a sua criação, para garantir que esse
arquivo está realmente selecionado.

Realizados todos esses passo só resta a programação da placa. Para isso deve-se clicar no
botão Configure, na janela Programmer. Será mostrada a evolução da programação da placa.
Quando acabar é sé clicar em OK e proceder com os teste na placa.

6.4 – Realização dos testes na placa

Para se realizar os testes na placa é só entrar com os dados e sinais de controle através das
chaves que você definiu como entrada e dar um pulso de clock com a chave bipolar. E, observar
os dados de saída através dos leds definidos como saídas.

Se você observar que as respostas não estão sendo as esperadas, deve dar uma revisada na
descrição Verilog do projeto, corrigir o erro, compilar, programar a placa e testar novamente.

6.5 – Bibliografia

01. Ajuda on-line da ferramenta de síntese lógica Max+Plus II, da Altera Corp.
02. Página da Placa para Ensino de Arquitetura de Computadores
(http://vulcano.dsc.ufpb.br/elmar/cursos/labarc/peac.hym)

Alexandre Scaico Dezembro/2000

Você também pode gostar