ELD129003-Engtelecom (Diário) - Prof. Marcos Moecke
Registro on-line das aulas
Unidade 1 - Aula inicial, Introdução a disciplina
- 1 ENCONTRO
Unidade 1 - Aula inicial, Introdução a disciplina |
---|
|
Unidade REV - PRIMEIRO CONTATO COM VHDL
- 3 ENCONTROS
Unidade REV - PRIMEIRO CONTATO COM VHDL | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
library library_name;
use library_name.package_name.all;
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 arch_name of entity_name is
[declarative_part]
begin
statement_part
end [architecture] [arch_name];
Para ilustrar essas instruções utilizaremos o exemplo de um Mux4x1. 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).
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> else
<value>;
Warning (13012): Latch ... has unsafe behavior
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 others;
Error (10313): VHDL Case Statement error ...: Case Statement choices must cover all possible values of expression
-- 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;
CONFIGURATION <configuration_name> OF <entity_name> IS
FOR <architecture_name> END FOR;
END CONFIGURATION;
-- 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;
Figura 2.1 - Código RTL do mux4x1 v_logica_pura Figura 2.2 - Código RTL do mux4x1 v_WHEN_ELSE Figura 2.3 - Código RTL do mux4x1 v_WITH_SELECT
|
Unidade 2 - Dispositivos Lógicos Programáveis
- 3 ENCONTROS
Unidade 3 - Circuitos sequenciais (Implementação com HDL)
- 8 ENCONTROS
Unidade 3 - Circuitos sequenciais (Implementação com HDL) |
---|
[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];
--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 --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
--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
Figura 5.4 - Comparação do Technology Map de um Latch_D (esquerda) com FF_D (direita)
-- 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
Figura 5.6 - RTL do Registrador (de 4 bits) com reset assíncrono Figura 5.7 - Techonogy Map do Registrador (de 4 bits) com reset assíncrono
-- 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];
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 Figura 5.9 - Simulação de Shift Register
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
Figura 5.11 - RTL contador crescente 0 a 5 Figura 5.12 - Simulação do contador crescente 0 a 5
Figura 5.13 - Simulação do contador decrescente 5 a 0
Figura 5.14 - Simulação do contador decrescente 5 a 0 com parada
Restringir a frequencia máxima de clock no Quartus II
Instruções do tipo LOOP: LOOP incondicional, FOR-LOOP, WHILE-LOOP, NEXT, EXIT
[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;
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
Figura 5.16 - Simulação do counting_zeros
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
[rótulo:] WAIT UNTIL <condition>;
[rótulo:] WAIT ON sensitivity_list;
[rótulo:] WAIT FOR time_expression;
Figura 5.2 - RTL do contador BCD 00 a 99 Figura 5.3 - Simulação do contador BCD 00 a 99
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.
ATUAL
<generate_label>:
if <condition> generate
-- Concurrent Statement(s)
end generate;
Essa instrução é utilizada para a geração condicional de código durante a elaboração. Com isso, partes do projeto são sintetizadas e outras não, dependendo de certas condições ou parâmetros definidos no projeto. Como ela faz parte do grupo de instruções concorrentes, ela não pode ser utilizada dentro de PROCESS, FUNCTION ou PROCEDURE. Para exemplificar, consideramos a situação em que um contador crescente (UP) OU um contador decrescente (DOWN) devem serm utilizados, mas o contador nunca será aplicado nas duas direções de contagem. Neste caso, é possível estabelecer um parâmetro GENERIC, que definirá se a contagem é UP ou DOWN. Analise o código a seguir: entity contador_up_down is
generic
(
MIN : natural := 3;
MAX : natural := 21;
UPDOWN : natural := 0 -- 0 => up; 1 => down
);
port
(
clk, rst : in std_logic;
count_out : out integer range MIN to MAX
);
end entity;
architecture ifsc_v1 of contador_up_down is
begin
L1: if UPDOWN = 0 generate
process (clk, rst)
variable cnt : integer range MIN to MAX;
begin
if rst = '1' then
cnt := MIN;
elsif (rising_edge(clk)) then
if cnt = MAX then
cnt := MIN;
else
cnt := cnt + 1;
end if;
end if;
count_out <= cnt;
end process;
end generate;
L2: if UPDOWN = 1 generate
process (clk, rst)
variable cnt : integer range MIN to MAX;
begin
if rst = '1' then
cnt := MAX;
elsif (rising_edge(clk)) then
if cnt = MIN then
cnt := MAX;
else
cnt := cnt - 1;
end if;
end if;
count_out <= cnt;
end process;
end generate;
end architecture;
Se o parâmetro UPDOWN for instanciado com 0, teremos um contador crescente. Caso seja instanciado com 1, o contador será decrescente. Veja a simulação nos dois casos. Figura 5.4 - Simulação do contador UPDOWN com 0 Figura 5.5 - Simulação do contador UPDOWN com 1
|
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 - :
- A2 - :
- A3 - :
- A4 - :
- R - Recuperação de A1 a A4 :
- Folha de consulta de VHDL
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.
AR1 - Conhecendo os dispositivos lógicos programáveis
- Atividade
Para esse desafio, no PASSO 3 da AE1, selecione o dispositivo EP4CE6E22C7 da família Cyclone IV E.
Utilizando o circuito que realiza o cálculo da distância de Hamming entre dois sinais, procure melhorar o processo de compilação de modo que consiga reduzir ao máximo o tempo de propagação entre entrada e saída.
- Insira restrições de atraso máximo para o compilador utilizando o Synopsys Design Constraints File
- Modifique a técnica utilizada pelo Quartus na otimização em em Optimization Technique por default está selecionado [x] Balanced (Normal flow) .
- selecione uma das opções de [x] Performance para "procurar" reduzir o tempo de propagação e/ou aumentar a frequência máxima do sistema.
- selecione uma das opções de [x] Power para "procurar" reduzir a potência utilizados no sistema.
- selecione [x] Area para "procurar" reduzir o número de elementos lógicos utilizados no sistema.
- Altere a semente iniciaal em Fitter Initial Placement Seed.
- Entregas
- Envie o QAR com o projeto compilado e configurado com menor tempo de propagação entre entrada e saída que você conseguiu.
- Envie a captura da imagem mostrando o relatório com este tempo.
- Envie no texto online os seguintes dados:
- 1) Optimization Technique usada
- 2) Fitter Initial Placement Seed usada
- 3) Paramentros usados no Synopsys Design Constraints File
- 4) O caminho crítico (aquele que tem o maior tempo de propagação) e o tempo obtido.
- Bonificação na A1
- 0,5 - para o(a) estudante que obtiver o menor tempo de propagação para o caminho crítico
- 0,3 - para o(a) estudante que obtiver o segundo menor tempo de propagação para o caminho crítico
- 0,2 - para o(a) estudante que obtiver o terceiro menor tempo de propagação para o caminho crítico
AR2 - Desafio: contador bidirecional
- Atividade
Implementar um contador bidirecional entre MIN e MAX. Uma entrada DIR indica a direção da contagem. Considere DIR = 0 (para contagem crescente) e DIR = 1 (para contagem decrescente). Avaliar a frequencia máxima (Fmax) em que o circuito funcionará utilizando o dispositivo EP4CE10F17A7.
- 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.
- Entregas
- Para realizar a simulação e análise de tempo use MIN = 2 e MAX = 13.
- Envie o QAR com o projeto compilado e configurado com o maior valor de Fmax que você conseguiu.
- Envie a captura da imagem mostrando o relatório com essa frequência.
- Envie a tela da simulação que mostra que o contador funciona (faça contar de 0 até MAX, e também decrementar até o MIN)
- Envie no texto online os seguintes dados:
- 1) Qual versão foi implentada (v1 ou v2)
- 2) O maior valor de Fmax obtido
- Bonificação na A1
- 1,0 - para o(a) primeiro estudante que enviar o contador funcionando (versão 1 ou 2)
- 1,0 - para o(a) estudante que obtiver o maior valor de Fmax (versão 1)
- 1,0 - para o(a) estudante que obtiver o maior valor de Fmax (versão 2)
- Dicas
AR3 - Desafio: contador bcd
- Atividade
Implementar um contador BCD de 00 a 99, com parada em qualquer valor MAX_DU. Se os parâmetros dos contador D = 5 e U = 9, isso implica em contar de 00 até 59 e ficar parado neste valor. A atingir o valor final MAX_DU, uma saída adicional OPA deve ser ativada. Avaliar a frequencia máxima (Fmax) em que o circuito funcionará utilizando o dispositivo EP4CE10F17A7.
- 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.
- Entregas
- Na simulação e na análise considere a contagem de 00 a 23, definindo os parâmetros D = 2 e U = 3.
- Envie o QAR com o projeto compilado e configurado com o maior valor de Fmax que você conseguiu.
- Envie a captura da imagem mostrando o relatório com essa frequência.
- Envie a tela da simulação que mostra que o contador funciona fazendo ele contar de 0 até 23 (ou 23 até 0), deixe o período a mais no final para mostrar que o contador parou.
- Envie no texto online os seguintes dados:
- 1) Qual versão foi implentada (v1, v2 ou v3).
- 2) O maior valor de Fmax obtido.
- 3) Qual o número de elementos lógicos utilizados no projeto.
- Bonificação na A1
- 1,0 - para o(a) primeiro estudante que enviar o contador funcionando (versão 1, 2 ou 3)
- 1,0 - para o(a) estudante que obtiver o maior valor de Fmax (versão 1)
- 1,0 - para o(a) estudante que obtiver o maior valor de Fmax (versão 2)
- 1,0 - para o(a) estudante que obtiver o maior valor de Fmax (versão 3)
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.
AE1 - Conhecendo os dispositivos lógicos programáveis
AE1 - Conhecendo os dispositivos lógicos programáveis |
---|
|
Referências Bibliográficas: