Vhdl ronhuse, Manual de Eletrônica Digital. Universidade Federal da Bahia (UFBA)
Vitor_Leao.Filardi
Vitor_Leao.Filardi18 de janeiro de 2016

Vhdl ronhuse, Manual de Eletrônica Digital. Universidade Federal da Bahia (UFBA)

PDF (171 KB)
49 páginas
2Números de download
388Número de visitas
Descrição
VHDL
20 pontos
Pontos de download necessários para baixar
este documento
baixar o documento
Pré-visualização3 páginas / 49

Esta é apenas uma pré-visualização

3 shown on 49 pages

baixar o documento

Esta é apenas uma pré-visualização

3 shown on 49 pages

baixar o documento

Esta é apenas uma pré-visualização

3 shown on 49 pages

baixar o documento

Esta é apenas uma pré-visualização

3 shown on 49 pages

baixar o documento
Microsoft Word - VHDL_FINAL.DOC

APOSTILA DE

VHDL

Ronaldo Hüsemann Professor das Disciplinas: Técnicas Digitais (2000) Sistemas Digitais (2001) Microprocessadores II (2002)

Departamento de Engenharia Elétrica Universidade Federal do Rio Grande do Sul

Ronaldo Hüsemann Apostila de VHDL - Página 2

Histórico

No final dos anos 70, o Departamento de Defesa dos Estados Unidos definiu um programa chamado VHSIC (Very High Speed Integrated Circuit) que visava a descrição técnica e projeto de uma nova linha de circuitos integrados. Com o avanço acelerado dos dispositivos eletrônicos entretanto este programa apresentou-se ineficiente, principalmente na representação de grandes e complexos projetos.

Em 1981, aprimorando-se as idéias do VHSIC, foi proposta uma linguagem de descrição de hardware mais genérica e flexível. Esta linguagem chamada VHDL (VHSIC Hardware Description Language) foi bem aceita pela comunidade de desenvolvedores de hardware e em 1987 se tornou um padrão pela organização internacional IEEE.

Em 1992 foram propostas várias alterações para a norma, sendo que 1993 foi lançada a versão revisada, mais flexível e com novos recursos. Esta norma revisada, chamada VHDL-93, é a hoje a mais amplamente utilizada e por isso a maioria dos exemplos aqui apresentados são baseados na mesma.

É objetivo desta apostila auxiliar estudantes e pesquisadores que necessitem aprender os preceitos da linguagem VHDL para desenvolvimento e simulação de projetos afins à área de eletrônica e sistemas digitais, mas acima de tudo procurando-se apresentar uma visão geral da linguagem.

Porto Alegre, maio de 2001

Ronaldo Hüsemann

Ronaldo Hüsemann Apostila de VHDL - Página 3

1- Elementos Básicos em VHDL

1.1 - Comentários

Os comentários em VHDL são permitidos após dois traços ‘-’ e são válidos até o final da linha corrente. Por exemplo:

bit0 := d0; -- Esta linha atribui o valor de d0 a variável bit0

1.2 - Identificadores

Os identificadores são usados para se atribuir nomes a sinais ou processos. Um identificador básico em VHDL:

-pode conter letras do alfabeto (‘A’ a ‘Z’ e ‘a’ a ‘z’), digitos decimais (‘0’ a ‘9’) e o caracter underline (‘_’);

-precisa começar com uma letra do alfabeto; -não pode terminar com um caracter underline; -não pode conter dois caracteres underline em sequência.

Alguns exemplos de identificadores:

contador data0 Novo_valor resultado_final_operacao_FFT

Não há distinção entre letras maiúsculas e minúsculas, logo valor, Valor ou VALOR são interpretados da mesma forma.

VHDL permite ainda a definição de identificadores estendidos que devem ser utilizados somente para interfaceamento com outras ferramentas que usam regras diferentes para definir seus identificadores. A definição de identificadores estendidos é feita entre ‘\’. Por exemplo:

\9data\ \proximo valor\ \bit#123\

1.3 - Números

VHDL define dois tipos básicos de números: inteiros e reais. Um número inteiro consiste de um número sem ponto decimal. Exemplos de números inteiros:

23 0 146

Os números reais, por sua vez, permitem a representação de números fracionários. Por exemplo:

23.1 0.2 34.118 Pode-se trabalhar com notação exponencial, desde que o número seja seguido

pela letra ‘E’ ou ‘e’. Exemplos:

3E2 18E-6 3.229e9

Ronaldo Hüsemann Apostila de VHDL - Página 4

Além disso pode-se trabalhar em VHDL com bases diferentes da decimal, bastando para isto indicar a base seguido pelo número entre ‘#’. Para bases maiores que 10, deve-se utilizar as letras ‘A’ a ‘F’ (ou ‘a’ a ’f’), indicando as bases 11 a 15. Não são permitidas bases maiores que 16. Como exemplo, tem-se o número 253 representado em diversas bases distintas:

2#11111101# 16#FD# 16#0fd# 8#0375#

