arquitetura

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

Upload: raphaell-mota-alves

Post on 04-Jan-2016

109 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Arquitetura

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

Page 2: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 2

A

Alexandre Scaico Dezembro/2000

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

Page 3: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 3

A

Alexandre Scaico Dezembro/2000

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

Page 4: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 4

A

Alexandre Scaico Dezembro/2000

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

Page 5: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 5

A

Alexandre Scaico Dezembro/2000

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

Page 6: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 6

A

Alexandre Scaico Dezembro/2000

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).

Page 7: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 7

A

Alexandre Scaico Dezembro/2000

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).

Page 8: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 8

A

Alexandre Scaico Dezembro/2000

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;

Page 9: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 9

A

Alexandre Scaico Dezembro/2000

- 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.

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.

PLD

Arranjos Lógicos

Programáveis

Arranjos de Portas

Programáveis

PAL PLA FPGA CPLD

Page 10: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 10

A

Alexandre Scaico Dezembro/2000

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

Page 11: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 11

A

Alexandre Scaico Dezembro/2000

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.

Page 12: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 12

A

Alexandre Scaico Dezembro/2000

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.

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.

PLD

PLD

PLD

PLD

Entradas Saídas

Conexões Programáveis

Page 13: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 13

A

Alexandre Scaico Dezembro/2000

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

Page 14: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 14

A

Alexandre Scaico Dezembro/2000

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

Page 15: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 15

A

Alexandre Scaico Dezembro/2000

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)

Page 16: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 16

A

Alexandre Scaico Dezembro/2000

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

Page 17: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 17

A

Alexandre Scaico Dezembro/2000

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.

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

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

Page 18: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 18

A

Alexandre Scaico Dezembro/2000

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

Page 19: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 19

A

Alexandre Scaico Dezembro/2000

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.

Page 20: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 20

A

Alexandre Scaico Dezembro/2000

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

Page 21: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 21

A

Alexandre Scaico Dezembro/2000

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.

Page 22: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 22

A

Alexandre Scaico Dezembro/2000

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

Page 23: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 23

A

Alexandre Scaico Dezembro/2000

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).

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).

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.

CD

S

AB

Cin

U1

U2 AB

CARRY

U1

SUM

Page 24: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 24

A

Alexandre Scaico Dezembro/2000

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.

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.

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

BS

SB SB SB SB

CB CB CB CB CB CB CB CB

BS

SB SB SB SB

CB CB CB CB CB CB CB CB

Page 25: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 25

A

Alexandre Scaico Dezembro/2000

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.

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.

Bloco X

Bloco Y

BlocoA

f

Entrada 1

Entrada 2

Saída 1

Saída 2

Page 26: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 26

A

Alexandre Scaico Dezembro/2000

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.

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.

Bloco A

Bloco X Bloco Y Bloco Z

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

Page 27: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 27

A

Alexandre Scaico Dezembro/2000

Fig. 18 – Contador de 4 bits

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

d q

D_FF clock

reset

q

q T_FF tff 0

q T_FF tff 0

qT_FF tff 0

q T_FF tff 0

q0 q1 q2 q3

clock

reset

Contador de 4 bits

Page 28: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 28

A

Alexandre Scaico Dezembro/2000

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.

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.

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.

somador completo

meio somadormeio somador

HALF_ADD U1

HALF_ADD U2

OR

FULL ADD

A

B

Cin

SUM

CARRY

Nomes de instância

Page 29: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 29

A

Alexandre Scaico Dezembro/2000

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.

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:

HALF_ADD U1

HALF_ADD U2

OR

FULL ADD

A

B

Cin

SUM

CARRY

ESTÍMULO

L1

L2

L3

módulo projetado

Bloco de estímulo

(estímulos)

(resultados)

Bloco de teste

módulo

de estímulo

módulo

do

projeto

Page 30: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 30

A

Alexandre Scaico Dezembro/2000

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

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.

XOR

AND

A

B

SUM

CARRY

HALF ADD

Page 31: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 31

A

Alexandre Scaico Dezembro/2000

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).

HALF_ADD U1

HALF_ADD U2

OR

FULL ADD

A

B

Cin

SUM

CARRY

I1

I2

I3

Page 32: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 32

A

Alexandre Scaico Dezembro/2000

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.

Page 33: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 33

