- Encontro 5 (1 mar)
- Introdução aos dispositivos lógicos programáveis:
- Conceito, tipos de PLDs
- SPLD:
- PARA O PRÓXIMO ENCONTRO
- Encontro 6 (5 mar)
- Arquitetura de FPGAs (Xilinx e Altera): CLB, LAB, LUT, Flip_flop D, RAM, DSP, Clock, PLL, DLL, I/O
- FONTE: FPGA Architecture - ALTERA
Exemplos de FPGA
|
Figura 2.9 - Arquitetura de um FPGA
Fonte: https://www.intel.com/content/www/us/en/docs/programmable/683176/18-1/fpga-overview-opencl-standard.html.
Figura 2.10 - Diagrama simplificado da ALM de um FPGA Intel/Altera
Fonte: https://www.intel.com/content/www/us/en/content-details/771003/fpga-architecture-8-input-lut-legacy-white-paper.html.
Figura 2.11 - Arquitetura interna de uma LUT
Fonte: FPGA Architecture - ALTERA.
Figura 2.12 - Configuração de uma LUT
Fonte: https://www.allaboutcircuits.com/technical-articles/purpose-and-internal-functionality-of-fpga-look-up-tables/.
Figura 2.13 - Arquitetura do Cyclone® V Intel/Altera
Fonte: https://www.intel.com.br/content/www/br/pt/products/details/fpga/cyclone/v/article.html.
Figura 2.14 - Leiaute de um FPGA Xilinx genérico
Fonte: https://www.sciencedirect.com/science/article/pii/B9780750678667500032.
Figura 2.15 - Roteamento de sinal em um FPGA
Fonte: https://www.sciencedirect.com/science/article/pii/B9780750678667500032.
Figura 2.16 - Tecnologias usadas na configuração de FPGAs
Fonte: https://www.sciencedirect.com/topics/computer-science/one-time-programmable.
- Ver também SRAM, EEPROM, What Is Flash Memory
- PARA O PRÓXIMO ENCONTRO
- Leia a assista a alguns dos vídeos sobre a historia e processo de produção dos chips.
- Encontro 7 (8 mar)
Figura 2.17 - Altera - Visão geral do dispositivo Arria V SX e ST
Fonte: https://br.mouser.com/datasheet/2/612/av_51001-1623623.pdf.
Figura 2.18 - Altera - Agilex 7 SoCs HPS Digrama de Blocos
Fonte: https://static6.arrow.com/aropdfconversion/b568cfe009abfed6a28eff56700189883d7fc179/ag-overview-683458-666707.pdf.
- PARA O PRÓXIMO ENCONTRO
-
- Fabricantes de DLPs/FPGAs e familias de DLPs atuais.
- ALTERA/INTEL - Stratix, Arria, Cyclone, Max, Agilex
- Xilinx/AMD - Virtex, Kintex, Artix, Zynq (SoC)
- Microchip - Igloo, PolarFire
- Lattice - ECP, iCE, Mach
|
Unidade 3 - Circuitos sequenciais (Implementação com HDL)
Unidade 3 - Circuitos sequenciais (Implementação com HDL)
|
- Encontro 8 (12 mar)
- Flip-Flop e circuitos sequenciais.
- Diferenças entre código concorrente e sequencial <=> circuitos combinacional e sequencial
- Diferenças entre os objetos SIGNAL e VARIABLE
- Tipos de elementos de memória: Latch x Flip-flop
- Latch D
- Flip-flop tipo D com reset assíncrono e com reset (clear) síncrono
- Seção de código sequencial PROCESS: lista de sensibilidade
[rótulo:] PROCESS [(lista_de_sensibilidade)] [IS]
[parte_declarativa]
BEGIN
afirmação_sequencial;
afirmação_sequencial;
...
END PROCESS [rótulo];
[rótulo:] IF condição THEN
afirmação_sequencial;
afirmação_sequencial;
...
ELSIF condição THEN
afirmação_sequencial;
afirmação_sequencial;
...
ELSE
afirmação_sequencial;
afirmação_sequencial;
...
END IF [rótulo];
-
- DFFs com Reset Assincrono e Reset Sincrono, com Enable, com Preset (Variação Ex 6.1).
--Flip Flop tipo D com reset assincrono, sensivel a borda de subida.
process (clock,reset)
begin
if (reset = '1') then
q <= '0';
-- elsif (clock'event and clock = '1') then or
elsif (rising_edge(clock)) then
q <= d;
end if;
end process;
Figura 5.1 - RTL de Flip-flop D de borda de subida, com reset assíncrono
Fonte: Elaborado pelo autor.
--Flip Flop tipo D com preset assincrono e sinal de enable, sensivel a borda de descida.
process (clock, preset)
begin
if (preset = '1') then
q <= '1';
elsif (falling_edge(clock)) then
if (enable = '1') then
q <= d;
end if;
end if;
end process;
Figura 5.2 - RTL de Flip-flop D de borda de descida, com preset assíncrono e enable
Fonte: Elaborado pelo autor.
- Encontro 9 (15 mar)
-
- Comparar com Latch (sem clk'event).
--Latch tipo D com reset assincrono.
process (enable, reset, d)
begin
if (reset = '1') then
q <= '0';
elsif (enable='1')) then
q <= d;
end if;
end process;
Figura 5.3 - RTL de Latch D de com reset assíncrono e enable ativo alto
Fonte: Elaborado pelo autor.
- Na figura abaixo, note que o Latch é implementado utilizando a LUT do elemento lógico do FPGA, enquanto que o Flip-flop utiliza o componente já disponível neste elemento lógico.
- Evite os latches no projeto
Figura 5.4 - Comparação do Technology Map de um Latch_D (esquerda) com FF_D (direita)
Fonte: Elaborado pelo autor.
-- Flip Flop tipo D com reset síncrono sensível a borda de subida.
-- Modifique a descrição para que o reset_ass seja assíncrono e reset_sinc seja síncrono.
-- Note que a função rising_edge(clock) é equivalente a (clock'event and clock'last_value = '0' and clock = '1'))
process (clock, reset)
begin
if (reset = '1') then
q <= '0';
elsif (clock'event and clock'last_value = '0' and clock = '1')) then
q <= d;
end if;
end process;
Figura 5.5 - RTL do Flip-flop D com reset assíncrono e reset síncrono
Fonte: Elaborado pelo autor.
- Exercício: Implemente um registrador com N FF_D no lugar de um único FF_D.
Figura 5.6 - RTL do Registrador (de 4 bits) com reset assíncrono
Fonte: Elaborado pelo autor.
Figura 5.7 - Techonogy Map do Registrador (de 4 bits) com reset assíncrono
Fonte: Elaborado pelo autor.
- Faça a simulação funcional do DFFs e do Latch
- Encontro 10 (22 mar)
- Implementar um registrador com N FF_D usando a instrução FOR GENERATE.
-- Instrução concorrente FOR GENERATE.
-- Note que neste caso o '''label''' é obrigatório
label: FOR identificador IN faixa GENERATE
[Parte_Declarativa
BEGIN]
Instruções_concorrentes
...
END GENERATE [label];
- Implementar um registrador de deslocamento de N bits.
entity shift_reg is
generic ( N : natural := 4);
port (
clock, reset : in std_LOGIC ;
d_in: in std_LOGIC;
q_out : out std_LOGIC);
end entity;
architecture ifsc_v1 of shift_reg is
signal d: std_logic_vector(N-1 downto 0);
signal q: std_logic_vector(N-1 downto 0);
begin
...
end architecture;
Figura 5.8 - Technology Map de Shift Register
Fonte: Elaborado pelo autor.
Figura 5.9 - Simulação de Shift Register
800 px
Fonte: Elaborado pelo autor.
- Implementar um contador crescente 0-N (baseado no Ex.6.2), com N = 2^Mbits-1 (1 3 7 15)
- Com overflow no valor máximo
entity conta_0_N is
generic (MAX : natural := 15);
port (clock, reset: in std_logic; q : out integer range 0 to MAX);
end entity;
architecture ifsc_v1 of conta_0_N is
begin
process (clock,reset)
variable count : integer range 0 to MAX;
begin
if (reset = '1') then
count := 0;
elsif (rising_edge(clock)) then
count := count + 1;
end if;
q <= count;
end process;
end architecture;
Figura 5.10 - RTL de contador crescente
Fonte: Elaborado pelo autor.
- Encontro 11 (26 mar)
- Implementar um contador crescente 0 até N, com N ≠ 2^Mbits (5, 10)
- Com overflow no valor máximo
Figura 5.11 - RTL contador crescente 0 a 5
Fonte: Elaborado pelo autor.
Figura 5.12 - Simulação do contador crescente 0 a 5
Fonte: Elaborado pelo autor.
- Com parada no valor máximo
- Implementar um contador decrescente N até 0, com N ≠ 2^Mbits (5, 10)
- Com underflow no valor mínimo
Figura 5.13 - Simulação do contador decrescente 5 a 0
Fonte: Elaborado pelo autor.
- Com parada no valor mínimo
Figura 5.14 - Simulação do contador decrescente 5 a 0 com parada
Fonte: Elaborado pelo autor.
- DESAFIO
- Implementar um contador bidirecional entre MIN e MAX. Uma entrada DIR indica a direção da contagem. Considere DIR = 0 (crescente) e DIR = 1 (decrescente).
- Versão 1: Com underflow no valor mínimo (MIN) e overflow no máximo (MAX).
- Versão 2: Com parada no valor mínimo (MIN), se decrescente e também no máximo (MAX) se crescente.
Restringir a frequencia máxima de clock no Quartus II
- Encontro 12 (2 abr.)
Instruções do tipo LOOP: LOOP incondicional, FOR-LOOP, WHILE-LOOP, NEXT, EXIT
- Instrução LOOP incondicional:
[rótulo:] LOOP
afirmação_sequencial;
afirmação_sequencial;
...
END LOOP [rótulo];
[rótulo:] FOR identificador IN faixa LOOP
afirmação_sequencial;
afirmação_sequencial;
...
END LOOP [rótulo];
[rótulo:] WHILE condição LOOP -- Executa as "afirmações enquanto a "condição" for verdadeira
afirmação_sequencial;
afirmação_sequencial;
...
END LOOP [rótulo];
[rótulo:] [FOR identificador IN faixa] LOOP
afirmação_sequencial;
EXIT [rótulo] [WHEN condição]; -- Se a "condição" é verdadeira, termina o "LOOP"
afirmação_sequencial;
...
END LOOP [rótulo];
[rótulo:] [FOR identificador IN faixa] LOOP
afirmação_sequencial;
NEXT [rótulo] [WHEN condição]; -- Se a "condição" é verdadeira, não executa as linhas até a linha "END LOOP"
-- e incrementa o "identificador".
afirmação_sequencial;
...
END LOOP [rótulo];
[rótulo opcional:] CASE expressão IS
WHEN valor => -- valor único
afirmação_sequencial;
afirmação_sequencial;
...
WHEN valor1 | valor2 | ... | valorN => -- lista de valores
afirmação_sequencial;
afirmação_sequencial;
...
WHEN valor1 TO valor2 => -- faixa de valores
afirmação_sequencial;
afirmação_sequencial;
...
WHEN OTHERS => -- para evitar latches
afirmação_sequencial;
afirmação_sequencial;
...
END CASE;
- Exemplos
- Leading Zeros (LOOP com EXIT) (Ex 6.5) - Esse circuito deve determinar quantos zeros tem em um vetor de entrada Data antes do primeiro bit '1', começando da esquerda para a direita.
- Fazer a síntese do circuito; fazer simulação no Modelsim; analisar a forma como o compilador implementou o incrementador.
entity leading_zeros is
generic (N : natural := 8);
port
( ________ : in std_logic_vector(0 to N-1);
count : out integer range 0 to N
);
end entity;
architecture ____ of leading_zeros is
begin
process (data)
variable count : integer ____ 0 to N
begin
count := 0;
for i ___ data'range ____
case data(i) is
when '0' => count := count + 1;
when _____ => exit;
end ___
end ____
zeros <= count;
end process;
end _______;
Figura 5.15 - Simulação do leading_zeros
Fonte: Elaborado pelo autor.
- Contador de zeros (LOOP com NEXT ou apenas LOOP) - Esse circuito deve determinar quantos zeros tem em um vetor de entrada Data.
- Fazer a síntese do circuito; fazer simulação no Modelsim; analisar a forma como o compilador implementou o incrementador.
Figura 5.16 - Simulação do counting_zeros
Fonte: Elaborado pelo autor.
- Ver pag. 161 a 164 de [1]
ATUAL
- Encontro 13 (5 abr.)
- Carry-Ripple Adder (FOR-LOOP) (Ex 6.4) - apenas analisar.
- Um somador do tipo carry ripple utiliza o bloco básico full adder para construir somadores de qualquer número de bits. Os bits carry são adicionados aos blocos posteriores, produzindo um hardware combinário.
- O full adder é baseado nas funções.
- onde é o carry out, é o carry in
Esse somador pode ser implementado tanto com código sequencial como com código concorrente. Note que no primeiro caso o bit de carry se definido como variable pode ser reaproveitado. No segundo caso é necessário criar um vetor completo para conectar os carry_out de um estágio ao carry_in do próximo.
library ieee;
use ieee.std_logic_1164.all;
entity carry_ripple_adder is
generic (N : integer := 3);
port (
a, b : std_logic_vector (N-1 downto 0);
cin : std_logic;
s : out std_logic_vector (N-1 downto 0);
cout : out std_logic
);
end entity;
architecture estrutural_sequencial_v1 of carry_ripple_adder is
begin
-- Uso de um codigo sequencial para geracao de um circuito combinacional
process (a, b, cin) is
variable c : std_logic;
begin
c := cin;
for i in 0 to N-1 loop
s(i) <= a(i) xor b(i) xor c;
c := (a(i) and b(i)) or (a(i) and c) or (b(i) and c);
end loop;
cout <= c;
end process;
end architecture;
architecture estrutural_concorrente_v1 of carry_ripple_adder is
signal c : std_logic_vector(N downto 0);
begin
-- Uso de um codigo concorrente para geracao de um circuito combinacional
c(0) <= cin;
l1: for i in 0 to N-1 generate
s(i) <= a(i) xor b(i) xor c(i);
c(i+1) <= (a(i) and b(i)) or (a(i) and c(i)) or (b(i) and c(i));
end generate;
cout <= c(N);
end architecture;
Figura 5.1 - RTL do carry_ripple_adder de 3 bits
Fonte: Elaborado pelo autor.
- Instrução WAIT: WAIT UNTIL, WAIT FOR (simulação apenas), WAIT ON (não implementada no Quartus II).
[rótulo:] WAIT UNTIL <condition>;
[rótulo:] WAIT ON sensitivity_list;
[rótulo:] WAIT FOR time_expression;
- Recomenda-se utilizar a lista de sensibilidade do PROCESS e a instrução IF no lugar do WAIT.
- Algumas instruções de WAIT serão utilizadas na criação de TestBench em VHDL para a simulação com o MODELSIM.
- Projetar um contador em BCD entre 0 e 99 (countBCD_DU.vhd), com entrada de clock, reset e saidas unidade(0 a 9) e dezena (0 a 9). Projete o contador para parar em qualquer valor de DU onde D é a dezena e U é a unidade.
- versão 1 - contagem crescente.
Figura 5.2 - RTL do contador BCD 00 a 99
Fonte: Elaborado pelo autor.
Figura 5.3 - Simulação do contador BCD 00 a 99
Fonte: Elaborado pelo autor.
- DESAFIO
Implementar um contador BCD de 00 a 99, com parada em qualquer valor MAX_DU. Onde se D = 5, U = 9, implica em contar de 000 até 59 e ficar parado neste valor. A atingir o valor final MAX_DU, uma saída adicional OPA deve ser ativada.
- Versão 1: O contador crescente deve usar a proposta de contagem separada de 0 a 9 da Unidade, Dezena (feito em aula), com parada em MAX_DU.
- Versão 2: O contador crescente deve fazer a contagem em binário, e incrementar 6 nos bits da unidade sempre que passar de 9(1001) para 10 (1010), com parada em MAX_DU.
- Versão 3: O contador decrescente deve usar a proposta de contagem separada de 0 a 9 da Unidade, Dezena (feito em aula), com início em MAX_DU e parada em 00.
|
|