A fim de facilitar a interpretação de números longos é permitido em VHDL utilizar-se o caracter underline (‘_‘) entre dígitos. Isto não altera o valor representado pelo número, apenas facilita a sua identificação visual. Por exemplo:

123_456 3.141_592 2#111_1100_0000_0000#

1.4 - Caracteres

A representação de caracteres em VHDL é permitida pelo uso de aspas simples como nos exemplos:

‘A’ ‘b’ ‘;’ ‘0’

1.5 - Strings

As strings, em VHDL, são definidas entre aspas duplas e representam uma sequência de caracteres, mas precisam estar inteiramente definidas em uma linha. Exemplos de strings:

“Teste de operacao” “2000 iteracoes”

A utilização de aspas dentro de um string é permitida duplicando-se o caracter de aspas ( " ). Por exemplo:

“O caracter “” faz parte da string”

Se for necessário definir-se uma string cujo comprimento seja maior que o de uma linha deve-se utilizar o operador de concatenação (‘&’) para unir as substrings em uma só. Exemplo:

“Esta string sera’ interpretada como uma unica string, ” & “pois foi utilizado o operador de concatenacao”

Ronaldo Hüsemann Apostila de VHDL - Página 5

1.6 - Strings de Bit

Assim como strings de caracteres, é possível a definição de strings de bits ou valores numéricos especiais (como representados por outras bases). O especificador de base pode ser:

-B para binário -O para octal -X para hexadecimal

A seguir alguns exemplos de strings de bit em base binária:

B”010001” b”1001_1101_1100”

base octal:

o”372” O"740"

e base hexadecimal:

X”D4” x“0F2”

Ronaldo Hüsemann Apostila de VHDL - Página 6

2 - Tipos de Dados

2.1 - Constantes e Variáveis

Um objeto é um modelo em VHDL que pode conter um valor de um tipo específico. São 4 classes de objetos: constantes, variáveis, sinais e arquivos.

2.1.1 - Constantes e Variáveis

Ambos os tipos constantes e variáveis devem ser definidas antes de serem utilizadas na descrição VHDL. Os elementos do tipo constante não podem ser sobrescritos, enquanto que os do tipo variável podem ser alterados a qualquer momento. A declaração de uma constante é feita através do uso da palavra-chave constant, como nos exemplos:

constant valor_de_pi : real := 3.141592653; constant ativado : bit := 1; constant atraso : time := 5ns;

A declaração de variáveis segue a mesma estrutura, utilizando a palavra-chave variable. Uma variável pode ser iniciada com algum valor prévio na sua declaração, o qual irá manter até que seja feita a primeira escrita. A seguir, alguns exemplos:

variable numero_de_contagens : integer := 50; variable liga_saida1 : bit := '0'; variable tempo_medida : time := 0ns;

As atribuições em VHDL para constantes e variáveis são feitas com o operador “:=“, como já pode ser visto nos exemplos anteriores.

2.1.2 - Sinais

Um sinal (signal) é utilizado para interligação de blocos em VHDL, funcionando de maneira similar a uma variável. O sinal traz porém a capacidade de permitir a ligação (ao ser ligado a uma porta de entrada e saída) ou troca de valores (quando opera com variáveis internas) entre blocos funcionais distintos.

As atribuições de sinais em VHDL é feita normalmente com o operador “<=“, por ser tratado analogamente a um pino de entrada e saída. Exemplos de sua utilização são apresentados no capítulo "Programação em VHDL" (item 5.3).

Na atribuição de sinais pode-se adicionalmente gerar de um atraso programado através da palavra-chave after. No exemplo:

x <= not y after 8ns;

o sinal x recebe o valor negado de y após um atraso de 8ns. Isto é especialmente importante para se simular atrasos de portas lógicas.

Ronaldo Hüsemann Apostila de VHDL - Página 7

É possível desta forma até mesmo construir-se um sinal como forma de onda ou pulso variável através do adequado uso dos comandos de atribuição de sinais. Por exemplo, a sentença abaixo gera um pulso positivo com atraso de propagação de 5ns e largura de 10ns no sinal de saída pinout:

pinout <= ‘1’ after 5ns, ‘0’ after 15ns;

como a representação feita na figura abaixo:

Figura 2.1 : Sinal gerado em pinout

A estrutura flexível do VHDL permite a atribuição de valores em processos vinculada a uma ou mais condições, ou seja a atribuição só se efetivará se uma condição (ou conjunto de condições) for verdadeira. Para se realizar esta operação em uma atribuição deve-se utilizar a palavra-chave when, seguida da condição que se deseja verificar para a validade da atribuição. Por exemplo, abaixo tem-se listada a descrição de um multiplexador de 4 entradas utilizando-se este recurso:

saida <= entrada0 when a = '0' and b = '0', entrada1 when a = '0' and b = '1',

entrada2 when a = '1' and b = '0', entrada3;

O sinal de saída irá receber um dos pinos de entrada de acordo com a condição dos sinais de seleção a e b. Note que a última atribuição (saida <= entrada3) é realizada se e somente se nenhuma das outras condições anteriores forem satisfeitas. Por isso nenhuma condição precisou ser descrita.

2.1.3 - Arquivos

Um arquivo (file) é uma classe de objeto em VHDL usada para armazenamento de dados. A declaração desta classe é feita definindo-se o tipo de arquivo e tipo de dados com que se deseja trabalhar. Por se tratar de um tipo deve-se iniciar a declaração com a palavra-chave type seguida pelo nome do arquivo. Em sequência, as palavras-chaves is file of e o tipo de dado a ser armazenado. Como exemplo a seguir tem-se uma definição de um tipo de arquivo de bits, chamado arq_binário.

type arq_binario is file of bits;

Uma vez tendo-se declarado o tipo de arquivo deve-se declarar a arquivo de entrada ou saída que irá ser manipulado. Isto é feito através do uso da palavra-chave file seguida pelo identificador do arquivo, dois pontos ':' e do tipo de arquivo declarado. A seguir utiliza-se a palavra-chave open com o modo de abertura do arquivo. São três os modos possíveis: modo leitura (read_mode), escrita (write_mode) e escrita anexada

Ronaldo Hüsemann Apostila de VHDL - Página 8

(append_mode). Por fim acrescenta-se is seguido pelo nome de referência do arquivo, que pode ser o nome do mesmo em um diretório ou simplesmente um nome usado para interfaceamento com uma memória.

Como exemplo a seguir se define um arquivo chamado arquivo_entrada do tipo anteriormente declarado arq_binario, de modo leitura e com nome "dados.dat":

file arquivo_entrada:arq_binario open read_mode is "dados.dat";

Para leitura deste arquivo usa-se o procedimento read e para escrita o procedimento write. O conceito de procedimentos é apresentado no capítulo de "Subprogramas" item 7.1. Exemplificando uma leitura de dados para a variável bit_in via arquivo:

read(arquivo_entrada, bit_in);

A escrita é feita de modo análogo desde que é claro tenha-se definido um arquivo de escrita ou escrita anexada. Exemplo:

file arquivo_saida:arq_binario open write_mode is "resultados"; write(arquivo_saida, bit_out);

Para conferência de fim de arquivo usa-se a função endfile(nome_arquivo), que retorna 1 se o arquivo chegou ao fim e 0 caso não. Funções são apresentados no item 7.2.

2.2 - Tipos Escalares

Variáveis tipo escalares são aquelas cujos valores são indivisíveis.

2.2.1 - Tipos Inteiros

Variáveis do tipo inteiro podem variar de -2.147.483.647 a +2.147.483.647, por serem representadas por 32 bits. Algumas vezes entretanto é útil definir-se novas faixas de operação para algumas variáveis. VHDL permite a definição destas faixas a partir das estruturas is range/to ou is range/downto, usadas para variações ascendentes e descendentes respectivamente. Algumas destas estruturas pode ser observadas nos exemplos:

type dia_da_semana is range 1 to 31; type valor_contagem is range 10 downto 0;

Em uma declaração de tipo, o valor inicial de uma variável (caso não atribuído) será igual ao valor mais a esquerda da faixa definida. Por exemplo uma variável do tipo dia_da_semana teria valor inicial 1 enquanto que uma do tipo valor_contagem teria 10.

Ronaldo Hüsemann Apostila de VHDL - Página 9

2.2.2 - Tipos Ponto Flutuante

Variáveis do tipo ponto flutuante são compostas por duas partes: uma mantissa e uma parte exponencial. Existe um tipo ponto flutuante pré-definido em VHDL que é o tipo real, que varia de -1.0E+38 até +1.0E38, com pelo menos seis dígitos de precisão. É possível a definição de outras variáveis do ponto flutuante conforme a necessidade da aplicação. Alguns exemplos são apresentados a seguir:

type valor_leitura is range -5.0 to 5.0; type porcentagem is range 0.0 to 100.0;

2.2.3 - Tipos Físicos

Variáveis do tipo físico (physical) são utilizadas na representação de quantidades físicas do mundo real, tais como comprimento, massa, tempo e tensão. Na definição destas variáveis é possível a atribuição das unidades respectivas através do uso da palavra-chave units. Abaixo apresenta-se um exemplo de uma medida física de resistores em VHDL:

type resistencia is range 0 to 1E9 units

ohm; kohm = 1000 ohm; Mohm = 1000 kohm;

end units resistencia;

Existe um tipo físico muito importante pré-definido em VHDL que é o tipo time, usado para operações com tempo. A declaração deste tipo pode ser observada a seguir:

type time is range implementation_defined units

fs; ps = 1000 fs; ns = 1000 ps; us = 1000 ns; ms = 1000 us; sec = 1000 ms; min = 60 sec; hr = 60 min;

end units;

Note que em VHDL a unidade de tempo é fs, apesar que na maior parte das vezes se adotam outras unidade mais comuns como ms ou ns.

Ronaldo Hüsemann Apostila de VHDL - Página 10

2.2.4 - Tipo Enumeração

O tipo especial de enumeração nada mais é do que uma lista ordenada de possíveis valores que uma determinada variável pode conter. Por exemplo a variável display definida por

type display is (‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ’8’, ‘9’);

pode assumir qualquer um dos 10 possíveis valores ‘0’ a ‘9’. Se por acaso esta variável devesse representar alguns valores hexadecimais, deveria ser definida como:

type display is (‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ’8’, ‘9’, ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’);

Existe diversos tipos pré-definidos de enumeração em VHDL . Por exemplo:

type severity_level is (note, warning, error, failure);

Na prática os tipos pré-definidos de enumeração mais importantes são:

- character - boolean - bit

A variável do tipo character apresenta 256 possíveis valores, sendo que os 128 primeiros representam a primeira metade da tabela ASCII.

A declaração do tipo character em VHDL é feita conforme pode ser visto a seguir na fig. 2.2.

Ronaldo Hüsemann Apostila de VHDL - Página 11

type character is ( nul, soh, stx, etx, eot, enq, ack, bel, bs, ht, lf, vt, ff, cr, so, si, dle, dc1, dc2, dc3, dc4, nak, syn, etb, can, em, sub, esc, fsp, gsp, rsp, usp,

' ', '!', '"', '#', '$', '%', '&', ''', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',

'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\', ']', '^', '_',

'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', del,

c128, c129, c130, c131, c132, c133, c134, c135, c136, c137, c138, c139, c140, c141, c142, c143, c144, c145, c146, c147, c148, c149, c150, c151, c152, c153, c154, c155, c156, c157, c158, c159,

-- the character code for 160 is there (NBSP), -- but prints as no char

' ', '¡', '¢', '£', '¤', '¥', '¦', '§', '¨', '©', 'ª', '«', '¬', '-', '®', '¯ ', '°', '±', '²', '³', '´', 'µ', '¶', '·', '¸', '¹', 'º', '»', '¼', '½', '¾', '¿',

'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', '×', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'Þ', 'ß',

'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ð', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', '÷', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'þ', 'ÿ' );

Figura 2.2: Declaração em VHDL do tipo character

Um variável do tipo boolean é bastante usada para operações lógicas cujo resultado deve ser verdadeiro ou falso. A definição do tipo boolean é:

type boolean is (false, true);

As variáveis do tipo bit são utilizadas para operações binárias em VHDL. A definição do tipo bit é:

type bit is (‘0’, ‘1’);

Note que os dois possíveis valores de bit são os caracteres '0' e '1' e não os números 0 e 1.

Ronaldo Hüsemann Apostila de VHDL - Página 12

2.3 - Tipos Compostos

Variáveis de tipo composto são montadas com um agrupamento de variáveis de tipos já conhecidos.

2.3.1 - Arrays

De uma forma geral, arrays são conjuntos de valores de um determinado tipo. O agrupamento de determinado tipo em um conjunto é especialmente importante para operações com tratamento de memória ou manipulação de matrizes.

A declaração de um array deve obrigatoriamente conter além do nome do array, o tipo de variável (ou variáveis) que deverá comportar e normalmente a faixa de validade (dimensão) do array. A forma mais simples de compreender a forma de declaração de arrays é através de exemplos práticos. Na declaração abaixo, por exemplo:

type matriz_entrada is array (0 to 9) of integer;

está-se definindo uma matriz de 10 elementos de tipo inteiro (integer) chamada matriz_entrada. Assim como em outras estruturas VHDL é possível o uso da palavra- chave downto para ordenação descendente, o que, em alguns casos, é bem útil. Por ser um arranjo mais genérico a declaração de arrays pode conter também valores não numéricos, como no exemplo a seguir:

type dias_semana is (DOM, SEG, TER, QUA, QUI, SEX, SAB); type dias_uteis is array (SEG to SEX) of dias_semana;

onde se define um array chamado dias_uteis que contém somente um conjunto dos cinco dias da semana de SEG a SEX a partir do conjunto dias_semana.

Em muitos casos arrays de uma única dimensão não são suficientes para as operações que se deseja. VHDL permite a definição de arrays multi-dimensionais de forma facilitada. Por exemplo, pode-se definir o array que representa uma imagem bidimensional de 10x20 da seguinte forma:

type imagem is array (1 to 10, 1 to 20) of integer;

Note que, no exemplo, imagem inicia da posição 1. Não é necessário se iniciar sempre do valor 0. Da mesma forma não há a obrigação de que os tipos definidos para cada dimensão de um array sejam iguais. É possível por isso construir-se arrays multi- dimensionais de tipos distintos como no exemplo:

type estado is (ativado, desativado, falha); type conjunto_processos is array (0 to 10, estado) of bit;

que define uma matriz de bits, cujas dimensões são dadas por tipos distintos. VHDL permite ainda a construção de arrays sem definição de limites através dos

símbolos “<>“, como pode ser visto a seguir:

type matriz is array (natural range <>) of integer;

Ronaldo Hüsemann Apostila de VHDL - Página 13

que define um array chamado matriz de inteiros, cuja dimensão não foi especificada, mas que deve estar contida dentro do espaço de números naturais (natural). Normalmente o tamanho de um array deste tipo é definido quando se atribui no programa uma constante ou variável que irá utilizar este tipo de array. Por exemplo:

variable matriz1 : matriz := (0.0, 0.0, 0.0, 0.0, 0.0);

define uma variável do tipo matriz (sem definição de limite) chamada matriz1 que tem 5 posições. A atribuição de valores a arrays merecem alguns comentários, pois em VHDL são disponibilizados alguns formatos especiais.

A atribuição mais simples já foi mostrada e trata do preenchimento direto dos valores de um array ou de um elemento, como na listagem a seguir:

type medidor is array (1 to 3) of integer := (0.0, 0.0, 0.0); medidor(1) := entrada1;

medidor(2) := entrada2; medidor(3) := (entrada1 + entrada2)/2;

A primeira linha permite o preenchimento de todo array com valores iniciais. As demais linhas acessam cada uma das posições colocando os valores apropriados, respectivamente. Para arrays muito grandes entretanto alguns recursos são especialmente úteis. Por exemplo para o caso a seguir:

type 7_segm is (1 to 7) of bit; variable display1: 7_segm := (1 =>1, 2 =>0, 3 =>0, 4 =>0, 5 =>0, 6 =>1,7 =>1);

variable display2: 7_segm := ( 1 =>1, 2 to 5 => 0; 6 to 7 =>1); variable display3: 7_segm := ( 1 | 6 | 7 => 1, 2 to 5 => 0); variable display4: 7_segm := ( 1 | 6 | 7 => 1, others => 0);

são definidos 4 variáveis de display de 7 segmentos que recebem os mesmos valores iniciais. Note que a palavra-chave to agrupa elementos consecutivos enquanto que o símbolo ‘|’ é utilizado para agrupar elementos separados. Além disso, a palavra- chave others é válida aqui para se permitir a atribuição de todos os elementos não referenciados anteriormente. Operações lógicas (ver item 3.3) com arrays são permitidas, desde que os arrays contenham variáveis do tipo bit ou boolean.

A cópia de arrays é possível desde que sejam arrays de mesmo tipo. Por exemplo:

matriz2 := matriz1;

realiza a cópia de todos os elementos do array matriz1 para a matriz2.

Ronaldo Hüsemann Apostila de VHDL - Página 14

2.3.2 - Records

Records, assim como arrays, são conjuntos de variáveis, permitindo porém o agrupamento de variáveis de tipos diferentes. Cada elemento de um determinado tipo dentro desta estrutura possui um nome próprio, que é utilizado para referenciá-lo dentro do record. Na sua declaração todos os elementos constituintes de uma estrutura do tipo record devem ser declarados em sequência com seus nomes próprios. Após o final da declaração da estrutura record seu nome deve ser repetido. Para ilustrar o uso deste tipo, no exemplo abaixo:

type horario is record segundo : integer range 0 to 59; minuto : integer range 0 to 59; hora : integer range 0 to 23; end record horario;

declara-se uma estrutura de horário composta por 3 inteiros segundo, minuto e hora, com as respectivas faixas de operação.

A atribuição de valores para um elemento específico é feito a partir do nome do record seguido de ‘.’ e o nome da variável que se pretende acessar. Por exemplo:

variable horario_atual: horario; horário_atual.segundo := 23; horário_atual.minuto := 42; horário_atual.hora := 10;

ajusta o horario atual do sistema para 10:42:23. Outra maneira de se realizar esta atribuição é:

horario_atual := (hora => 10, minuto => 42, segundo => 23);

Similarmente ao caso de arrays, são permitidos os usos dos recursos ‘|' e others para atribuição de um conjunto de variáveis ao mesmo tempo. Também é possível a cópia de records como em:

estrutura2 := estrutura1;

que realiza a cópia de todos elementos do record estrutura1 para a estrutura2.

Ronaldo Hüsemann Apostila de VHDL - Página 15

2.4 - Subtipos

Uma vez tendo-se definido um tipo de variável, em VHDL, é possível se definir um subtipo ou seja um tipo de variável que seja um subset do tipo já definido através do uso da palavra-chave subtype. Como exemplo são apresentados 3 subtipos pré- definidos em VHDL para números naturais, positivos e atraso de tempo, respectivamente:

subtype natural is integer range 0 to highest_integer; subtype positive is integer range 1 to highest_integer; subtype delay_length is integer range 0 to highest_time;

2.5 - Conversão de Tipos

A conversão, ou seja a transformação de um tipo de variável para outro é permitido em VHDL. Para implementar isto deve-se descrever o tipo de variável que se deseja obter seguido pelo valor entre parênteses. Por exemplo a conversão:

integer(39.382)

produz o número inteiro mais próximo (no caso, 39). Enquanto que:

real(123);

gera o número em ponto flutuante 123.0;

Ronaldo Hüsemann Apostila de VHDL - Página 16

2.6 -Diagrama Completo de Tipos de Dados em VHDL

Figura 2.3: Hierarquia dos tipos de dados em VHDL

Ronaldo Hüsemann Apostila de VHDL - Página 17

3 - Expressões e Operadores

3.1 - Operações Aritméticas

Operador Operação Tipo do operador da esquerda

Tipo do operador da direita

Tipo do resultado

+ Adição numérico mesmo do anterior igual aos operandos - Subtração numérico mesmo do anterior igual aos operandos & Concatenação array 1 dimensão mesmo do anterior igual aos operandos * Multiplicação inteiro ou ponto

flutuante mesmo do anterior igual aos operandos

físico inteiro ou ponto flutuante

físico

inteiro ou ponto flutuante

físico físico

/ Divisão inteiro ou ponto flutuante

mesmo do anterior igual aos operandos

físico inteiro ou ponto flutuante

físico

físico físico inteiro mod Módulo inteiro mesmo do anterior igual aos operandos rem Resto da

divisão inteiro mesmo do anterior igual aos operandos

** Potenciação Inteiro ou ponto flutuante

inteiro igual ao operador da esquerda

abs Valor absoluto numérico numérico not Negação bit, boolean ou

array (bit, boolean) igual ao operador da direita

3.2 - Operações de Comparação

Operador Operação Tipo do operador da esquerda

Tipo do operador da direita

Tipo do resultado

= Igualdade qualquer mesmo do anterior boolean /= Desigualdade qualquer mesmo do anterior boolean < Menor que escalar ou array mesmo do anterior boolean <= Menor ou igual escalar ou array mesmo do anterior boolean > Maior que escalar ou array mesmo do anterior boolean >= Maior ou igual escalar ou array mesmo do anterior boolean

Ronaldo Hüsemann Apostila de VHDL - Página 18

3.3 - Operações Lógicas

Operador Operação Tipo do operador da esquerda

Tipo do operador da direita

Tipo do resultado

and Lógica E bit, boolean ou array(bit,boolean)

mesmo do anterior boolean

or Lógica OR bit, boolean array(bit,boolean)

mesmo do anterior boolean

nand Lógica E negada

bit, boolean array(bit,boolean)

mesmo do anterior boolean

nor Lógica OR Negada

bit, boolean array(bit,boolean)

mesmo do anterior boolean

xor Lógica OR exclusivo

bit, boolean array(bit,boolean)

mesmo do anterior boolean

xnor Lógica XOR negada

bit, boolean array(bit,boolean)

mesmo do anterior boolean

3.4 - Operações de Deslocamento e Rotação

Operador Operação Tipo do operador da esquerda

Tipo do operador da direita

Tipo do resultado

sll desloc. lógico para esquerda

array de bit ou boolean

inteiro array de bit ou boolean

srl desloc. lógico para direita

array de bit ou boolean

inteiro array de bit ou boolean

sla desl. aritmético para esquerda

array de bit ou boolean

inteiro array de bit ou boolean

sra desl. aritmético para direita

array de bit ou boolean

inteiro array de bit ou boolean

rol rotação para a esquerda

array de bit ou boolean

inteiro array de bit ou boolean

ror rotação para a direita

array de bit ou boolean

inteiro array de bit ou boolean

Ronaldo Hüsemann Apostila de VHDL - Página 19

4 - Estruturas e Comandos em VHDL

4.1 - Estrutura IF

Em aplicações onde o estado de alguma variável (ou conjunto de variáveis) determina as operações que devem ser tomadas é muito comum o uso da estrutura IF. A forma mais simples de utilização é através da estrutura if-then-endif como apresentado a seguir:

if chave = 1 then saida1 := valor_saida;

endif

onde a condição (chave = 1) é testada para permitir a operação necessária. Se a condição for verdadeira, valor_saida é atribuído à variável saida1, caso não nada é feito.

Em alguns casos é desejado realizar-se uma operação (ou sequência de operações) para quando a condição for verdadeira e outra quando a condição for falsa. Ver exemplo de uma estrutura if-then-else-endif:

if chave = 1 then saida1 := valor_saida; else

saida1 := 255; registrador := valor_saida

endif

Este caso é idêntico ao caso anterior só que quando a condição chave = 1 for falsa são executadas as linhas saida1 := 255 e registrador := valor_saida.

Uma outra variação desta estrutura é permitida através da utilização da palavra- chave elseif, que funciona como uma nova estrutura de comparação dentro da estrutura if corrente. São possíveis tantos elseif quantos forem necessários para refinar as comparações. A seguir tem-se um exemplo:

if painel = OFF then led1 := OFF; led2 := OFF; elseif leitura = 1 or leitura = 3 then

led1 := ON; led2 := OFF;

elseif leitura = 2 or leitura = 4 then led1 := OFF; led2 := ON

endif

onde os valores de saída led1 e led2são vinculados aos valores da variável de entrada leitura. Se leitura for igual a 1 ou 3 (através do uso do operador or) a saída led1 é ativada. Se leitura for igual a 2 ou 4 a saída led2 é ativada. Isto é claro somente se a condição painel = OFF for falsa, ou seja a chave de entrada do painel estiver ligada.

Ronaldo Hüsemann Apostila de VHDL - Página 20

4.2 - Estrutura CASE

Uma outra estrutura de comparação de valores para seleção de operações é a estrutura case-is-when-endcase. Esta estrutura é mais utilizada para aplicações onde uma determinada variável pode assumir um número limitado de valores, cada qual associado a um conjunto de operações. A seguir tem-se o exemplo de um multiplexador implementado com esta estrutura:

case seletor is when 0 =>

saída <= entrada0; when 1 =>

saída <= entrada1; when 2 =>

saída <= entrada2; when 3 =>

saída <= entrada3; endcase;

Para se implementar a função OU em estruturas CASE usa-se o caracter “|”. Como exemplo apresenta-se uma forma alternativa de implementar a função de acionamento das saídas led1 e led2 de acordo com a variável leitura (aplicação apresentada no item 4.1):

case leitura is when 1 | 3 =>

led1 := ON; led2 := OFF;

when 2 | 4 => led1 := OFF; led2 := ON

endcase

Para a área de sistemas digitais a grande utilidade da estrutura CASE é na implementação de máquinas de estado. No exemplo a seguir:

case estado is when estado_A =>

saida <='0'; if entrada = '1' then estado := estado_B; end if;

when estado_B => if entrada = '0' then estado := estado_C; end if;

when estado_C => estado := estado_A; saida <= '1';

end case;

Ronaldo Hüsemann Apostila de VHDL - Página 21

implementa-se a máquina de estados da figura 4.1. Note que, apesar de não indicado, a estrutura apresentada deveria estar dentro de um processo sincronizado com o clock, o que é normalmente subentendido em sistemas de máquinas de estados.

Figura 4.1: Máquina de estados implementada no exemplo

4.3 - Estrutura LOOP

As estruturas de loop em VHDL são bastante usadas principalmente para a execução repetitiva de uma determinada sequência de operações. Existe um série de variações de estruturas de loop possíveis em VHDL, de acordo com a finalidade do software. Estas estruturas serão a seguir apresentadas em sequência para melhor entendimento.

4.3.1 - Estrutura Loop Infinito

A forma mais simples de uma estrutura for é chamada desta forma por não apresentar condição de saída. Esta estrutura é particularmente útil para aplicações de sistemas simples que só executam uma tarefa, como por exemplo um controle de nível a seguir:

loop if nivel_atual < nivel_desejado -2 then

valvula_entrada := ON; elseif nivel_atual > nivel_desejado +2 then

valvula_entrada := OFF; endif

endloop

que tenta manter o nível em um valor desejado em um sistema ON/OFF com uma histerese de largura 4.

Ronaldo Hüsemann Apostila de VHDL - Página 22

4.3.2 - Estrutura Loop com Saída Forçada por Exit

Um estrutura LOOP pode entretanto precisar de uma condição de saída. Isto é previsto em VHDL pela palavra-chave exit, que força a saída do loop quando uma determinada condição for atendida. Por exemplo:

loop loop

exit when reset_contador = '1'; contador := contador +1; saida := contador;

endloop contador := 0;

endloop

A estrutura acima implementa um contador que reseta sua contagem se a condição reset_contador = '1' for verdadeira. Note que é possível o encadeamento de loops, ou seja a montagem de um loop dentro de outro. A linguagem VHDL permite a atribuição de nomes a loops e a seleção de qual saída será forçada a partir destes nomes.

Um exemplo de uso de estrutura for com diversos loops encadeados é descrito a seguir:

loop_externo : loop contador := 0;

loop_intermediario : loop loop_interno : loop saida := contador; exitwhen contagem_habilitada = '0'; exit loop_intermediario when reset_contador = '1'; endloop loop_interno contador := contador +1;

endloop loop_intermediario endloop loop_externo

onde existem duas condições de saída. A primeira testa se a contagem está desabilitada (contagem_habilitada = '0'), quando então sai do loop_interno para proceder uma nova contagem. A segunda condição de saída testa se reset_contador = '1' e caso for, salta para fora do loop_intermediario, resetando o contador.

4.3.3 - Estrutura Loop com Reinício Forçado por Next

Esta estrutura é similar ao caso de saída anterior, só que a palavra-chave next serve para reiniciar a sequência de operações do loop. Na descrição a seguir tem-se um monitor de temperatura, que só executa as medidas de emergência (aquecedor:= OFF e

Ronaldo Hüsemann Apostila de VHDL - Página 23

alarme:=ON) se a temperatura medida exceder o limite. Note que com o uso de next a execução não sai fora do loop

loop medida_temperatura = entrada_medidor; next when medida_temperatura < temperatura_maxima; aquecedor := OFF; alarme := ON;

endloop

Assim como no caso do exit, também é possível com next, a definição de qual loop deve ser iniciado quando se estiver trabalhando com loops encadeados. O formato de utilização é o seguinte:

... next nome_loop when condicao = true ...

4.3.4 - Estrutura WHILE-LOOP

A estrutura while-loop é um caso especial de estrutura de loop, onde uma condição é testada inicialmente antes de qualquer operação do loop e caso seja verdadeira, o loop é executado. Se a condição não for satisfeita, o loop pára de ser executado, seguindo-se além deste.

Um exemplo desta estrutura é apresentada a seguir:

numero := valor_entrada; raiz_quadrada := 0; while raiz_quadrada*raiz_quadrada < numero loop

raiz_quadrada := raiz_quadrada + 0.1; end loop;

onde o cálculo simples de uma raiz quadrada é feito até que se encontre o valor mais próximo. Note que se o valor de entrada for zero, a condição do loop não é satisfeita e o mesmo não é executado, resultando no valor raiz_quadrada := 0 que é o valor correto.

4.3.5 - Estrutura Loop com Contagem Tipo For

O uso de estrutura de for-loop é utilizado principalmente para execução de operações a serem repetidas por um número determinado de vezes. Por exemplo a sequência abaixo descreve o cálculo do fatorial do número 10.

resultado := 1; for n in 1 to 10 loop

resultado := resultado *n; end loop;

Ronaldo Hüsemann Apostila de VHDL - Página 24

A estrutura for-loop permite também a realização de iterações em ordem decrescente. Neste caso basta utilizar-se a palavra-chave downto no lugar de to, como em:

contador := 5; resultado := 0; for contador in 10 downto 1 loop resultado := contador; end loop;

É interessante notar que a variável utilizada para as contagens da estrutura for-loop mascara dentro do loop uma outra variável externa com o mesmo nome, mas quando for finalizado a variável externa terá seu valor intacto. No caso acima, por exemplo, ao final desta execução a variável contador terá valor 5 e a variável resultado terá o valor 1.

4.4 - Comando WAIT

A operação ou comando de espera (wait) tem como finalidade suspender a execução da sequência corrente até que uma determinada condição ocorra.

A sua utilização é feita a partir da palavra-chave wait. Este comando pode ser empregado para esperar-se simplesmente a mudança de estado de um sinal ou aguardar- se por uma variação específica.

4.4.1 - Espera por uma Variação Qualquer

O modo mais simples de utilização do comando wait é para se aguardar uma mudança qualquer de estado em um determinado sinal. Isto é feito com a palavra-chave on seguido pelo sinal que se deseja monitorar. Por exemplo, na execução de uma descrição em VHDL que contenha:

... wait on a; ...

a sequência de operação irá ser suspensa na linha apresentada até que o sinal a mude de valor, quando então irá seguir em execução normal. É possível a combinação de mais de um sinal de entrada como no caso abaixo:

... wait on a, b; ...

onde a sequência de operação é suspensa até que haja uma variação em qualquer dos sinais a ou b.

Ronaldo Hüsemann Apostila de VHDL - Página 25

4.4.2 - Espera por uma Variação Específica

Para a programação da sensibilidade para um único tipo de variação deve-se utilizar a palavra-chave until seguida pelo sinal e a condição que se deseja aguardar. Este formato de comando de espera é especialmente importante para a síntese de componentes sensíveis a um tipo de borda, como latches e flip-flops.

O exemplo abaixo ilustra a utilização deste comando para a implementação de um componente sensível a borda positiva do sinal clk:

... wait until clk = '1'; ...

4.4.3 - Espera por Nível

Em alguns casos, a função que se deseja sintetizada deve ser sensível não a borda, mas sim a um nível de sinal. Para tanto deve-se especificar além dos parâmetros vistos no item anterior a informação de tempo de persistência da condição.

Agrega-se então à estrutura de comando de espera visto anteriormente a palavra- chave for seguida pelo tempo que a condição deve ser mantida verdadeira para que o programa saia do modo suspenso. Por exemplo:

... wait until int_in = '1' for 1ms; ...

implementa a espera de um sinal de nível lógico '1' com duração de 1ms na porta int_in para dar continuidade à sequência de operação.

4.4 - Comando GENERATE

O comando de geração (generate) é usado para gerar réplicas de uma dada parte da descrição VHDL. De forma simples este comando permite a realização de uma cópia dos comandos ou componentes inseridos entre as palavras-chaves generate e end generate. A forma clássica de uso deste comando está na réplica de componentes, quando se deseja montar um projeto que apresenta blocos que devem ser repetidos várias vezes.

Por exemplo, a descrição a seguir:

comentários (0)

Até o momento nenhum comentário

Seja o primeiro a comentar!

Esta é apenas uma pré-visualização

3 shown on 49 pages

baixar o documento