ELD129002-Engtelecom (Diário) - Prof. Marcos Moecke

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar

Registro on-line das aulas

Unidade 1 - Aula inicial, Introdução a disciplina

  • 1 ENCONTRO
Unidade 1 - Aula inicial, Introdução a disciplina
Encontro 1 (27 jul)
  • ELD129002 - ELETRÔNICA DIGITAL I (ELD1): Sistema de numeração e códigos. Lógica booleana. Circuitos combinacionais. Circuitos aritméticos. Linguagem de descrição de hardware. Implementação e teste de circuitos digitais. Projeto de circuitos lógicos.
  • ELD129003 - ELETRÔNICA DIGITAL II (ELD2): Dispositivos lógicos programáveis. Circuitos sequenciais. Metodologia síncrona. Projeto hierárquico e parametrizado. Máquinas de estados finita. Register Transfer Methodology. Teste de circuitos digitais. Implementação em FPGA. Introdução a Linguagem de Descrição de Hardware.
  • AOC129004 - ARQUITETURA E ORGANIZAÇÃO DE COMPUTADORES (AOC): Introdução à Arquitetura Computadores. Linguagem Assembly. Linguagem de Máquina. Programação Assembly. Modos de Endereçamento. Processo de compilação e carga de um programa. Introdução à Organização de Computadores. Organização Monociclo e Multiciclo. Pipeline. Memória e Sistema de E/S.
  • MIC129007 - MICROCONTROLADORES (MIC): Introdução a Microcontroladores e Aplicações. Arquitetura de um microcontrolador. Pilha e Subrotinas. Interrupção. Contadores e Temporizadores. Interface com Periféricos. Programação em alto nível (ex.: C, C++ e RUST) para Microcontroladores: Mapeamento de tipos e estruturas de alto nível para sistemas com recursos limitados. Projeto de hardware e firmware com microcontroladores.
  • STE129008 - STE - SISTEMAS EMBARCADOS (STE): Conceitos em Sistemas Embarcados. Metodologia de Desenvolvimento de Sistemas Embarcados. Sistemas Operacionais para Sistemas Embarcados. Ferramentas de desenvolvimento e depuração. Barramentos e dispositivos de acesso a redes. Desenvolvimento de Projeto.
  • Nesta página está o REGISTRO DIÁRIO E AVALIAÇÕES.
  • A entrega de atividades e avaliações será através da plataforma Moodle. A inscrição dos alunos é automática a partir do SIGAA.
  • Para a comunicação entre professor-aluno, além dos avisos no SIGAA, utilizaremos o chat institucional. A princípio todos os alunos já estão previamente cadastrados pelo seu email institucional. Confiram enviando uma mensagem de apresentação.
  • Utilizaremos durante as aulas algumas ferramentas computacionas como o site do Falstad para entender circuitos digitais e fazer simulações básicas.
  • Também utilizaremos os softwares Quartus Light e ModelSim instalados nas maquinas do laboratório para praticar a parte de programação de hardware (descrição de hardware). Esses softwares também podem ser usados através da NUVEM do IFSC..
LER PARA O PRÓXIMO ENCONTRO

Unidade 2 - Sistema de numeração e códigos

  • 4 ENCONTROS
Unidade 2 - Sistema de numeração e códigos
Encontro 2 (1 ago) - Sistemas numéricos

O ser humano precisa contar para determinar quantidades de coisas, com as quantidades ele pode fazer operações matemáticas e comparações.

  • Os números permitem representar quantidades de forma simbólica.
  • Os símbolos utilizados são chamados de dígitos.
  • Em alguns sistemas a posição do símbolo faz diferença (sistemas posicionais), enquanto que em outros o símbolo já representa a quantidade.
  • Dependendo do sistema podem existir diferentes tipos e quantidades de símbolos.
  • Sistema decimal:
  • É o sistema utilizado no dia a dia das tarefas diárias
  • Utiliza 10 símbolos (dígitos). 0, 1, 2, 3, 4, 5, 6, 7, 8 e 9
  • É um sistema posicional, onde a posição do dígito tem um peso dado pela base (10) elevado ao expoente da posição.
  • Exemplo: o número representado 135, corresponde a 1 centena (10² = 100), 3 dezenas (10¹ = 10) e 5 unidades (10⁰ = 1), pois
1*10² + 3*10¹ + 5*10⁰ = 1*100 + 3*10 + 5*1 = 100 + 30 + 5 = 135
  • Com o sistema podemos contar quantidades, representar quantidades inteiras e fracionárias, comparar valores (quantidades), fazer operações de soma, subtração, multiplicação, divisão, entre outras;
  • Exemplos:
Contar: …, 34, 35, 36, 37, …
Somar: 21 + 46 + 100 = 100 + 20 + 40 + 1 + 6 = 100 + 60 + 7 = 167;
Multiplicar: 3 x 6 = 6 + 6 + 6 = 18;
Dividir: 35/7 = (5+ 5 + 5 + 5 + 5 + 5 +5)/7 = (5*7)/7 = 5;
Representar frações: 12/10 = 1,2; 3/4 = 0,75
Comparar valores: 145 > 14,5; 230 = 2,3x102
  • Outros sistemas:
  • Nos computadores e circuitos digitais, para fazer a representação de números são utilizadas normalmente duas tensões, sendo uma para representar o dígito “0” (0 volt), e outra para representar o dígito “1” ( X volts).
  • Este sistema é chamado de sistema binário, pois utiliza apenas dois dígitos (0 e 1).
  • O sistema também é posicional, e permite representar quantidades e fazer operações matemáticas e comparações
  • OBS: Muitas vezes os números binários são representados através do sistema hexadecimal ou do sistema octal (já em desuso).
  • Sistema binário:
  • Utiliza apenas 2 símbolos (dígitos). 0 e 1
  • É um sistema posicional, onde a posição do dígito tem um peso dado pela base (2) elevado ao expoente da posição.
  • Exemplo: o número representado 111, corresponde a 1 quadra (2² = 4), 1 dupla (2¹ = 2) e 1 unidade (2⁰ = 1).
1*2² + 1*2¹ + 1*2⁰ = 1*4 + 1*2 + 1*1 = 4 + 2 + 1 = 7
LER PARA O PRÓXIMO ENCONTRO
Encontro 3 (3 ago) - Sistemas numéricos
  • O que são bits, nibbles, bytes e word (palavra) de bits
↓msb lsb↓
0 1 1 0 0 1 1 0 1 1 1 0 0 0 1 1
nibble nibble nibble nibble
byte (MSB) byte (LSB)
word (palavra)
  • Note no quadro acima:
  • o nibble corresponde ao grupo de 4 bits (meio byte)
  • o byte corresponde ao grupo de 8 bits
  • a word corresponde ao grupo de 16 bits (as vezes 32 bits)
  • a double word corresponte ao grupo de 32 bits (as vezes 64 bits)
  • o bit menos significativo (lsb - less significative bit)
  • o bit mais significativo (msb - most significative bit)
  • o byte menos significativo (LSB - Less Significative Byte)
  • o byte mais significativo (MSB - Most Significative Byte)
  • Prefixos e multiplos utilizados para quantidades de informação
Nome Símbolo Número de bytes Aproximação decimal
Byte B / Byte 1 1
kilobyte kB / kByte (mil)
Megabyte MB / MByte (milhão)
Gigabyte GB / GByte (bilhão)
Terabyte TB / TByte (trilhão)
Petabyte PB / PByte (quadrilhão)

Ler mais sobre Byte e os prefixos binários na Wikipedia

Códigos numéricos binários
  • Número sem sinal (UNSIGNED)
Neste caso apenas números inteiros naturais podem ser representados.
Usando bits é possível representar números inteiros no intervalo de .
Por exemplo usando 8 bits =>
bit 7 6 5 4 3 2 1 0
valor 1 0 1 0 0 1 1 1
peso 27 26 25 24 23 22 21 20
peso +128 +64 +32 +16 +8 +4 +2 +1
somar +128 +32 +4 +2 +1
resultado 128 + 32 + 4 + 2 + 1 = 167
  • Número com sinal (Sinal-Magnitude ou Magnitude e Sinal)
Neste caso os números inteiros negativos são representados com 1 no msb, e o positivos com 0 no msb.
Usando bits é possível representar números inteiros no intervalo de . Nesta representação existem dois zeros, o +0 e o -0.
Por exemplo usando 8 bits =>
bit 7 6 5 4 3 2 1 0
peso 26 25 24 23 22 21 20
peso +64 +32 +16 +8 +4 +2 +1
valor 1 0 1 0 0 1 1 1
somar - +32 +4 +2 +1
resultado - ( 32 + 4 + 2 + 1) = - 39
valor 0 0 1 0 0 1 1 1
somar + +32 +4 +2 +1
resultado + ( 32 + 4 + 2 + 1) = +39
  • Número com sinal (Complemento de 2 ou SIGNED)
