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 (15 fev)
  • A página da UC contém os materiais que não alteram entre semestre.
  • Relação com as outras UCs do Eixo Sistemas Computacionais (Marrom). Ver grafo do curriculo
  • 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 dos encontros 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

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 [1]
  • 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 [2]
  • Implementar a implementar em VHDL
  • Demultiplexador com enable. [3]
  • 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 [4]
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. [5]
  • 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 [8]
  • 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