A

Alexandre Scaico Dezembro/2000

- 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

Page 34: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 34

A

Alexandre Scaico Dezembro/2000

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.

Page 35: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 35

A

Alexandre Scaico Dezembro/2000

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.

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

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

Declarações de wires, regs e outras variáveis

Declarações de fluxo de dados (assign)

Instanciação de módulos de nível inferior

Blocos always e initial. Todas declarações comportamentais vão nesses blocos

Funções e tarefas

Declaração endmodule

Page 36: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 36

A

Alexandre Scaico Dezembro/2000

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.

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

Sbar (set)

Rbar (reset)

Q

Qbar

Page 37: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 37

A

Alexandre Scaico Dezembro/2000

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.

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

b

c-in

somador completo (4 bits)

fulladd4 c-out

sum

estimulo

Page 38: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 38

A

Alexandre Scaico Dezembro/2000

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.

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

reg ou net net

inout

input output

reg ou net net

net

net

Page 39: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 39

A

Alexandre Scaico Dezembro/2000

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:

Page 40: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 40

A

Alexandre Scaico Dezembro/2000

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.

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

Out

In0 Sel1

In1

Sel0

In2

In3

Y1

Y2

Y0

Y3

NotSel1

NotSel0

Page 41: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 41

A

Alexandre Scaico Dezembro/2000

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

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

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

and lógico

and lógico

and lógico

and lógico

or lógico

not lógico

not lógico

In0

In1

In2

In3

Sel1

Sel0

Out

In0

In1

In2

In3

Out

Sel1 Sel0

Page 42: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 42

A

Alexandre Scaico Dezembro/2000

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)

Page 43: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 43

A

Alexandre Scaico Dezembro/2000

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 Divisão Adição

Subtração Módulo

Dois Dois Dois Dois Dois

Lógico ! && | |

NOT lógico AND lógico OR lógico

Um Dois Dois

Relacional > <

> = < =

Maior que Menor que

Maior ou igual que Menor ou igual que

Dois Dois Dois Dois

Igualdade = = ! =

= = = ! = =

Igualdade Desigualdade

Igualdade Case Desigualdade Case

Dois Dois Dois Dois

Page 44: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 44

A

Alexandre Scaico Dezembro/2000

Bitwise ~ & | ^

^ ~ ou ~ ^

NOT AND OR

XOR XNOR

Um Dois Dois Dois Dois

Redução & ~ &

| ~ | ^

^ ~ ou ~ ^

AND redutor NAND redutor

OR redutor NOR redutor XOR redutor

XNOR redutor

Um Um Um Um Um Um

Deslocamento > > < <

Deslocamento a direita Deslocamento a

esquerda

Dois Dois

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.

Page 45: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 45

A

Alexandre Scaico Dezembro/2000

// 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

contiverem bits do tipo x 0, 1, x

A ! = B A diferente de B, o resultado é do tipo x se A ou B contiverem bits do tipo x

0, 1, 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.

Page 46: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 46

A

Alexandre Scaico Dezembro/2000

// 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;

Page 47: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 47

A

Alexandre Scaico Dezembro/2000

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;

Page 48: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 48

A

Alexandre Scaico Dezembro/2000

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

Page 49: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 49

A

Alexandre Scaico Dezembro/2000

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.

Page 50: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 50

A

Alexandre Scaico Dezembro/2000

- 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;

Page 51: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 51

A

Alexandre Scaico Dezembro/2000

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

Page 52: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 52

A

Alexandre Scaico Dezembro/2000

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)

Page 53: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 53

A

Alexandre Scaico Dezembro/2000

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

Page 54: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 54

A

Alexandre Scaico Dezembro/2000

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.

Page 55: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 55

A

Alexandre Scaico Dezembro/2000

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;

Page 56: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 56

A

Alexandre Scaico Dezembro/2000

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.

Page 57: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 57

A

Alexandre Scaico Dezembro/2000

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.

Page 58: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 58

A

Alexandre Scaico Dezembro/2000

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

Page 59: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 59

A

Alexandre Scaico Dezembro/2000

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.

Page 60: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 60

A

Alexandre Scaico Dezembro/2000

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

Page 61: Arquitetura

Projeto de Sistemas Digitais na Atualidade pág. 61

A

Alexandre Scaico Dezembro/2000

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)