Neste caso o msb corresponde ao peso negativo, de modo que ao colocar 1 no msb o número inteiro passa a ser negativo, e se o msb for 0, o número será positivo.
Usando bits é possível representar números inteiros no intervalo de . Nesta representação existem apenas um zero.
Por exemplo usando 8 bits =>
Neste caso note que quando todos os bits são 1, o número representado será o -1,
bit 7 6 5 4 3 2 1 0
peso 27
26 25 24 23 22 21 20
peso -128 +64 +32 +16 +8 +4 +2 +1
valor 1 0 1 0 0 1 1 1
somar -128 +32 +4 +2 +1
resultado - 128 + 32 + 4 + 2 + 1 = -128 + 39 = -89
valor 0 0 1 0 0 1 1 1
somar +32 +4 +2 +1
resultado 32 + 4 + 2 + 1 = +39
valor 1 1 1 1 1 1 1 1
somar -128 +64 +32 +16 +8 +4 +2 +1
resultado -128 + 64 + 32 +16 + 8 + 4 + 2 + 1 = -128 + 127 = -1


Comparação das representações

Representação binária
Decimal Sem sinal Sinal-magnitude Complemento de um Complemento de dois
+15 1111
+14 1110
+13 1101
+12 1100
+11 1011
+10 1010
+9 1001
+8 1000
+7 0111 0111 0111 0111
+6 0110 0110 0110 0110
+5 0101 0101 0101 0101
+4 0100 0100 0100 0100
+3 0011 0011 0011 0011
+2 0010 0010 0010 0010
+1 0001 0001 0001 0001
+0 0000 0000
0 0000 0000
−0 1000 1111
−1 1001 1110 1111
−2 1010 1101 1110
−3 1011 1100 1101
−4 1100 1011 1100
−5 1101 1010 1011
−6 1110 1001 1010
−7 1111 1000 1001
−8 1000
  • Para obter o número negativo em complemento de um deve-se complementar (inverter) todos os bits do número binário positivo.
  • Para obter o número negativo em complemento de dois deve-se: a) obter o complemento de um (complementar (inverter) todos os bits do número binário positivo ); b) somar 1 ao resultado.
  • Para obter o número negativo em sinal-magnitude é necessário apenas adicionar um bit 1 a esquerda do lsb.
  • Note que em todos os casos a representação de números com sinal, sempre implica na necessidade de um bit a mais.
 13 (decimal) = 01101 (binário sem sinal)
-13 (decimal) = 10010 (binário em complemento de um)
-13 (decimal) = 10010 + 1 = 10011 (binário em complemento de dois)
-13 (decimal) = 11101 (binário em sinal-magnitude)
Código ASCII

O código ASCII (American Standard Code for Information Interchange), é um padrão de codificação de caracteres para comunicação digital. Ele tem apenas 128 pontos de código, sendo 95 são caracteres imprimíveis e os demais são não imprimíveis (em azul no quadro abaixo), sendo usados para diversos controles de equipamentos eletrônicos. Atualmente esse código está sendo substituido pelos códigos UNICODE, que tem milhões de pontos de código, mas nos UNICODE os primeiros 128 são iguais ao conjunto ASCII.

Código ...0000 ...0001 ...0010 ...0011 ...0100 ...0101 ...0110 ...0111 ...1000 ...1001 ...1010 ...1011 ...1100 ...1101 ...1110 ...1111
…0 …1 …2 …3 …4 …5 …6 …7 …8 …9 …A …B …C …D …E …F
000... 0… NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI
001... 1… DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US
010... 2… SP ! " # $ % & ' ( ) * + , - . /
011... 3… 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
100... 4… @ A B C D E F G H I J K L M N O
101... 5… P Q R S T U V W X Y Z [ \ ] ^ _
110... 6… ` a b c d e f g h i j k l m n o
111... 7… p q r s t u v w x y z { } ~ DEL

Exemplo de leitura do quadro acima:

  • A letra "A" é representado pelo número hexadecimal 41, o que corresponde a 01000001 em binário
  • A letra "a" é representado pelo número hexadecimal 61, o que corresponde a 01100001 em binário
  • O espaço "SP" é representado pelo número hexadecimal 20, o que corresponde a 00100000 em binário

Descubra o que está escrito em:

45 6e 67 74 65 6c 65 63 6f 6d 20 64 6f 20 49 46 53 43 20 
01000010 01101111 01101101 00100000 01100100 01101001 01100001 00100000 01110000 01100101 01110011 01110011 01101111 01000001 01001100 01001100


Código UNICODE

O Unicode é capaz de representar uma ampla variedade de caracteres, incluindo caracteres alfabéticos, numéricos, símbolos, caracteres especiais e até mesmo caracteres em idiomas e sistemas de escrita complexos, como chinês, árabe, hindi, hebraico, japonês, emojis entre outros. O Unicode possui um espaço de codificação grande o suficiente para suportar milhares de caracteres diferentes. O Unicode é implementado nos esquemas de codificação UTF-8, UTF-16 e UTF-32. O mais utilizado na web é o UTF-8, por ser eficiente em uso de número de bits e ser compatível com o ASCII. Hoje em dia o UTF-8 é usado em 98% de todos os websites conhecidos [1]. Para cobrir uma vasta gama de caracteres, o Unicode os organiza em blocos. Exemplos de blocos: "Latin basic","Greek and Coptic", "Chess Symbols", "Emoticons", "Mayan Numerals", etc.


Encontro 4 (8 ago) - Sistemas numéricos
  • Outros códigos binários:
  • Gray - É um código em que dois valores consecutivos diferem em apenas um bit. Isso é útil para minimizar erros de leitura em sistemas eletrônicos, já que a transição entre estados ocorre com uma única mudança de bit, facilitando a detecção de erros.
Note por exemplo:
  • Em código binário convencional o número adjacente a 0111 (7) é o 1000 (8), mudança em 4 bits.
  • Em código Gray o número adjacente a 0100 (7) é o 1100 (8), mudança de apenas 1 bit.
  • One-hot - Neste código cada valor é representado por uma única posição ativa (ALTO) dentro do conjunto de bits, enquanto todas as outras posições estão inativas (BAIXO). Esse código é frequentemente usado em sistemas digitais para representar estados discretos, como em máquinas de estados finitos, e também na geração de sinais de seleção de múltiplos circuitos tais como memórias. A vantagem principal reside na simplicidade da detecção de um único estado ativo, evitando ambiguidades e permitindo uma implementação eficiente em hardware.
  • Johnson - Neste código é gerado deslocando-se sucessivamente todos os bits para a esquerda e colocando o bit complementar do msb como lsb. A codificação normalmente começa com todos bits "0". Devido a sua simplicidade, ele é utilizado para contadores utilizados em controle de sistemas digitais simples de alta velocidade. Por sempre ter apenas 1 bit de diferença entre números adjacentes, ele fornece boa proteção contra erros, mas necessita de mais bits para representar a mesma faixa de valores que um binário sequencial.
  • BCD (Binary-coded decimal) - Esse código basicamente consiste em representar cada digito decimal de 0 a 9 por um grupo de 4 bits (0 -> 0000, 1 -> 0001, ... 8 -> 1000 e 9 -> 1001). Ele é utilizado em mostradores de sete segmentos, onde cada um deles indica um dígito.
Decimal Hexadecimal Octal Binário
convencional
Binário
Gray
Binário
One Hot
Binário
Johnson
BCD
00 0 00 0000 0000 0000.0000.0000.0001 00000000 0000.0000
01 1 01 0001 0001 0000.0000.0000.0010 10000000 0000.0001
02 2 02 0010 0011 0000.0000.0000.0100 11000000 0000.0010
03 3 03 0011 0010 0000.0000.0000.1000 11100000 0000.0011
04 4 04 0100 0110 0000.0000.0001.0000 11110000 0000.0100
05 5 05 0101 0111 0000.0000.0010.0000 11111000 0000.0101
06 6 06 0110 0101 0000.0000.0100.0000 11111100 0000.0110
07 7 07 0111 0100 0000.0000.1000.0000 11111110 0000.0111
08 8 10 1000 1100 0000.0001.0000.0000 11111111 0000.1000
09 9 11 1001 1101 0000.0010.0000.0000 01111111 0000.1001
10 A 12 1010 1111 0000.0100.0000.0000 00111111 0001.0000
11 B 13 1011 1110 0000.1000.0000.0000 00011111 0001.0001
12 C 14 1100 1010 0001.0000.0000.0000 00001111 0001.0010
13 D 15 1101 1011 0010.0000.0000.0000 00000111 0001.0011
14 E 16 1110 1001 0100.0000.0000.0000 00000011 0001.0100
15 F 17 1111 1000 1000.0000.0000.0000 00000001 0001.0101
  • Resolução de exercícios:
  • Exercícios 1.9 a 1.40
Encontro 5 (10 ago) - Sistemas numéricos
Extensão de bits de um número inteiro sem sinal
  • Para estender um número de M bits para N bits, basta adicionar (N-M) zeros à esquerda, de modo a ter N bits no total.
Exemplo: Estender o número binário sem sinal de 5 bits "01101" para 8 bits:
Número original: 01101      = (13 em decimal), pois 8 + 4 + 1 = 13
Número estendido: 00001101  = (13 em decimal), pois 8 + 4 + 1 = 13
Extensão de bits de um número inteiro com sinal em complemento de 2
  • Para estender um número de M bits para N bits em complemento de 2, o msb (o bit mais significativo) deve ser estendido (copiado) (N-M) vezes para os novos bits à esquerda, de modo a ter N bits no total.
Exemplo: Estender o número binário com sinal em complemento de 2 de 5 bits "10011" para 8 bits:
Número original: 10011      = (-13 em decimal), pois -16 + 2 + 1 = -13
Número estendido: 11110011  = (-13 em decimal), pois -128 + 64 + 32 + 16 + 2 + 1 = -13
Note que para números positivos o resultado é similar a estender o número inteiro sem sinal.
Extensão de bits de um número inteiro com sinal em sinal-magnitude
  • Para estender um número de M bits para N bits do tipo sinal-magnitude, o msb (o bit mais significativo) deve ser movido para o novo msb, e os demais novos bits devem ser zerados.
Exemplo: Estender o número binário com sinal em sinal-magnitude de 5 bits "10011" para 8 bits:
Número original: 11101      = (-13 em decimal), pois -(+8 + 4 + 1) = -13
Número estendido: 10001101  = (-13 em decimal), pois -(+8 + 4 + 1) = -13

Ponto Fixo
  • É um número binário que permite representares números fracionários. Os valores são todos escalonados por um fator constante para transformar em um número inteiro. Assim, o número 5,25 pode ser escalonado por 2² => 5,25 x 4 = 21, e portanto 5,25 = 21 / 2². Assim, usando dois bits fracionarios, o número 5,25 pode ser escrito em binário como 10101, onde o separador fracionário esta em 101,01.
  • Usando bits para representar um número de ponto fixo Q(M,F) com F bits fracionários, é possível representar números fracionários no intervalo de . Neste caso a resolução (menor quantidade que se pode representar) é de
Por exemplo usando Q(8,3) => , e a resolução é de .
bit 4 3 2 1 0 -1 -2 -3
valor 1 0 1 0 0 1 1 1
peso 24 23 22 21 20 2-1 2-2 2-3
peso +16 +8 +4 +2 +1 +0,5 +0,25 +0,125
somar +16 +4 +0,5 +0,25 +0,125
resultado 16 + 4 + 0,5 + 0,25 + 0,125 = 20,875
  • Note que que é possível obter rapidamente o valor de um número de ponto fixo, obtendo o valor do seu número inteiro correspondente, dividindo-o por 2-F. No exemplo acima, 10100111, corresponde ao inteiro 167, ou seja se o número é do tipo Q(8,3), o valor é de 167/2-F = 20,875.
  • Assim como nos números inteiros, é possível representar também números em ponto fixo negativos usando complemento de 2 ou sinal-magnitude.
Ponto Flutuante (floating point)

Os números de ponto flutuante são agrupados da esquerda para a direita:1) bit de sinal, 2) expoente e 3) mantissa. Para os formatos binários IEEE 754 (básico e estendido) que possuem implementações de hardware existentes, eles são distribuídos da seguinte forma:

Tipo Sinal Exponente Mantissa Total
bits
Viés do
exponente
Precisão
em bits
Half-precision 1 5 10 16 15 11
Single-precision 1 8 23 32 127 24
Double-precision 1 11 52 64 1023 53

Embora o expoente possa ser positivo ou negativo, em formatos binários ele é armazenado como um número sem sinal que possui um "viés" fixo adicionado a ele. A faixa de expoente para números normais é [−126, 127] para precisão simples, [−1022, 1023] para dupla. Existem três tipos principais de números: normalizados, denormalizados (ou desnormalizados) e especiais (como infinito e NaN - "Not a Number").

Nos formatos IEEE, o bit 1 inicial de um significando normalizado não é realmente armazenado. É chamado de bit "oculto" ou "implícito". Por causa disso, o formato de precisão simples na verdade tem um significando com 24 bits de precisão, o formato de precisão dupla tem 53.

O layout para o ponto flutuante de 32 bits e de 64 bits são mostrados abaixo:

PontoFlutuante32.png
PontoFlutuante64.png
  • Como converter de decimal para floating point?
  • Como converter de floating point para decimal?
  1. Identifique se o número é de 16, 32 ou 64 bits.
  2. Obtenha o sinal do número a partir do msb (S = 0 => +; S = 1 => -)
  3. Obtenha o número correspondente ao expoente (E).
  4. Considerando o viés, calcule o exponente (e = E - vies)
  5. Obtenha o valor da mantissa (M) e acrescente o 1 inteiro (se o numero estiver normalizado) (1.M)
  6. O resultado em decimal é
Exemplo: Dado o número floating point de 32 bits =  01000000111000000000000000000000
Sinal (msb): 0 => positivo
Viés: (28-1 - 1) = -127
Expoente (8 bits): 10000001 = 129 - 127 = 2
Mantissa: (23 bits): 11000000000000000000000
Valor (24 bits): 1.11000000000000000000000 = 1,75
Resultado: (-) 1,75 x 22 = 7
  • Números denormalizados.

Os números denormalizados não usam um "1" implícito no início da mantissa, ao contrário dos números normalizados. Isso significa que a mantissa dos números denormalizados começa com um "0" explícito antes da parte fracionária, permitindo representar valores muito pequenos que não podem ser normalizados devido à limitação dos bits do expoente.

  • Números especiais.
  • Infinito Positivo (Inf):
Bit de sinal: 0 (positivo)
Expoente: Todos os bits definidos como 1 (8 bits)
Mantissa: Todos os bits definidos como 0 (23 bits)
Representação em 32 bits: 0 11111111 00000000000000000000000
  • Infinito Negativo (-Inf):
Bit de sinal: 1 (negativo)
Expoente: Todos os bits definidos como 1 (8 bits)
Mantissa: Todos os bits definidos como 0 (23 bits)
Representação em 32 bits: 1 11111111 00000000000000000000000
  • NaN (Not a Number):
Bit de sinal: Pode ser 0 ou 1 (geralmente usado para sinalizar erros ou operações indefinidas)
Expoente: Todos os bits definidos como 1 (8 bits)
Mantissa: Pelo menos um bit não nulo (23 bits)
Representação: x 11111111 yyyyyyyyyyyyyyyyyyyyyyy (onde "x" é o bit de sinal e "y" são bits da mantissa)
  • Exemplos de conversores online.

Unidade 3 - Funções, portas lógicas e álgebra booleana

  • 10 ENCONTROS
Unidade 3 - Funções, portas lógicas e álgebra booleana
Encontro 6-8 (15,17,22 ago) - Funções e portas lógicas
Encontro 9 (24 ago) - Álgebra booleana
Encontro 10 (29 ago) - Projeto de circuitos combinacionais
Encontro 11 (31 ago) - Exercícios de álgebra de Boole
Encontro 12 (5 set) - Expressão booleana - Tabela verdade - Circuito com portas lógicas
Encontro 13 a 15 (12, 14 e 19 set) - Simplificação de expressões lógicas - Mapas de Karnaugh-Veitch

Unidade 4 - Introdução a linguagem VHDL e Quartus/ModelSim

  • 6 ENCONTROS
Unidade 4 - Introdução a linguagem VHDL e Quartus/ModelSim
Encontro 16 (21 set) - Linguagem VHDL
Encontro 17 (26 set) - Avaliação A1b
Encontro 18 (28 set) - Linguagem VHDL (cont)
  • Estrutura do código VHDL
  • Declaração das bibliotecas e pacotes LIBRARY / PACKAGE
 library library_name;
 use library_name.package_name.all;
  • ENTITY
 entity entity_name is
   [generic (
     cons_name1: const_type const_value;
     cons_name2: const_type const_value;
     ...
     cons_nameN: const_type const_value);]
   [port (
     signal_name1: mode signal_type;
     signal_name2: mode signal_type;
     ...
     signal_nameN: mode signal_type);]
   [declarative_part]
 [begin
   statement_part]
 end [entity] [entity_name];
  • ARCHITECTURE
 architecture arch_name of entity_name is
   [declarative_part]
 begin
   statement_part
 end [architecture] [arch_name];
  • Exemplo - Declaração de uma porta NAND em VHDL
library std;
use std.standard.all;

entity nand_gate is
	port (a, b: in bit; x: out bit);
end entity;

architecture nome_arch of nand_gate is
begin
	x <= a nand b;
end architecture;
  • Uso do ambiente EDA - QUARTUS Prime para programação em VHDL.
PASSO 0

Acesse a nuvem do IFSC usando um terminal via ssh:

USER=LOGIN_SIGAA
ssh $USER@quartus.sj.ifsc.edu.br -XC  

Insira a senha do SIGAA

LOGIN_SIGAA@quartus.sj.ifsc.edu.br's password:
PASSO 1

Abra o Quartus Prime digitando no terminal

quartus20.1.sh

Em seguida abra um arquivo para inserir o código VHDL. No menu superior selecione [File > New > Design Files: VHDL File] e [OK]

PASSO 2
  • Copie o código VHDL acima para o espaço de edição e salve o arquivo com o nome da entity: nand_gate.vhd, em um pasta exclusiva para este projeto.
  • Ao ser perguntado se deseja criar um novo projeto, responda [Yes]. Os próximos passos podem ser realizados da seguinte forma:
  • Na tela Introduction [Next >]
  • Na tela Directory, Name, Top-Level Entity
  • Note onde o projeto será salvo.
 /home/USER/PASTA_DO_PROJETO/
  • Note o nome do projeto. Se quiser pode mudá-lo
nand_gate
  • Note o nome da top-level design entity
nand_gate
  • Em seguida [Next >]
  • Na tela Project Type [Next >]
  • Na tela Add Files [Next >], pois seu arquivo já está na lista dos arquivos.
  • Na tela Family, Device & Board Settings, escolha a Family = [Cyclone IV E] e o Device = [EP4CE6E22A7] e [Next >]
  • Na tela EDA Tool Setting [Next >]
  • Note na tela Summary os dados do projeto e clique [Finish]
PASSO 3

Realize a Analysis & Synthesis [Processing > Start > Start Analysis & Synthesis], ou use um dos botões que o professor mostrou em aula.

  • Note o Compilation Report
PASSO 4
  • Use o RTL Viewer para ver a descrição RTL do circuito. Selecione [Tools > Netlist Vieweres > RTL Viewer].
  • Use o Technology Map Viewer para ver a como o circuito foi mapeado para os elementos lógicos disponíveis no dispositivo FPGA selecionado. Selecione [Tools > Netlist Vieweres > Technology Map Viewer].
PASSO 5
  • Modifique a descrição do circuito para implementar o circuito da função Y = (A.B)' + C.D'B', salve o projeto Ckt2.vhd e de o mesmo nome para a entity.
Encontro 19 (3 out.) - Simulador ModelSim
  • Abra o circuito que foi salvo na aula anterior. Após abrir o Quartus, clique em [File > Open Project] e selecione a pasta onde salvou o projeto. Depois clique sobre o arquivo nand_gate.qpf. Note que abrir um projeto é diferente de abrir um arquivo, pois todos os arquivos de configuração estão associados a esse .qpf.
Encontro 20 (5 out.)
  • Avaliação A1c - Simplificação de expressões lógicas:


Encontro 21 (10 out.)
  • Escreva o código VHDL e faça a simulação para o circuito correspondente a expressão lógica:
Y = AB + AC'
Z = A'BC + C'

Unidade 5 - Circuitos lógicos combinacionais (com VHDL)

  • 12 ENCONTROS
Unidade 5 - Circuitos lógicos combinacionais (com VHDL)
Encontro 22, 23 (17 e 20 out.)
Encontro 24 (24 out.)
  • Conhecer o Código Gray
  • Implementação de conversor Binário para Gray (bin2gray)
-------------------------
-- File: bin2gray_v1.vhd  --
-------------------------
entity bin2gray_v1 is
	port
	(
		b0, b1, b2, b3  : in bit;
		g0, g1, g2, g3  : in bit
	);
end entity;
--Exemplo implementando o circuito diretamente com as portas lógicas
architecture ifsc_v1 of ____ is
begin

end architecture;

Como o circuito de um conversor bin2gray, possui uma certa quantidade de bits de entrada e a mesma quantidade de saída, não é adequado descrever esse circuito utilizando o tipo bit. O VHDL dispõe do tipo bit_vector; de vetores para descrever esse tipo de entrada e saída.

-------------------------
-- File: bin2gray_v2.vhd  --
-------------------------
entity bin2gray_v2 is
	port
	(
		b  : in bit_vector(3 downto 0);
		g  : out bit_vector(3 downto 0)
	);
end entity;
--Exemplo implementando o circuito diretamente com as portas lógicas
architecture ifsc_v2 of ____ is
begin

end architecture;

Caso se deseje aumentar o número de bits da entrada, na abordagem acima é necessário aumentar o número de operações ou exclusivo, e para cada quantidade de bits é necessário ter uma nova descrição. Usando corretamente a instrução generic, e a instrução for generate, é possível escrever um código único (genérico) para qualquer numero de bits.

  • O GENERIC permite parametrizar um circuito, definindo os valores que se deseja alterar em um circuito em diferentes soluções. Um exemplo comum é alterar o número de bits das entradas e saídas do circuito. Essa instrução é declarada na ENTITY, antes da declaração das PORT.
 
   [generic (
     cons_name1: const_type const_value;
     cons_name2: const_type const_value;
     ...
     cons_nameN: const_type const_value);]
  • Uso da instrução FOR-GENERATE
 
label: FOR identificador IN faixa GENERATE
   [Parte_Declarativa
BEGIN]
   Instruções_concorrentes
   ...
END GENERATE [label];


-------------------------
-- File: bin2gray_v3.vhd  --
-------------------------
entity bin2gray_v3 is
	generic (N : natural := 4 );
	port
	(
		b  : in bit_vector(N-1 downto 0);
		g  : out bit_vector(N-1 downto 0)
	);
end entity;
architecture ifsc_v3 of ____ is
begin

end architecture;
  • Após cada implementação analise o diagrama RTL e verifique se as 3 soluções apresentadas resultam no mesmo circuito.
  • Efetua a simulação com o Modelsim para verificar se as entradas em código binário sequêncial de "0000" até "1111" resultam corretamente nas saídas em Código Gray.
  • Verifique se a versão bin2gray_v3 pode ser alterada para 10 bits e continua gerando o circuito correto.
  • Descubra quantas portas ou exclusivo seriam necessárias para o caso de N bits.


  • DESAFIO: Implementação de conversor Gray para Binário (gray2bin)

Considerando o que aprendeu com as duas versões do conversor bin2gray, descreva o circuito do conversor gray2bin.

-------------------------
-- File: gray2bin.vhd  --
-------------------------
entity gray2bin is
	generic (N : natural := 4 )
	port
	(
		g  : in std_logic_vector(____)
		b  : out std_logic_vector(____)
	)
end entity

architecture ifsc_v1 of ____ is
begin

end architecture
architecture ifsc_v2 of ____ is
begin

end architecture
Encontro 25 e 26 (26 e 31 out.)
  • Conhecer o multiplexador digital.

Um multiplexador digital de N entradas e 1 saída, frequentemente abreviado como MUX N:1, é um circuito digital muito utilizado para rotear sinais digitais Ele desempenha a função de selecionar uma das entradas para ser encaminhada para a saída com base em um sinal de seleção (ou controle).

  • MUX2:1

A tabela verdade que descreve um MUX2:1 é mostrada abaixo:

X1 X0 Sel Y
0 0 0 0
0 0 1 0
0 1 0 1
0 1 1 0
1 0 0 0
1 0 1 1
1 1 0 1
1 1 1 1

O MUX2:1 também pode ser representado de forma resumida por:

X1 X0 Sel Y
- X0 0 X0
X1 - 1 X1

Onde o X0 e X1 na entrada podem assumir os valores 0 ou 1, e o simbolo "-" corresponde ao don't care (em VDHL)

A função booleana que descreve a operação de um MUX 2:1 pode ser representada da seguinte forma:



Onde Y é a saída; Sel é o sinal de seleção; X0 e X1 são as entradas.

  • MUX4:1

O MUX4:1 pode ser representado de forma resumida pela tabela verdade:

Entradas Seleção Saída
X3 X2 X1 X0 Sel1 Sel0 Y
- - - X0 0 0 X0
- - X1 - 0 1 X1
- X2 - - 1 0 X2
X3 - - - 1 1 X3

A função booleana que descreve a operação de um MUX 4:1 pode ser representada da seguinte forma:



Dada a função booleana do MUX4:1 é simples para descreve-lo em VHDL utilizando apenas operadores lógicos.

entity mux4x1 is
	port
	(
		-- Input ports
		X: in  bit_vector (3 downto 0);
                Sel : in bit_vector (1 downto 0);
		-- Output ports
		Y : out bit
	);
end entity;

-- Implementação com lógica pura
architecture v_logica_pura of mux4x1 is

begin
 Y <= (X(0) and (not Sel(1)) and (not Sel(0))) or
      ...
end architecture;

No entanto, o MUX4:1 também pode ser descrito utilizando a instrução WHEN-ELSE

<optional_label>: <target> <= 
	<value> when <condition> else
	<value> when <condition> else 
	<value> when <condition> else
	...
	<value>;
  • Importante: O último ELSE deve cobrir todos os demais valores para evitar a criação de LATCHES.
Warning (13012): Latch ... has unsafe behavior
  • No QuartusII existe um template pronto para ser utilizado em: [Edit > Insert Template > Language templates = VHDL (+) > Constructs (+) > Concurrent Statemens (+) > Conditional Signal Assignment]

No caso do MUX4:1 ele poderia ser descrito como:

-- Implementação com WHEN ELSE
architecture v_WHEN_ELSE of mux4x1 is

begin
 Y <= X(0) when Sel = "00" else
      X(1) when Sel = "01" else
      X(2) when Sel = "10" else
      X(3);
end architecture;

Outra forma de descrever o MUX4:1 seria utilizando a instrução WITH-SELECT

<optional_label>: with <expression> select
	<target> <= 
		<value> when <choices>,
		<value> when <choices>,
		<value> when <choices>,
	 	...
		<value> when others;
  • Importante: Para cobrir todas as demais possibilidades deve ser utilizado o WHEN OTHERS evitando novamente a criação de LATCHES, ou erros de análise.
Error (10313): VHDL Case Statement error ...: Case Statement choices must cover all possible values of expression
  • No QuartusII existe um template pronto para ser utilizado em: [Edit > Insert Template > Language templates = VHDL (+) > Constructs (+) > Concurrent Statemens (+) > Selected Signal Assignment]. Mas ATENÇÃO, faltam as virgulas após cada escolha.
-- Implementação com WITH SELECT
architecture v_WITH_SELECT of mux4x1 is

begin
 with Sel select
 Y <= X(0) when "00",    -- note o uso da ,
      X(1) when "01",
      X(2) when "10",
      X(3) when others;  -- note o uso de others, para todos os demais valores.  
                         -- Não pode ser substituido por "11" mesmo que o signal seja bit_vector.
end architecture;
  • Note que para associar uma entre várias arquiteturas com a sua ENTITY pode-se utilizar a instrução CONFIGURATION. No exemplo abaixo a ARCHITECTURE que está descomentada é a que será associada a ENTITY mux4x1.
  • Caso não se use a instrução CONFIGURATION, a última ARCHITECTURE será associada a ENTITY.
  • Apesar de apenas uma das ARCHITECTUREs ser associada, todas elas devem estar sintaticamente corretas, pois passarão pelo processo de ANÁLISE E SINTESE.
-- Design Unit que associa a architecture com a entity
configuration cfg_ifsc of mux4x1 is
	for v_logica_pura end for;
--	for v_WHEN_ELSE end for;
--	for v_WITH_SELECT end for;
end configuration;
  • Faça a análise e sintese do mux4x1, associando a architecture v_logica_pura, depois v_WITH_SELECT, depois v_WHEN e por último v_IF_ELSE.
  • Note a diferença entre os RTL Viewer obtidos para cada architecture.

Figura 2.1 - Código RTL do mux4x1 v_logica_pura
RTL mux4x1v1.png
Fonte: Elaborado pelo autor.

Figura 2.2 - Código RTL do mux4x1 v_WHEN_ELSE
RTL mux4x1v2.png
Fonte: Elaborado pelo autor.

Figura 2.3 - Código RTL do mux4x1 v_WITH_SELECT
RTL mux4x1v3.png
Fonte: Elaborado pelo autor.
OBS: Register Transfer-Level (RTL) é uma abstração na qual o circuito é descrito em termos de fluxo de sinais entre os registradores presentes no hardware e as operações combinacionais realizadas com esses dados.
  • Note a que ao verificar o Technology Map Viewer, nos 3 primeiros casos serão usados os mesmos elementos lógicos.

Figura 2.4 - Technology Map do mux4x1 para a família Cyclone
TM mux4x1.png
Fonte: Elaborado pelo autor.
  • Note que o elemento lógico acima possui uma LUT (LookUp Table) que basicamente implementa o circuito combinacional através de uma tabela de consulta (Tabela Verdade), a qual pode ser visualizada clicando com o botão Direito do Mouse e selecionando Properties, juntamente com Mapa de Karnaugh e seu Circuito Lógico representado por portas. Todas as representações são equivalentes.

Figura 2.5 - Elemento Lógico usado no mux4x1 para a família Cyclone (node properties)
LE mux4x1.png
Fonte: Elaborado pelo autor.
  • Dependendo da família de FPGA que se estiver usando, o compilador implementar o circuito descrito com um número diferente de elementos lógicos (LEs). No caso da família Cyclone, na qual a LUT tem 4 entradas, são necessários 2 LEs para mapear uma lógica combinacional com 6 entradas e 1 saída (Mux4x1).

No entanto se utilizarmos um dispositivo FPGA da família Aria 10, que tem LUT tem 6 entradas, será necessário apenas 1 LE, conforme ilustrado a seguir.


Figura 2.5 - Technology Map do mux4x1 para a família Aria 10
TM mux4x1 S3.png
Fonte: Elaborado pelo autor.
  • Realize a simulação das 3 arquiteturas do MUX4:1 no Modelsim
  • Crie um arquivo tb_mux4x1_v1.do que repita a simulação da arquitetura v1
  • Crie um arquivo tb_mux4x1_v2.do que repita a simulação da arquitetura v2
  • Crie um arquivo tb_mux4x1_v3.do que repita a simulação da arquitetura v1
  • Inclua todos os arquivos .do no projeto do Quartus e salve o arquivo QAR
Encontro 27 e 28 (ANP e 7 nov.)
Encontro 29 (9 nov.)
Encontro 30 (14 nov.)
  • Decodificador de 4 endereços [3]
  • Implementar em VHDL usando with-select e portas lógicas
  • Implementar a implementar em VHDL de um decodificador de 32 endereços


Encontro 31 e 32 (16 e 21 nov.)
  • Demultiplexador de 1 para 4 [4]
  • Implementar a implementar em VHDL
  • Demultiplexador com enable. [5]
  • Implementar a implementar em VHDL
NOTA
No dia 16 nov. ocorreram fortes chuvas na grande Florianópolis, e em virtude disso muitos alunos não puderam comparecer. As 8h50 faltou energia no campus e as aulas foram suspensas.
Encontro 33 (23 nov.)
  • Comentários no código (duplo traço --)
-- Isso eh uma linha de comentario
y <= a * b ; --o sinal y recebe o resultado da multiplicacao a x b 
  • Representação de caracteres, strings e números em VHDL. No circuito, os caracteres são representados através de bits de acordo com a tabela ASCII básica (00 a 7F). A definição dessa tabela é feita o pacote standard.vhd da biblioteca std.
  • Caracteres (entre aspas simples)
caracter:  'A' 'x' '#' (com aspas simples)
  • Palavras (entre aspas duplas), é definida no VHDL como um vetor de caracteres.
   type string is array (positive range <>) of character;
string: "IFSC" "teste" "teste123"
  • Números em geral
elemento ("bit") único:  '0' '1' 'Z' (entre aspas simples)
vetor de elementos ("bits"): "0110"  "101001Z" (entre aspas duplas)
vetor de 1 elemento ("bit"): "0" "1" (entre aspas duplas)
inteiros: 5 1101 1102  (sem aspas)
  • Números binários:
0 -> '0'
7 (em base 2) -> "0111" ou b"0111" ou B"0111"
1023 (em base 2) -> "001111111111" ou b"1111111111"  ou B"1111111111" 
  • Números octais:
44  (em base 8) ->  5*8^1 + 4*8^0  -> O"54" ou o"54"
1023 (em base 8)->  1*8^3 + 7*8^2 + 7*8^1 + 7*8^0 -> o"1777" 8#1777#
  • Números Hexadecimais:
1023 (em base 16) -> 3*16^2 + 15*16^1 + 15*16^0 = X"3FF" ou x"3FF" 16#3FF#
  • Números decimais:
1023 -> 1023 ou 1_023
1000 -> 1000 ou 1_000 ou 1E3 ou 10#1000#
Cuidado ao usar o "_" pois algumas ferramentas não o reconhecem.
  • Números em outras bases (de 2 a 16)
85 (em base 5) ->  (3*5^2 + 2*5^1 + 0*5^0) -> 5#320#
1539 (em base 3) -> (2*3^2+0*3^1+1*3^0)*3^4 -> 3#201#E4 
  • Tipos de dados em VHDL.
  • Objetos de VHDL: CONSTANT, SIGNAL, VARIABLE, FILE.

O objeto CONSTANT pode ser declarado na parte declarativa da ENTITY, ARCHITECTURE, PACKAGE, PACKAGE_BODY, BLOCK, GENERATE, PROCESS, FUNCTION e PROCEDURE.

constant <constant_name> : <type> := <constant_value>;

-- Declarações comuns de constantes

constant GND : std_logic := '0';
constant VCC : std_logic := '1';
constant SSD_0 : std_logic_vector(0 to 6) := "1111110";
constant MAX : natural := 44;

O objeto SIGNAL pode ser declarado na parte declarativa da ENTITY, ARCHITECTURE, PACKAGE, BLOCK, GENERATE. Os sinais não podem ser declarados no código sequencial (PROCESS, FUNCTION e PROCEDURE), mas podem ser usados.

-- Signal sem valor default
-- Para atribuir um valor a um signal use  "<=" como operador. 

signal <name> : <type>;

-- Signal com valor default
signal <name> : <type> := <default_value>;

-- Declarações comuns de signals

signal <name> : std_logic;
signal <name> : std_logic_vector(<msb_index> downto <lsb_index>);
signal <name> : integer;
signal <name> : integer range <low> to <high>;

O objeto VARIABLE (variável) só pode ser declarada e usada dentro do escopo no código sequencial (PROCESS, FUNCTION e PROCEDURE).

-- Variables devem ser declarada em process ou subprogramas.
-- Para atribuir um valor a um variable use  ":=" como operador.

-- Variable sem valor default.	
variable <name> : <type>;

-- Variable com valor default.
variable <name> : <type> := <default_value>;

-- Declarações comuns de variables
variable <name> : std_logic;
variable <name> : std_logic_vector(<msb_index> downto <lsb_index>);
variable <name> : integer;
variable <name> : integer range <low> to <high>;
  • Palavra chave OTHERS para formação de agregados

Exemplos de declaração de CONSTANT, SIGNAL, VARIABLE, inicializando o valor usando o agregados

CONSTANT a: BIT_VECTOR(5 DOWNTO 0) := (OTHERS => '0');  --  "000000"

CONSTANT b: BIT_VECTOR(7 DOWNTO 0) := (7 => '0', OTHERS => '1');  -- "01111111"
CONSTANT c: BIT_VECTOR(7 DOWNTO 0) := (7 => '0', 6 DOWNTO 0 => '1');  -- "01111111"
CONSTANT d: BIT_VECTOR(7 DOWNTO 0) := "01111111";

SIGNAL e: STD_LOGIC_VECTOR(7 DOWNTO 0);   -- Not initialized
SIGNAL f: STD_LOGIC_VECTOR(1 TO 8) := (2|3|8 => '1', 4 => 'Z', OTHERS => '0' ); -- "011Z0001"

VARIABLE g: BIT_VECTOR(1 TO 16);  -- Not initialized
VARIABLE h: BIT_VECTOR(1 TO 16) := (1 TO 8 => '1', OTHERS => '0');  -- "1111111100000000"
Ver pag. 31 a 35 de [1]
  • ATENÇÃO!!! Não use as bibliotecas que não são padrão (std_logic_arith, std_logic_unsigned, std_logic_signed)
  • Classificação dos tipos de dados.

A biblioteca standard.vhd define os tipos BIT, BIT_VECTOR, BOOLEAN, INTEGER, NATURAL, POSITIVE, CHARACTER, STRING.

	package standard is
	type boolean is (false,true); 
	type bit is ('0', '1');
	type severity_level is (note, warning, error, failure); 
	type integer is range -2147483647 to 2147483647; 
	type real is range -1.0E308 to 1.0E308; 
	type time is range -2147483648 to 2147483647 
		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;
	subtype natural is integer range 0 to integer'high; 
	subtype positive is integer range 1 to integer'high; 
	type string is array (positive range <>) of character; 
	type bit_vector is array (natural range <>) of bit;

A biblioteca Std logic 1164.vhd define os tipos STD_(U)LOGIG, STD_(U)LOGIG_VECTOR.

	PACKAGE std_logic_1164 IS
	TYPE std_ulogic IS ( 'U',  -- Uninitialized
                         'X',  -- Forcing  Unknown
                         '0',  -- Forcing  0
                         '1',  -- Forcing  1
                         'Z',  -- High Impedance   
                         'W',  -- Weak     Unknown
                         'L',  -- Weak     0       
                         'H',  -- Weak     1       
                         '-'   -- Don't care
                       );
	TYPE std_ulogic_vector IS ARRAY ( NATURAL RANGE <> ) OF std_ulogic;
	SUBTYPE std_logic IS resolved std_ulogic;
	TYPE std_logic_vector IS ARRAY ( NATURAL RANGE <>) OF std_logic;

A biblioteca Std logic 1164.vhd ainda define algumas funções importantes como a rising_edge que determina se um sinal está na borda de subida (usado em sinais de clock).

    -------------------------------------------------------------------
    -- conversion functions
    -------------------------------------------------------------------
    FUNCTION To_bit             ( s : std_ulogic;        xmap : BIT := '0') RETURN BIT;
    FUNCTION To_bitvector       ( s : std_logic_vector ; xmap : BIT := '0') RETURN BIT_VECTOR;
    FUNCTION To_StdULogic       ( b : BIT               ) RETURN std_ulogic;
    FUNCTION To_StdLogicVector  ( b : BIT_VECTOR        ) RETURN std_logic_vector;

    -------------------------------------------------------------------    
    -- edge detection
    -------------------------------------------------------------------    
    FUNCTION rising_edge  (SIGNAL s : std_ulogic) RETURN BOOLEAN;
    FUNCTION falling_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN;

   -------------------------------------------------------------------    
    -- edge detection
    -------------------------------------------------------------------    
    FUNCTION rising_edge  (SIGNAL s : std_ulogic) RETURN BOOLEAN IS
      -- altera built_in builtin_rising_edge
    BEGIN
        RETURN (s'EVENT AND (To_X01(s) = '1') AND 
                            (To_X01(s'LAST_VALUE) = '0'));
    END;

A biblioteca Numeric std.vhd define os tipos UNSIGNED e SIGNED.

package NUMERIC_STD is
  type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
  type SIGNED is array (NATURAL range <>) of STD_LOGIC;

A biblioteca Numeric std.vhd ainda define os operadores (abs, "+", "-", "*", "/", rem, mod, sll, slr, ror, rol), comparações ("=", '/=', ">", ">=", "<", "<=") e operadores lógicos (not, and, nand, or, nor, xor, xnor) para os tipos SIGNED e UNSIGNED. Além disso também define algumas funções muito utilizadas como:

  --============================================================================
  --   RESIZE Functions
  --============================================================================
  function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED;
  function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED;

  --============================================================================
  -- Conversion Functions
  --============================================================================
  function TO_INTEGER (ARG: UNSIGNED) return NATURAL;
  function TO_INTEGER (ARG: SIGNED) return INTEGER;
  function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED;
  function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED;
Ver pag. 73 a 78 de [1]
  • Resumo dos Tipos predefinidos.
Tipo de Dado Package Library Valores Observações
BOOLEAN standard std TRUE e FALSE sintetizável
BIT standard std valores '0', '1' sintetizável
INTEGER standard std números inteiros de 32 bits [de -2^31-1 até + (2^31 - 1)] sintetizável
NATURAL standard std números inteiros não negativos [de 0 até + (2^31 - 1)] sintetizável
POSITIVE standard std números inteiros positivos [de 1 até + (2^31 - 1)] sintetizável
BOOLEAN_VECTOR standard (2008) std vetor de BOOLEAN sintetizável
BIT_VECTOR standard std vetor de BIT sintetizável
INTEGER_VECTOR standard (2008) std vetor de INTEGER sintetizável
REAL standard std números reais [de -1.0E-38 até + 1.0E38] simulação
CHARACTER standard std caracteres ASCII
STRING standard std vetor de CHARACTER
Tipo de Dado Package Library Valores Observações
STD_LOGIC std_logic_1164 ieee valores 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-' sintetizável
STD_LOGIC_VECTOR std_logic_1164 ieee vetor de STD_LOGIC sintetizável
SIGNED numeric_std ieee STD_LOGIC_VECTOR que aceitam operações aritméticas com sinal sintetizável
UNSIGNED numeric_std ieee STD_LOGIC_VECTOR que aceitam operações aritméticas sem sinal sintetizável
SIGNED numeric_bit ieee BIT_VECTOR que aceitam operações aritméticas com sinal sintetizável
UNSIGNED numeric_bit ieee BIT_VECTOR que aceitam operações aritméticas sem sinal sintetizável
SIGNED std_logic_arith ieee STD_LOGIC_VECTOR que aceitam operações aritméticas com sinal sintetizável (não é padrão, não utilizar)
UNSIGNED std_logic_arith ieee STD_LOGIC_VECTOR que aceitam operações aritméticas sem sinal sintetizável (não é padrão, não utilizar)
UFIXED fixed_pkg + (2008) ieee números de ponto fixo sem sinal sintetizável
SFIXED fixed_pkg + (2008) ieee números de ponto fixo com sinal sintetizável
FLOAT float_pkg + (2008) ieee Números de ponto flutuante sintetizável
  • Exemplo: Buffer Tri-state
  • Ver como funciona em [6]
library ieee;
use ieee.std_logic_1164.all;

entity tri_state is
  generic (N: NATURAL := 1);
  port 
  (
    input      : in std_logic_vector(N-1 downto 0);
    ena        : in std_logic;
    output     : out std_logic_vector(N-1 downto 0);
  );
end entity;

architecture tri_state of tri_state is
begin
  output <= input when ena = '1' else "Z";
end architecture;
Importante: O terceiro estado 'Z' só pode ser usado em saídas, e a sua realização nos FPGAs só ocorre nos nós de I/O.
Curiosidade
Existem circuitos comerciais que implementam essa função three-state 16 buffers, 8 buffers, 1 buffer. Porque não utilizar um CPLD ou FPGA em seu lugar?
Exemplo de aplicação
  • Demultiplexador com saída em 3-state. [7]
  • Baseado no Demultiplexador com enable, implemente ele com 3-state. Se o circuito não estiver habilitado, as saídas devem ficar em 3-state.
  • Para implementar em VHDL será necessário utilizar o tipo de dado std_logic ou std_logic_vector

Unidade 6 - Circuitos aritméticos (com VHDL)

  • 5 ENCONTROS
Unidade 6 - Circuitos aritméticos (com VHDL)
Encontro 34 (28 nov.)
  • Circuitos aritméticos: somadores, incrementador, decrementador, complemento de dois, multiplicador, comparadores
Encontro 35 (30 nov.)
  • Ver slides [10]
  • Ver pag. XXX a XXX de [2]
Encontro 36 (05 dez.)
  • Usando o tipo integer

Para implementar circuitos aritméticos, ao invés de se descrever o circuito com portas lógicas conforme mostrado para somadores, subtratores, comparadores e multiplicadores, deve-se utilizar os operadores aritméticos, e o compilador realizará a escolha do melhor circuito para cada caso. Inicialmente apresentamos alguns exemplos utilizando dados do tipo integer.

Para o uso do tipo integer, se não houver limitação da faixa de valores, o compilador entenderá que os sinais devem ter 32 bits, o que gera circuitos muito maiores que normalmente necessário. Assim, ao usar as entradas e saidas como integer sem range, o diagrama RTL mostrará que o circuito foi construido com 32 bits [31..0]. Nos dispositivos da familia Cyclone IV E serão utilizados 32 elementos lógicos para tal circuito.

entity somador is
	port ( 
	a, b : in integer; 
	s : out integer;
end entity;

architecture ifsc of somador is
begin
	s <=  a + b;
end architecture;

Figura 4.1 - Código RTL do somador com tipo integer sem range
RTL somadorv1.png
Fonte: Elaborado pelo autor.

Figura 4.2 - Technology Map do somador com tipo integer sem range
TM somadorv1.png
Fonte: Elaborado pelo autor.

Por isso, o uso correto do tipo integer, exige que se limite a faixa de valores (range 0 to 15), o que fará com que o compilador atribua para os sinais a quantidade correta de bits, gerando circuitos de tamanho adequado.

Assim, ao usar as entradas e saidas como integer com range 0 to 15, o diagrama RTL mostrará que o circuito foi construido com 4 bits [3..0]. Nos dispositivos da familia Cyclone IV E serão utilizados 4 elementos lógicos para tal circuito.

entity somador is
	port ( 
	a, b : in integer range 0  to 15; 
	s : out integer range 0  to 15);
end entity;

architecture ifsc of somador is
begin
	s <=  a + b;
end architecture;

Figura 4.3 - Código RTL do somador com tipo integer com range
RTL somadorv2.png
Fonte: Elaborado pelo autor.

Figura 4.4 - Technology Map do somador com tipo integer com range
TM somadorv2.png
Fonte: Elaborado pelo autor.

Para fazer uma subtração, basta trocar o operador "+" pelo "-", e o compilador irá implementar um subtrator realizando o complemento 2 da entrada b.

entity subtrator is
	port ( 
	a, b : in integer range 0  to 15; 
	s : out integer range 0  to 15);
end entity;

architecture ifsc of subtrator is
begin
	s <=  a - b;
end architecture;

Figura 4.5 - Código RTL do subtrator com tipo integer com range
RTL subtratorv1.png
Fonte: Elaborado pelo autor.

Note nesta figura que as entradas b[3..0] são conectadas ao B[4..1] do somador, e que o B[0] é conectado ao Vcc ("1"). O mesmo ocorre com a entrada A. Ao mesmo tempo a entrada b é invertida, gerando assim o complemento de dois dessa entrada. Assim para realizar uma subtração pode ser utilizado o mesmo circuito do somador.

Para fazer uma multiplicação, basta usar o operador "*"e o compilador irá implementar um multiplicador. Neste caso para evitar o overflow é importante definir o range da saída com um tamanho suficiente para comportar o maior produto

entity multiplicador is
	port ( 
	a, b : in integer range 0  to 15; 
	s : out integer range 0  to 15*15);
end entity;

architecture ifsc of multiplicador is
begin
	s <=  a * b;
end architecture;

Figura 4.6 - Código RTL do multiplicador com tipo integer com range
RTL multiplicadorv1.png
Fonte: Elaborado pelo autor.

Note que esse circuito no Cyclone IV E necessita de 31 elementos lógicos, e no caso em que multiplicador tem entradas com 4 bits [3..0], a saída terá 8 bits [7..0] Caso a saída não tenha a quantidade suficiente de bits, haverá overflow e a resultado poderá estar incorreto.

Caso se esqueça de limitar o range dos sinais de entrada, o compilador novamente assumirá que devem ser usada a faixa inteira dos inteiros (32 bis).


Figura 4.7 - Código RTL do multiplicador com tipo integer sem range
RTL multiplicadorv2.png
Fonte: Elaborado pelo autor.

Note que esse circuito no Cyclone IV E aparentemente utiliza apenas 28 elementos lógicos, mas é importante observar que ele utiliza 6 dispositivo DSP (multiplicador de bits), os quais estão disponíveis dentro do FPGA. Se desativar o uso dos multiplicadores internos, forçando o uso dos elementos lógicos o total de elementos lógicos passará para 592, mostrando o desperdício de hardware que pode ocorrer. Para forçar o uso de elementos lógicos no lugar dos DSP realize a seguinte sequencia: Assignments > Settings > Compiler Settings > [Advanced Settings (Synthesis)] > Filter = DSP > DSP Block Balancing = Logic Elements > [OK]

Detalhando a sequencia
  • No menu, vá para "Assignments" e depois escolha "Settings".
  • Na janela "Settings", clique em "Compiler Settings". Em seguida, clique em "Advanced Settings (Synthesis)".
  • Digite em Filter = DSP e na opção "DSP Block Balancing" configure com "Logic Elements" para forçar o uso dos elementos lógicos no lugar dos DSPs.
  • Depois clique em "OK" para aplicar as alterações.

Para fazer uma divisão, basta usar o operador "/" e o compilador irá implementar um divisor inteiro. O tamanho do quociente deve ser igual ao dividendo.

entity divisor is
	port ( 
	dividendo : in integer range 0  to 15; 
	divisor : in integer range 0  to 3;
	quociente : out integer range 0  to 15;
	resto : out integer range 0  to 3
);

end entity;

architecture ifsc of divisor is
begin
	quociente <=  dividendo / divisor;
	resto <=  dividendo rem divisor;
end architecture;

Figura 4.8 - Código RTL do divisor com tipo integer com range
RTL divisorv1.png
Fonte: Elaborado pelo autor.

Multiplicações e divisões por potências de 2 (2, 4, 8, 16, ... $2^N$) não necessitam de nenhum elemento lógico pois podem ser implementados pelo simples deslocamento dos signais.


Figura 4.8 - Código RTL do multiplicador por 4
RTL multiplicador4.png
Fonte: Elaborado pelo autor.

Figura 4.9 - Código RTL do divisor por 2
RTL divisor2.png
Fonte: Elaborado pelo autor.

Multiplicações por constantes não precisam utilizar os multiplicadores, e são implementadas através de simples deslocamentos de sinais e somas. Assim multiplicar por 10 corresponde a multiplicar por 2 somar com a multiplicação por 8.


Figura 4.10 - Código RTL do multiplicador por 10
RTL multiplicador10.png
Fonte: Elaborado pelo autor.
Encontro 37 (07 dez.)
package NUMERIC_STD is
  type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
  type SIGNED is array (NATURAL range <>) of STD_LOGIC;

A biblioteca Numeric std.vhd ainda define os operadores (abs, "+", "-", "*", "/", rem, mod, sll, slr, ror, rol), comparações ("=", '/=', ">", ">=", "<", "<=") e operadores lógicos (not, and, nand, or, nor, xor, xnor) para os tipos SIGNED e UNSIGNED. Além disso também define algumas funções muito utilizadas como:

  --============================================================================
  --   RESIZE Functions
  --============================================================================
  function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED;
  function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED;

  --============================================================================
  -- Conversion Functions
  --============================================================================
  function TO_INTEGER (ARG: UNSIGNED) return NATURAL;
  function TO_INTEGER (ARG: SIGNED) return INTEGER;
  function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED;
  function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED;
Ver pag. 73 a 78 de [1]

SumaryOfNumeric std.gif

Numeric stdConvertions.gif

FONTE: http://www.doulos.com/knowhow/vhdl_designers_guide/numeric_std/

Ler e guardar a página sobre Aritmética com vetores em VDHL

Exemplo 1

Fazer um circuito que detecte se existe alguma vaga vazia em um lote de 4 vagas. A entrada x(n) está baixo '0' se a vaga está vazia, e alto '1' se tem carro. A saída y estará alta '1' sempre que houver uma ou mais vagas vazias, e em baixo '0' se não houver nenhuma vaga.

Para fazer este circuito, podemos testar cada posição da entrada x e verificar se alguma delas está com '0', e neste caso mudar a saída para '1', caso contrário a saída será '0'. Conforme veremos a seguir, é possível realizar diversas descrições em VHDL para esse circuito.

Solução 1

Testar cada uma das entradas x e verificar se há alguma delas com '0', então indicar que a saída é '1', senão a saída será '0'.

library ieee;
use ieee.std_logic_1164.all;
entity vagas is
    generic (N : natural := 4    );

    port     (
        x : in std_logic_vector  (N-1 downto 0);
        y : out std_logic 
    );
end entity;

architecture ifsc_v1 of vagas is
begin
	-- usando when-else
	y <= '1' when x(0) = '0' else 
        '1' when x(1) = '0' else	
        '1' when x(2) = '0' else	
        '1' when x(3) = '0' else	
	'0';
end architecture;

Figura 4.12 - RTL do indicador de vagas com when-else
RTLvagas4.png
Fonte: Elaborado pelo autor.

Figura 4.13 - Technology Map do indicador de vagas
TMvagas4.png
Fonte: Elaborado pelo autor.

Note neste Technology Map que para implementar esse circuito, o compilador deduziu que basta inverter as entradas X e realizar a operação OR sobre elas para determinar se tem ou não vagas.

Fazendo a simulação do circuito podemos perceber que ele está funcionando, pois a saída y está em '1' sempre quando existe alguma vaga x(i) = '0'. A única situação em que a saída y está em '0' é quando todas as entradas estão em '1' (todas vagas ocupadas).


Figura 4.14 - Simulação do indicador de vagas
Vagas9.png
Fonte: Elaborado pelo autor.
Solução 2

Realizar uma operação ou sobre todas as entradas x invertidas.

architecture ifsc_v2 of vagas is
begin
	-- usando or e not
	y <=  (not x(0)) or (not x(1)) or (not x(2)) or (not x(3));
end architecture;

Figura 4.15 - RTL do indicador de vagas com portas NOT e OR
RTLvagas or.png
Fonte: Elaborado pelo autor.

Note que o Technology Map e a simulação produzem o mesmo resultado, apesar da descrição do hardware ser complemente diferente.

Tanto na solução 1 como na 2, se tivermos mais vagas para verificar, será necessário alterar a descrição. Então para realizar uma descrição que seja genérica é necessário transformar essas soluções ou encontrar outras.

Solução 3

Realizar uma operação ou sobre todas as entradas x invertidas. Para tornar genérico o código use o for generate para fazer a operação de NOT e OR sobre as entradas. A seguir é apresentado o esboço da ideia, e fica por conta do estudante implementar essa solução.

architecture ifsc_v3 of vagas is
	signal tmp : std_logic_vector(N downto 0);
begin
	tmp(0) <= '0';  -- inicializar tmp(0) com 0, pois nao afeta o resultado do OR.
	-- use o  for-generate para implementar de forma generica as seguintes linhas:
	--	tmp(1) <= tmp(0) or (not x(0));   -- retorna 0 OR (not x0) => (not x0)
	--	tmp(2) <= tmp(1) or (not x(1));   -- retorna (not x0) OR (not x1)
	--	tmp(3) <= tmp(2) or (not x(2));   -- retorna (not x0) OR (not x1) OR (not x2)
	--	
	--	tmp(i+1) <= tmp(i) or (not x(i));
	--	...
	--	tmp(N) <= tmp(N-1) or (not x(N-1));  -- retorna (not x0) OR (not x1) ... OR (not xN)


	y <= tmp(N);     -- tmp(N) tem o resultado, precisa ser enviado para a saida y.
end architecture;


Ver pag. 39 a 54 de [1]
Encontro 38 (12 dez.)
  • Exercícios da Unidades 4 e 5
Encontro 39 (14 dez.)
  • Avaliação A2 (Unidades 4 e 5).
Encontro 40 (19 dez.)
  • Avaliação REC1 e REC2 (Unidades 1 a 5).

Avaliações

Durante o semestre serão realizadas 4 avaliações. As avaliações devem ser enviadas pela plataforma Moodle com os arquivos solicitados.

Data das avaliações
  • A1 - : dividida em 3 avaliações A1a (Sistemas Numéricos e códigos), A1b (Funções e portas lógicas), A1c (Álgebra booleana e simplificação de funções lógicas, mapa de Karnaugh)
  • A2 - :
  • R - Recuperação de A1 a A2 : dia 19/12

Atividade relâmpago (AR)

As atividades relâmpago devem ser entregues no Moodle da disciplina. A não entrega dessas atividades não gera nenhum desconto, apenas geram pontos de BÔNUS que são adicionados aos conceitos das avaliações A1 a AN.

Atividade extra-classe (AE)

A média ponderada das atividades extra-classe será considerada no cálculo do conceito final da UC. A entrega das mesmas será feita pelo Moodle, e cada dia de atraso irá descontar 0,2 na nota da atividade. Muitas dessas atividades também geram pontos de BÔNUS que são adicionados aos conceitos das avaliações A1 a AN. Para os BÔNUS só serão considerados projetos entregues no prazo.

Referências Bibliográficas:

  1. 1,0 1,1 1,2 1,3 Erro de citação: Marca <ref> inválida; não foi fornecido texto para as refs chamadas PEDRONI2010b
  2. PEDRONI, Volnei A. Eletrônica digital moderna e VHDL; 1ª ed. Rio de Janeiro:Elsevier, 2010. 619p. . ISBN 9788535234657


Curso de Engenharia de Telecomunicações