ELD129003-Engtelecom (Diário) - Prof. Marcos Moecke: mudanças entre as edições
Ir para navegação
Ir para pesquisar
(317 revisões intermediárias por 2 usuários não estão sendo mostradas) | |||
Linha 4: | Linha 4: | ||
{{collapse top | expand=true | Unidade 1 - Aula inicial, Introdução a disciplina}} | {{collapse top | expand=true | Unidade 1 - Aula inicial, Introdução a disciplina}} | ||
;Encontro 1 ( | ;Encontro 1 (12 ago.): | ||
* A '''[[ELD2-EngTelecom (Página) | página da UC]]''' contém os materiais que não alteram entre semestre. | * A '''[[ELD2-EngTelecom (Página) | 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 [https://docente.ifsc.edu.br/moecke/ppc-engtelecom/PPC2023/ grafo do curriculo] | * Relação com as outras UCs do '''Eixo Sistemas Computacionais (Marrom)'''. Ver [https://docente.ifsc.edu.br/moecke/ppc-engtelecom/PPC2023/ grafo do curriculo] | ||
Linha 18: | Linha 18: | ||
*Utilizaremos durante as aulas algumas ferramentas computacionas como o site do [https://www.falstad.com/circuit/circuitjs.html Falstad] para entender circuitos digitais e fazer simulações básicas. | *Utilizaremos durante as aulas algumas ferramentas computacionas como o site do [https://www.falstad.com/circuit/circuitjs.html 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 '''[[Acesso ao IFSC-CLOUD (NUVEM)|Nuvem do IFSC]]'''.. | *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 '''[[Acesso ao IFSC-CLOUD (NUVEM)|Nuvem do IFSC]]'''.. | ||
*Para a prática de implementação dos circitos em dispositivos lógicos utilizaremos os kits de FPGA disponíveis no LabSiDi. Ver [[Media:ManualDE2-115.pdf | User Manual da DE2-115]], e [[Media:ManualMercurio.pdf | Manual do Usuário da Mercúrio IV]]. | |||
;LER PARA O PRÓXIMO ENCONTRO: | ;LER PARA O PRÓXIMO ENCONTRO: | ||
*Revisão dos conceitos sobre circuitos combinacionais vistos em CIL/ELD1 | *Revisão dos conceitos sobre circuitos combinacionais vistos em CIL/ELD1 | ||
*Para alunos que não cursaram ELD1 (não conhecem VHDL), irei fornecer uma sequência de estudos para conhecer melhor as instruções concorrentes do VHDL. | *Para alunos que não cursaram ELD1 (não conhecem VHDL), irei fornecer uma sequência de estudos para conhecer melhor as instruções concorrentes do VHDL. | ||
*Ler [https:// | *Ler página [[Preparando para gravar o circuito lógico no FPGA]] | ||
*Ler slides [https://drive.google.com/file/d/1VNUqU3nBkNWv3w-yT3HT18eY878JcgXz/view?usp=drive_link Introdução a linguagem de descrição de hardware (DHL)] | |||
{{collapse bottom}} | {{collapse bottom}} | ||
===Unidade REV - PRIMEIRO CONTATO COM VHDL === | ===Unidade REV - PRIMEIRO CONTATO COM VHDL === | ||
; | * 5 ENCONTROS | ||
* [https:// | {{collapse top | expand=true | Unidade REV - PRIMEIRO CONTATO COM VHDL}} | ||
<!-- | |||
;Nivelamento 1: | |||
* [https://wiki.sj.ifsc.edu.br/images/7/75/Introdu%C3%A7%C3%A3o_a_linguagem_de_descri%C3%A7%C3%A3o_de_hardware.pdf Introdução a linguagem de descrição de hardware (DHL)] | |||
* Estrutura do código VHDL | * Estrutura do código VHDL | ||
Linha 67: | Linha 70: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
*[[Uso do ambiente EDA - QUARTUS Prime para programação em VHDL]] | |||
*[[Uso do ambiente EDA - QUARTUS Prime para programação em VHDL]] | ;Nivelamento 2: | ||
*Descrição do harware utilizando código VHDL no Quartus. | |||
*Rever a IDE do Quartus | |||
*Realizar análise e síntese. | |||
*Obter Diagrama RTL e Technology Map do circuito | |||
*Realizar simulação funcional com ModelSim | |||
*Conhecer a IDE do ModelSim | |||
*Seguir o procedimento descrito em [[Uso do ambiente EDA - QUARTUS Prime para programação em VHDL]] | |||
;PARA O PRÓXIMO ENCONTRO: | ;PARA O PRÓXIMO ENCONTRO: | ||
Linha 77: | Linha 88: | ||
* Para conhecer um pouco mais da linguagem VHDL, ler [https://pt.wikipedia.org/wiki/VHDL VHDL] ou [https://en.wikipedia.org/wiki/VHDL VHDL.en]. A maioria dessas instruções serão tratadas posteriormente. | * Para conhecer um pouco mais da linguagem VHDL, ler [https://pt.wikipedia.org/wiki/VHDL VHDL] ou [https://en.wikipedia.org/wiki/VHDL VHDL.en]. A maioria dessas instruções serão tratadas posteriormente. | ||
; | ;Nivelamento 3- Simulação: | ||
* | *[[Como arquivar um projeto]] | ||
* | *[[Simulação Funcional usando o ModelSim]]; | ||
* | |||
* | ;Nivelamento 4 - Circuitos aritméticos: | ||
* | *Circuitos aritméticos: somadores, incrementador, decrementador, complemento de dois, multiplicador, comparadores | ||
* | :* [https://drive.google.com/file/d/1kql0io2sh9Mp4FfnqpEPrdUFkVhHBx6_/view?usp=drive_link slides] | ||
* | :* Incrementador de 4 bits [https://tinyurl.com/2b2feccq] [https://tinyurl.com/2xzje3w6] | ||
:* Decrementador de 4 bits [https://tinyurl.com/2aks3mgp] [https://tinyurl.com/22c8v57r] | |||
:* Somador completo [https://tinyurl.com/yqkt49kl] | |||
:* Somador de 4 bits [https://tinyurl.com/yucqnkwz] | |||
:* Complemento de dois de 4 bits [https://tinyurl.com/23532lga] | |||
*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. | |||
<syntaxhighlight lang=vhdl> | |||
entity somador is | |||
port ( | |||
a, b : in integer; | |||
s : out integer; | |||
end entity; | |||
{{ | architecture ifsc of somador is | ||
begin | |||
< | s <= a + b; | ||
end architecture; | |||
</syntaxhighlight> | |||
{{fig|4.1|Código RTL do somador com tipo integer sem range| RTL_somadorv1.png| 300 px |}} | |||
{{fig|4.2|Technology Map do somador com tipo integer sem range| TM_somadorv1.png| 1000 px |}} | |||
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. | |||
| | |||
<syntaxhighlight lang=vhdl> | |||
| | 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; | |||
</syntaxhighlight> | |||
{{fig|4.3|Código RTL do somador com tipo integer com range| RTL_somadorv2.png| 300 px |}} | |||
{{fig|4.4|Technology Map do somador com tipo integer com range| TM_somadorv2.png| 600 px |}} | |||
Para fazer uma subtração, basta trocar o operador "+" pelo "-", e o compilador irá implementar um subtrator realizando o complemento 2 da entrada b. | |||
<syntaxhighlight lang=vhdl> | |||
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; | |||
</syntaxhighlight> | |||
{{fig|4.5|Código RTL do subtrator com tipo integer com range| RTL_subtratorv1.png| 300 px |}} | |||
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 um incrementador, um dos fatores do somador é substituído por '1' e o compilador irá implementar um circuito incrementador. | |||
<syntaxhighlight lang=vhdl> | |||
entity incrementador is | |||
port ( | |||
a : in integer range 0 to 15; | |||
inc : out integer range 0 to 15); | |||
end entity; | |||
architecture ifsc of incrementador is | |||
< | begin | ||
inc <= a + 1; | |||
end architecture; | |||
</syntaxhighlight> | |||
</ | |||
{{fig|4.6|Código RTL do incrementador com tipo integer com range| RTL_incrementadorv1.png| 300 px |}} | |||
Note que no incrementador apenas a segunda entrada do módulo RTL somador passa a ter um valor fixo '1'. Isso faz com que o hardware necessário para efetuar a soma (+1) é reduzido. | |||
Para fazer o decrementador, um dos fatores do somador é substituído por '-1' e o compilador irá implementar um circuito decrementador. | |||
{{ | <syntaxhighlight lang=vhdl> | ||
entity decrementador is | |||
port ( | |||
a : in integer range 0 to 15; | |||
dec : out integer range 0 to 15); | |||
end entity; | |||
architecture ifsc of decrementador is | |||
begin | |||
dec <= a - 1; | |||
end architecture; | |||
</syntaxhighlight> | |||
{{fig|4.7|Código RTL do decrementador com tipo integer com range| RTL_decrementadorv1.png| 300 px |}} | |||
Note que no decrementador apenas a segunda entrada do módulo RTL somador passa a ter um valor fixo, mas também nas duas entradas o sinal A(0) e B(0) recebem o valor fixo '1', para produzir um ''carry_in'' para a soma do bit A(1) com B(1). | |||
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. | |||
<syntaxhighlight lang=vhdl> | |||
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; | |||
</syntaxhighlight> | |||
{{fig|4.6|Código RTL do multiplicador com tipo integer com range| RTL_multiplicadorv1.png| 300 px |}} | |||
{| | |||
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. | |||
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. | |||
| | <syntaxhighlight lang=vhdl> | ||
| | 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; | |||
</syntaxhighlight> | |||
{{fig|4.8|Código RTL do divisor com tipo integer com range| RTL_divisorv1.png| 300 px |}} | |||
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. | |||
{{fig|4.8|Código RTL do multiplicador por 4| RTL_multiplicador4.png| 300 px |}} | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|} | |||
{{fig|4.9|Código RTL do divisor por 2| RTL_divisor2.png| 300 px |}} | |||
'''ATENÇÃO:''' Multiplicações por constantes não utilizam os multiplicadores, pois 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. | |||
{{fig|4.10|Código RTL do multiplicador por 10| RTL_multiplicador10.png| 300 px |}} | |||
O tipo INTEGER não é muito adequado para realizar as operações aritméticas por três motivos: | |||
# Com INTEGER as operações só podem ser feita com no máximo 32 bits. | |||
# Se não for dado um RANGE, as operações serão feitas com 32 bits, gerando hardware desnecessário | |||
# Alguns simuladores (como o ModelSim) ao incrementarem um INTEGER além do valor máximo interrompem a simulação por overflow. | |||
{{collapse top | tb_somador_int.do}} | |||
<syntaxhighlight lang=tcl> | |||
# Define o nome do componente VHDL | |||
set arq_vhd somador_int | |||
vlib rtl_work | |||
vmap work rtl_work | |||
vcom -93 -work work "../../${arq_vhd}.vhd" | |||
vsim work.${arq_vhd}(ifsc) | |||
# Adiciona sinais ao waveform | |||
add wave -position end sim:/$arq_vhd/a | |||
add wave -position end sim:/$arq_vhd/b | |||
add wave -position end sim:/$arq_vhd/s | |||
#Adiciona sinais ao waveform e mostra o valor em UNSIGNED | |||
add wave -position end -radix unsigned sim:/$arq_vhd/a | |||
add wave -position end -radix unsigned sim:/$arq_vhd/b | |||
add wave -position end -radix unsigned sim:/$arq_vhd/s | |||
# Força valores em b e varia a de 0 a 15 | |||
force -freeze sim:/$arq_vhd/b 7 0 | |||
for {set i 0} {$i < 16} {incr i} { | |||
force -freeze sim:/$arq_vhd/a 10#$i 0 | |||
run 1 ns | |||
} | |||
# Ajustes visuais | |||
configure wave -timelineunits ns | |||
wave zoom full | |||
</syntaxhighlight> | |||
{{collapse bottom}} | |||
{{fig|4.11|Simulação com parada devido a erro de overflow no ModelSim | OverflowModelSim_somador_int.png| 800 px |}} | |||
Note que nessa simulação, ao atingir a soma 9 + 7 = 16, ocorre o overflow e o simulador indica o '''Fatal error''' e para. | |||
** Fatal: (vsim-3421) Value '''16 is out of range 0 to 15.''' | |||
{{fig|4.12|Erro Fatal no ModelSim | OverflowModelSim.png| 800 px |}} | |||
Veja como ficaria um somador usando o tipo UNSIGNED como portas de entrada e saída. | |||
<syntaxhighlight lang=vhdl> | <syntaxhighlight lang=vhdl> | ||
entity | library ieee; | ||
use ieee.numeric_std.all; | |||
( | |||
entity somador is | |||
generic (N : natural := 4); | |||
port ( | |||
a, b : in unsigned(N-1 downto 0); | |||
s : out unsigned(4 downto 0) | |||
); | ); | ||
end entity; | end entity; | ||
- | architecture ifsc of somador is | ||
architecture | s <= a + b; | ||
end architecture; | |||
</syntaxhighlight> | |||
Mesmo essa solução acima não é a mais adequada, pois utiliza portas que não estão de acordo com a recomendação do padrão industrial e que é compatível com as ferramentas de EDA no mercado. O ideal é ter sempre as portas definidas com tipos std_logic ou std_logic_vector. Por isso a recomendação é adotar uma solução como a seguinte: | |||
<syntaxhighlight lang=vhdl> | |||
library ieee; | |||
use ieee.std_logic_1164.all; | |||
use ieee.numeric_std.all; | |||
entity somador_slv is | |||
generic (N : natural := 4); | |||
port ( | |||
a, b : in std_logic_vector(N-1 downto 0); | |||
s : out std_logic(4 downto 0); | |||
); | |||
end entity; | |||
architecture ifsc_v1 of somador_slv is | |||
begin | |||
s <= std_logic_vector(unsigned(a) + unsigned(b)); | |||
end architecture; | |||
architecture ifsc_v2 of somador_slv is | |||
signal a_uns, b_uns : unsigned(N-1 downto 0); | |||
signal s_uns : unsigned(N-1 downto 0); | |||
begin | begin | ||
s <= std_logic_vector(s_uns) | |||
s_uns <= a_uns + b_uns; | |||
a_uns <= unsigned(a); | |||
a_uns <= unsigned(b); | |||
end architecture; | end architecture; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
{{fig|4.12|Simulação correta no ModelSim | SomadorModelSim.png| 800 px |}} | |||
Note que nessa simulação, ao atingir a soma 9 + 7 = 16, ocorre o overflow, como são apenas 4 bits que são utilizados, o resultado 10000 é guardado como 0000 e e o simulador indica corretamente o s = 0 no instante 9ns. | |||
Para utilizar corretamente os tipos UNSIGNED e SIGNED leia atentamente | |||
*A biblioteca [[Numeric std.vhd]] define os tipos UNSIGNED e SIGNED. | |||
<syntaxhighlight lang=vhdl> | <syntaxhighlight lang=vhdl> | ||
package NUMERIC_STD is | |||
type UNSIGNED is array (NATURAL range <>) of STD_LOGIC; | |||
type SIGNED is array (NATURAL range <>) of STD_LOGIC; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
* | 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: | ||
<syntaxhighlight lang=vhdl> | |||
--============================================================================ | |||
-- 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; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
:Ver pag. 73 a 78 de <ref name="PEDRONI2010b"> PEDRONI, V. A. '''Circuit design and simulation with VHDL'''. 2nd. ed. New Delhi: PHI Learning Private, 2015.</ref> | |||
[[Arquivo:SumaryOfNumeric_std.gif]] | |||
[[Arquivo:Numeric_stdConvertions.gif]] | |||
FONTE: http://www.doulos.com/knowhow/vhdl_designers_guide/numeric_std/ | |||
<center> | |||
{{Mensagem | |||
|indent = | |||
|title= | |||
|equation = <big> Ler e guardar a página sobre [[Aritmética com vetores em VDHL]] </big> | |||
|cellpadding= 6 | |||
|border | |||
|border colour = #0073CF | |||
|background colour=#F5FFFA}} | |||
</center> | |||
;Nivelamento 5 - Instruções WHEN_ELSE, WITH_SELECT, CONFIGURATION: | |||
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). | |||
{{collapse top | Mux2x1}} | |||
A tabela verdade que descreve um MUX2:1 é mostrada abaixo: | |||
<center> | |||
{| class="wikitable" style="text-align:center;" | |||
|- style="font-weight:bold;" | |||
! X1 | |||
! X0 | |||
! Sel | |||
! style="background-color:#c0c0c0;" | Y | |||
|- | |||
| 0 | |||
| 0 | |||
| 0 | |||
| style="background-color:#c0c0c0;" | 0 | |||
|- | |||
| 0 | |||
| 0 | |||
| 1 | |||
| style="background-color:#c0c0c0;" | 0 | |||
|- | |||
- | | 0 | ||
| 1 | |||
| 0 | |||
- | | style="background-color:#c0c0c0;" | 1 | ||
- | |- | ||
| 0 | |||
| 1 | |||
| 1 | |||
| style="background-color:#c0c0c0;" | 0 | |||
|- | |||
| 1 | |||
| 0 | |||
| 0 | |||
| style="background-color:#c0c0c0;" | 0 | |||
|- | |||
| 1 | |||
| 0 | |||
| 1 | |||
| style="background-color:#c0c0c0;" | 1 | |||
|- | |||
| 1 | |||
| 1 | |||
| 0 | |||
| style="background-color:#c0c0c0;" | 1 | |||
|- | |||
| 1 | |||
| 1 | |||
| 1 | |||
| style="background-color:#c0c0c0;" | 1 | |||
|} | |||
</center> | |||
=== | O MUX2:1 também pode ser representado de forma resumida por: | ||
<center> | |||
{| class="wikitable" style="text-align:center;" | |||
|- style="font-weight:bold;" | |||
; | ! X1 | ||
! X0 | |||
! Sel | |||
! style="background-color:#c0c0c0;" | Y | |||
|- | |||
: | | - | ||
| X0 | |||
| 0 | |||
| style="background-color:#c0c0c0;" | X0 | |||
|- | |||
| X1 | |||
| - | |||
| 1 | |||
| style="background-color:#c0c0c0;" | X1 | |||
|} | |||
</center> | |||
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: | |||
{ | <math> Y = \overline{Sel} . X0 + Sel . X1 </math> | ||
Onde Y é a saída; Sel é o sinal de seleção; X0 e X1 são as entradas. | |||
{{collapse bottom}} | {{collapse bottom}} | ||
{{collapse top | expand=false |Mux4x1}} | |||
O MUX4:1 pode ser representado de forma resumida pela tabela verdade: | |||
<center> | |||
{| class="wikitable" style="text-align:center;" | |||
|- style="font-weight:bold;" | |||
! colspan="4" | Entradas | |||
! colspan="2" | Seleção | |||
! Saída | |||
|- style="font-weight:bold;" | |||
; | | X3 | ||
| X2 | |||
| X1 | |||
| X0 | |||
| Sel1 | |||
| Sel0 | |||
| style="background-color:#c0c0c0;" | Y | |||
|- | |||
| - | |||
| - | |||
| - | |||
| X0 | |||
| 0 | |||
| 0 | |||
| style="background-color:#c0c0c0;" | X0 | |||
|- | |||
| - | |||
| - | |||
| X1 | |||
| - | |||
| 0 | |||
| 1 | |||
| style="background-color:#c0c0c0;" | X1 | |||
|- | |||
| - | |||
| X2 | |||
| - | |||
| - | |||
| 1 | |||
| 0 | |||
| style="background-color:#c0c0c0;" | X2 | |||
|- | |||
| X3 | |||
| - | |||
| - | |||
: | | - | ||
| 1 | |||
| 1 | |||
| style="background-color:#c0c0c0;" | X3 | |||
|} | |||
</center> | |||
A função booleana que descreve a operação de um MUX 4:1 pode ser representada da seguinte forma: | |||
<math> Y = X0 . \overline{Sel1} . \overline{Sel0} + X1 . \overline{Sel1} . Sel0 + X2 . Sel1 . \overline{Sel0} + X3 . Sel1 . Sel0 </math> | |||
{{collapse bottom}} | |||
{{ | |||
Dada a função booleana do MUX4:1 é simples para descreve-lo em VHDL utilizando apenas operadores lógicos. | |||
<syntaxhighlight lang=vhdl> | |||
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; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
: | |||
No entanto, o MUX4:1 também pode ser descrito utilizando a instrução '''WHEN-ELSE''' | |||
<syntaxhighlight lang=vhdl> | <syntaxhighlight lang=vhdl> | ||
<optional_label>: <target> <= | |||
<value> when <condition> else | |||
<value> when <condition> else | |||
... | |||
<value> else | |||
<value>; | |||
</syntaxhighlight> | |||
*Importante: O '''último ELSE''' sem condição para 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: | ||
<syntaxhighlight lang=vhdl> | <syntaxhighlight lang=vhdl> | ||
-- | -- Implementação com WHEN ELSE | ||
architecture v_WHEN_ELSE of mux4x1 is | |||
begin | begin | ||
Y <= X(0) when Sel = "00" else | |||
X(1) when Sel = "01" else | |||
X(2) when Sel = "10" else | |||
X(3); | |||
end architecture; | |||
end | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Outra forma de descrever o MUX4:1 seria utilizando a instrução '''WITH-SELECT''' | |||
<syntaxhighlight lang=vhdl> | <syntaxhighlight lang=vhdl> | ||
<optional_label>: with <expression> select | |||
<target> <= | |||
<value> when <choices>, | |||
<value> when <choices>, | |||
... | |||
<value> when others; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
*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'''. | |||
<syntaxhighlight lang=vhdl> | <syntaxhighlight lang=vhdl> | ||
-- | -- Implementação com WITH SELECT | ||
architecture v_WITH_SELECT of mux4x1 is | |||
begin | 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. | |||
end | -- Não pode ser substituido por "11" mesmo que o signal seja bit_vector. | ||
end architecture; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
* 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. | |||
<syntaxhighlight lang=vhdl> | |||
CONFIGURATION <configuration_name> OF <entity_name> IS | |||
FOR <architecture_name> END FOR; | |||
END CONFIGURATION; | |||
</syntaxhighlight> | |||
<syntaxhighlight lang=vhdl> | <syntaxhighlight lang=vhdl> | ||
-- | -- 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; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
* | * 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. | ||
{{fig| | * Note a diferença entre os RTL Viewer obtidos para cada architecture. | ||
{{fig| | {{fig|2.1|Código RTL do mux4x1 v_logica_pura| RTL_mux4x1v1.png| 300 px |}} | ||
{{fig|2.2|Código RTL do mux4x1 v_WHEN_ELSE| RTL_mux4x1v2.png| 400 px |}} | |||
{{fig|2.3|Código RTL do mux4x1 v_WITH_SELECT| RTL_mux4x1v3.png| 200 px |}} | |||
:'''OBS''': [https://en.wikipedia.org/wiki/Register-transfer_level 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. | |||
; | ;RESUMO: | ||
* | *[https://wiki.sj.ifsc.edu.br/images/5/5c/3-concorrente.pdf Slides Declarações Concorrentes] | ||
;PARA O PRÓXIMO ENCONTRO: | |||
-- | *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 | |||
*Ver essa página [[Simulação Funcional usando o ModelSim]] | |||
--> | |||
{{collapse bottom}} | |||
===Unidade 2 - Dispositivos Lógicos Programáveis === | |||
* 5 ENCONTROS | |||
{{collapse top | expand=true | Unidade 2 - Dispositivos Lógicos Programáveis}} | |||
<!-- | |||
;Encontro 2 (20 mar.): | |||
*[https://drive.google.com/file/d/1VNUqU3nBkNWv3w-yT3HT18eY878JcgXz/view?usp=drive_link Introdução a linguagem de descrição de hardware (DHL)] | |||
<syntaxhighlight lang=vhdl> | <syntaxhighlight lang=vhdl> | ||
-- Exemplo: Declaração do circuito combinacional | |||
-- Y = A'.B + A.B' | |||
-- Autor: prof. Marcos Moecke | |||
-- Data: 20/03/2025 | |||
-- Filename: REV1.vhd | |||
-- A declaracao abaixo nao e necessaria pois o pacote standart da biblioteca std e autodeclarada (por default) | |||
library std; | |||
use std.standard.all; | |||
-- | |||
entity REV1 is | |||
port (a, B: in bit; y: out bit); | |||
end entity; | end entity; | ||
architecture ifsc_v1 of | -- Implementacao direta com funcoes logicas | ||
architecture ifsc_v1 of rev1 is | |||
begin | begin | ||
Y <= (not a and b) or (A and not B); | |||
end architecture; | end architecture; | ||
-- Implementacao com funcoes logica por etapas | |||
: | architecture ifsc_v2 of rev1 is | ||
< | signal nota, notb : bit; -- sinais internos podem ser declarados em uma unica linha se forem do mesmo tipo | ||
signal and_1 : bit; -- o nome dos sinais nao pode usar palavras reservadas do VHDL como and. | |||
signal and_2 : bit; -- usar uma linha para cada sinal pode ser uma boa pratica de documentacao | |||
signal or_3 : bit; | |||
end | begin | ||
notA <= not A; | |||
notb <= not B; | |||
and_1 <= nota and b; | |||
and_2 <= (A and notB); | |||
or_3 <= and_1 or and_2; | |||
Y <= or_3; -- assim se faz a conexao entre um sinal interno uma saida | |||
-- as ultimas 2 linhas acima poderiam ser tambem simplificadas | |||
-- Y <= and_1 or and_2; | |||
end architecture; | |||
architecture | -- Implementacao com WHEN-ELSE | ||
architecture ifsc_v3 of rev1 is | |||
begin | |||
end architecture; | |||
-- Implementacao com WITH-SELECT | |||
architecture ifsc_v4 of rev1 is | |||
begin | |||
end architecture; | end architecture; | ||
-- associacao da architetura a entidade. | |||
-- Se nao for feita, a ultima arquitetura e associada | |||
configuration rev1_cfg of REV1 is | |||
-- for ifsc_v1 end for; | |||
for ifsc_v2 end for; | |||
-- for ifsc_v3 end for; | |||
-- for ifsc_v4 end for; | |||
end configuration; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
; | ;PARA O PRÓXIMO ENCONTRO: | ||
* | * Alunos que fizeram ELD129002 : reveja [[Uso do ambiente EDA - QUARTUS Prime para programação em VHDL]] | ||
: | * Alunos que não fizeram ELD129002 : siga o procedimento [[Uso do ambiente EDA - QUARTUS Prime para programação em VHDL]]. | ||
* Se tiver dúvidas pergunte no chat da turma, que o professor ou algum colega pode ajudá-lo | |||
* | * Implente e teste as várias versões de '''architecture''' da '''entity REV1''' . | ||
: | :1) diretamente com as funções lógicas | ||
:2) com funções lógicas por etapas | |||
:3) com WHEN-ELSE | |||
:4) com WITH-SELECT | |||
;Encontro 3 (25 mar.): | |||
*Introdução aos dispositivos lógicos programáveis: | |||
:* Conceito, tipos de PLDs | |||
:* SPLD: | |||
::*PAL (e.g. [https://wiki.sj.ifsc.edu.br/images/8/86/PAL16.pdf#page=5| PAL16 da Texas Instruments (1984)]) | |||
::*PLA (e.g. [https://wiki.sj.ifsc.edu.br/images/5/57/PLS100.pdf#page=2| PLS100 da Philips Semiconductors (1993)]) | |||
::*GAL (e.g. [https://wiki.sj.ifsc.edu.br/images/5/5d/GAL16V8.pdf#page=6| GAL16V8 da Lattice (2004)]) | |||
:* CPLDs (e.g. [https://wiki.sj.ifsc.edu.br/images/c/c8/ATF2500C.pdf#page=9| ATF2500C da Atmel (2008)], [https://br.mouser.com/c/ds/semiconductors/programmable-logic-ics/cpld-complex-programmable-logic-devices/ Complex Programmable Logic Devices Datasheets - Mouser]) | |||
{{collapse top | expand=true| Exemplos de PLDs}} | |||
: | {{fig|2.1|Exemplo de PAL| PedroniFig4_4a.png| 400 px | http://www.vhdl.us/book/Pedroni_VHDL_3E_Chapter4.pdf}} | ||
{{fig|2.2|Exemplo de PLA| PedroniFig4_4b.png| 400 px | http://www.vhdl.us/book/Pedroni_VHDL_3E_Chapter4.pdf}} | |||
{{fig|2.3|Macrobloco do PLD EP300 da ALTERA| ep310_macrocell.jpg| 400 px | https://www.altera.com/solutions/technology/system-design/articles/_2013/in-the-beginning.html}} | |||
{{fig|2.4|Macrocélula dos PLDs Clássicos EP600, EP900, EP1800 da ALTERA (1999)| Macrocell_EP900.png| 400 px | https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ds/archives/classic.pdf}} | |||
{{fig|2.5| Princípio de construção de uma LUT| LUT_pedroni.png | 400 px | https://www.vhdl.us/book/Pedroni_VHDL_3E_Chapter4.pdf}} | |||
{{fig|2.6|Architetura do PLD EP1800 da ALTERA| ep1800_block_diagram.jpg| 400 px | https://www.altera.com/solutions/technology/system-design/articles/_2013/in-the-beginning.html}} | |||
{{fig|2.7|Architetura do PLD EP1800 da ALTERA| ep1800_block_diagram2.jpg| 400 px | https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ds/archives/classic.pdf}} | |||
{{fig|2.8|Pinagem e tipos de encapsulamento do PLD EP1800 da ALTERA| PackagePinOut_EP1810.png| 400 px | https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ds/archives/classic.pdf }} | |||
{{fig|2.9|Architetura do CPLD MAX 5000 da ALTERA| max_5000_architecture.jpg| 400 px | https://www.altera.com/solutions/technology/system-design/articles/_2013/in-the-beginning.html}} | |||
{{collapse bottom}} | |||
;PARA O PRÓXIMO ENCONTRO: | |||
*[https://youtu.be/7qa1dsCpMMo Memória EEPROM e FLASH] , [https://youtu.be/yLyQRtybfhc EEPROMs Market Value Explained] - Microchip (ingles) | |||
[ | *[https://www.youtube.com/watch?v=BA12Z7gQ4P0 Using an EEPROM to replace combinational logic] - | ||
*[https://www.intel.com/content/www/us/en/programmable/customertraining/webex/PLDBasics_History/presentation_html5.html History of Programmable Logic] Intel | |||
*[https://www.intel.com/content/www/us/en/products/details/fpga/platforms.html See why Microsoft chose Intel FPGAs to accelerate their next generation cloud infrastructure] | |||
*[https://www.intel.com/content/www/us/en/products/docs/programmable/text-speech-synthesis-demo.html Text to Speech Synthesis Demo Using Stratix® 10 NX FPGA] | |||
*Seção 4.1 a 4.5 de [http://www.vhdl.us/book/Pedroni_VHDL_3E_Chapter4.pdf Review of Field Programmable Gate Arrays (FPGAs)], Volnei A. Pedroni. (ou para quem preferir em português, leia as seções 18.1 a 18.3 do livro: PEDRONI, Volnei A '''Eletrônica Digital Moderna e VHDL: Princípios Digitais, Eletrônica Digital, Projeto Digital, Microeletrônica e VHDL'''; 1ª ed. Rio de Janeiro:Elsevier, 2010. 619p. ISBN 9788535234657. Têm 16 exemplares na [http://biblioteca.ifsc.edu.br/index.asp?codigo_sophia=30631 biblioteca do Campus]. Número de chamada: 621.392 P372e) | |||
*Seção 2.1 Dispositivos lógicos programáveis do TCC [[Integração de ramais analógicos com FPGA utilizando processador softcore]], Renan Rodolfo da Silva. | |||
* | ;Encontro 4 (27 mar.): | ||
* Arquitetura de FPGAs (Xilinx e Altera): CLB, LAB, LUT, Flip_flop D, RAM, DSP, Clock, PLL, DLL, I/O | |||
:FONTE: [[Media: FPGA_Architecture.pdf | FPGA Architecture]] - ALTERA | |||
{{collapse top | expand=true |Exemplos de FPGA}} | |||
{{fig|2.9|Arquitetura de um FPGA | Architecture_FPGAs.png| 600 px | https://www.intel.com/content/www/us/en/docs/programmable/683176/18-1/fpga-overview-opencl-standard.html}} | |||
architecture | {{fig|2.10|Diagrama simplificado da ALM de um FPGA Intel/Altera | ALM_LUT_FPGAs.png| 600 px | https://www.intel.com/content/www/us/en/content-details/771003/fpga-architecture-8-input-lut-legacy-white-paper.html}} | ||
{{fig|2.11|Arquitetura interna de uma LUT | LUT_FPGAs.png| 800 px | [[Media: FPGA_Architecture.pdf | FPGA Architecture]] - ALTERA}} | |||
{{fig| | |||
{{fig|2.12|Configuração de uma LUT | LUT_FPGAs_Config.png| 1000 px | https://www.allaboutcircuits.com/technical-articles/purpose-and-internal-functionality-of-fpga-look-up-tables/}} | |||
{{fig| | {{fig|2.13|Arquitetura do Cyclone® V Intel/Altera | CycloneV_FPGAs.jpg| 600 px | https://www.intel.com.br/content/www/br/pt/products/details/fpga/cyclone/v/article.html}} | ||
{{fig|2.14|Leiaute de um FPGA Xilinx genérico | Leiaute2_FPGAs.jpg| 600 px | https://www.sciencedirect.com/science/article/pii/B9780750678667500032 }} | |||
{{fig|2.15|Roteamento de sinal em um FPGA | Roteamento_FPGAs.jpg| 600 px | https://www.sciencedirect.com/science/article/pii/B9780750678667500032 }} | |||
: | |||
{{fig|2.16|Tecnologias usadas na configuração de FPGAs| FPGA_programming.png| 800 px | https://www.sciencedirect.com/topics/computer-science/one-time-programmable }} | |||
{{collapse bottom}} | |||
:Ver também [https://www.youtube.com/watch?v=kU2SsUUsftA&t=2s SRAM], [https://www.youtube.com/watch?v=7qa1dsCpMMo EEPROM], [https://www.youtube.com/watch?v=ELl3abwYQ90&list=PL9B4edd-p2agcmJl2EscTdLudLv58uXHt&index=1 What Is Flash Memory] | |||
* [https://wiki.sj.ifsc.edu.br/index.php/ELD129003-Engtelecom_(Di%C3%A1rio)_-_Prof._Marcos_Moecke#AE1_-_Conhecendo_os_dispositivos_l.C3.B3gicos_program.C3.A1veis AE1 - Conhecendo os dispositivos lógicos programáveis] - Passo 1 e 2 | |||
* [https://wiki.sj.ifsc.edu.br/index.php/ELD129003-Engtelecom_(Di%C3%A1rio)_-_Prof._Marcos_Moecke#AE1_-_Conhecendo_os_dispositivos_l.C3.B3gicos_program.C3.A1veis AE1 - Conhecendo os dispositivos lógicos programáveis] - Passo 3 e 4 | |||
;PARA O PRÓXIMO ENCONTRO: | |||
* Leia a assista a alguns dos vídeos sobre a historia e processo de produção dos chips. | |||
:*[https://www.semiwiki.com/forum/content/1535-brief-history-fabless-semiconductor-industry.html A Brief History of the Fabless Semiconductor Industry] | |||
:*[http://www.semiwiki.com/forum/content/1539-brief-history-tsmc.html Taiwan Semiconductor Manufacturing Corporation (TSMC)], [http://www.globalfoundries.com/ GLOBALFOUNDRIES] | |||
:*[https://www.linkedin.com/pulse/free-copy-fabless-transformation-semiconductor-industry-daniel-nenni-1 Fabless: The Transformation of the Semiconductor Industry, 2014] - Download free | |||
:*[https://www.youtube.com/watch?v=W3rfVpkNquA Produção do FinFET], [https://www.youtube.com/watch?v=d9SWNLZvA8g] | |||
:*[https://en.wikipedia.org/wiki/3_nm_process 3 nm process], [https://en.wikipedia.org/wiki/Multigate_device multi-gate MOSFET] | |||
:*[https://www.youtube.com/watch?v=UvluuAIiA50 GLOBALFOUNDRIES Sand to Silicon], [https://www.youtube.com/watch?v=F2KcZGwntgg How Microchips are made] - Processo de fabricação de um chip | |||
:*[https://en.wikipedia.org/wiki/Foundry_model Foundries], [https://en.wikipedia.org/wiki/List_of_semiconductor_fabrication_plants List of semiconductor fabrication plants] | |||
:*[https://www.youtube.com/watch?v=GU87SH5e0eI A dependência do mundo com a TMSC] | |||
:*[https://www.youtube.com/watch?v=kU2SsUUsftA What is SRAM?], [https://www.youtube.com/watch?v=Lozf9sceW_o What is DRAM?] - Microchip | |||
;Encontro 5 (1 abr.): | |||
* System on Chip | |||
{{fig|2.17|Altera - Visão geral do dispositivo Arria V SX e ST| ArriaV_SX_ST_Chip.png| 800 px | https://br.mouser.com/datasheet/2/612/av_51001-1623623.pdf}} | |||
{{fig| | {{fig|2.18|Altera - Agilex 7 SoCs HPS Digrama de Blocos| Agilex7SoC_Blocos.png| 800 px | https://static6.arrow.com/aropdfconversion/b568cfe009abfed6a28eff56700189883d7fc179/ag-overview-683458-666707.pdf}} | ||
* | * [https://wiki.sj.ifsc.edu.br/index.php/ELD129003-Engtelecom_(Di%C3%A1rio)_-_Prof._Marcos_Moecke#AE1_-_Conhecendo_os_dispositivos_l.C3.B3gicos_program.C3.A1veis AE1 - Conhecendo os dispositivos lógicos programáveis] - Passo 1 a 4 | ||
;PARA O PRÓXIMO ENCONTRO: | |||
[ | :* Ver preços de DLPs em | ||
::*[https://www.arrow.com/ ARROW] | |||
::*[https://www.digikey.com/ Digikey] | |||
::*[https://mouser.com Mouser Electronics] | |||
::*[https://www.newark.com/ Newark] | |||
:* Fabricantes de DLPs/FPGAs e familias de DLPs atuais. | |||
::*[https://www.altera.com/products/fpga/overview.html ALTERA/INTEL] - Stratix, Arria, Cyclone, Max, Agilex | |||
::*[https://www.xilinx.com/products/silicon-devices/fpga.html Xilinx/AMD] - Virtex, Kintex, Artix, Zynq (SoC) | |||
::*[https://www.microchip.com/en-us/products/fpgas-and-plds/fpgas Microchip] - Igloo, PolarFire | |||
::*[http://www.latticesemi.com/Products.aspx#_D5A173024E414501B36997F26E842A31 Lattice] - ECP, iCE, Mach | |||
;Encontro 6 (3 abr.): | |||
* [https://wiki.sj.ifsc.edu.br/index.php/ELD129003-Engtelecom_(Di%C3%A1rio)_-_Prof._Marcos_Moecke#AE1_-_Conhecendo_os_dispositivos_l.C3.B3gicos_program.C3.A1veis AE1 - Conhecendo os dispositivos lógicos programáveis] - Passo 1 a 4 | |||
--> | |||
{{collapse bottom}} | |||
===Unidade 3 - Circuitos sequenciais (Implementação com HDL) === | |||
* 18 ENCONTROS | |||
{{collapse top | expand=true | Unidade 3 - Circuitos sequenciais (Implementação com HDL)}} | |||
<!-- | |||
;Encontro 6 (3 abr.): | |||
*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 | |||
<syntaxhighlight lang=vhdl> | <syntaxhighlight lang=vhdl> | ||
[rótulo:] PROCESS [(lista_de_sensibilidade)] [IS] | |||
[parte_declarativa] | |||
BEGIN | |||
afirmação_sequencial; | |||
afirmação_sequencial; | |||
... | |||
END PROCESS [rótulo]; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
:*Instrução '''IF''' | |||
<syntaxhighlight lang=vhdl> | |||
[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]; | |||
</syntaxhighlight> | |||
:*Exemplos: | |||
::* DFFs com Reset Assincrono e Reset Sincrono, com Enable, com Preset (Variação Ex 6.1). | |||
<syntaxhighlight lang=vhdl> | <syntaxhighlight lang=vhdl> | ||
--Flip Flop tipo D com reset assincrono, sensivel a borda de subida. | |||
process (clock,reset) | |||
begin | 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; | |||
</syntaxhighlight> | |||
{{fig|3.1|RTL de Flip-flop D de borda de subida, com reset assíncrono| FF_D_RST.png| 400 px | }} | |||
<syntaxhighlight lang=vhdl> | |||
--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; | |||
</syntaxhighlight> | |||
{{fig|3.2|RTL de Flip-flop D de borda de descida, com preset assíncrono e enable| FF_D_PRST.png| 400 px | }} | |||
::* Comparar com Latch (sem clk'event). | |||
<syntaxhighlight lang=vhdl> | |||
--Latch tipo D com reset assincrono. | |||
process (enable, reset, d) | |||
begin | |||
if (reset = '1') then | |||
q <= '0'; | |||
elsif (enable='1')) then | |||
q <= d; | |||
end | end if; | ||
end process; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
{{fig|3.3|RTL de Latch D de com reset assíncrono e enable ativo alto| LATCH_D_RST.png| 400 px | }} | |||
{{fig| | * 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]] | |||
{{fig|3.4|Comparação do ''Technology Map'' de um Latch_D (esquerda) com FF_D (direita)| FF_D_LATCH_D.png| 800 px | }} | |||
* | :* Ver pag. 151 a 156 de <ref name="PEDRONI2010b"/> | ||
:* Ver [https://tinyurl.com/2xu3vwd7 simulação de Latch tipo D] (Falstad) | |||
:* Ver [https://tinyurl.com/2al6kkbs simulação de Flipflop tipo D] (Falstad) | |||
:* Ver [[Especificando o valor de Power-Up do flip-flop D]] | |||
<syntaxhighlight lang=vhdl> | |||
-- 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'; | |||
{{fig|5 | elsif (clock'event and clock'last_value = '0' and clock = '1')) then | ||
q <= d; | |||
* | end if; | ||
end process; | |||
</syntaxhighlight> | |||
{{fig|3.5|RTL do Flip-flop D com reset assíncrono e reset síncrono| FF_D_RST_SINC_ASINC.png| 400 px | }} | |||
*[[Como evitar o uso da lógica combinacional no reset síncrono]] | |||
;Encontro 7 (8 abr.): | |||
*Exercício: Implemente um registrador com N FF_D no lugar de um único FF_D. | |||
{{fig|3.6|RTL do Registrador (de 4 bits) com reset assíncrono| REG_RST.png| 400 px | }} | |||
{{fig| | {{fig|3.7|Techonogy Map do Registrador (de 4 bits) com reset assíncrono| TM_REG_RST.png| 400 px | }} | ||
* Faça a simulação funcional do DFFs e do Latch | |||
{ | ;Para o próximo encontro: | ||
*Use o script do arquivo de simulação tb_FFD_v_ruim.do para repetir a simulação feita em aula. | |||
*Melhore o script eliminando comentários desnecessários. | |||
*Deixe no inicio do script os comandos (alguns estarão comentados) | |||
vlib rtl_work | |||
:Função: Criar uma biblioteca de trabalho chamada rtl_work. | |||
vmap work rtl_work | |||
:Função: Faz o mapeamento da biblioteca padrão work para a biblioteca rtl_work criada anteriormente. | |||
vcom -93 -work work {../../FFD_N.vhd} | |||
:Função: Compila o arquivo VHDL FFD_N.vhd utilizando o padrão VHDL-93, e coloca o resultado da compilação na biblioteca work. | |||
vsim work.ffd_n(ifsc_v1) | |||
:Função: Inicia a simulação do componente ffd_n, presente na biblioteca work, utilizando a configuração ifsc_v1. | |||
add wave -r sim:/ffd_n/* | |||
:Função: Adicione todos os sinais da hierarquia a janela Wave. | |||
*Para cada estímulo (entrada) faça com que haja apenas uma linha de comando '''force''' usando o padrão abaixo: | |||
force -freeze sim:/ffd_n/<nome do estimulo> valor1 tempo1, valor2 tempo2, valor3 tempo3 | |||
*Para a entrada '''clock''' use: | |||
force -freeze sim:/ffd_n/clock v1 t1, v2 t2 -r Tclk | |||
:onde: | |||
::o primeiro par (v1 t1) indica o valor inicial do clock v1 = 1 => começa ALTO. v1 = 0 => começa BAIXO. t1 é normalmente 0, indica quando o valor v1 deve ser gerado. | |||
::o segundo par (v2 t2) indica o valor final do clock, v2 deve ser o complemento de v1. t2 é a duração do valor v1 em ps (ou outra unidade) | |||
::o tempo Tclk é o período em que o sinal deve ser repetido. | |||
:Exemplo de um sinal de período de 100ps => fclk = 10GHz; | |||
force -freeze sim:/ffd_n/clock 1 0, 0 50 -r 100 | |||
*Conclua a simulação com uma linha de '''run''' que seja suficiente para variar todos os estímulos e obter os resultados: | |||
run XXX ps ou | |||
run XXX ns|us|ms|sec|min|hr | |||
*Para visualizar todo o período de tempo simulado inclua o seguinte comando no script | |||
wave zoom full | |||
*Ao final crie o arquivo FFD_N.qar que deve conter além dos arquivos de projeto, também os dois scripts de simulação. Use o Quartus para incluir esses arquivos e gerar o qar. Confira o seu conteúdo no arquivo FFD_N.qarlog | |||
<pre> | |||
=========== Files Selected: =========== | |||
/home/moecke/ELD2/2025.1/AULA7/FFD_N.qpf | |||
/home/moecke/ELD2/2025.1/AULA7/FFD_N.qsf | |||
/home/moecke/ELD2/2025.1/AULA7/FFD_N.vhd | |||
/home/moecke/ELD2/2025.1/AULA7/simulation/modelsim/tb_FFD_v2_melhor.do | |||
/home/moecke/ELD2/2025.1/AULA7/simulation/modelsim/tb_FFD_v_ruim.do | |||
/opt/intelFPGA/20.1/quartus/linux64/assignment_defaults.qdf | |||
======= Total: 6 files to archive ======= | |||
</pre> | |||
{{fig|5. | ;Encontro 8(10 abr.): | ||
*[https://drive.google.com/file/d/1O7zeVBDCJ_qKp6QTugiO0ax7N3nzGVjP/view?usp=drive_link Projeto de Circuitos Sequenciais: Princípios] Slides do prof. Roberto de Matos | |||
;Circuito síncrono vs assíncrono: | |||
Tipo de Circuito Características | |||
*Síncrono: Usa flip-flops com um clock global comum. Estados mudam apenas na borda do clock. | |||
*GALS (Globally Asynchronous, Locally Synchronous): Módulos internos síncronos com seus próprios clocks, mas sem sincronismo global. Comunicação entre módulos requer cuidados especiais. | |||
*Assíncrono: Não utiliza clock. As transições de estado dependem apenas das mudanças nas entradas e no tempo de propagação dos sinais. Difícil de projetar corretamente. | |||
*Circuito globalmente síncrono: todos os elementos de memória (D FFs) controlados (sincronizados) por um sinal de clock global comum. | |||
*Circuito globalmente assíncrono, mas localmente síncrono (GALS). | |||
*Circuito globalmente assíncrono: Usa DFF, mas não um clock global. Não usa sinal de clock. | |||
Um dos aspectos de projeto mais difíceis de um circuito sequencial é satisfazer as restrições (constraints) de tempo (ex.: Tsetup e Thold). No MÉTODO SÍNCRONO, todos os DFFs utilizam em um único clock. Assim apenas é necessário lidar com a restrição de tempo de um elemento de memória. | |||
;Circuito Sequencial Síncrono - Diagrama Conceitual: | |||
{{fig|5.21|Diagrama conceitual de circuitos síncronos | Concept_RT.png | 600 px | <ref name="CHU2006"> CHU, P. P. '''RTL Hardware Design Using VHDL: Coding for Efficiency, Portability, and Scalability'''. 1a ed. [S.l]:Wiley-IEEE Press, 2006. 694p. ISBN 9780471720928.</ref> }} | |||
*'''External Input''': Entradas externas fornecem os sinais que afetam a transição entre estados. | |||
* | *'''Next-State Logic''' (lógica de próximo estado): Circuito combinacional que determina qual será o próximo estado (state_next) com base no estado atual (state_reg) e nas entradas externas. | ||
:- | *'''State Register''' (registrador de estado): Elemento de memória (Flip-Flop tipo D) que armazena o estado atual. Ele captura o valor de state_next na borda ativa do sinal de clock (clk). | ||
: | * '''Output Logic''' (lógica de saída): Circuito combinacional que gera as saídas do sistema com base no estado atual. Pode ou não depender das entradas (Moore vs Mealy): | ||
: | :*'''Moore''': Saída depende apenas do estado. | ||
:*'''Mealy''': Saída depende do estado e das entradas. | |||
:Funcionamento - Fluxo de dados: | |||
*O sinal de clock (clk) sincroniza todas as mudanças de estado. | |||
*O registrador atualiza seu valor na borda do clock, armazenando o ''state_next'' calculado anteriormente. | |||
*A lógica combinacional (tanto de próximo estado quanto de saída) opera continuamente, processando entradas e o estado atual. | |||
*O sistema avança de estado apenas no clock, garantindo que as transições ocorrem de forma ordenada e previsível. | |||
* Glitches não tem efeitos na saída, desde que o ''state_next'' esteja estável quando ocorre a borda de subida do clock, e ''Tsetup'' e ''Thold'' sejam respeitados. | |||
;Encontro | ;Encontro 9 (15 abr.): | ||
*Contador | *[https://drive.google.com/file/d/1O7zeVBDCJ_qKp6QTugiO0ax7N3nzGVjP/view?usp=drive_link Projeto de Circuitos Sequenciais: Princípios] Slides do prof. Roberto de Matos | ||
: | *Contador binário livre com pulso de máximo | ||
: | :*Código com 2 segmentos: 1) parte sequencial (apena atualiza o r_reg) 2) parte combinatória (cálcula o r_next) | ||
*Contador | :*Código com 1 segmento: todo o código fica em um único process. | ||
*Contador decimal (mod-10) | |||
: | *Analisar a diferença entre utilizar signal e variable. O signal é atualizado apenas ao final do process (end process), enquanto que a variable é atualizada imediatamente. Essa diferença pode gerar códigos que não fazem exatamente o que desejamos. | ||
* | ;DOIS segmentos vs. UM segmento: | ||
: ( | *Código de dois segmentos | ||
: | :*Separa o segmento de memória do resto do código; | ||
* | :*Pode ser um pouco complicado (lógica separada); | ||
: | :*Tem um mapeamento claro para o componente de hardware. | ||
: | *Código de um segmento | ||
: | :*Mistura o segmento de memória e lógica de próximo estado/lógica de saída; | ||
:*Em alguns casos pode ser mais compacto; | |||
:*Mapeamento de hardware não é claro; | |||
:*'''Propenso a erros'''. | |||
No exemplo do contador binário livre com pulso de máximo é possível perceber um dos tipos de erros que o uso de código em um segmento pode gerar. Como cada atribuição feita a um sinal dentro do '''if rising_edge(clk) then''', gera um flip-flop para a saida '''max_pulse''', e pode causar atrasos indesejados em sinais. | |||
<syntaxhighlight lang=vhdl> | |||
architecture extra_ff_max_pulse of binary_counter4_pulse is | |||
signal r_reg: unsigned(3 downto 0); | |||
begin | |||
process(clk,reset) | |||
begin | |||
if (reset='1') then | |||
r_reg <= (others=>'0'); | |||
elsif rising_edge(clk) then | |||
r_reg <= r_reg + 1; | |||
if r_reg="1111" then | |||
max_pulse <= '1'; | |||
else | |||
max_pulse <= '0'; | |||
end if; | |||
end if; | |||
end process; | |||
q <= std_logic_vector(r_reg); | |||
end architecture; | |||
</syntaxhighlight> | |||
{{fig|5.22|Diagrama RTL contador com max_pulse output | max_pulse_RTL.png | 600 px | }} | |||
{{fig|5.22|Diagrama RTL contador com extra flip-flop in max_pulse output | FF_max_pulse_RTL.png | 600 px | }} | |||
{{fig|5.23|Simulação do extra flip-flop in max_pulse output - errado| FF_max_pulse_SIM.png | 600 px | }} | |||
{{fig|5.24|Simulação do max_pulse output - correto | max_pulse_SIM.png | 600 px | }} | |||
No exemplo do contador decimal (mod-10) é possível perceber um outro tipo de erros que o uso de código em um segmento pode gerar. | |||
Como um '''sinal (signal) é atualizado apenas no final do processo''', isso pode levar a códigos com erro como mostrado no exemplo a seguir. | |||
; | <syntaxhighlight lang=vhdl> | ||
architecture one_seg_arch_signal of mod10_counter is | |||
constant TEN: integer := 10; | |||
; | signal r_reg: unsigned(3 downto 0); | ||
begin | |||
-- register | |||
process(clk,reset) | |||
begin | |||
if (reset='1') then | |||
r_reg <= (others => '0'); | |||
elsif rising_edge(clk) then | |||
r_reg <= r_reg + 1; | |||
if r_reg=TEN then | |||
r_reg <= (others => '0'); | |||
end if; | |||
end if; | |||
end process; | |||
-- output logic | |||
q <= std_logic_vector(r_reg); | |||
end architecture; | |||
</syntaxhighlight> | |||
Na comparação '''r_reg=TEN''', espera-se que o r_reg tenha sido incrementado ('''r_reg <= r_reg + 1'''), mas o valor de r_reg ainda é o valor que tinha ao entrar no process. Assim o contador acaba contando de 0 a 10 e não de 0 a 9. | |||
<syntaxhighlight lang=vhdl> | <syntaxhighlight lang=vhdl> | ||
architecture one_seg_arch_variable of mod10_counter is | |||
</syntaxhighlight> | constant TEN: integer := 10; | ||
begin | |||
-- register | |||
process(clk,reset) | |||
variable r_reg: unsigned(3 downto 0); | |||
begin | |||
if (reset='1') then | |||
r_reg := (others => '0'); | |||
elsif rising_edge(clk) then | |||
r_reg := r_reg + 1; | |||
if r_reg = TEN then | |||
r_reg := (others => '0'); | |||
end if; | |||
end if; | |||
-- output logic | |||
q <= std_logic_vector(r_reg); | |||
end process; | |||
end architecture; | |||
</syntaxhighlight> | |||
A solução acima utiliza '''variable''' no lugar de '''signal''' para o r_reg. Neste caso a comparação '''r_reg = TEN''' irá comparar corretamente o valor atual de r_reg já incrementado ('''r_reg := r_reg + 1'''), e a contagem será correta de 0 a 9. | |||
; | ;Para o próximo encontro: | ||
*Implementar um contador BCD que efetue a contagem de 000 a 999. O contador deve ter uma entrada de '''enable''' que habilita a contagem, além das entradas de '''reset''' (assincrono) e '''clock'''. O contador deve ter 3 saídas de 4 bits '''std_logic_vector(3 downto 0)''', uma para '''unidade''', uma para '''dezena''' e outra para a '''centena'''. | |||
*O código deverá ser implementado em 2 segmentos separados. Um contendo apenas a parte sequencial ('''state register'''), e outro contendo a parte combinacional. A parte combinacional deve ter a '''next state logic''' e em separado a '''output logic'''. | |||
*Implementar um contador | *Exemplo do que pode ter no state register: | ||
* | <syntaxhighlight lang=vhdl> | ||
--> | -- state register | ||
process(clock,reset) | |||
begin | |||
if (reset='1') then | |||
centena_reg <= (others=>'0'); | |||
dezena_reg <= (others=>'0'); | |||
unidade_reg <= (others=>'0'); | |||
elsif rising_edge(clock) then | |||
centena_reg <= centena_next; | |||
dezena_reg <= dezena_next; | |||
unidade_reg <= unidade_next; | |||
end if; | |||
end process; | |||
</syntaxhighlight> | |||
= | ;Encontro 10 (17 abr.): | ||
*[https://drive.google.com/file/d/1O7zeVBDCJ_qKp6QTugiO0ax7N3nzGVjP/view?usp=drive_link Projeto de Circuitos Sequenciais: Princípios] Slides do prof. Roberto de Matos | |||
*Variações do contador BCD | |||
=== | :*Em 2 segmentos com WHEN ELSE | ||
:*Em 2 segmentos com IFs aninhados | |||
*Registrador de Deslocamento | |||
Abaixo estão três formas distintas de implementar um registrador de deslocamento, todas com a mesma funcionalidade, mas com diferenças na legibilidade, generalização e estilo de codificação: | |||
* | :*Usando operador de concatenação: | ||
<syntaxhighlight lang=vhdl> | |||
r_next <= d & r_reg(3 downto 1); | |||
q <= r_reg(0); | |||
</syntaxhighlight> | |||
Essa abordagem é compacta e permite facilmente estender o registrador para um número genérico de bits. | |||
:* Atribuições bit a bit (sem laço): | |||
<syntaxhighlight lang=vhdl> | |||
r_next(3) <= d; | |||
r_next(2) <= r_reg(3); | |||
r_next(1) <= r_reg(2); | |||
r_next(0) <= r_reg(1); | |||
q <= r_reg(0); | |||
</syntaxhighlight> | |||
Apesar de ser explícita e didática, essa forma não é escalável, pois exige reescrever todas as atribuições para cada nova largura de registrador. | |||
:*Atribuições bit a bit com '''for generate''': | |||
<syntaxhighlight lang=vhdl> | <syntaxhighlight lang=vhdl> | ||
r_next(3) <= d; | |||
l1: for i in 2 downto 0 generate | |||
r_next(i) <= r_reg(i + 1); | |||
end generate; | |||
q <= r_reg(0); | |||
</syntaxhighlight> | |||
Esta versão combina clareza com generalização. Assim como a primeira, é facilmente adaptável para registradores de qualquer tamanho. | |||
'''Observação:''' A primeira e a terceira implementações são mais adequadas quando se deseja gerar registradores de deslocamento de largura genérica, facilitando a reutilização do código. Já a segunda, apesar de simples, não é prática para registros maiores, pois não é escalável. | |||
;Para o próximo encontro: | |||
*'''DESAFIO''': Desenvolver um contador genérico capaz de contar em BCD com qualquer número de dígitos. | |||
;Encontro 11 (22 abr.): | |||
:*Para replicar hardware várias vezes, utilize estruturas como: '''for generate''' ou '''for loop''' | |||
*Instrução Concorrente '''FOR-GENERATE''': | |||
<syntaxhighlight lang=vhdl> | |||
-- Note que neste caso o '''label''' é obrigatório | |||
label: FOR identificador IN faixa GENERATE | |||
[Parte_Declarativa | |||
BEGIN] | |||
afirmação_concorrente; | |||
afirmação_concorrente; | |||
... | |||
END GENERATE [label]; | |||
</syntaxhighlight> | |||
*Instrução Sequencial '''FOR-LOOP''': | |||
<syntaxhighlight lang=vhdl> | |||
[rótulo:] FOR identificador IN faixa LOOP | |||
afirmação_sequencial; | |||
afirmação_sequencial; | |||
... | |||
END LOOP [rótulo]; | |||
</syntaxhighlight> | |||
*Implementar um registrador com N FF_D usando a instrução '''FOR GENERATE'''. | |||
{{fig|5.8|Technology Map de Shift Register| shift_reg_TM.png| 800 px | }} | |||
{{fig|5.9|Simulação de Shift Register| shift_reg_SIM.png| 800 px | }} | |||
*Implementar uma porta or (and) ou xor de N entradas usando a instrução '''FOR GENERATE'''. | |||
Novas dicas para representar N dígitos BCD, cada um com 4 bits, será necessário criar um novo tipo de dado: | |||
<syntaxhighlight lang=vhdl> | |||
type bcd_digits is array (natural range <>) of unsigned(3 downto 0); | |||
signal bcd : bcd_digits(0 to N-1); | |||
</syntaxhighlight> | |||
:*Para utilizar esse tipo na declaração das portas (interface do componente), a declaração do tipo deve estar dentro de um pacote (package), e esse pacote deve ser importado no seu arquivo com: | |||
<syntaxhighlight lang=vhdl> | |||
library work; | |||
use work.nome_do_pacote.all; | |||
</syntaxhighlight> | |||
;Para o próximo encontro: | |||
*'''DESAFIO''': Desenvolver um contador genérico capaz de contar em BCD com qualquer número de dígitos. | |||
;Encontro 12 (24 abr.): | |||
*Temporizações de um Flip-Flop. | |||
:*atraso do clock para saída (Tcq) | |||
:*tempo de setup (T_{setup}) e tempo de hold (T_{hold}) | |||
{{fig|5.22|Temporizações de um Flip Flop | FF_timing.png | 600 px | <ref name="CHU2006"/> }} | |||
'''Nota:''' a violação do tempo de setup ou hold leva ao estado de meta-estabilidade, na qual a saída fica temporariamente em um valor indefenido. | |||
*Os circuitos devem ser projetos para serem globalmente síncronos. | |||
*Violação do tempo de Setup do FF e frequência máxima do circuito (Fmax). | |||
{{fig|5.23|Modelo de Circuito Sequencial | SequencialCktModel.png | 800 px | <ref name="CHU2006"/> }} | |||
{{fig|5.24|Tempo de Setup e Fmax | SetupxFmax.png | 1000 px | <ref name="CHU2006"/> }} | |||
{{fig|5.25|Equações do Tempo de Setup e Fmax (1/Tc(min)) | EquationSetupxFmax.png | 600 px | <ref name="CHU2006"/> }} | |||
{{fig|5.26|Equações do Tempo de Hold | EquationHold.png | 600 px | <ref name="CHU2006"/> }} | |||
{{fig|5.27|Atraso da saída | EquationOutputDelay.png | 600 px | <ref name="CHU2006"/> }} | |||
;Para o próximo encontro: | |||
*ver [[Restringir a frequencia máxima de clock no Quartus]] | |||
*Pensar em exemplos de contadores com projeto Sincrono. | |||
:*Contador de sequencia arbitraria (implementado com when else) | |||
:*Contador de livre com indicação de valor máximo. (implementado com incrementador) - Já feito | |||
:*Contador com opções de clear sincrono, load, e parada | |||
:*Contador de modulo 10 - Já feito | |||
:*Contador de modulo m (onde m é uma entrada). | |||
;Encontro 13 (29 abr.): | |||
Instruções do tipo '''LOOP''': LOOP incondicional, '''FOR-LOOP''', '''WHILE-LOOP''', '''NEXT''', '''EXIT''' | |||
*Instrução '''LOOP''' incondicional: | |||
<syntaxhighlight lang=vhdl> | <syntaxhighlight lang=vhdl> | ||
[rótulo:] LOOP | |||
afirmação_sequencial; | |||
afirmação_sequencial; | |||
... | |||
END LOOP [rótulo]; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
= | *Instrução '''WHILE-LOOP''': | ||
<syntaxhighlight lang=vhdl> | |||
; | [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]; | ||
</syntaxhighlight> | |||
*Instrução LOOP com '''EXIT''': | |||
<syntaxhighlight lang=vhdl> | |||
[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]; | |||
</syntaxhighlight> | |||
*Instrução LOOP com '''NEXT''': | |||
<syntaxhighlight lang=vhdl> | |||
[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]; | |||
</syntaxhighlight> | |||
== | *Instrução '''CASE''' | ||
<syntaxhighlight lang=vhdl> | |||
[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; | |||
</syntaxhighlight> | |||
;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. | |||
:* | |||
<syntaxhighlight lang=vhdl> | |||
entity leading_zeros is | |||
generic (N : natural := 8); | |||
port | |||
:1) | ( ________ : 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 _______; | |||
</syntaxhighlight> | |||
{{fig|5.15|Simulação do leading_zeros| SIM_LZ.png| 800 px | }} | |||
* 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. | ||
{{fig|5.16|Simulação do counting_zeros| SIM_CZ.png| 800 px | }} | |||
* | |||
; | *Ver pag. 161 a 164 de <ref name="PEDRONI2010b"/> | ||
* | |||
* | ;Encontro 14 (6 mai.): | ||
* | *Implemente o contador de sequencia arbitraria (implementado com when else) (ver Listing 8.11 - Arbitrar-sequence counter). | ||
*Implemente o contador com opções de clear sincrono, load, e parada (ver Listing 8.13 - Featured binary counter). | |||
*Implemente o contador de modulo m (onde m é uma entrada) (ver Listing 8.15 e 8.16 - Programmable mod-m counter). | |||
; | ;Encontro 15 (8 mai.): | ||
* | * Projetar um divisor de clock que dado um clock de entrada de fclk Hz, produza na saída um sinal de clock de f/N onde N é um número inteiro ('''div_clk''') | ||
* | <syntaxhighlight lang=vhdl> | ||
entity div_clk is | |||
port( | |||
clk: in std_logic; | |||
reset: in std_logic; | |||
clk_1ms: out std_logic; | |||
clk_10sec: out std_logic; | |||
clk_1sec: out std_logic | |||
); | |||
end entity; | |||
</syntaxhighlight> | |||
:* Utilize esse circuito para obter um clock de 1 Hz (1 sec) '''clk_1sec''' a partir do sinal de 50MHz existente no kit DE2-115. | |||
;Para o próximo encontro: | |||
*Completar o projeto do divisor de clock, acrescentando: | |||
:*Implemente uma segunda saída para um clock de 1kHz (1 ms) '''clk_1ms''' | |||
:*Implemente uma terceira saída para um clock de 0,1 Hz (10 sec) '''clk_10sec''' | |||
:* Configure o circuito no kit DE2-115 dispositivo '''EP4CE115F29C7''', usando 1 led para sinalizar cada um desses clocks gerados. | |||
::ver [[Preparando para gravar o circuito lógico no FPGA]] e [[Interfaces de entrada e saída da DE2-115]] | |||
<center> | |||
{| class="wikitable" style="text-align:center;" | |||
|- style="font-weight:bold; background-color:#c0c0c0;" | |||
! porta | |||
! pino | |||
! nome do sinal no kit | |||
|- | |||
| clk || Y2 || CLOCK_50 | |||
|- | |||
| reset || AB28 || SW[0] | |||
|- | |||
| clk_1sec || F17 || LEDG[8] | |||
|- | |||
| clk_10sec || E21 || LEDG[0] | |||
|- | |||
| clk_1ms || G19 || LEDR[0] | |||
|} | |||
</center> | |||
:* No laboratório siga os passos: [https://wiki.sj.ifsc.edu.br/index.php/Preparando_para_gravar_o_circuito_l%C3%B3gico_no_FPGA#Programando_o_FPGA_na_m%C3%A1quina_local_com_o_c%C3%B3digo_em_nuvem Programando o FPGA na máquina local com o código em nuvem] | |||
* | *Preparar o código dos seguintes circuitos: | ||
* | :*Contador de segundos e minutos com clock derivado (ver Listing 9.5) | ||
* | :*Contador de segundos e minutos síncrono (ver Listing 9.6) | ||
;Encontro 16 (13 mai.): | |||
*Fazer a compilação completa, simular e fazer o timing analysis dos seguintes circuitos: | |||
:*Contador de segundos e minutos com clock derivado (ver Listing 9.5) | |||
{{fig|3.17|Contador de segundos e minutos - clock derivado| contaSSMMclk.png| 600 px | <ref name="CHU2006"/> }} | |||
:*Contador de segundos e minutos síncrono (ver Listing 9.6) | |||
{{fig|3.18|Contador de segundos e minutos - clock síncrono | contaSSMMsync.png| 600 px | <ref name="CHU2006"/>}} | |||
; | ;Encontro 17(15 mai.): | ||
Comparar o desempenho Fmax, número de elementos lógicos, número de registradores, número de pinos dos seguintes contadores, considerando uma saída de N_bits. | |||
*Contador binario sequencial | |||
b_next <= b_reg+1; | |||
*1 | |||
== | *Contador Gray (só troca um bit por vez) [https://drive.google.com/file/d/1GTkw-JvBRljvfJJNOA_cGmZzWkKDhp8M/view?usp=drive_link L9.7 de <ref name="CHU2006"/>] | ||
:: ver [[Código Gray]] | |||
b <= g_reg xor ('0' & b(WIDTH-1 downto 1)); | |||
b1 <= b+1; | |||
g_next <= b1 xor ('0' & b1(WIDTH-1 downto 1)); | |||
= | *Contador em anel (desloca um padrão inicial) [https://drive.google.com/file/d/1KEswDlpNqbgROcsr4MMh4BCr2tmDB3-k/view?usp=drive_link L9.8 e 9.9 de <ref name="CHU2006"/>] | ||
r_next <= r_reg(0) & r_reg(WIDTH-1 downto 1); | |||
; | |||
; | *Contador Johnson (uso de um inversor na realimentação do contador em anel) | ||
* | r_next <= (not r_reg(0)) & r_reg(WIDTH-1 downto 1); | ||
: | *Contador LFSR (Linear Feedback Shift Register) [https://drive.google.com/file/d/1wjypyztGMxiUxsPNwZ8j-PQkTMwoyFu3/view?usp=drive_link L9.10 e 9.11 de <ref name="CHU2006"/>] | ||
:* | fb <= r_reg(1) xor r_reg(0); | ||
r_next <= fb & r_reg(3 downto 1); | |||
: | :* | ||
: | ;Para o próximo encontro | ||
:* | * Ver como se pode implementar um contador [https://en.wikipedia.org/wiki/Linear-feedback_shift_register LFSR] de n bits. | ||
* Consultar [https://users.ece.cmu.edu/~koopman/lfsr/] ou a página 5 de [https://docs.amd.com/v/u/en-US/xapp052] para obter os termos que são usados na realimentação. | |||
* | |||
;Encontro 18(20 mai.): | |||
*'''Circuito de PWM''' (''Pulse Width Modulation'' - Modulação por largura de pulso) [https://drive.google.com/file/d/1FLvKLrSAZs9HQkz-QxkB3rsDHyGryf1-/view?usp=drive_link L9.14 de <ref name="CHU2006"/>]. | |||
:*Em algumas aplicações ao invés de usar diretamente a contagem, se usa o estado do contador para geram sinais de saída. Um exemplo é um circuito de modulação por largura de pulso (PWM), que gera um pulso de saída com um ciclo de trabalho ajustável. | |||
:*Por exemplo, em um circuito PWM que tem 16 passos, o ciclo de trabalho pode ser ajustado em incrementos de 1/16, ou seja, o ciclo de trabalho pode ser 1/16, 2/16, 3/16, ..., até 16/16. Este circuito pode ser implementado por um contador mod-16 com um circuito de saída especial, que define o valor da saída em alto de acordo com o valor da contagem. O período dos pulsos de saída neste caso sempre será de 16 vezes o período do relógio. | |||
:* | :*Note que uma expressão booleana adicional, w="0000", é incluída para acomodar a condição especial. | ||
<syntaxhighlight lang=vhdl> | |||
:* | buf_next <= '1' when (r_reg<unsigned(w)) or (w="0000") else '0'; | ||
:* | </syntaxhighlight> | ||
: | {{fig|5.X|RTL do circuito de PWM| PWM_RTL.png| 600 px | }} | ||
Na simulação abaixo, um clock de 50 ps foi utilizado, e o '''valor da entrada w''' foi definida como (3, 8, 0, 1, 15) a cada 1600 ps. Note que a largura do pulso da '''saída pwm_pulse''' está de acordo com aquela entrada. | |||
{{fig|5.X|Simulação do circuito de PWM| PWM_SIM.png| 1000 px | }} | |||
*Implementar um contador decrescente N até 0, com N ≠ 2^Mbits (5, 10) | |||
: | :*Com underflow no valor mínimo | ||
{{fig|5.13|Simulação do contador decrescente 5 a 0| Counter_5_0_SIM.png| 800 px | }} | |||
; | |||
*Implementar um contador decrescente com parada no valor mínimo | |||
{{fig|5.14|Simulação do contador decrescente 5 a 0 com parada| Counter_5_0_SIM_stop.png| 800 px | }} | |||
#Use preferencialmente o [[Uso_do_Overleaf | Overleaf]] para gerar o relatório. Mas o uso de MS-Word, Libreoffice e Google Docs também é permitida. | |||
#A entrega será feita através do Moodle da disciplina. Observe o prazo de entrega. | *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). | ||
{{collapse bottom}} | :*'''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. | |||
===AE2 - Estudando uma FIFO=== | ;Encontro 19 (22 mai.): | ||
{{collapse top | expand=true | bg=lightyellow | AE2 - Estudando uma FIFO}} | *Instrução '''IF GENERATE''' | ||
<syntaxhighlight lang=vhdl> | |||
<generate_label>: | |||
if <condition> generate | |||
-- Concurrent Statement(s) | |||
end generate; | |||
</syntaxhighlight> | |||
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 escrito em segmento único e usando variável: | |||
<syntaxhighlight lang=vhdl> | |||
entity contador_up_down_if_generate is | |||
generic | |||
( | |||
MIN : natural := 3; | |||
MAX : natural := 21; | |||
UPDOWN : natural := 0 -- 0 => up; 1 => down | |||
); | |||
port | |||
( | |||
clk, rst : in std_logic; | |||
cnt_out : out integer range MIN to MAX -- Aqui deveria ser usado std_logic_vector | |||
); | |||
end entity; | |||
</syntaxhighlight> | |||
<syntaxhighlight lang=vhdl> | |||
architecture ifsc_v1 of contador_up_down_if_generate 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; | |||
cnt_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; | |||
cnt_out <= cnt; | |||
end process; | |||
end generate; | |||
end architecture; | |||
</syntaxhighlight> | |||
Agora analise o mesmo contador descrito em dois segmentos, parte sequencial e parte de logica de próximo estado: | |||
<syntaxhighlight lang=vhdl> | |||
architecture ifsc_v2 of contador_up_down_if_generate is | |||
signal reg_cnt, next_cnt : integer range MIN to MAX; | |||
begin | |||
-- Contagem crescente | |||
L1: if UPDOWN = 0 generate | |||
-- Segmento sequencial | |||
process (clk, rst) | |||
begin | |||
if rst = '1' then | |||
reg_cnt <= MIN; | |||
elsif rising_edge(clk) then | |||
reg_cnt <= next_cnt; | |||
end if; | |||
end process; | |||
-- Segmento de próximo estado | |||
next_cnt <= MIN when reg_cnt = MAX else reg_cnt + 1; | |||
end generate; | |||
-- Contagem decrescente | |||
L2: if UPDOWN = 1 generate | |||
-- Segmento sequencial | |||
process (clk, rst) | |||
begin | |||
if rst = '1' then | |||
reg_cnt <= MAX; | |||
elsif rising_edge(clk) then | |||
reg_cnt <= next_cnt; | |||
end if; | |||
end process; | |||
-- Segmento de próximo estado | |||
next_cnt <= MAX when reg_cnt = MIN else reg_cnt - 1; | |||
end generate; | |||
-- Código de saída | |||
cnt_out <= reg_cnt; | |||
end architecture; | |||
</syntaxhighlight> | |||
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. | |||
{{fig|5.20|Simulação do contador UPDOWN com 0 | MODELSIM_countUP.png | 800 px |}} | |||
{{fig|5.21|Simulação do contador UPDOWN com 1 | MODELSIM_countDOWN.png | 800 px |}} | |||
*Uso de duas architecture para obter a mesma opção do '''IF GENERATE''' | |||
<syntaxhighlight lang=vhdl> | |||
entity contador_up_down_two_arch is | |||
generic | |||
( | |||
MIN : natural := 3; | |||
MAX : natural := 21 | |||
); | |||
port | |||
( | |||
clk, rst : in std_logic; | |||
count_out : out integer range MIN to MAX | |||
); | |||
end entity; | |||
architecture arch_up of contador_up_down_two_arch is | |||
begin | |||
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 architecture; | |||
architecture arch_down of contador_up_down_two_arch is | |||
begin | |||
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 architecture; | |||
configuration ifsc_cfg of contador_up_down_2arch is | |||
-- for arch_up end for; | |||
for arch_down end for; | |||
end configuration; | |||
</syntaxhighlight> | |||
*Uso de uma porta de entrada UPDOWN fixada em '0' ou '1' para obter a mesma opção do '''IF GENERATE''' | |||
<syntaxhighlight lang=vhdl> | |||
entity contador_up_down_pin is | |||
generic | |||
( | |||
MIN : natural := 3; | |||
MAX : natural := 21 | |||
); | |||
port | |||
( | |||
clk, rst : in std_logic; | |||
UPDOWN : natural := 1; -- 0 => up; 1 => down | |||
count_out : out integer range MIN to MAX | |||
); | |||
end entity; | |||
architecture ifsc_v1 of contador_up_down_pin is | |||
signal cnt_down, cnt_up : integer range MIN to MAX; | |||
begin | |||
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; | |||
cnt_up <= cnt; | |||
end process; | |||
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; | |||
cnt_down <= cnt; | |||
end process; | |||
count_out <= cnt_up when UPDOWN = 1 else cnt_down; | |||
end architecture; | |||
</syntaxhighlight> | |||
;Encontro 20 (27 mai.): | |||
*Uso de componentes e instanciação de componentes. | |||
<blockquote style="background: lightblue; border: 3px solid black; padding: 1em;"> | |||
Nesta parte da materia, o aluno deverá aprender a perguntar para uma ferramente de IA (e.g. ChatGPT) sobre um conteúdo específico formulando perguntas que conduzam a resposta e detalhamento desejado. De acordo com as respostas as perguntas precisam ser adaptadas. As respostas precisam ser avaliadas, pois podem conter erros graves. Exemplo de ordem de perguntas: | |||
:1) Como é feita a instanciação de componentes em VHDL? | |||
:2) Como devem ser os arquivos da entidade e do top level? | |||
:3) Quais tipos de instanciação existem? Além dessa instanciação nominal, também existe a posicional, podes explicar e exemplificar os dois casos? | |||
:4) O que devo fazer se não for utilizada uma porta de entrada ou de saída na instanciação de um componente? | |||
</blockquote> | |||
{{collapse top | expand=true | Resposta do ChatGPT}} | |||
A instanciação de componentes em VHDL é o processo de incluir e conectar componentes em um design hierárquico. Isso permite que você reutilize módulos já implementados em diferentes partes do projeto. O processo de instanciação segue algumas etapas, conforme descrito abaixo: | |||
; Declaração do componente: | |||
Antes de usar um componente em uma arquitetura, ele precisa ser declarado no escopo da arquitetura (a menos que você esteja usando bibliotecas com pacotes, onde a declaração pode ser omitida). A declaração define os sinais de entrada e saída do componente. | |||
component_declaration ::= | |||
component identifier [ is ] | |||
[ generic_clause ] | |||
[ port_clause ] | |||
end component [ identifier ] ; | |||
Exemplo de declaração do componente: | |||
<syntaxhighlight lang=vhdl> | |||
component MeuComponente is | |||
generic ( | |||
WIDTH : natural := 4 | |||
) | |||
port ( | |||
clk : in std_logic; | |||
reset : in std_logic; | |||
data : in std_logic_vector(7 downto 0); | |||
valid : out std_logic | |||
); | |||
end component; | |||
</syntaxhighlight> | |||
;Instanciação do componente: | |||
Após declarar o componente, ele pode ser instanciado dentro do corpo da arquitetura. Na instanciação, você define um "rótulo" (um nome para a instância) e conecta as portas do componente aos sinais locais do módulo que o utiliza. Existem duas formas principais de conectar as portas durante a instanciação: | |||
Conexão posicional: As portas são conectadas pela ordem em que aparecem no port map. Deve-se garantir que a ordem dos sinais corresponda à ordem definida no componente. | |||
Exemplo: | |||
<syntaxhighlight lang=vhdl> | |||
Instancia2: MeuComponente | |||
generic map ( | |||
8 | |||
) | |||
port map ( | |||
clk_signal, | |||
reset_signal, | |||
input_data, | |||
output_valid | |||
); | |||
</syntaxhighlight> | |||
Conexão nomeada: As portas são conectadas explicitamente pelo nome, o que é mais claro e menos propenso a erros. Este é o método preferido, especialmente em designs complexos. | |||
<syntaxhighlight lang=vhdl> | |||
Instancia1: MeuComponente | |||
generic map ( | |||
WIDTH => 8 | |||
) | |||
port map ( | |||
clk => clk_signal, | |||
reset => reset_signal, | |||
data => input_data, | |||
valid => output_valid | |||
); | |||
</syntaxhighlight> | |||
No exemplo acima | |||
*'''Instancia1''' é o rótulo da instância. | |||
*'''clk, reset, data,''' e '''valid''' são os nomes das portas do componente. | |||
*'''clk_signal, reset_signal, input_data''', e '''output_valid''' são os sinais do módulo que está utilizando o componente. | |||
Em VHDL, os arquivos da entidade (componente) e do top level (nível superior do design) seguem uma estrutura organizada para garantir a modularidade, reutilização de código e facilidade de manutenção. Abaixo está uma explicação de como estruturar esses arquivos corretamente. | |||
;Arquivo da Entidade (Componente): | |||
Um arquivo que define uma entidade (componente) deve conter: | |||
*A declaração da entidade, que define as entradas e saídas do módulo. | |||
*A arquitetura, que contém a lógica do componente (ou uma descrição de como ele é implementado). | |||
Exemplo de Arquivo para o Componente: | |||
<syntaxhighlight lang=vhdl> | |||
-- Arquivo: MeuComponente.vhd | |||
library IEEE; | |||
use IEEE.STD_LOGIC_1164.ALL; | |||
-- Declaração da entidade | |||
entity MeuComponente is | |||
port ( | |||
clk : in std_logic; | |||
reset : in std_logic; | |||
data : in std_logic_vector(7 downto 0); | |||
valid : out std_logic | |||
); | |||
end MeuComponente; | |||
-- Declaração da arquitetura | |||
architecture Behavioral of MeuComponente is | |||
begin | |||
-- Implementação da lógica do componente | |||
process(clk, reset) | |||
begin | |||
if reset = '1' then | |||
valid <= '0'; | |||
elsif rising_edge(clk) then | |||
if data = "11111111" then | |||
valid <= '1'; | |||
else | |||
valid <= '0'; | |||
end if; | |||
end if; | |||
end process; | |||
end Behavioral; | |||
</syntaxhighlight> | |||
Neste exemplo: | |||
*Entidade: Define as portas (clk, reset, data, valid). | |||
*Arquitetura: Implementa a lógica funcional do componente. | |||
;Arquivo do Top Level: | |||
O arquivo do Top Level é responsável por integrar e conectar os componentes em um design hierárquico. Ele também define as entradas e saídas globais do sistema e instancia os componentes (como o MeuComponente no exemplo). | |||
Exemplo de Arquivo Top Level: | |||
<syntaxhighlight lang=vhdl> | |||
-- Arquivo: TopLevel.vhd | |||
library IEEE; | |||
use IEEE.STD_LOGIC_1164.ALL; | |||
-- Declaração da entidade do Top Level | |||
entity TopLevel is | |||
port ( | |||
clk : in std_logic; | |||
reset : in std_logic; | |||
data : in std_logic_vector(7 downto 0); | |||
valid : out std_logic | |||
); | |||
end TopLevel; | |||
-- Declaração da arquitetura do Top Level | |||
architecture Structural of TopLevel is | |||
-- Sinais internos para conexão | |||
signal clk_signal : std_logic; | |||
signal reset_signal : std_logic; | |||
signal input_data : std_logic_vector(7 downto 0); | |||
signal output_valid : std_logic; | |||
-- Declaração do componente | |||
component MeuComponente is | |||
port ( | |||
clk : in std_logic; | |||
reset : in std_logic; | |||
data : in std_logic_vector(7 downto 0); | |||
valid : out std_logic | |||
); | |||
end component; | |||
begin | |||
-- Conectando sinais externos aos sinais internos | |||
clk_signal <= clk; | |||
reset_signal <= reset; | |||
input_data <= data; | |||
-- Instanciação do componente | |||
Instancia1: MeuComponente | |||
port map ( | |||
clk => clk_signal, | |||
reset => reset_signal, | |||
data => input_data, | |||
valid => output_valid | |||
); | |||
-- Conectando o sinal interno à saída global | |||
valid <= output_valid; | |||
end Structural; | |||
</syntaxhighlight> | |||
Neste exemplo: | |||
*O Top Level possui sua própria entidade e arquitetura. | |||
*Ele instancia o componente MeuComponente e conecta os sinais externos (entradas e saídas globais) aos sinais internos que se conectam ao componente. | |||
;Organização dos Arquivos: | |||
Nomeação dos Arquivos: | |||
*O nome do arquivo deve corresponder ao nome da entidade definida dentro dele. | |||
*Por exemplo: | |||
:*Para a entidade MeuComponente, o arquivo deve ser MeuComponente.vhd. | |||
:*Para a entidade TopLevel, o arquivo deve ser TopLevel.vhd. | |||
Separação de Arquivos: | |||
*Cada entidade e arquitetura deve estar em um arquivo separado. | |||
*Isso facilita a reutilização e a organização, especialmente em projetos maiores. | |||
Hierarquia: | |||
*O Top Level deve ser o ponto de entrada do design. Ele referencia (ou instancia) os componentes. | |||
;Como Compilar e Simular: | |||
Para que os arquivos funcionem juntos, siga estas etapas: | |||
Compilação: | |||
*Compile primeiro os arquivos dos componentes, como MeuComponente.vhd. | |||
*Depois, compile o arquivo do Top Level, que depende dos componentes. | |||
Simulação: | |||
*Simule o arquivo do Top Level, pois ele integra todos os componentes. | |||
*Use um banco de testes (testbench) conectado ao Top Level para verificar o comportamento geral. | |||
Ferramentas de Desenvolvimento: | |||
*Use ferramentas como ModelSim, Quartus, Xilinx Vivado ou GHDL para compilar, simular e sintetizar os arquivos. | |||
Quando uma porta de entrada ou saída de um componente não é utilizada durante a instanciação em VHDL, você deve explicitamente informar isso no momento da conexão com o port map. Isso garante que o design seja claro e sem erros de compilação, já que todas as portas devem ser conectadas (mesmo que não sejam usadas). | |||
A forma de lidar com isso depende se a porta é de entrada ou saída: | |||
;Para uma Porta de Entrada Não Utilizada | |||
As portas de entrada devem receber um valor, mesmo que não sejam usadas na lógica. Nesse caso, você pode: | |||
Você pode conectar a porta a um literal (como '0', '1' ou "000..."). | |||
Exemplo: | |||
<syntaxhighlight lang=vhdl> | |||
Instancia1: MeuComponente | |||
port map ( | |||
clk => clk, | |||
reset => reset, | |||
data => (others => '0'), -- Porta de entrada não utilizada | |||
valid => valid_signal | |||
); | |||
</syntaxhighlight> | |||
No exemplo acima, a entrada data foi conectada a (others => '0'), indicando que todos os bits do vetor serão definidos como 0. | |||
;Para uma Porta de Saída Não Utilizada: | |||
As portas de saída não precisam ser conectadas diretamente a nada, mas é necessário indicar explicitamente que você está ignorando a saída. Para isso, você pode usar a palavra-chave '''open'''. | |||
Exemplo: | |||
<syntaxhighlight lang=vhdl> | |||
Instancia3: MeuComponente | |||
port map ( | |||
clk => clk, | |||
reset => reset, | |||
data => data_signal, | |||
valid => open -- Porta de saída não utilizada | |||
); | |||
</syntaxhighlight> | |||
O '''open''' informa que a saída valid não será usada e evita que o compilador gere erros. | |||
{{collapse bottom}} | |||
Ao fazer as mesmas perguntas para a mesma IA, as respostas podem ser diferentes. Por isso, todas respostas de IA deve passar por um processo de curadoria por humanos. | |||
;Encontro 21 a 23 (29 mai. a 05 jun.): Timer de segundos, com mostrador SSD | |||
*Utilize como componente o contador BCD 00-99 já foi construido em aula anterior ('''contaBCD.vhd'''). Será necessário acrescentar um sinal de enable ao contador, também assegure-se que seja possível configurar a contagem de 00 até NN. Através do IF GENERATE disponibilize um contador que faça o overflow, e outro que pare ao chegar ao final da contagem. Também inclua uma entrada ZERAR, e outra de CONTAR, que tem a função dada pelo nome. | |||
*Utilize como componente o divisor de clock para gerar um sinal de enable para o contador a cada segundo ('''div_clk.vhd'''). | |||
*Projete um componente para converter de BCD para SSD - display de sete segmentos ('''bcd2ssd.vhd'''). Esse conversor deve ter uma entrada que permite escolher se o mostrador é do tipo anodo comum ou catodo comum, utilizando a instrução IF GENERATE. Para possibilitar mostrar ou não o zero, deve haver uma entrada que ao ser ativada fará com que o número zero não seja mostrada no mostrador. | |||
*Crie um projeto top_level no qual existem 4 instancias. 2 instancias do componente '''bcd2ssd.vhd''' uma em cada saída do contaBCD.vhd, o qual deverá contar apenas de 00 a 59 e reiniciar a contagem. Utilize o componente div_clk.vhd para habilitar o contaBCD.vhd. | |||
*Faça a simulação de cada um dos componentes e simule o timer completo. | |||
*Escolha um dos kits disponíveis no lab e implemente o projeto. Em seguida configure o circuito para ser implementado nos 2 mostradores (HEX0, HEX1). | |||
:1) Verifique se o mostrador do seu kit é do tipo anodo comum ou catodo comum. | |||
:2) Confira quais os clocks estão disponíveis no kit. | |||
:3) Defina quais serão as chaves de controle do timer. CONTAR, ZERAR, RESET | |||
:4) A entrada que permite esconder o zero deve ser configurada de modo que a primeira instância mostre o número zero, enquanto a segunda instância ocultará o zero. | |||
<syntaxhighlight lang=vhdl> | |||
entity timer_seg is | |||
generic (DEZENA : natural :=5; UNIDADE : natural := 9; FCLK := 5); -- para simulaçao | |||
port ( | |||
CLK50MHZ, RESET : in std_logic; | |||
CONTAR : std_logic; | |||
ZERAR : std_logic; | |||
LED_SEG : out std_logic; | |||
SSD_DEZENA : out std_logic_vector(6 downto 0); | |||
SSD_UNIDADE : out std_logic_vector(6 downto 0); | |||
); | |||
end entity; | |||
architecture ifsc of top_level is | |||
begin | |||
end architecture; | |||
</syntaxhighlight> | |||
{{fig|5.17|RTL timer_sec | RTL_timer_sec.png| 800 px |}} | |||
A seguir o resultado da simulação do '''timer_sec''' de segundos desde 00 até 59 segundos. No próximo segundo é feito o overflow, retornando a 00. O teste da entrada '''CONTAR''' é feito mantendo ela ativa inicialmente, e desativando-a entre 7,5 e 12,3 segundos, o que para a contagem. Para testar a entrada '''ZERAR''', ela é atividada no segundo 86,3, zerando o contador na próxima borda do clock. A contagem reinicia em 87 segundos quando o sinal ZERAR é desativado. O sinal '''RESET''' é apenas usado no início da simulação para inicializar os registradores. | |||
{{fig|5.18|Simulação do timer_sec | SIM_timer_sec.png| 800 px |}} | |||
{{fig|5.19|Simulação do div_clk | SIM_div_clk.png| 800 px |}} | |||
{{fig|5.20|Simulação do conta_bcd| SIM_conta_bcd.png| 800 px |}} | |||
{{fig|5.21|Simulação do bcd2ssd (Catodo Comum)| SIM_bcd2ssdCC.png| 800 px |}} | |||
{{fig|5.22|Simulação do bcd2ssd (Anodo Comum)| SIM_bcd2ssdAC.png| 800 px |}} | |||
*Ver funcionamento do [[Display de 7 segmentos]] | |||
--> | |||
<!-- | |||
;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. | |||
::<math> s_k = a_k \oplus b_k \oplus c_k </math> | |||
::<math> c_{k+1} = a_k . b_k + a_k . c_k + b_k . c_k </math> | |||
:: onde <math> c_{k+1} </math> é o '''carry out''', <math> c_{k} </math> é 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. | |||
<syntaxhighlight lang=vhdl> | |||
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; | |||
</syntaxhighlight> | |||
{{fig|5.17|RTL do carry_ripple_adder de 3 bits | RTL_carry_ripple_adder3.png| 800 px |}} | |||
--> | |||
<!-- | |||
;Encontro 17 (12 nov.): | |||
* Uso de type para definir novos tipos de dados. Exemplo de integer_vector | |||
*Instrução '''WAIT''': WAIT UNTIL, WAIT FOR (simulação apenas), WAIT ON (não implementada no Quartus II). | |||
<syntaxhighlight lang=vhdl> | |||
[rótulo:] WAIT UNTIL <condition>; | |||
[rótulo:] WAIT ON sensitivity_list; | |||
[rótulo:] WAIT FOR time_expression; | |||
</syntaxhighlight> | |||
: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. | |||
{{fig|5.18|RTL do contador BCD 00 a 99 | RTL_countBCD00-99.png| 800 px |}} | |||
{{fig|5.19|Simulação do contador BCD 00 a 99 | MODELSIM_countBCD00-99.png| 800 px |}} | |||
;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. | |||
;Encontro 19 e 20 (19 e 21 nov.): | |||
;Encontro 21 (26 nov.): | |||
* Projetar um divisor de clock que dado um clock de entrada de f Hz, produza na saída um sinal de clock de f/N onde N é um número inteiro ('''div_clk_N''') | |||
:* Utilize esse circuito para obter um clock de 1 Hz a partir do sinal de 50MHz existente no kit DE2-115. | |||
:* Utilize um segundo circuito para obter um clock de 0,1 Hz | |||
:* Teste o circuito no kit DE2-115. | |||
;Encontro 22 (28 nov.): | |||
;Encontro 24 e 25 (5 e 10 dez.) | |||
*Implementação de um relógio HHMMSS usando os componentes desenvolvidos nas aulas anteriores. | |||
*[https://wiki.sj.ifsc.edu.br/index.php/ELD129003-Engtelecom_(Di%C3%A1rio)_-_Prof._Marcos_Moecke#AE2_-_Laborat.C3.B3rio_de_programa.C3.A7.C3.A3o_de_FPGA_-_Rel.C3.B3gio_HHMMSS AE2 - Laboratório de programação de FPGA - Relógio HHMMSS] | |||
*Análise da necessidade de utilizar um sinal de ENABLE para ativar os contadores de SS MM e HH no lugar de gerar o clock pelo circuito anterior. | |||
;Encontro 26 (12 dez.) | |||
* Testes finais do relógio HHMMSS (se todos alunos estiverem com simulações feitas e pinagem pronta). | |||
* Implementação da função de LOAD para definir os valores iniciais da HH, MM e SS no relógio. | |||
:*Sugestão utilizar 4 chaves para definir o valor em binário da unidade, outras 4 chaves para definir a dezena, e por último 1 chave para carregar a hora, 1 para o minuto e 1 para o segundo. É fundamental que a chave stop esteja funcionando para permitir iniciar o relógio no momento exato. | |||
:* Ajustar pelo [https://www.horariodebrasilia.org/ Horário de Brasilia] | |||
;Encontro 27 e 28 (17 e 19 dez.) | |||
* Registradores como armazenamento temporário | |||
--> | |||
{{collapse bottom}} | |||
===Unidade 4 - Maquinas de Estado Finitas=== | |||
* 5 ENCONTROS | |||
{{collapse top | expand=true | Unidade 4 - Maquinas de Estado Finitas}} | |||
<!-- | |||
;Encontro 26 (12 jun.) | |||
* O que é uma FSM - Finite State Machine | |||
{{fig|4.1|Exemplo de diagrama de estados de uma FSM Fig4.1(a) e implementação em hardware da FSM Fig4.2(a)|Fig11_1_FSM.png|800 px|Figura 11.1 e 11.2 de <ref name="PEDRONI2010b"/>}} | |||
* Modelo básico em VHDL de FSM | |||
<syntaxhighlight lang=vhdl> | |||
LIBRARY ieee; | |||
USE ieee.std_logic_1164.ALL; | |||
---------------------------------------------------------- | |||
ENTITY < entity_name > IS | |||
PORT ( | |||
clk, rst : IN STD_LOGIC; | |||
entradas : IN < data_type > ; | |||
saidas : OUT < data_type >); | |||
END entity; | |||
---------------------------------------------------------- | |||
ARCHITECTURE < architecture_name > OF < entity_name > IS | |||
TYPE state IS (A, B, C, ...); | |||
SIGNAL pr_state, nx_state : state; | |||
-- ATTRIBUTE ENUM_ENCODING : STRING; --optional attribute | |||
-- ATTRIBUTE ENUM_ENCODING OF state : TYPE IS "sequential"; | |||
-- ATTRIBUTE SYN_ENCODING OF state : TYPE IS "safe"; | |||
BEGIN | |||
------Logica Sequencial da FSM:------------ | |||
PROCESS (clk, rst) | |||
BEGIN | |||
IF (rst = '1') THEN | |||
pr_state <= A; | |||
ELSIF rising_edge(clk) THEN | |||
-- apenas na borda do "clk" ocorre a mudança de estado da FSM | |||
pr_state <= nx_state; | |||
END IF; | |||
END PROCESS; | |||
------Logica Combinacional da FSM:------------ | |||
PROCESS (pr_state, entradas) | |||
BEGIN | |||
------Valores default das saidas------------ | |||
saidas <= < valor > ; | |||
CASE pr_state IS | |||
WHEN A => | |||
-- é necessário um WHEN para definir as "saidas" durante cada estado | |||
-- e analisar as "entradas" para definir o próximo estado | |||
saidas <= < valor > ; -- apenas se diferente do valor default | |||
IF (entradas = < valor >) THEN | |||
nx_state <= B; | |||
... | |||
ELSE | |||
nx_state <= A; | |||
END IF; | |||
WHEN B => | |||
saidas <= < valor > ; -- apenas se diferente do valor default | |||
-- dependendo das "entradas", pode ser que hajam mais de um estados de destino | |||
IF (entradas = < valor >) THEN | |||
nx_state <= C; | |||
ELSIF (entradas = < valor >) THEN | |||
nx_state <= A; | |||
ELSE | |||
nx_state <= B; | |||
END IF; | |||
WHEN C => | |||
saidas <= < valor > ; -- apenas se diferente do valor default | |||
-- a passagem para outro estado pode não depender de nenhuma "entrada" | |||
nx_state <= D; | |||
WHEN ... | |||
END CASE; | |||
END PROCESS; | |||
------Seção de Saída (opcional):------- | |||
-- Essa seção visa garantir que a saida new_output esteja sincronizada com o clk. | |||
-- Se isso não for importante, ela pode ser suprimida | |||
PROCESS (clk, rst) | |||
BEGIN | |||
IF (rst = '1') THEN | |||
new_output <= < valor > ; | |||
ELSIF rising_edge(clk) THEN --or falling_edge(clk) | |||
new_output <= output; | |||
END IF; | |||
END PROCESS; | |||
END architecture; | |||
</syntaxhighlight> | |||
;Dica: Se ao discrever uma FSM, faltar algum estado, o Quartus dará erro durante a compilação. Para resolver temporariamente isso pode se usar antes de encerrar o case | |||
<syntaxhighlight lang=vhdl> | |||
WHEN others => | |||
nx_state <= <initial_state>; | |||
</syntaxhighlight> | |||
:* Usando o template acima descreva em VHDL a FSM indicada na Figura 11.1. | |||
:* Faça a simulação da FSM com Modelsim utilizando um testbench em VHDL que faça a FSM seguir os estados | |||
<center> | |||
<math> RST \to A \xrightarrow{\text{x=0}} A \xrightarrow{\text{x=1}} A \xrightarrow{\text{x=2}} B \xrightarrow{\text{x=2}} B \xrightarrow{\text{x=0}} C \xrightarrow{\text{x=0}} C \xrightarrow{\text{x=2}} C \xrightarrow{\text{x=1}} A \xrightarrow{\text{x=2}} B \xrightarrow{\text{x=1}} A </math> | |||
</center> | |||
:: Ver pag. 277 a 280 de <ref name="PEDRONI2010b"/> | |||
:: Note que o uso da atribuição manual do '''enum_encoding''' pode faz com que o compilador do Quartus não reconheça a FSM, mas use logica regular para representar o sistema. | |||
;Encontro 27 (12 jun.) | |||
* AE16 - Controlador de Semáforo de duas vias - trabalho remoto na nuvem | |||
;Encontro 28 (17 jun.) | |||
* AE16 - Controlador de Semáforo de duas vias | |||
:*Use o template da FSM para modelar o controlador semafórico da figurar a seguir. | |||
{{fig|4.2|FSM - Controlador semafórico para duas vias (diagrama de estados)|FSM_Sema2Vias.png|800 px| }} | |||
;Encontro 29 (24 jun.) | |||
* Diagrama de blocos de uma FSM completa. Diferença entre saída Moore e saída Mealy. | |||
:No diagrama abaixo, uma FSM (''Finite State Machine'') é modelada através dos seus componentes básicos: | |||
:* '''Entradas''' - são os sinais que fazem a FSM evoluir para os próximos estados. | |||
:* '''Clock''': o clock (relógio) é o sinal que sincroniza as transições entre os estados. A mudança sempre ocorre na transição (borda) desse sinal. | |||
:* '''Lógica do Próximo Estado''': é um circuito combinacional que Determina o próximo estado com base no estado atual e nas entradas. | |||
:* '''Registrador de Estado''': Armazena o estado atual | |||
:* '''Lógica de Saída Moore''': Gera a saída apenas com base no estado atual. | |||
:* '''Lógica de Saída Mealy''': Gera a saída com base no estado atual e na entrada. | |||
{{fig|4.3|Diagrama de blocos de um FSM|BlockDiagramFSM.png|1000 px|}} | |||
* Modelagem de FSM com Diagrama de Estados e ASM (''Algorithmic State Machine''). | |||
{{fig|4.4|Blocos de um diagrama ASM |ASM_Block.png|600 px|Figure 10.4 de <ref name="CHU2006" />}} | |||
*Exemplo da modelagem de um controlador de memória com modo de leitura '''BURST'''. | |||
{{fig|4.5|Diagrama de estados de um controlador de memória|Mem_ctrl_SD.png|400 px|Figure 10.3 de <ref name="CHU2006"/>}} | |||
{{fig|4.6|ASM de um controlador de memória|Mem_ctrl_ASM.png|400 px|Figure 10.9 <ref name="CHU2006"/>}} | |||
* A partir da descrição da FSM em diagrama de estados ou na forma ASM, é possível implementar essa FSM em VHDL. No código a seguir, é feita a descrição da FSM usando um código em dois segmentos, no qual o primeiro PROCESS realiza a atualização do Registrador de Estado, e o segundo PROCESS realiza a Lógica do Próximo Estado, Lógicas de Saída Moore e a Lógica de Saída Mealy. | |||
<syntaxhighlight lang=vhdl> | |||
library ieee; | |||
use ieee.std_logic_1164.all; | |||
entity mem_ctrl is | |||
port ( | |||
clk : in std_logic; | |||
reset : in std_logic; | |||
mem, rw, burst : in std_logic; | |||
oe, we, we_me : out std_logic | |||
); | |||
end entity; | |||
architecture two_seg_arch2 of mem_ctrl is | |||
type mc_state_type is | |||
(idle, read1, read2, read3, read4, write1); | |||
signal state_reg, state_next : mc_state_type; | |||
begin | |||
process (clk, reset) | |||
begin | |||
if (reset = '1') then | |||
state_reg <= idle; | |||
elsif rising_edge(clk) then | |||
state_reg <= state_next; | |||
end if; | |||
end process; | |||
process (state_reg, mem, rw, burst) | |||
begin | |||
oe <= '0'; | |||
we <= '0'; | |||
we_me <= '0'; | |||
case state_reg is | |||
when idle => | |||
if mem = '1' then | |||
if rw = '1' then | |||
state_next <= read1; | |||
else | |||
we_me <= '1'; | |||
state_next <= write1; | |||
end if; | |||
else | |||
state_next <= idle; | |||
end if; | |||
when write1 => | |||
we <= '1'; | |||
state_next <= idle; | |||
when read1 => | |||
oe <= '1'; | |||
if (burst = '1') then | |||
state_next <= read2; | |||
else | |||
state_next <= idle; | |||
end if; | |||
when read2 => | |||
oe <= '1'; | |||
state_next <= read3; | |||
when read3 => | |||
oe <= '1'; | |||
state_next <= read4; | |||
when read4 => | |||
oe <= '1'; | |||
state_next <= idle; | |||
end case; | |||
end process; | |||
end architecture; | |||
</syntaxhighlight> | |||
Fonte: adaptado <ref name="CHU2006"/>. | |||
{{fig|4.7|RTL do controlador de memória|Mem_ctrl_RTL.png|600 px| Quartus Light}} | |||
{{fig|4.8|FSM do controlador de memória|Mem_ctrl_FSM.png|1000 px| Quartus Light}} | |||
* Simulação do controlador de memória. | |||
Na figura abaixo a FSM modelada tem duas saídas Moore ("oe" e "we"), e uma saída Mealy ("we_me"). Note que as saídas do tipo Moore sempre tem a duração de um período de clock, e elas não dependem diretamente de nenhuma entrada, mas são consequência do estado em que se encontra a FSM. No caso da saída Mealy, as entradas afeta diretamente a saída, conforme se pode ver os gliches da entrada "mem" são transmitidas para a saída "we_me". | |||
{{fig|4.9|Simulação do controlador de memoria - diferença entre a saída Moore e saída Mealy|FSM_Moore_Mealy_SIM.png|1000 px|}} | |||
{{fig|4.10|Simulação de escritas, leituras simples e leitura em burst no controlador de memoria |FSM_Mem_SIM.png|1000 px|}} | |||
;Encontro 30 (26 jun.) | |||
*Circuito detector de borda | |||
{{fig|4.11|Diagram de estados do detector de borda - implementação com saídas Moore|SD_edge_detector_moore.png|200 px| Fonte: <ref name="CHU2006"/>}} | |||
<syntaxhighlight lang=vhdl> | |||
library ieee; | |||
use ieee.std_logic_1164.all; | |||
entity edge_detector1 is | |||
port( | |||
clk, reset: in std_logic; | |||
strobe: in std_logic; | |||
p1: out std_logic | |||
); | |||
end edge_detector1; | |||
architecture moore_arch of edge_detector1 is | |||
type state_type is (zero, up, one); | |||
signal state_reg, state_next: state_type; | |||
begin | |||
-- state register | |||
process(clk,reset) | |||
begin | |||
if (reset='1') then | |||
state_reg <= zero; | |||
elsif (clk'event and clk='1') then | |||
state_reg <= state_next; | |||
end if; | |||
end process; | |||
-- next-state logic | |||
process(state_reg,strobe) | |||
begin | |||
case state_reg is | |||
when zero=> | |||
if strobe= '1' then | |||
state_next <= up; | |||
else | |||
state_next <= zero; | |||
end if; | |||
when up=> | |||
if strobe= '1' then | |||
state_next <= one; | |||
else | |||
state_next <= zero; | |||
end if; | |||
when one => | |||
if strobe= '1' then | |||
state_next <= one; | |||
else | |||
state_next <= zero; | |||
end if; | |||
end case; | |||
end process; | |||
-- Moore output logic | |||
p1 <= '1' when state_reg=up else | |||
'0'; | |||
end moore_arch; | |||
</syntaxhighlight> | |||
Fonte: <ref name="CHU2006"/>. | |||
{{fig|4.12|Simulação do detector de borda - implementação com saídas Moore|FSM_edge_detector_moore.png|1000 px|}} | |||
Ao simular o detector de borda, percebe-se que o primeiro pulso (entre 140 e 180 ps) não foi detectado, pois não durou tempo suficiente para ter o estado atualizado no próximo clock. Isso ocorre pois na saída tipo Moore, as mudanças das saídas só acontecem sincronizadas com o clock. Note ainda que os pulsos em p1 tem a duração exata de um período de clock. | |||
{{fig|4.13|Diagram de estados do detector de borda - implementação com saídas Mealy|SD_edge_detector_mealy.png|200 px| Fonte: <ref name="CHU2006"/>}} | |||
<syntaxhighlight lang=vhdl> | |||
library ieee; | |||
use ieee.std_logic_1164.all; | |||
entity edge_detector2 is | |||
port( | |||
clk, reset: in std_logic; | |||
strobe: in std_logic; | |||
p2: out std_logic | |||
); | |||
end edge_detector2; | |||
architecture mealy_arch of edge_detector2 is | |||
type state_type is (zero, one); | |||
signal state_reg, state_next: state_type; | |||
begin | |||
-- state register | |||
process(clk,reset) | |||
begin | |||
if (reset='1') then | |||
state_reg <= zero; | |||
elsif (clk'event and clk='1') then | |||
state_reg <= state_next; | |||
end if; | |||
end process; | |||
-- next-state logic | |||
process(state_reg,strobe) | |||
begin | |||
case state_reg is | |||
when zero=> | |||
if strobe= '1' then | |||
state_next <= one; | |||
else | |||
state_next <= zero; | |||
end if; | |||
when one => | |||
if strobe= '1' then | |||
state_next <= one; | |||
else | |||
state_next <= zero; | |||
end if; | |||
end case; | |||
end process; | |||
-- Mealy output logic | |||
p2 <= '1' when (state_reg=zero) and (strobe='1') else | |||
'0'; | |||
end mealy_arch; | |||
</syntaxhighlight> | |||
Fonte: <ref name="CHU2006"/>. | |||
{{fig|4.14|Simulação do detector de borda - implementação com saídas Mealy |FSM_edge_detector_mealy.png|1000 px|}} | |||
Ao simular o detector de borda, percebe-se que o primeiro pulso (entre 140 e 180 ps) agora foi detectado. Isso ocorre pois na saída tipo Mealy, as mudanças das saídas dependem do estado atual e da entrada, e por isso não são sincronizadas com o clock. Note que agora os pulsos em p1 tem duração variável, e menor que um período de clock. | |||
;DESAFIO1: | |||
*Descreva o diagrama de estados abaixo em VHDL, e simule o detector de borda. Note que agora os pulsos em p1 tem duração variável, mas todos terão duração um pouco maior que um período de clock. | |||
;DESAFIO2: | |||
*Descreva os 3 diagramas de estado dos detectores de borda usando ASM. | |||
{{fig|4.15|Diagram de estados do detector de borda - implementação com saídas Mealy melhorado|SD_edge_detector_mealy2.png|200 px| Fonte: <ref name="CHU2006"/>}} | |||
--> | |||
<!-- | |||
;Encontro reserva | |||
:* Máquina de vendas | |||
::*Use o template da FSM para modelar o sistema mostrado na figurar a seguir. | |||
{{fig|7.2|FSM - Máquina de vendas (diagrama de estados)|FSM_MVD.png|800 px|Adaptado da Figura 11.3 de <ref name="PEDRONI2010b"/> }} | |||
{{fig|7.3|FSM - Máquina de vendas (diagrama de estados com default |FSM_MVD_default.png|800 px|}} | |||
::*Simule a FSM com Modelsim utilizando um testbench em VHDL para gerar o teste mostrado na figura abaixo. | |||
{{fig|7.4|FSM - Máquina de vendas (simulação)|FSM_tb40.png|800 px|}} | |||
:* Exercício: Altere a FSM para vender doces que custam 30 centavos. Considere que as moedas aceitas são 5, 10, 25 e 50 centavos. Desenho primeiro a FSM e em seguida implemente-a em VHDL e faça a simulação. | |||
:: Ver pag. 281 a 282 de <ref name="PEDRONI2010b"/> | |||
:: '''Dica''': para desenhar a FSM recomendo utilizar um software on-line para tal finalidade. Por Ex. [https://online.visual-paradigm.com/pt/ Visual Paradigm]. | |||
;DESAFIO: | |||
*Implementar um controlador para máquina de Lavar Roupas baseado na FSM abaixo. | |||
{{fig|7.4|FSM da Máquina de Lavar Roupas |FSM_LavaRoupas.png|1200 px|}} | |||
;PARA A PRÓXIMA AULA: | |||
* Implementação em VHDL da FSM de máquina de Lavar Roupas | |||
* Simulação em ModelSim da FSM de máquina de Lavar Roupas | |||
--> | |||
{{collapse bottom}} | |||
===Unidade 5 - Metodologia RT (Register Transfer)=== | |||
* 7 ENCONTROS | |||
{{collapse top | expand=true | Unidade 5 - Metodologia RT (Register Transfer)}} | |||
<!-- | |||
A fonte principal dessa unidade é o capítulo 11 e 12 do livro "RTL Hardware Design Using VHDL: Coding for Efficiency, Portability, and Scalability, P. P. Chu." <ref name="CHU2006"/> É recomendado que os alunos leiam estes capítulos e usem como fonte de consulta. | |||
;Encontro 31 (1 jul.) | |||
:* Um algoritmo é uma sequência detalhada de ações ou passos para realizar uma tarefa ou resolver um problema. Como a semântica das linguagens de programação tradicionais também se baseia na execução sequencial, um algoritmo pode ser facilmente convertido em um programa utilizando as construções dessas linguagens. O programa, então, é compilado em instruções de máquina e executado em um computador de uso geral. | |||
*Exemplo de '''algoritmo que soma de 4 números''' e divide o resultado por 8. | |||
<pre> | |||
# entrada a(0), a(1), a(2) e a(3) | |||
# saída out_q | |||
size = 4 | |||
sum = 0; | |||
for i in (0 to size - 1) do { | |||
sum = sum + a(i); | |||
} | |||
q = sum / 8; | |||
r = sum rem 8; | |||
if (r > 3) { | |||
q = q + 1; | |||
} | |||
out_q = q; | |||
</pre> | |||
O algoritmo primeiro soma os elementos individuais e armazena o resultado em uma variável chamada sum. Em seguida, usa as operações de divisão (/) e de resto (rem) para encontrar o quociente e o resto. Se o resto for maior que 3, adiciona-se 1 extra ao quociente para realizar o arredondamento. | |||
*Uma variável em um algoritmo ou pseudocódigo pode ser interpretada como uma "localização de memória com um endereço simbólico" (ou seja, o nome da variável). Ela é usada para armazenar um resultado intermediário de um cálculo. Por exemplo, na segunda instrução, o valor 0 é armazenado na localização de memória com o endereço simbólico sum. Dentro do laço for, o valor a(i) é somado ao conteúdo atual de sum, e o resultado da soma é armazenado de volta na mesma localização. Na quarta instrução, o conteúdo de sum é dividido por 8 e o resultado é armazenado em uma localização de memória com um endereço simbólico. | |||
*A execução de um algoritmo é realizada de forma sequencial, e a ordem dos passos é importante. Por exemplo, a soma dos elementos precisa ser feita antes que a operação de divisão possa ser executada. Note que a ordem de execução pode depender de certas condições, como nos comandos for e if. | |||
*O algoritmo poderia ser descrito na forma estrutural baseada em fluxo de dados usando VHDL desenrolando o laço do algoritmo e converter as variáveis em sinais de conexão internos. Suponha que sum seja um sinal de 8 bits. Além disso a divisão por 8 pode ser implementado através de uma rotação a direita de 3 posições, sendo o resto os bits que foram rotacionados (2 downto 0). | |||
<pre> | |||
sum(0) <= a(0); | |||
sum(1) <= sum(0) + a(1); | |||
sum(2) <= sum(1) + a(2); | |||
sum(3) <= sum(2) + a(3); | |||
q <= "000" & sum(3)(7 downto 3); | |||
r <= "00000" & sum(3)(2 downto 0); | |||
out_q <= q + 1 when (r > 3) else q; | |||
</pre> | |||
* A implementação estrutural baseada em fluxo de dados não é geral e só pode ser aplicada a algoritmos simples e triviais. | |||
* As duas variações a seguir do algoritmo anterior ilustram a limitação dessa abordagem. | |||
:* Em primeiro, vamos considerar um vetor com 10 elementos. No pseudocódigo, isso pode ser feito substituindo o número 4 por 10 na primeira instrução. Isso aumenta o número de iterações do laço. Podemos desenrolar o laço (loop unrolling) e derivar a implementação estrutural baseada em fluxo de dados, o que exigiria nove somadores. Se o número de elementos do vetor continuar a crescer, o '''número de somadores aumentará''' proporcionalmente. Claramente, essa abordagem exige recursos de hardware excessivos e não é prática para um vetor maior. | |||
:*Em segundo lugar, vamos supor que o '''tamanho do vetor não seja fixo''', mas seja '''especificado por uma entrada adicional, n'''. Para realizar isso no algoritmo, basta substituir o valor fixo na primeira instrução por n, ou seja, fazer size = n. Isso será muito difícil de implementar com uma abordagem estrutural baseada em fluxo de dados. Como o hardware não pode se expandir ou encolher dinamicamente, seria necessário construir um circuito capaz de calcular os resultados para todos os possíveis valores de n e, em seguida, usar um multiplexador para direcionar o valor desejado para a saída. | |||
*A '''metodologia de transferência entre registradores''' ('''metodologia RT''') é voltada para possibilitar realizar algoritmos em hardware. | |||
As características principais dessa metodologia RT são: | |||
:* Usar '''registradores''' para armazenar os dados intermediários e imitar as variáveis utilizadas em um algoritmo; | |||
:* Usar um '''caminho de dados''' (datapath) personalizado para realizar todas as operações necessárias com os registradores; | |||
:* Usar um '''caminho de controle''' (control path) personalizado para especificar a ordem das operações nos registradores. | |||
*Quando um algoritmo é implementado usando a metodologia RT, a manipulação e o roteamento dos dados são realizados por hardware dedicado. O circuito de manipulação de dados, a rede de roteamento e os registradores, juntos, são conhecidos como o '''caminho de dados''' ('''data path'''). | |||
*Como um algoritmo é descrito como uma '''sequência de ações''', precisamos de um circuito que controle quando e quais operações de transferência entre registradores devem ocorrer. Esse circuito é conhecido como '''caminho de controle''' ('''control path'''). | |||
*Um '''caminho de controle''' pode ser '''implementado por uma máquina de estados finitos (FSM)''', que pode usar estados para impor a ordem dos passos desejados e caixas de decisão para imitar os desvios (branches) e iterações (laços) de um algoritmo. | |||
* Podemos usar uma máquina de estados finita estendida (FSM estendida) para descrever a operação geral do sistema. Ela é conhecida como '''FSM com caminho de dados''' ('''FSMD'''). | |||
* A principal diferença entre uma variável em um algoritmo e um registrador em um sistema com clock é que neste último as operações são feitas implicitamene como operações de transferência de registros (Operação básica de RT). Sua forma básica é: | |||
rdest ← f(rsrc1, rsrc2, ...); | |||
* A interpretação dessa operação é: | |||
:* Na borda de subida do clock, as saídas dos registradores '''rsrc1, rsrc2''', etc., ficam disponíveis; | |||
:* Essas saídas são enviadas para um circuito combinacional que executa a função '''f( )''' (por exemplo: soma, multiplicação, deslocamento, etc.); | |||
:* Na próxima borda de subida do clock, o resultado da operação é armazenado no registrador de destino '''rdest'''. | |||
*Ver slides do [https://drive.google.com/file/d/1-w9S39oHsx70K4Gom3i-y1WfQPyvv10d/view?usp=drive_link capítulo 11] (slide 1 a 30). | |||
*Visão geral do FSMD | |||
{{fig|5.1|Diagrama de blocos básico de uma FSMD |FSMD_block_diagram.png|500 px| <ref name="CHU2006"/>}} | |||
;Encontro 32 e 33 (3 e 8 jul.) - Multiplicador por adição repetitivas. | |||
''Nota: Este exemplo é apresentado no livro <ref name="CHU2006"/> na seção 11.3'' | |||
Considere um multiplicador como os dois operandos da multiplicação sendo '''a_in''' e '''b_in''', e a saída '''r_out''' onde todos os três sinais são do tipo UNSIGNED. Um algoritmo sequencial simples consiste em somar '''a_in''' repetidamente por'''b_in''' vezes. Por exemplo, 7×5 pode ser calculado como 7 + 7 + 7 + 7 + 7. Embora esse método não seja eficiente, ele é simples, e permite apreender a elaboração do diagrama ASMD e do hardware. | |||
;Pseudocódigo do algoritmo: | |||
Esse algoritmo pode ser representado pelo pseudocódigo: | |||
<pre> | |||
if (a_in = 0 or b_in = 0) then | |||
r_out = 0 | |||
else | |||
a = a_in | |||
n = b_in | |||
r = 0 | |||
while (n ≠ 0) | |||
r = r + a | |||
n = n - 1 | |||
r_out = r | |||
</pre> | |||
Como o diagrama ASMD não possui uma construção de laço (loop), mas usa uma caixa de decisão com uma condição booleana para escolher um entre dois caminhos de saída possíveis. Portanto é semelhante a uma combinação de '''if''' com instrução '''goto'''. O pseudocódigo revisado fica assim: | |||
<pre> | |||
if (a_in = 0 or b_in = 0) then | |||
r_out = 0 | |||
else | |||
a = a_in | |||
n = b_in | |||
r = 0 | |||
op: r = r + a | |||
n = n - 1 | |||
if (n = 0) then | |||
goto stop | |||
else | |||
goto op | |||
stop: r_out = r | |||
</pre> | |||
;ASMD do algoritmo: | |||
Observe na ASMD abaixo que os sinais '''start''' (início) e '''ready''' (pronto) foram adicionados para permitir a operação sequencial do sistema. Imaginando o multiplicador sequencial como parte de um sistema principal, quando ele deseja executar uma operação de multiplicação, primeiro verifica o sinal '''ready'''. Se estiver alto, coloca os dois operandos nas entradas de dados '''a_in''' e '''b_in''' e ativa o sinal '''start'''. Ao detectar o sinal start, o multiplicador sequencial captura os operandos e inicia o processamento. Após a conclusão do cálculo, o sinal ready é ativado para informar ao sistema principal que o resultado está disponível em '''r_out'''. | |||
O diagrama ASMD, mostrado na figura abaixo, segue de forma fiel o pseudoalgoritmo. Ele utiliza os registradores de dados '''n''', '''a''' e '''r''' para representar as três variáveis do algoritmo, emprega caixas de decisão para implementar as estruturas condicionais (if) e utiliza operações de transferência entre registradores (operações RT) para executar as instruções sequenciais. | |||
{{fig|5.2|Diagrama ASMD do algoritmo multiplicador L11.1 |ASMD_mult_sum.png|400 px| <ref name="CHU2006"/>}} | |||
;FSMD do algoritmo: | |||
;Construção do CONTROL PATH: | |||
A construção do '''caminho de controle''' (CONTROL PATH) (1 - next state logic), (2 - state reg) e (3 - output logic) é a mesma utilizada com a máquina de estados (FSM). Os sinais dentro da caixa de decisão são as entradas da FSM. No diagrama ASMD, as expressões booleanas utilizam quatro sinais: '''start''' (comando externo) e '''a_is_0''' (8), '''b_is_0'''(9) e '''count_0''' (10) ('''sinais de status''' internos, provenientes do caminho de dados). Eles são ativados quando as condições correspondentes são satisfeitas. Os sinais (8) e (9) são resultado direto da comparação das entradas a_in = 0 e 'b_in = 0. O sinal (10) por utilizar um sinal interno necessita utilizar a entrada do registrador '''n''' (n_next = 0). | |||
A saída do caminho de controle inclui o sinal externo de status '''ready''' (pronto) e os '''sinais de controle''' que especificam as operações de transferência entre registradores (operações RT) no '''caminho de dados'''. Neste exemplo, foi usada a saída do registrador de estado como sinal de controle ('''idle''', '''ab0''', '''load''', '''op'''), os quais controlam a seleção nos multiplexadores usados na rede de roteamento do caminho de dados. | |||
;Construção da DATA PATH: | |||
A construção do caminho de dados pode ser derivada de forma sistemática seguindo diretrizes simples: | |||
:1 - Liste todas as '''operações RT''' possíveis no diagrama ASMD, incluindo as operações RT padrão (default). | |||
:2 - Agrupe as operações RT de acordo com seus registradores de destino. | |||
:3 - Para cada grupo, derive o circuito seguindo o processo: | |||
::(a) Construa o registrador de destino. | |||
::(b) Construa os circuitos combinacionais envolvidos em cada operação RT. | |||
::(c) Adicione circuitos de multiplexação e roteamento se o registrador de destino estiver associado a múltiplas operações RT. | |||
:4 - Adicione os circuitos necessários para gerar os sinais de status. | |||
No exemplo da multiplicação por adição repetitiva as operações RT | |||
*com o registrador r: | |||
:r ← r (no estado idle) | |||
:r ← 0 (nos estados load e ab0) | |||
:r ← r + a (no estado op) | |||
*com o registrador n: | |||
:n ← n (no estado idle) | |||
:n ← b-in (nos estados load e ab0) | |||
:n ← n - 1 (no estado op) | |||
*com o registrador a: | |||
:a ← a (nos estados idle e op) | |||
:a ← a-in (nos estados load e ab0) | |||
{{fig|5.3|FSMD do algoritmo multiplicador L11.1 |FSMD_mult_sum.png|600 px| <ref name="CHU2006"/>}} | |||
;Melhoria da implementação do algoritmo com saída Mealy: | |||
Observando o ASMD acima, pode-se perceber que as saídas do estado ab0 e load são as mesmas, e portanto elas poderiam ser inseridas após a decisão '''start = 1''', como saídas Mealy. Essa modificação produz um novo ASMD para o mesmo algoritmo, que apenas tem 2 estados. | |||
{{fig|5.4|Diagrama ASMD do algoritmo multiplicador L11.6 (saída Mealy) | ASMDMealy_mult_sum.png|400 px| <ref name="CHU2006"/>}} | |||
*Testar as implementações em VHDL dos [https://drive.google.com/file/d/1f7DqWL9390nTGgXUVdd01CaSAJX-UxOC/view?usp=drive_link Listing 11.1 a L11.6] de <ref name="CHU2006"/>. | |||
;Encontro 34 (10 jul.) - Multiplicador por adição repetitivas. | |||
*Simulação essa FSMD, verificando o funcionamento da FSM através da simulação no MODELSIM. Teste com multiplicações por zero (0 x 31 = 0); (31 x 0 = 0), multiplicações menores (2 x 31 = 62); (31 x 2 = 62) e multiplicações maiores (9 x 31 = 279) (31 x 9 = 279). | |||
:*Anote a '''Fmax''' e meça o número de clocks ('''N_clk''') transcorrido entre duas bordas de subida do sinal '''READY'''. Dica use dois cursores para medir o tempo total , e divida pelo período do clock utilizado na simulação. | |||
:* Analise se ocorre alguma melhorias em termos de tempo de processamento ('''N_clk/Fmax''') e número de elementos lógicos nas versões L11.1 a L11.3, L11.5 e L11.6. Também verifique se o resultado está correto em todas as versões. | |||
<center> | |||
{| class="wikitable" style="text-align:center;" | |||
|- style="font-weight:bold;" | |||
! style="background-color:#c0c0c0;" | Listing 11. | |||
! colspan="2" style="background-color:#c0c0c0;" | 1 | |||
! colspan="2" style="background-color:#c0c0c0;" | 2 | |||
! colspan="2" style="background-color:#c0c0c0;" | 3 | |||
! colspan="2" style="background-color:#c0c0c0;" | 5 | |||
! colspan="2" style="background-color:#c0c0c0;" | 6 | |||
|- style="text-align:left;" | |||
| style="text-align:center;" | Fmax | |||
| colspan="2" | | |||
| colspan="2" | | |||
| colspan="2" | | |||
| colspan="2" | | |||
| colspan="2" | | |||
|- style="font-weight:bold; background-color:#c0c0c0;" | |||
| || Nclk || Top || Nclk || Top || Nclk || Top || Nclk || Top || Nclk || Top | |||
|- | |||
| 0x31 | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|- | |||
| 31x0 | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|- | |||
| 2x31 | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|- | |||
| 31x2 | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|- | |||
| 9x31 | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|- | |||
| 31x9 | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|} | |||
</center> | |||
;Encontro 35 a 37 (15 a 22 jul.) - Revisão de projeto hierárquico. | |||
* Implementar um controlador de semáforo construído com os seguintes componentes: 1 divisor de clock ('''div_clk'''), 1 temporizador de segundos com contagem crescente em BCD ('''timer_bcd'''), 2 conversores de BCD para SSD ('''bcd2ssd'''), uma FSM para semáforo de 2 vias ('''FSM_2vias'''). | |||
* Os componentes devem ser declarados como STUB, isto é a '''archicteture''' deve estar vazia. Isso facilita o entendimento do projeto hierárquico sem a ocorrência de erros internos nos componentes. | |||
* O desenvolvimento dos componentes pode ser postergado para uma segunda etapa do projeto. | |||
* Ao final da atividade os alunos devem enviar a [https://moodle.ifsc.edu.br/mod/assign/view.php?id=296897 AE17 - Controlador de Semáforo de duas vias (simulação de entrega)] | |||
{{fig|5.30|Diagrama de RTL do top level |RTL_TL.png|800 px| Igor & Ygor 2025}} | |||
--> | |||
<!-- | |||
;Encontro 35 (18 fev.) | |||
*Implementação de um multiplicador por deslocamento de bits e somas sequenciais | |||
*Implemente em VHDL o [https://drive.google.com/file/d/1f7DqWL9390nTGgXUVdd01CaSAJX-UxOC/view?usp=drive_link Listing 11.7 de <ref name="CHU2006"/>] | |||
{{fig|4.14|Diagrama ASMD do algoritmo multiplicador L11.7 e 11.8 |ASMD_mult_shift_sum.png|300 px| <ref name="CHU2006"/>}} | |||
*Análise de tempo e desempenho do FSMD | |||
*Implementação de um multiplicador por somas sucessivas em dataflow (a + a + a + ...) | |||
*Implementação de um multiplicador pelo bloco multiplicador (a x b) | |||
;Encontro 36 a 39 (20, 22, 25, 27 fev.) | |||
*Realização da [https://wiki.sj.ifsc.edu.br/index.php/ELD129003-Engtelecom_(Di%C3%A1rio)_-_Prof._Marcos_Moecke#AE4_-_Compara%C3%A7%C3%A3o_de_Hardware_projetado_por_FSMD_e_Dataflow AE4 - Comparação de Hardware projetado por FSMD e Dataflow] | |||
;Encontro 40 (6 mar.) | |||
*Atividade de recuperação para alunos com conceito inferior a 6. | |||
*Os demais alunos foram dispensados | |||
<!-- | |||
;Encontro 36 (20 ago.) | |||
*Circuito gerador de pulso (Implementação em lógica regular, em FSM, em FSMD) | |||
{{fig|4.14|Diagrama ASMD do algoritmo do gerador de pulso|ASMD_pulse_generator.png|600 px| <ref name="CHU2006"/>}} | |||
*Circuito para cálculo do máximo divisor comum (gcd) | |||
{{fig|4.15|Diagrama ASMD do algoritmo do GCD|ASMD_gcd.png|600 px| <ref name="CHU2006"/>}} | |||
;Encontro 37 (23 ago.) | |||
*Avaliação A2 | |||
Implemente o algoritmo original de Euclides usando a metodologia RT. | |||
Ver descrição em [https://seriouscomputerist.atariverse.com/media/pdf/book/Art%20of%20Computer%20Programming%20-%20Volume%202%20(Seminumerical%20Algorithms).pdf] . | |||
- GCD é descrito em 4.5.2. The Greatest Common Divisor), pag 346 do PDF | |||
- Algorithm E (Original Euclidean algorithm). pag 349 do PDF. | |||
- Apresente um relatório com a simulação mostrando como obteve o número de clocks necessários para realizar o cálculo, que inclua uma tabela comparando os algoritmos. | |||
- Obtenha os dados de numero de elementos lógicos, Tempo de cálculo, e compare com os dois algoritmos do gcd slow e fast. | |||
Enviar nesta tarefa os arquivos | |||
Q1.QAR, Q1-RTL.PNG, Q1-TM.PNG, Q1-SIM.PNG e o relatório | |||
Os arquivos tb_XXX.do e wave.do devem ser enviados dentro do QAR | |||
Pontuação | |||
*7 pontos - pelo relatório e projeto com os resultados dos algoritmos gcd slow e fast. | |||
*3 pontos - pelo relatório e projeto com os resultados do "Original Euclidean algorithm" em dataflow ou RT metodology | |||
--> | |||
{{collapse bottom}} | |||
==Avaliações== | |||
Durante o semestre serão realizadas 2 avaliações e várias atividades feitas extra classe. | |||
;Data das avaliações: | |||
*A1 : Avaliação A1 (peso 35) XX/2025 | |||
*A2 : Avaliação A2 (peso 45) XX/2025 | |||
*AEs : Média ponderada das AEs (peso 20) | |||
*R1 : Recuperação de A1 : XX/2025 | |||
*R2 : Recuperação de A2 : XX/2025 | |||
*[[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: | |||
* [[Restringir a frequencia máxima de clock no Quartus II]] | |||
* [[Como obter o Fmax do projeto no Quartus]] | |||
===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=== | |||
{{collapse top | expand=true| bg=lightyellow | AE1 - Conhecendo os dispositivos lógicos programáveis}} | |||
;Objetivos: | |||
*Conhecer o Quartus Prime e as características dos dispositivos lógicos programáveis | |||
*Analisar os tempos de propagação em um circuito combinacional | |||
*Alterar configurações do compilador | |||
*Fazer a simulação funcional e temporal de um circuito combinacional. | |||
;Atividades: | |||
*'''PASSO 1:''' Realize a atividade descrita em [[Conhecendo os dispositivos lógicos programáveis - QUARTUS PRIME]] | |||
:*Ao escolher a família de FPGAS, escolha inicialmente um dispositivo da família '''Max II'''. Anote o código ('''Name'''), tensão de alimentação no núcleo ('''Core Voltage'''), Número de elementos lógicos configuráveis ('''LEs''' ou '''ALMs''') desse dispositivo. | |||
:*Capture as telas solicitadas e depois utilize-as no relatório da atividade. | |||
:*Anote o tempo utilizado para cada uma das etapas do processo de compilação. | |||
:*Anote o número de '''elementos lógicos configuráveis''' utilizados e o número de pinos utilizados, bem com o percentual em relação ao número total do dispositivo. | |||
:*Anote algum erro ('''Error''') ou alertas ('''Warnings''') que o Quartus II indicar no painel de mensagens '''[Messages]''' | |||
:*Ao final salve o projeto em um arquivo QAR (sugestão PJ1.QAR) | |||
*'''PASSO 2''': Repita a atividade descrita em [[Conhecendo os dispositivos lógicos programáveis - QUARTUS PRIME]], trocando a família e dispositivo a ser usado na implementação. Escolha nesta vez um dispositivos da família '''Cyclone IV E''', '''Cyclone V''', '''Cyclone 10''' ou '''Arria 10'''. Anote o código ('''Name'''), tensão de alimentação no núcleo ('''Core Voltage'''), Número de elementos lógicos configuráveis ('''LEs''' ou '''ALMs''') desse dispositivo. | |||
:*Observe as mudanças que ocorrem tanto no tipo de elemento lógico configurável, no Chip Planner, no Pin Planner, e no circuito dos pinos de I/O. Note que estes FPGAs também apresenta novos componentes, tais como: Memória, Multiplicadores, DSP, PLL, DLL, etc. Verifique se consegue encontra-los no leiaute mostrado no Chip Planner, e documente aqueles que encontrar. | |||
:*Compare os resultados obtidos nos procedimentos do PASSO 1 e PASSO 2. | |||
*'''PASSO 3''': Realize o procedimento descrito em [[Medição de tempos de propagação em circuitos combinacionais - Quartus Prime]], com o circuito '''hamming_distance'''. | |||
:*Ao escolher a família de FPGAS, escolha um dispositivo FPGA da família '''Cyclone IV E'''. Anote o código ('''Name'''), tensão de alimentação no núcleo ('''Core Voltage'''), Número de elementos lógicos configuráveis ('''LEs''' ou '''ALMs''') desse dispositivo. | |||
:*Capture as telas mostradas no roteiro e depois utilize-as no relatório da atividade. | |||
:*Anote o máximo tempo de propagação entre entrada e saída. | |||
:*Anote o número de elementos lógicos utilizados e o número de pinos utilizados, bem com o percentual em relação ao número total do dispositivo. | |||
:*Experimente modificar as configurações do compilador, conforme mostrado em '''Configurando o compilador'''. Se desejar mude a semente inicial trocando o valor de '''[Seed: 1]''' | |||
:*Experimente inserir diferentes restrições de atraso máximo para o compilador, e analise o resultado obtido. | |||
:*Anote algum erro ('''Error''') ou alertas ('''Warnings''') que o Quartus II indicar no painel de mensagens '''[Messages]''' | |||
:*Ao final salve o projeto em um arquivo QAR (sugestão PJ2.QAR) | |||
*'''PASSO 4''': Realize a simulação funcional do circuito '''hamming_distance''' | |||
:*Capture as telas que mostram o circuito funcionando e depois utilize-as no relatório da atividade. | |||
;Entregas: | |||
#Envie um arquivo QAR contendo todos os arquivos necessário para compilar cada um dos projetos. | |||
#Envie um relatório em PDF, incluindo as imagens capturadas (inclua um título para cada figura) e escreva para cada imagem um texto comentando o que representa. O relatório também deve ter a identificação (autor, título, data) uma breve introdução e uma conclusão. A descrição dos procedimentos feita na página wiki não precisa incluída no relatório. | |||
#Use preferencialmente o [[Uso_do_Overleaf | Overleaf]] para gerar o relatório. Mas o uso de MS-Word, Libreoffice e Google Docs também é permitida. | |||
#A entrega será feita através do Moodle da disciplina. Observe o prazo de entrega. | |||
{{collapse bottom}} | |||
===AE2 - Contador BCD 000 a 999=== | |||
{{collapse top | expand=true| bg=lightyellow | AE2 - Contador BCD 000 a 999}} | |||
;Objetivos: | |||
*Construir um contador BCD de 000 a 999, utilizando um código de dois segmentos. | |||
:*o primeiro segmento contém apenas a parte sequencial | |||
:*o segundo segmento contém a parte combinatorial '''Next State Logic''' e lógica de saída | |||
*Analisar o desempenho de um circuito pelo Fmax. | |||
;Passo 1 - Projeto um contador BCD: | |||
*Projete um contador BCD que conte, Unidades, Dezenas, Centenas. | |||
<syntaxhighlight lang=vhdl> | |||
entity contador_bcd is | |||
Port ( clock : in std_logic; | |||
reset : std_logic; | |||
enable : std_logic; | |||
centena : out std_logic_vector(3 downto 0); | |||
dezena : out std_logic_vector(3 downto 0); | |||
unidade : out std_logic_vector(3 downto 0) | |||
); | |||
end entity; | |||
</syntaxhighlight> | |||
*Capture o diagrama RTL do contador. | |||
;Passo 2 - Realize a simulação funcional do circuito do contador BCD: | |||
*Faça a simulação do contador realizando a contagem de 0 a 999 e novamente até 999. Verifique se o contador retorna a zero após o overflow em 999. | |||
*Utilize como clock um sinal de 1 sec, e escolhe como escala de tempo o sec (segundo) no Wave do Modelsim. | |||
*Capture detalhes da simulação que mostram as contagem das Unidades, Dezenas, Centenas e também o Overflow. Use tantas capturas quantos achar necessário. | |||
;Passo 3 - Otimização de área e desempenho em Fmax | |||
*Use a família de FPGAS '''Cyclone IV E''', o dispositivo EP4CE6E22A7. Anote a tensão de alimentação no núcleo ('''Core Voltage'''), Número de elementos lógicos configuráveis ('''LEs''' ou '''ALMs''') desse dispositivo. | |||
* Utilize o procedimento descrito em [[Como obter o Fmax do projeto no Quartus]]. | |||
* Anote a Fmax do projeto (do modelo Slow 1200mV 125ºC), número de elementos lógicos utilizados e o número de pinos utilizados. | |||
* Utilize o procedimento indicado em [[Restringir a frequencia máxima de clock no Quartus]], modificando a frequencia do clock de modo a forçar o compilador a obter melhores resultados. | |||
* Anote a Fmax do projeto, número de elementos lógicos utilizados e o número de pinos utilizados. | |||
* Experimente modificar as configurações do compilador, conforme mostrado em '''Configurando o compilador'''. Se desejar mude a semente inicial trocando o valor de '''[Seed: 1]''' | |||
* Anote a Fmax do projeto, número de elementos lógicos utilizados e o número de pinos utilizados, e eventuais elementos DSPs utilizados. | |||
* Apresente os resultados obtidos em uma tabela única. | |||
;Entregas: | |||
#Envie um arquivo QAR contendo todos os arquivos necessário para compilar o projeto. | |||
#Envie um relatório em PDF, incluindo as imagens capturadas (inclua um título para cada figura) e escreva para cada imagem um texto comentando o que representa. O relatório também deve ter a identificação (autor, título, data) uma breve introdução e uma conclusão. A descrição dos procedimentos feita na página wiki não precisa incluída no relatório. | |||
#O relatório deve indicar os ajustes que foram feitos para obter a maior Fmax e o menor número de elementos lógicos. | |||
#Use preferencialmente o [[Uso_do_Overleaf | Overleaf]] para gerar o relatório. Mas o uso de MS-Word, Libreoffice e Google Docs também é permitida. | |||
#A entrega será feita através do Moodle da disciplina. Observe o prazo de entrega. | |||
;Bônus: | |||
*1 ponto na Avaliação A1 para o(a) estudante que apresentar o projeto que funcione com a maior Fmax. | |||
*0,5 ponto na Avaliação A1 para o(a) estudante que apresentar o projeto com o menor número de elementos lógicos. | |||
*0,5 ponto na Avaliação A1 para o(a) estudante que apresentar o projeto que funcione com o segundo maior Fmax. | |||
*0,3 ponto na Avaliação A1 para o(a) estudante que apresentar o projeto com o segundo menor número de elementos lógicos. | |||
:*Em caso de empate, o critério de desempate é a data de entrega | |||
:*Cada estudante pode receber no máximo 1 ponto na Avaliação A1 através da AE2. | |||
{{collapse bottom}} | |||
===AE3 - Contador BCD genérico === | |||
{{collapse top | expand=true| bg=lightyellow | AE3 - Contador BCD genérico}} | |||
;Objetivos: | |||
*Construir um contador BCD genérico, que permita definir qualquer número de dígitos BCD, desde 1 até N, utilizando um código de dois segmentos. | |||
:*o primeiro segmento contém apenas a parte sequencial | |||
:*o segundo segmento contém a parte combinatorial '''Next State Logic''' e lógica de saída | |||
*Criar tipos de dados e utiliza-los como portas da entity e sinais internos. | |||
*Utilizar estruturas de repetição de hardware. | |||
*Gerar e utilizar sinais de Enable para ativar os diversos contadores de 0 a 9. | |||
*Analisar o desempenho de um circuito pelo Fmax. | |||
;Passo 1 - Projeto um contador BCD genérico: | |||
*Projete um contador BCD genérico, que conte, Unidades, Dezenas, Centenas, Unidades de Milhar, Dezenas de Milhar, etc. conforme solicitado no parâmetro genérico N. | |||
*Obtenha um contador para 3 digitos BCD, e capture o diagrama RTL do contador. | |||
*Obtenha um contador para 6 digitos BCD, e capture o diagrama RTL do contador. | |||
;Passo 2 - Realize a simulação funcional do circuito do contador BCD genérico: | |||
*Faça a simulação do contador para N = 3 digitos BCD. Verifique se o contador retorna a zero após o overflow em 999. | |||
*Capture detalhes da simulação que mostram as contagem das Unidades, Dezenas, Centenas e também o Overflow. Use tantas capturas quantos achar necessário. | |||
;Passo 3 - Geração de um sinal de Enable a cada 1 ms. | |||
* Projete um circuito que gere um sinal de enable para o contador de miléssimo de segundo. O sinal de Enable deve durar exatamente o período do clock do kit a ser utilizado. | |||
* A geração do sinal de Enable só deve ocorrer se a entrada START estiver em 1. | |||
*Conecte esse circuito ao contador BCD com N = 5, sendo que os 2 digitos mais significativos devem contar os segundos, e os 3 dígitos menos significativos os milessimos de segundo. | |||
;Passo 4 - Implemente o contador com o divisor de clock no kit | |||
*Utilize o kit DE2-115 na implementação do contador de 0 a 99,999 sec. Ver [[Preparando para gravar o circuito lógico no FPGA]] | |||
*Ao escolher a família de FPGAS, escolha o dispositivo FPGA da família '''Cyclone IV E''' do kit e anote o código ('''Name'''), tensão de alimentação no núcleo ('''Core Voltage'''), Número de elementos lógicos configuráveis ('''LEs''' ou '''ALMs''') desse dispositivo. | |||
* Utilize o procedimento indicado em [[Restringir a frequencia máxima de clock no Quartus]], modificando a frequencia do clock de modo a definir o clock desejado como 50MHz, pois é o clock do kit a ser utilizado | |||
* Utilize o procedimento descrito em [[Como obter o Fmax do projeto no Quartus]] | |||
* Anote a Fmax do projeto, número de elementos lógicos utilizados e o número de pinos utilizados. | |||
* Verifique o funcionamento correto do contador comparando o tempo total da contagem 100 segundos com um cronometro (https://dollyclock.com/pt/stopwatch) | |||
;Dicas: | |||
*Para replicar um hardware N vezes vai precisar instruções como FOR GENERATE e FOR LOOP. | |||
*Para gerar N saída BCD com 4 bits para cada dígito, será necessário criar um novo tipo de dado. | |||
type bcd_digits is array (natural range <>) of unsigned(3 downto 0); | |||
signal bcd : bcd_digits(0 to N-1); | |||
*Para que um tipo seja conhecido na declaração das portas é necessario incluir essa declação do tipo em um pacote e incluir o pacote no arquivo. | |||
<syntaxhighlight lang=vhdl> | |||
-- FILE : ifsc_pkg.vhd | |||
library ieee; | |||
use ieee.std_logic_1164.all; | |||
use ieee.numeric_std.all; | |||
package ifsc_pkg is | |||
type bcd_digits is array (natural range <>) of unsigned(3 downto 0); | |||
end package; | |||
</syntaxhighlight> | |||
;Entregas: | |||
#Envie um arquivo QAR contendo todos os arquivos necessário para compilar o projeto. | |||
#Envie um relatório em PDF, incluindo as imagens capturadas (inclua um título para cada figura) e escreva para cada imagem um texto comentando o que representa. O relatório também deve ter a identificação (autor, título, data) uma breve introdução e uma conclusão. A descrição dos procedimentos feita na página wiki não precisa incluída no relatório. | |||
#Use preferencialmente o [[Uso_do_Overleaf | Overleaf]] para gerar o relatório. Mas o uso de MS-Word, Libreoffice e Google Docs também é permitida. | |||
#Grave um vídeo mostrando que o contador está funcionando de acordo com o cronometro, e disponibilize o link para o vídeo. | |||
#A entrega será feita através do Moodle da disciplina. Observe o prazo de entrega. | |||
{{collapse bottom}} | |||
===AE4 - Análise de contadores digitais === | |||
{{collapse top | expand=true| bg=lightyellow | AE4 - Análise de contadores digitais}} | |||
;Objetivos: | |||
*Implementar e simular diferentes tipos de contadores digitais: | |||
:*Contador binario sequencial; | |||
:*Contador Gray; | |||
:*Contador em anel; | |||
:*Contador Johnson e | |||
:*Contador LFSR. | |||
*Acrescentar um sinal de '''Enable''' em cada um dos contadores fornecidos em aula. | |||
*Todos os contadores devem ser implementados em 2 segmentos de código (parte sequencial e parte combinatória) | |||
*Analisar a influência do tipo de contador e número de bits sobre a área usada (número de elementos lógicos) e desempenho em velocidade (Fmax). | |||
;Divisão em equipes: | |||
*As equipes (ou estudante individual) deverão modificar os contadores vistos em aula para que fique com a seguinte quantidade de bits: | |||
<pre> | |||
E1 - 5 e 15 bits | |||
E2 - 6 e 14 bits | |||
E3 - 7 e 13 bits | |||
E4 - 8 e 18 bits | |||
E5 - 7 e 10 bits | |||
E6 - 8 e 17 bits | |||
I1 - 9 bits | |||
I2 - 11 bits | |||
I3 - 12 bits | |||
I4 - 16 bits | |||
I5 - 13 bits | |||
I6 - 14 bits | |||
I7 - 18 bits | |||
I8 - 19 bits | |||
I9 - 17 bits | |||
</pre> | |||
*Nos trabalhos individuais apenas um contador de cada tipo será implementado e simulado. | |||
*Nos trabalhos em equipe dois contadores precisam ser implementados e simulados. | |||
;Em todos os contadores: | |||
* Capture o diagrama RTL do contador. | |||
* Capture a tela de simulação que mostram a contagem (as contagens podem se bem altas, neste caso faça a contagem até 1000) | |||
* Ao escolher a família de FPGAS, escolha o dispositivo FPGA da família '''Cyclone IV E''' do kit e anote o código ('''Name'''), tensão de alimentação no núcleo ('''Core Voltage'''), Número de elementos lógicos configuráveis ('''LEs''' ou '''ALMs''') desse dispositivo. | |||
* Utilize o procedimento indicado em [[Restringir a frequencia máxima de clock no Quartus]], modificando a frequencia do clock de modo a definir o clock desejado como 50MHz, pois é o clock do kit a ser utilizado | |||
* Utilize o procedimento descrito em [[Como obter o Fmax do projeto no Quartus]] | |||
* Anote a Fmax do projeto, número de elementos lógicos utilizados e o número de pinos utilizados. | |||
* Salve o arquivo QAR com todos os arquivos VHDL, arquivos de simulação tb_XXX.do e wave_XXX.do, e demais necessaários para repetir o projeto. | |||
;Passo 1 - Projeto um contador binário sequencial: | |||
* Adapte o código do contador binário para que seja genérico e uso o número de bits indicado para sua equipe. | |||
;Passo 2 - Contador Gray: | |||
* Adapte o código do contador Gray para que seja genérico e uso o número de bits indicado para sua equipe. | |||
;Passo 3 - Contador em anel: | |||
* Adapte o código do contador em anel para que seja genérico e uso o número de bits indicado para sua equipe. | |||
;Passo 4 - Contador Johnson: | |||
* Adapte o código do contador Johnson para que seja genérico e uso o número de bits indicado para sua equipe. | |||
;Passo 5 - Contador LFSR: | |||
* Adapte o código do contador LFSR para o número de bits indicado para sua equipe. | |||
* Ver como se pode implementar um contador [https://en.wikipedia.org/wiki/Linear-feedback_shift_register LFSR] de n bits. | |||
* Consultar [https://users.ece.cmu.edu/~koopman/lfsr/] ou a página 5 de [https://docs.amd.com/v/u/en-US/xapp052] para obter os termos que são usados na realimentação. | |||
;Entregas: | |||
#Envie um arquivo QAR contendo todos os arquivos necessário para compilar os projetos de todos os contadores. | |||
#Envie um relatório em PDF, incluindo as imagens capturadas (inclua um título para cada figura) e escreva para cada imagem um texto comentando o que representa. O relatório também deve ter a identificação (autor, título, data) uma breve introdução e uma conclusão. A descrição dos procedimentos feita na página wiki não precisa incluída no relatório. | |||
#Use preferencialmente o [[Uso_do_Overleaf | Overleaf]] para gerar o relatório. Mas o uso de MS-Word, Libreoffice e Google Docs também é permitida. | |||
#A entrega será feita através do Moodle da disciplina. Observe o prazo de entrega. | |||
{{collapse bottom}} | |||
===AE15 - Timer de Segundos com Mostrador SSD === | |||
{{collapse top | expand=true| bg=lightyellow | AE15 - Timer de Segundos com Mostrador SSD}} | |||
;Objetivos: | |||
* Desenvolver um timer de segundos, exibindo a contagem de 00 até DU através de dois displays de sete segmentos (SSD). | |||
* Realizar um projeto hierárquico com componentes já utilizados anteriormente. | |||
* Utilizar parâmentros genéricos na instanciação dos componentes para definir o valor total da contagem DU. | |||
* Utilizar sinais ZERAR e CONTAR para controlar o contador BCD. | |||
* Possibilitar a ocultação do número zero na casa da dezena de segundo. | |||
* O projeto deverá ser implementado em FPGA em um dos kits disponíveis no LabSiDi. | |||
;PASSO 0 - Contador BCD: | |||
* Adapte o contador BCD ('''contaBCD.vhd''') | |||
:* Baseie-se no contador desenvolvido em aula (faixa 00–99). | |||
:* O clock do contador deverá ser o clock fornecido pelo kit (50MHz => 20ns) | |||
:* São necessárias as seguintes modificações: | |||
::* Adicione entradas: 1) ENABLE para controlar a contagem. 2) ZERAR: zera a contagem. 3) CONTAR: habilita ou desabilita a contagem. | |||
::* Adicione os parâmetros (generics) para limitar a contagem de 00 até DU. | |||
::* Use IF GENERATE para disponibilizar: 1) Um modo com overflow automático (contagem contínua). 2) Um modo com parada ao atingir o valor final (DU). | |||
*Simule o contador e verifique que funciona. | |||
:*Use um CLOCK de 10Hz e um sinal de ENABLE de 1Hz com duty cycle de 10% | |||
:*Teste o funcionamento das entradas ZERAR e CONTAR. | |||
:*Verifique se os parâmetros genéricos D e U limitam corretamente a contagem. Teste com D = 2 e U = 3. O contador deve contar de 00 a 23. | |||
:* Verifique se as opções de overflow e parada funcionam. | |||
;PASSO 1 - Divisor de Clock: | |||
* Adapte o divisor de clock ('''div_clk.vhd''') | |||
:* Gere um pulso de habilitação (ENABLE_OUT) para o contador a cada 1 segundo, a partir do clock disponível no kit. O pulso deve durar o período de 1 clock (20ns) | |||
:* Se ainda não tiver, inclua uma entrada de RESET assincrono neste componente. | |||
:* Gere também um sinal de CLOCK_OUT de 1 segundo com duty cycle de 50% para ser conectado a um led externo. | |||
*Simule o divisor de clock e verifique que funciona. | |||
:*Use um CLOCK de 50Hz e verifique se as saidas CLOCK_OUT e ENABLE_OUT estão corretas | |||
;PASSO 2 - Conversor BCD2SSD: | |||
* Projeto o conversor BCD para SSD ('''bcd2ssd.vhd''') | |||
:* Converta o valor de entrada BCD (0 a 9) para o padrão de 7 segmentos. | |||
:* Usando IF GENERATE selecionar o tipo de display: a) Ânodo comum b) cátodo comum. | |||
:* Inclua uma entrada OCULTA_ZERO para ocultar o zero no display. | |||
*Simule o conversor BCD para SSD e verifique que funciona. | |||
:*Use na entradas valores BCD de 0 a 9 e verifique se as saidas SSD estão corretas | |||
:*Teste com a opção ânodo comum e cátodo comum. | |||
:*Teste se a entrada OCULTA_ZERO funciona. | |||
;PASSO 3 - Entity Top-Level: | |||
* Implemente a entity Top-Level ('''timer_seg.vhd''') | |||
:* Instancie os componentes: | |||
::2x bcd2ssd.vhd → um para as unidades, outro para as dezenas. | |||
::1x contaBCD.vhd → configurado para contar de 00 a 59, com reset automático ao final. | |||
::1x div_clk.vhd → para gerar o sinal de ENABLE de 1 Hz e o clock de 1 sec. | |||
<syntaxhighlight lang=vhdl> | |||
entity timer_seg is | |||
generic (DEZENA : natural := 5; UNIDADE : natural := 9; FCLOCK : natural := 50); | |||
port ( | |||
CLOCK50MHz : in std_logic; | |||
RESET_PB : in std_logic; | |||
CONTAR_SW : in std_logic; | |||
ZERAR_PB : in std_logic; | |||
LED_1SEC : out std_logic; | |||
SSD_DEZENA : out std_logic_vector(6 downto 0); | |||
SSD_UNIDADE : out std_logic_vector(6 downto 0)); | |||
end entity; | |||
Arquitetura sugerida | |||
architecture ifsc of timer_seg is | |||
-- Sinais internos: BCD_UNIDADE, BCD_DEZENA, ENABLE_1SEC, etc. | |||
-- Declaração dos componentes usados | |||
begin | |||
-- Instância do divisor de clock | |||
-- Instância do contador BCD | |||
-- Instâncias dos conversores BCD para SSD | |||
end architecture; | |||
</syntaxhighlight> | |||
*O projeto deve ser sincrono, portanto todos os registradores (flip-flops) devem estar conectados ao CLOCK50MHz | |||
*Conecte o RESET_PB a entrada reset dos componentes '''div_clk.vhd''' e '''contaBCD.vhd'''. | |||
*Conecte a saída de ENABLE_OUT ao ENABLE do contador | |||
*Conecte a saída BCD das dezenas a um dos conversores bcd2ssd.vhd e a saída das unidades ao outro. | |||
*O display das dezenas podeve ocultar o zero, enquanto que o display das unidades sempre deve mostrar o zero. | |||
*Simule o timer para contar de 00 a 59 com reinício automático (overflow), e para display de cátodo comum. | |||
*Simule o timer para contar de 00 a 23 com parada, e para display de ânodo comum. | |||
;PASSO 4 - Implemetação no Kit FPGA: | |||
Implemente o projeto no FPGA: | |||
* Escolha um dos kits disponíveis no laboratório. | |||
* Configure o projeto para exibir nos dois mostradores HEX (HEX0 e HEX1) ou DISP (DISP0 e DISP1). | |||
* Verifique se o display do kit é ânodo comum ou cátodo comum, e configure o bcd2ssd.vhd corretamente. | |||
* Verifique os clocks disponíveis no kit (Ex.: 50 MHz, 100 MHz), e configure corretamente o parâmetro FCLOCK, para que o ENABLE_1SEC e LED_1SEC estejam com período de 1 segundo. | |||
* Defina as chaves (ou botões) de controle para: CONTAR (SW), ZERAR (PB), RESET (PB). Verifique se os PUSH BUTTON (PB) são normalmente BAIXOS ou ALTOS. No segundo caso é necessário incluir um inversor no top-level. | |||
* Configure o parâmetro DU para que a contagem seja de 00 até 59 e depois reinicie automaticamente. | |||
;PASSO 5 - Entregas: | |||
*Documentar o experimento em um relatório técnico que contenha no mínimo: | |||
:*Identificação (título, disciplina, data, autores); | |||
:*Introdução; | |||
:*Descrição dos componentes utilizados e do sistema completo. Cada componente deve ser descrito em termos funcionais, e também deve ter uma simulação que demonstre o seu funcinamento. | |||
:*Documente todas as simulações com ondas claras para cada componente e para o sistema completo. | |||
:*Resultados obtidos (com imagens dos itens importantes) e análise dos resultados; | |||
:*Apresente tabelas da pinagem utilizada na configuração do FPGA, número de elementos lógicos usados em cada componente e pelo sistema completo. | |||
:*Conclusão. | |||
*O relatório deve também responder as questões levantadas e mostrar que os objetivos apresentados na introdução foram atendidos. | |||
*O arquivo QAR contendo o projeto com todos os arquivos .vhd .do necessários para repetir o projeto e as simulações | |||
*O arquivo SOF usado na programação do FPGA. | |||
*Se for solicitado disponibilize vídeos demonstrando o funcionamento do timer. | |||
<center> {{#ev:youtube|orjy0GURH_U}} </center> | |||
{{collapse bottom}} | |||
===AE16 - Controlador de Semáforo de duas vias === | |||
{{collapse top | expand=true| bg=lightyellow | AE16 - Controlador de Semáforo de duas vias}} | |||
;Objetivos: | |||
* Projetar uma Maquina de Estados Finita (FSM) para controlar um semáforo, com timer de segundos em componente externo. | |||
* Reutilizar o timer de segundos (binário) | |||
* Reutilizar o divisor de clock, e gerador de sinal de enable a cada segundo. | |||
* Realizar um projeto hierárquico. | |||
* Realize um projeto sincrono | |||
* Os componentes deve usar um código em dois segmentos, no qual o primeiro segmento realiza a atualização dos registrador, e o segundo segmento realiza a Lógica do Próximo Estado, e as Lógicas de Saída. | |||
* O projeto '''pode''' ser implementado em FPGA em um dos kits disponíveis no LabSiDi, mas '''não é obrigatório'''. | |||
;PASSO 0 - Timer de Segundos: | |||
* Adapte o timer de segundos para contar em binário ('''timer_sec.vhd''') | |||
:* O clock do contador deverá ser o clock fornecido pelo kit (50MHz => 20ns) | |||
::* Adicione entradas: 1) ENABLE para controlar a contagem. 2) ZERAR: zera a contagem. 3) CONTAR: habilita ou desabilita a contagem. | |||
::* Adicione os parâmetros (generics) para limitar a contagem de 0 até MAX, onde MAX é o tempo máximo de verde do semáforo. | |||
*Simule o contador e verifique se funciona. | |||
:*Use um CLOCK de 10Hz e um sinal de ENABLE de 1Hz com duty cycle de 10% | |||
:*Teste o funcionamento das entradas ZERAR e CONTAR. | |||
;PASSO 1 - Divisor de Clock: | |||
* Utilize o divisor de clock ('''div_clk.vhd''') da atividade AE15. Nenhuma adaptação é necessária. | |||
;PASSO 2 - FSM do semáforo: | |||
* Projeto da FSM do semáforo ('''FSM_semaforo.vhd''') | |||
:*Utilize o template fornecido para descrever a FSM representada pelo seguinte diagrama de estados: | |||
{{fig|AE16a|FSM - Controlador semafórico para duas vias (diagrama de estados)|FSM_Sema2Vias.png|800 px| }} | |||
:* Adicione uma saída Mealy enviar um signal ZERAR o timer que é usado nas transições da FSM. | |||
:* Opcionalmente, você pode enviar um signal ZERAR usando uma saída Moore, que é ativada em 6 estados adicionais inseridos antes de entrar em cada um dos 6 estados da FSM. | |||
*Simule a FSM do semáforo e verifique se funciona. | |||
:*Para testar, é necessário gerar manualmente o sinal de ATIVAR e os valores do timer para verificar o avanço dos estados da FSM | |||
:*Verifique se o sinal de saida ZERAR é ativado corretamente. | |||
:*Mostre claramente a FSM alternando entre AM1 e AM2, e depois faça o semáforo evoluir por 2 ciclos de controle das vias. | |||
;PASSO 3 - Entity Top-Level: | |||
* Implemente a entity Top-Level ('''timer_seg.vhd''') | |||
:* Instancie os componentes: | |||
::1x FSM_semaforo.vhd → FSM com saida ZERAR_CNT do tipo Mealy (ou Moore). | |||
::1x timer_sec.vhd → configurado para contar de 00 a 99, sendo reiniciado pelo sinal ZERAR_CNT . | |||
::1x div_clk.vhd → para gerar o sinal de ENABLE de 1 Hz e o clock de 1 sec. | |||
{{fig|AE16b|Diagrama RTL do Controlador semafórico para duas vias |RTL_Sema2Vias.png|800 px| }} | |||
<syntaxhighlight lang=vhdl> | |||
entity controlador_semaforo IS | |||
generic ( | |||
tAMG : natural := 5; tVD1G : natural := 60; tVD2G : natural := 30; | |||
Nbits_timer :natural := 6; | |||
FCLK : natural := 50; Nbits_clk : natural := 6); | |||
port ( | |||
CLK50MHz : in std_logic; | |||
RESET_PB : in std_logic; | |||
ATIVAR_SW : in std_logic; | |||
CONTAR_SW : in std_logic; | |||
LED_1sec : out std_logic; | |||
vm1_LED, vd1_LED, am1_LED, vm2_LED, vd2_LED, am2_LED : out std_logic); | |||
end entity; | |||
Arquitetura sugerida | |||
architecture ifsc of controlador_semaforo is | |||
-- Sinais internos: timer_std, zerar_cnt, ena_1sec, etc. | |||
-- Declaração dos componentes usados | |||
begin | |||
-- Instância do divisor de clock | |||
-- Instância do timer binario de 1 sec | |||
-- Instância da FSM do semaforo | |||
end architecture; | |||
</syntaxhighlight> | |||
*O projeto global deve ser sincrono, portanto todos os registradores (flip-flops) devem estar conectados ao CLOCK50MHz | |||
*Simule o funcionamento da FSM no modo amarelo piscante (ativar = 0). | |||
{{fig|AE16c|Simulação do Controlador semafórico para duas vias (amarelo piscante)|SIM_Sema2ViasAM1AM2.png|800 px| }} | |||
*Simule o funcionamento da FSM no modo normal (ativar = 1), permitindo pelo menos dois ciclos de VERDE nas duas vias controladas. | |||
{{fig|AE16d|Simulação do Controlador semafórico para duas vias (ciclo verde)|SIM_Sema2ViasVD1VD2.png|800 px| }} | |||
;PASSO 4 - Entregas: | |||
*Documentar o experimento em um relatório técnico que contenha no mínimo: | |||
:*Identificação (título, disciplina, data, autores); | |||
:*Introdução; | |||
:*Descrição dos componentes utilizados e do sistema completo. Cada componente deve ser descrito em termos funcionais, e também deve ter uma simulação que demonstre o seu funcionamento. | |||
:*A FSM deve ser descrita usando um diagrama de estados ou um ASM. | |||
:*Nas simulações de FSM é importante destacar a evolução dos estados da FSM. | |||
:*Documente todas as simulações com ondas claras para cada componente e para o sistema completo. | |||
:*Resultados obtidos (com imagens dos itens importantes) e análise dos resultados; | |||
:*Descrever claramente o papel de cada membro da equipe no projeto. Lembre-se que todos devem ter um papel, e podem ser questionados sobre sua participação. | |||
:*Conclusão. | |||
*O relatório deve também responder as questões levantadas e mostrar que os objetivos apresentados na introdução foram atendidos. | |||
*O arquivo QAR contendo o projeto com todos os arquivos .vhd .do necessários para repetir o projeto e as simulações | |||
{{collapse bottom}} | |||
<!-- | |||
===AE5 - Controlador de ventoinha === | |||
{{collapse top | expand=true| bg=lightyellow | AE5 - Controlador de ventoinha}} | |||
;Objetivos: | |||
;Materiais auxiliares: | |||
<center>[https://drive.google.com/file/d/1VhZLehwB_ijpc0V14Wg_of998NUMeAvw/view?usp=drive_link Datasheet da ventoinha ADDA AD0912UX-A7BGL]</center> | |||
{{fig|AE5.a|Diagrama elétrico da ventoinha| DiagramaVentoinha.png| 600 px |https://i1.wp.com/nets-nuts.com.br/wp-content/uploads/2015/12/cooler_pwm2. jpg}} | |||
{{fig|AE5.a|Conexão elétrica da ventoinha| FiosVentoinha.png| 600 px |https://hardzone.es/tutoriales/mantenimiento/ventiladores-3-4-pines-diferencias/}} | |||
{{collapse bottom}} | |||
<!-- | |||
===AE3 - Laboratório de programação de FPGA - Relógio HHMMSS=== | |||
{{collapse top | bg=lightyellow | AE3 - Laboratório de programação de FPGA - Relógio HHMMSS}} | |||
;Objetivos: | |||
*Desenvolver sistemas utilizando componentes já desenvolvidos. | |||
*Apreender a instanciar componentes e conectá-los com sinais. | |||
*Realizar um projeto hierárquico. | |||
;Consulte: | |||
*[[Preparando para gravar o circuito lógico no FPGA]] | |||
*[[Interfaces de entrada e saída da DE2-115]] | |||
*[[Display de 7 segmentos]] | |||
;Passo 1 - Projeto do Relogio_HHMMSS: | |||
*Projete um relógio para indicar hora (HH), minuto (MM) e segundo (SS), mostrando as unidades e dezenas em 6 [[Display de 7 segmentos]], usando os seguintes componentes: 1) Divisor de clock para obter um sinal de período de 1 segundo. ('''div_clk'''); 2) Contador configurável BCD de 00 a 99 ('''contador_bcd''') 3) Conversor de BCD para SSD, com configuração de apagamento do zero e tipo de ligação dos segmentos. | |||
*Componente 1 - Divisor de Clock, com o valor da divisão configurável pelo parâmetro '''fclk2'''. O sinal de saída será usado como "enable" ou "clock" a cada 1 segundo para o componente '''contador_bcd'''. | |||
<syntaxhighlight lang=vhdl> | |||
component div_clk is | |||
generic (fclk2 : natural := 50); -- frequencia para simulacao | |||
port ( | |||
clk_in : in std_logic; | |||
rst : in std_logic; | |||
clk_out : out std_logic | |||
); | |||
end component; | |||
</syntaxhighlight> | |||
*Componente 2 - Contador de 00 a 99 com saída em BCD, (pode ser um contador em BCD (ou um contador binário + conversor bin2bcd). O valor final deve ser configurável pelos parâmetros '''max_dezena e max_unidade''' | |||
<syntaxhighlight lang=vhdl> | |||
component contador_bcd is | |||
generic (max_dezena : natural := 5; max_unidade : natural := 9); | |||
port ( | |||
clk: in std_logic; | |||
rst: in std_logic; | |||
fim: out std_logic; | |||
bcd_unidade, bcd_dezena : out std_logic_vector(3 downto 0) | |||
); | |||
end component; | |||
</syntaxhighlight> | |||
Para esse contador pode ser usado o desenvolvido em aula, mas ele precisa ser modificado para permitir que o ''clock'' seja síncrono em todos os ''flip-flops''. Assim é necessário usar um sinal de '''enable_in''' para habilitar a contagem durante um período de clock. Também será necessário gerar o sinal de '''enable_out''' para habilitar a contagem do próximo contador. | |||
*Componente 3 - Conversor de BCD para SSD, com um parâmetro configurável '''ac_ccn''' para selecionar o tipo de mostrador (Anodo Comum / Catodo Comum). | |||
<syntaxhighlight lang=vhdl> | |||
component bcd2ssd is | |||
generic (ac_ccn : natural := 0); -- 1 para mostrador de anodo comum, 0 para mostrador de catodo comum | |||
port ( | |||
bcd_in : in std_logic_vector(3 downto 0); | |||
z_opc: in std_logic; -- 1 o zero é mostrado, 0 - o zero é apagado. | |||
ssd_out : out std_logic_vector(6 downto 0) | |||
); | |||
end component; | |||
</syntaxhighlight> | |||
*O valor '''ac_ccn''' será utilizado para configurar o circuito de modo a acender os segmentos com ALTO para display de catodo comum (ac_ccn=0), ou BAIXO para display de anodo comum (ac_ccn=1). | |||
*A entrada '''zero_option''' pode ser usada para apagar a dezena da HH, MM e SS. | |||
* '''Opção 1''' - Na entidade TOP LEVEL, podem ser instanciados os seguintes componentes: um '''div_clk'''; três '''contador_bcd''' e seis '''bcd2ssd'''. Além disso, se necessário podem ser inseridos os inversores necessários para adequar ao hardware do kit DE2-115. | |||
* '''Opção 2''' - Se quiser, você pode criar um componente com um '''contador_bcd''' e dois '''bcd2ssd''' e replicar 3 vezes esse componente na entidade TOP LEVEL. | |||
*'''IMPORTANTE''': É necessário incluir um RESET no circuito sequencial e também uma entrada de enable no contador. | |||
<syntaxhighlight lang=vhdl> | |||
entity relogio_HHMMSS IS | |||
-- O valor do fclk2 corresponde a metade do periodo do clock de entrada em Hz | |||
generic (fclk2 : natural := 50); -- ao simular o circuito utilize um valor baixo para acelerar a simulaçao | |||
-- generic (fclk2 : natural := 25000000); -- ao implementar no hardware use o valor do clock em Hz | |||
port | |||
( | |||
clk_50MHz_kit: in STD_LOGIC; | |||
rst_SW: in STD_LOGIC; -- use uma chave deslizante para essa função RESET | |||
stop_SW: in STD_LOGIC; -- use uma chave deslizante para essa função PARAR e CONTINUAR | |||
z_opc_SW: in STD_LOGIC; -- use uma chave deslizante para essa função apagar o zero das dezenas | |||
ssd_DS, ssd_DM, ssd_DH: out STD_LOGIC_VECTOR(6 downto 0); | |||
ssd_US, ssd_UM, ssd_UH: out STD_LOGIC_VECTOR(6 downto 0) | |||
); | |||
end entity; | |||
</syntaxhighlight> | |||
{{fig|AE2.a|RTL do Relógio Digital de 24 horas| Rtl_relogio24h.png| 800 px |}} | |||
;Passo 2 - Simule os componentes e o relógio completo: | |||
* Efetue a simulação funcional do '''div_clock''', definindo a entrada de '''clk_in''' como um sinal de 100 Hz, e realizando a simulação para produzir um clk_out de 1Hz. Certifique-se que a duração do sinal alto é de apenas 1 período do sinal de clk_in. | |||
* Efetue a simulação funcional do '''contador_bcd''' fazendo a contagem de 00 a 99 e também de 00 a DU, onde DU é um valor qualquer configurável pelo genéricos D e U. O contador só deverá contar se o '''enable_in''' estiver ALTO. Durante a mudança de DU para 00 o '''enable_out''' deverá ir para ALTO. Na simulação use um clock de 1 segundo, e faça uma simulação de pelo menos 120 segundos. | |||
* Efetue a simulação do '''bcd2ssd''' testando o circuito para as estradas bcd_in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9). Para os valores inválidos de entrada (10, 11, 12, 13, 14, 15), a saída deve mostrar "E" (de erro). | |||
* Nas simulações dos circuitos sequencias é necessário iniciar o circuito com um RESET de 10 ps. | |||
* Realize a simulação do relógio completo '''relogio_HHMMSS''' durante 48 horas. Para esta simulação é importante configurar o divisor de clock para realizar uma divisão com um fator menor que aquele a ser usado no circuito final (veja o comentário no código acima). | |||
{{fig|AE4.b|Simulação funcional do Relógio Digital de 24 horas| Sim_relogio24h.png| 800 px |}} | |||
{{fig|AE4.c|Simulação funcional do Relógio Digital de 24 horas - detalhe enable 1sec| Sim_relogio24h_enable.png| 800 px |}} | |||
;Passo 3 - Implemente o relógio no kit DE2-115: | |||
*Após verificar que a simulação do circuito está funcionando, configurar um FPGA para implementar este circuito. Existem duas opções de kit disponíveis com displays de sete segmentos. As informações necessárias estão em [[Preparando para gravar o circuito lógico no FPGA]]. Neste caso iremos usar o kit DE2-115 da TERASIC, pois precisamos de 6 mostradores de 7 segmentos. | |||
* Analise no diagrama esquemático como funcionam as chaves e também o mostrador de sete segmentos. Note que no projeto o signal RST foi descrito como normalmente ALTO, por isso dependendo da chave que usar pode ser necessário acrescentar um inversor neste sinal para que funcione corretamente. O [[Display de 7 segmentos]] da DE2-115 é do tipo anodo comum (aplicando um nível lógico '0' no pino correspondente fará com que o segmento acenda, enquanto a aplicação do nível lógico '1' fará com com que o segmento apague). | |||
*Anote a pinagem que será utilizada para conectar o circuito projetado no FPGA aos circuitos externos do kit (mostradores, chaves e leds). | |||
{{collapse top| definição dos pinos}} | |||
{| class="wikitable sortable" style="text-align:center;" | |||
|- style="font-weight:bold; background-color:#c0c0c0;" | |||
! To | |||
! Direction | |||
! Location | |||
|- | |||
| clk50MHz | |||
| Input | |||
| PIN_Y2 | |||
|- | |||
| clk_1sec_LED | |||
| Output | |||
| PIN_F17 | |||
|- | |||
| rst_sw | |||
| Input | |||
| PIN_AB28 | |||
|- | |||
| ssd_DHH[0] | |||
| Output | |||
| PIN_AD17 | |||
|- | |||
| ssd_DHH[1] | |||
| Output | |||
| PIN_AE17 | |||
|- | |||
| ssd_DHH[2] | |||
| Output | |||
| PIN_AG17 | |||
|- | |||
| ssd_DHH[3] | |||
| Output | |||
| PIN_AH17 | |||
|- | |||
| ssd_DHH[4] | |||
| Output | |||
| PIN_AF17 | |||
|- | |||
| ssd_DHH[5] | |||
| Output | |||
| PIN_AG18 | |||
|- | |||
| ssd_DHH[6] | |||
| Output | |||
| PIN_AA14 | |||
|- | |||
| ssd_DMM[0] | |||
| Output | |||
| | |||
|- | |||
| ssd_DMM[1] | |||
| Output | |||
| | |||
|- | |||
| ssd_DMM[2] | |||
| Output | |||
| | |||
|- | |||
| ssd_DMM[3] | |||
| Output | |||
| | |||
|- | |||
| ssd_DMM[4] | |||
| Output | |||
| | |||
|- | |||
| ssd_DMM[5] | |||
| Output | |||
| | |||
|- | |||
| ssd_DMM[6] | |||
| Output | |||
| | |||
|- | |||
| ssd_DSS[0] | |||
| Output | |||
| | |||
|- | |||
| ssd_DSS[1] | |||
| Output | |||
| | |||
|- | |||
| ssd_DSS[2] | |||
| Output | |||
| | |||
|- | |||
| ssd_DSS[3] | |||
| Output | |||
| | |||
|- | |||
| ssd_DSS[4] | |||
| Output | |||
| | |||
|- | |||
| ssd_DSS[5] | |||
| Output | |||
| | |||
|- | |||
| ssd_DSS[6] | |||
| Output | |||
| | |||
|- | |||
| ssd_UHH[0] | |||
| Output | |||
| | |||
|- | |||
| ssd_UHH[1] | |||
| Output | |||
| | |||
|- | |||
| ssd_UHH[2] | |||
| Output | |||
| | |||
|- | |||
| ssd_UHH[3] | |||
| Output | |||
| | |||
|- | |||
| ssd_UHH[4] | |||
| Output | |||
| | |||
|- | |||
| ssd_UHH[5] | |||
| Output | |||
| | |||
|- | |||
| ssd_UHH[6] | |||
| Output | |||
| | |||
|- | |||
| ssd_UMM[0] | |||
| Output | |||
| | |||
|- | |||
| ssd_UMM[1] | |||
| Output | |||
| | |||
|- | |||
| ssd_UMM[2] | |||
| Output | |||
| | |||
|- | |||
| ssd_UMM[3] | |||
| Output | |||
| | |||
|- | |||
| ssd_UMM[4] | |||
| Output | |||
| | |||
|- | |||
| ssd_UMM[5] | |||
| Output | |||
| | |||
|- | |||
| ssd_UMM[6] | |||
| Output | |||
| | |||
|- | |||
| ssd_USS[0] | |||
| Output | |||
| | |||
|- | |||
| ssd_USS[1] | |||
| Output | |||
| | |||
|- | |||
| ssd_USS[2] | |||
| Output | |||
| | |||
|- | |||
| ssd_USS[3] | |||
| Output | |||
| | |||
|- | |||
| ssd_USS[4] | |||
| Output | |||
| | |||
|- | |||
| ssd_USS[5] | |||
| Output | |||
| | |||
|- | |||
| ssd_USS[6] | |||
| Output | |||
| | |||
|} | |||
{{collapse bottom}} | |||
*Dica para testar o relógio sem aguardar 24 horas. Acelere o clock de entrada do contador de segundos de 60 (ou 1440 vezes), com isso o sistema realizará a contagem de 00:00:00 a 23:59:59 em 24 minutos (ou 1 minuto). | |||
;Passo 4 - Entregas: | |||
*Documentar o experimento em um relatório técnico que contenha no mínimo: | |||
:*identificação (título, disciplina, data, autores); | |||
:*introdução; | |||
:*Descrição dos componentes utilizados e do sistema completo. Cada componente deve ser descrito em termos funcionais, e também deve ter uma simulação que demonstre o seu funcinamento. | |||
:*resultados obtidos (com imagens dos itens importantes) e análise dos resultados; | |||
:*apresente tabelas da pinagem utilizada na configuração do FPGA, número de elementos lógicos usados em cada componente e pelo sistema completo. | |||
:*conclusão. | |||
:*apêndice (se desejar pode ser disponibilizados vídeos do funcionamento do circuito | |||
*O relatório deve também responder as questões levantadas e mostrar que os objetivos apresentados na introdução foram atendidos. | |||
*O arquivo QAR contendo o projeto | |||
*Os arquivos para simulação (DO) necessárias para simular o sistema '''relogio_HHMMSS''' e seus componentes. | |||
*O arquivo SOF usado na programação do FPGA. | |||
<center> {{#ev:youtube|orjy0GURH_U}} </center> | |||
{{collapse bottom}} | |||
===AE3 - Projeto de uma FSM para controle semafórico=== | |||
{{collapse top | bg=lightyellow | AE3 - Projeto de uma FSM para controle semafórico}} | |||
;Objetivos: | |||
*Aplicar o conhecimento de FSM no projeto de um controle semafórico. | |||
*Obter a especificação do projeto pela observação do funcionamento do equipamento atual | |||
*Fazer a simulação funcional dos componentes individuais e do controle semafórico | |||
*Utilizar saídas do tipo Moore (para os focos luminosos) e Meally (inicialização das temporizações) | |||
*O projeto será desenvolvido por equipes de até 2 estudantes, e cada equipe deverá escolher um cruzamento de vias que tenha além de dois grupos semafóricos progressivo, também pelo menos um semáforo de pedestre. | |||
*Cada equipe deverá sugerir e implementar uma melhoria em relação ao equipamento atual instalado no cruzamento das vias. Um dos objetivos do projeto é buscar por soluções semafóricas inovadoras, incluindo aprimoramentos específicos para o período noturno ou economia de energia. O objetivo é proporcionar uma experiência mais segura e visível para veículos e pedestres ao cruzar vias durante o dia e a noite. | |||
Como material auxiliar se sugere consultar o [[media:Manual_Brasileiro_de_Sinalização_de_trânsito_VOLUME_V.pdf | Manual Brasileiro de Sinalização de trânsito: VOLUME V - Sinalização Semafórica]] do CONTRAN. Outro material resumido sobre o tema pode ser consultado em [https://ecivilufes.files.wordpress.com/2013/07/aula9.pdf Sinalização semafórica: definições] - Universidade Presbiteriana Mackenzie | |||
;Atividades: | |||
*'''PASSO 1 -''' fazer o levantamento do semáforo selecionado para o projeto. | |||
:*Selecionar um semáforo e obter a imagem das vias e da área de conflito que é controlada pelo semáforo. | |||
{{fig|AE3.1|Imagem aérea do Google do cruzamento Shibuya Crossing, em Tóquio, Japão |Shibuya_Crossing_Aerea.png|900 px|Google maps|[https://www.google.com.br/maps/@35.6596989,139.700302,150m/data=!3m1!1e3?entry=ttu&g_ep=EgoyMDI1MDIwNS4xIKXMDSoJLDEwMjExMjM0SAFQAw%3D%3D]}} | |||
:*Fazer um croqui das vias e passagens de pedestre dessa área. | |||
{{fig|AE3.2|Diagrama do cruzamento Shibuya Crossing |Shibuya_Crossing_ruas.png|900 px|Google Maps| [https://www.google.com.br/maps/@35.6595402,139.7003597,19.5z?entry=ttu&g_ep=EgoyMDI1MDIwNS4xIKXMDSoJLDEwMjExMjM0SAFQAw%3D%3D]}} | |||
:*Elaborar um rascunho ou foto dos semáforos existentes | |||
{{fig|AE3.3|Imagem do Google Street do cruzamento Shibuya Crossing |Shibuya_Crossing_Street.png|900 px| Google Street | [https://www.google.com.br/maps/@35.6595077,139.7001449,3a,90y,104.81h,109.96t/data=!3m7!1e1!3m5!1sN731RghU_E2dIIVGCaKDHQ!2e0!6shttps:%2F%2Fstreetviewpixels-pa.googleapis.com%2Fv1%2Fthumbnail%3Fcb_client%3Dmaps_sv.tactile%26w%3D900%26h%3D600%26pitch%3D-19.961007189407056%26panoid%3DN731RghU_E2dIIVGCaKDHQ%26yaw%3D104.80587305998158!7i16384!8i8192?entry=ttu&g_ep=EgoyMDI1MDIwNS4xIKXMDSoJLDEwMjExMjM0SAFQAw%3D%3D ]}} | |||
:*Elaborar um rascunho do '''diagrama de estágios''' [https://wiki.sj.ifsc.edu.br/images/9/97/Manual_Brasileiro_de_Sinaliza%C3%A7%C3%A3o_de_tr%C3%A2nsito_VOLUME_V.pdf#page=71 pag. 72] e [https://wiki.sj.ifsc.edu.br/images/9/97/Manual_Brasileiro_de_Sinaliza%C3%A7%C3%A3o_de_tr%C3%A2nsito_VOLUME_V.pdf#page=149 pag. 150] | |||
:*Medir os tempos de ciclo do semáforo. | |||
:*Elaborar um rascunho do '''diagrama de intervalos luminosos''' (Diagrama de barras). [https://wiki.sj.ifsc.edu.br/images/9/97/Manual_Brasileiro_de_Sinaliza%C3%A7%C3%A3o_de_tr%C3%A2nsito_VOLUME_V.pdf#page=71 pag.72] e [https://wiki.sj.ifsc.edu.br/images/9/97/Manual_Brasileiro_de_Sinaliza%C3%A7%C3%A3o_de_tr%C3%A2nsito_VOLUME_V.pdf#page=189 pag. 190] | |||
*'''PASSO 2 -''' Projetar a FSM do controlador de semáforo | |||
:*Desenhar o diagrama de transições da FSM | |||
:*Desenhar o ASM | |||
:*Escrever o código em VHDL da FSM | |||
:*Fazer a '''Análise e Síntese''' no Quartus | |||
:*Observar e analisar o RTL e o diagrama de estados no Quartus | |||
:*Verificar o número de elementos lógicos usados | |||
:*Fazer Timing Analysis e anotar as FMax | |||
:*Fazer a simulação funcional, permitindo um (ou dois) ciclos completo do controlador semafórico (Dica utilize cores verde, vermelha e amarela para facilitar a visualização dos semáforos). | |||
*'''PASSO 3 - ''' Implementar um sistema hierárquico para o controlador | |||
:*Para a geração do tempo do controlador de semáforo utilize pelo menos um componente para o contador de segundos (binário ou BCD). | |||
:*O controlador semafórico deve ser um componente separado | |||
:*Se preferir utilize também um componente para o divisor de clock para gerar o sinal de 1 segundo a partir do clock de 50MHz, não esqueça de usar um divisor menor na simulação (sugestão 5) | |||
:*O Top Level do projeto deve conter apenas a instanciação dos componentes do projeto. | |||
:*Observar e analisar o RTL e o diagrama de estados no Quartus | |||
:*Verificar o número de elementos lógicos usados e o FMax | |||
:*Fazer a simulação funcional de um ciclo completo do controlador semafórico. | |||
;Entregas: | |||
#Envie um arquivo QAR contendo todos os arquivos necessário para compilar e simular o projeto. O QAR deve conter todos os arquivos .vhd e arquivos .do dos componentes e do top level. | |||
#Envie um relatório em PDF, incluindo as imagens capturadas (inclua um título para cada figura) e escreva para cada imagem um texto comentando o que representa. O relatório também deve ter a identificação (autor, título, data) uma breve introdução e uma conclusão. A descrição dos procedimentos feita na página wiki não precisa incluída no relatório. Dados numéricos devem ser apresentados na forma gráfica ou tabela, jamais como imagem capturada de tela. | |||
#Use preferencialmente o [[Uso_do_Overleaf | Overleaf]] para gerar o relatório. Mas o uso de MS-Word, Libreoffice e Google Docs também é permitida. | |||
#A entrega será feita através do Moodle da disciplina. Observe o prazo de entrega. | |||
{{collapse bottom}} | |||
===AE4 - Comparação de Hardware projetado por FSMD e Dataflow=== | |||
{{collapse top | bg=lightyellow | AE4 - Comparação de Hardware projetado por FSMD e Dataflow}} | |||
;Objetivos: | |||
*Analisar o funcionamento de diferentes versões de FSMD para multiplicação de dois números. | |||
*Analisar o funcionamento de diferentes versões de algoritmos dataflow para multiplicação de dois números. | |||
*Fazer a simulação funcional de várias FSMDs e comparar com a implentação estruturada em fluxo de dados. | |||
*Analisar a influência do número de bits sobre o número de elementos lógicos, frequencia máxima e tempo total de cálculo. | |||
*O projeto será desenvolvido por equipes de até 2 estudantes. | |||
*Cada exipe deverá realizar a simulação com pelo menos duas multiplicações, uma com um fator baixo (< 5) e outra com ambos fatores > 10. As equipes devem informar de antemão os valores que irão utilizar, e não poderão usar valores iguais as demais equipes. | |||
;Atividades: | |||
*'''PASSO 1 -''' Entender e testar os códigos das Listing (L11.1 ou L11.2 ou L11.3), L11.5, L11.6, L11.7 e L11.8 de <ref name="CHU2006"/>. | |||
::Entre as L11.1, L11.2 e L11.3, escolha apenas uma delas para os testes. A L11.4 fica de fora pois conter erro. | |||
:*Realize a '''Analyses e Synthesis''', '''Fitter''' e '''Timing Analysis''' de cada versão | |||
:*Obtenha os valores de frequência máxima ('''Fmax''') e número de elementos lógicos ('''Nel''') de cada versão | |||
:*Efetue a simulação utilizando um clock de 1 ns com pelo menos duas multiplicações, uma com um fator baixo (< 5) e outra com ambos fatores > 10. Essa etapa ajuda a determinar o número de clocks | |||
:*Meça o número de clocks ('''Nclk''') necessário para realizar a operação, e calcule o tempo total ('''Tcal''') para realizar a operação. | |||
*'''PASSO 2 -''' Análise da variação do número de bits | |||
:*Altere o código para que funcione para um número genérico de bits. | |||
::Dica: Para gerar um vetor de N zeros, crie uma constante e utilize a constante no código. | |||
constant zeros : std_logic_vector(N-1 downto 0) := (others => '0'); | |||
:*Repita o PASSO 1 variando o tamanho do multiplicador para 4, 8, 16, 32, 64 bits. | |||
::'''Nota:''' A simulação com 32 e 64 bits da (L11.1 ou L11.2 ou 11.3) ficará muito longa, e por isso não deve ser feita. Nestes casos estime o número de clocks a partir dos fatores multiplicadores. | |||
:*Anote em uma tabela os valores '''Fmax, Nel, Nclk, Tcal''' para cada uma das versões e número de bits | |||
:*Guarde a imagem do circuito RTL para 4 bits obtido em cada versão, incluindo o diagrama de estado da FSM se for o caso. | |||
:*Ao efetuar a simulação use um fator alto que seja proporcional ao número de bits. Ou seja para 8 bits use um número maior que 128 = 2^(8-1). | |||
*'''PASSO 3 -''' Análise de um multiplicador direto | |||
:*Escreva um código de um multiplicador que utilize diretamente a função de multiplicação | |||
<syntaxhighlight lang=vhdl> | |||
r <= a * b; | |||
</syntaxhighlight> | |||
:*Também insira registradores nas duas entradas de dados e também na saída, de modo que fique semelhante ao destacado na figura em contorno vermelho. | |||
{{fig|AE4.1|RTL do multiplicador direto|RTL_multiplicador_direto.png|900 px||}} | |||
:*Faça toda a análise para 4, 8, 16, 32, 64 bits. | |||
:*Anote em uma tabela os valores '''Fmax, Nel, Nclk, Tcal''' para cada número de bits | |||
:*Guarde a imagem do circuito RTL para 4 bits obtido. | |||
:*Ao efetuar a simulação use os mesmos fator utilizados no PASSO 2 para cada tamanho do multiplicador. | |||
*'''PASSO 4 -''' Análise de um multiplicador por somas sucessivas | |||
:*Escreva um código de um multiplicador que efetue somas sucessivas para efetuar a multiplicação | |||
<syntaxhighlight lang=vhdl> | |||
-- declare o sinal aux como um vetor de dados do tipo unsigned | |||
type uns_vector is array (0 to 2**W) of unsigned(2*W-1 downto 0); | |||
signal aux : uns_vector; | |||
-- utilize o vetor aux para guardar as sucessivas somas da entrada a_in | |||
-- utilize a entrada b_in para decidir qual dos somas correspode ao resultado. | |||
-- NOTA: este código é muito ineficiente, e está apenas sendo usado para comparar com os códigos desenvolvidos com a metodologia RT; | |||
aux(0) <= to_unsigned(0,2*W); | |||
l1: for k in 0 to 2**W-1 generate | |||
aux(k+1) <= aux(k) + resize(unsigned(a_in),2*W); | |||
end generate; | |||
r <= std_logic_vector(aux(to_integer(unsigned(b_in)))); | |||
</syntaxhighlight> | |||
:*Também insira registradores nas duas entradas de dados e também na saída, de modo que fique semelhante ao destacado na figura em contorno vermelho. | |||
{{fig|AE4.2|RTL do multiplicador por somas sucessivas|RTL_multiplicador_somas.png|900 px||}} | |||
:*Faça toda a análise para 4 e 8 bits apenas. | |||
:*Anote em uma tabela os valores '''Fmax, Nel, Nclk, Tcal''' para cada número de bits | |||
:*Guarde a imagem do circuito RTL para 4 bits obtido. | |||
:*Ao efetuar a simulação use os mesmos fator utilizados no PASSO 2 para cada tamanho do multiplicador. | |||
;Entregas: | |||
#Envie um arquivo QAR contendo todos os arquivos necessário para compilar e simular o projeto. O QAR deve conter todos os arquivos .vhd e arquivos .do. | |||
#Envie um relatório em PDF, incluindo as imagens capturadas (inclua um título para cada figura) e escreva para cada imagem um texto comentando o que representa. O relatório também deve ter a identificação (autor, título, data) uma breve introdução e uma conclusão. A descrição dos procedimentos feita na página wiki não precisa incluída no relatório. Dados numéricos devem ser apresentados na forma gráfica ou tabela, jamais como imagem capturada de tela. | |||
#Faça uma extensa análise sobre o tempo de cálculo x áreas que o circuito ocupa no FPGA para as diferentes versões. Faça a análise para os diferentes tamnhos do barramento de entrada e saída. | |||
#Sugira qual circuito utilizaria em diferentes situações e quais jamais utilizaria. | |||
#Escreva uma boa conclusão sobre isso | |||
#Use preferencialmente o [[Uso_do_Overleaf | Overleaf]] para gerar o relatório. Mas o uso de MS-Word, Libreoffice e Google Docs também é permitida. | |||
#A entrega será feita através do Moodle da disciplina. Observe o prazo de entrega. | |||
{{collapse bottom}} | |||
===AE2 - Estudando uma FIFO=== | |||
{{collapse top | expand=true | bg=lightyellow | AE2 - Estudando uma FIFO}} | |||
;Objetivos: | ;Objetivos: | ||
*Conhecer um file register, controlador de FIFO e uma FIFO completa | *Conhecer um file register, controlador de FIFO e uma FIFO completa | ||
Linha 1 285: | Linha 3 769: | ||
#A entrega será feita através do Moodle da disciplina. Observe o prazo de entrega. | #A entrega será feita através do Moodle da disciplina. Observe o prazo de entrega. | ||
{{collapse bottom}} | {{collapse bottom}} | ||
--> | |||
==Referências Bibliográficas:== | ==Referências Bibliográficas:== | ||
<references/> | <references/> | ||
Será que uma boa parte do que fazemos com calculo digital será analógico no futuro? [https://www.youtube.com/watch?v=GVsUOuSjvcg Future Computers Will Be Radically Different (Analog Computing)] | |||
{{ENGTELECO}} | {{ENGTELECO}} |
Edição atual tal como às 11h22min de 11 de agosto de 2025
1 Registro on-line das aulas
1.1 Unidade 1 - Aula inicial, Introdução a disciplina
- 1 ENCONTRO
Unidade 1 - Aula inicial, Introdução a disciplina |
---|
|
1.2 Unidade REV - PRIMEIRO CONTATO COM VHDL
- 5 ENCONTROS
Unidade REV - PRIMEIRO CONTATO COM VHDL |
---|
1.3 Unidade 2 - Dispositivos Lógicos Programáveis
- 5 ENCONTROS
Unidade 2 - Dispositivos Lógicos Programáveis |
---|
1.4 Unidade 3 - Circuitos sequenciais (Implementação com HDL)
- 18 ENCONTROS
Unidade 3 - Circuitos sequenciais (Implementação com HDL) |
---|
1.5 Unidade 4 - Maquinas de Estado Finitas
- 5 ENCONTROS
Unidade 4 - Maquinas de Estado Finitas |
---|
1.6 Unidade 5 - Metodologia RT (Register Transfer)
- 7 ENCONTROS
Unidade 5 - Metodologia RT (Register Transfer) |
---|
2 Avaliações
Durante o semestre serão realizadas 2 avaliações e várias atividades feitas extra classe.
- Data das avaliações
- A1 : Avaliação A1 (peso 35) XX/2025
- A2 : Avaliação A2 (peso 45) XX/2025
- AEs : Média ponderada das AEs (peso 20)
- R1 : Recuperação de A1 : XX/2025
- R2 : Recuperação de A2 : XX/2025
- Folha de consulta de VHDL
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.
4 Referências Bibliográficas:
Será que uma boa parte do que fazemos com calculo digital será analógico no futuro? Future Computers Will Be Radically Different (Analog Computing)