Escolar Documentos
Profissional Documentos
Cultura Documentos
Autores:
Orientador:
Artur
Lemos
Mário
Vaz
Ioav
Lichtenstein
Thiago
Lobo
Índice:
1.
Introdução
3
2.
Instalação
4
3.
Criando
um
novo
projeto
5
4. VHDL
Básico
8
5. Simulando
um
projeto
15
6.
Criando
um
DCM
23
7.
Implementando
um
projeto
na
FPGA
26
8.
Exemplos
de
Código
27
2
1.
Introdução
O
ISE
(Integrated
Software
Environment)
é
um
software
criado
pela
Xilinx
para
síntese
e
análise
de
modelos
HDL.
O
usuário
poderá
escrever,
compilar,
realizar
análises
temporais
(utilizando
diferentes
estímulos
como
entrada)
e/
ou
configurar
FPGA’s
com
o
modelo
criado.
Este
tutorial
visa
fornecer
ao
usuário
uma
visão
geral
do
software,
mostrando,
de
forma
simples,
desde
a
ativação
do
programa
até
a
compilação,
visualização
de
diagramas
RTL
e
configuração
da
FPGA
Spartan
3AN
com
códigos
VHDL.
Desenvolveremos
o
tutorial
baseando-‐nos
num
módulo
divisor
de
freqüência,
e
forneceremos
outros
exemplos
de
código
na
última
sessão.
3
2.
Instalação
Para
ativar
o
ISE,
deve-‐se
baixar
os
arquivos
no
link
https://www.del.ufrj.br/pastas-‐das-‐disciplinas/eel480
-‐
sistemas-‐digitais,
garantir
que
estão
na
pasta
~/Downloads
e
executar
a
seguinte
instrução
no
Terminal:
cd
;
tar
xvf
∼/Downloads/Xilinx.tar
;
./ise.sh
Feito
isso,
o
ISE
deverá
estar
ativado
e
para
executá-‐lo,
deve-‐se
utilizar
o
seguinte
comando,
também
no
Terminal:
ise
&
O
que
nos
leva
à
tela
principal
do
programa:
4
3.
Criando
um
novo
projeto
Na
tela
principal
do
ISE,
devemos
começar
pelo
menu
“File
>
New
Project”
e
a
janela
“New
Project
Wizard”
será
aberta.
Campos:
“Name”
-‐
nome
do
projeto
“Location”
-‐
localização
onde
o
projeto
será
salvo*
“Description”
-‐
descrição
do
projeto
5
Feito
isso,
clicar
em
“Next”.
Agora,
devemos
escolher
outros
parâmetros
de
projeto:
“Evaluation
Development
Board”
-‐
Spartan
3AN
Starter
Kit
“Synthesis
Tool”
-‐
XST
“Prefered
Language”
-‐
VHDL
“VHDL
Source
Analysis
Standard”
-‐
VHDL-‐93
Após
clicar,
mais
uma
vez,
em
“Next”,
uma
janela
que
resume
os
parâmetros
do
projeto
será
exibida.
Confira
os
dados
e
caso
estejam
corretos,
clique
em
“Finish”.
Agora,
temos
um
projeto
(.xise)
pronto,
basta
adicionar
códigos-‐fonte
VHDL
e
poderemos
trabalhar
com
os
modelos.
Para
importar
um
código
VHDL
já
escrito,
devemos
acessar
o
menu
“Project
>
Add
Copy
of
Source”,
navegar
até
o
arquivo
e
selecioná-‐lo.
Isso
copiará
o
arquivo
para
o
workspace
do
projeto
e
permitirá
sua
edição.
Sempre
que
a
edição
dos
arquivos
estiver
concluída,
devemos
utilizar
o
menu
“Project
>
Archive”,
para
salvar
o
projeto
na
pasta
do
6
usuário
em
formato
.zip.
Para
utilizar
esse
projeto
posteriormente,
basta
descompactar
o
.zip
gerado
dentro
da
pasta
/tmp
e
abri-‐lo
na
primeira
tela
do
ISE
(“Open
Project”).
7
4.
VHDL
Básico
VHDL
é
uma
linguagem
de
descrição
de
hardware
que
foi
inicialmente
utilizada
para
documentar
componentes
digitais
e
acabou
sendo
aproveitada
para
simulações/
implementações
em
FPGA
desses
mesmos
componentes.
Um
arquivo
VHDL
deve
conter,
no
mínimo,
uma
entity
e
uma
architecture.
A
entity
consiste
na
descrição
da
interface
do
módulo
como
uma
caixa
preta:
especificando
apenas
as
entradas
e
saídas.
A
architecture
descreve
o
funcionamento
do
módulo,
propriamente
dito.
Costumamos
separar
architectures
em
duas
classes:
comportamentais
e
estruturais.
As
comportamentais
servem
para
definir
como
um
módulo
funcionará
e
as
estruturais
servem
para
definir
como
um
módulo
de
alta
hierarquia
interliga
diferentes
módulos
“menores”
(o
que
não
deixa
de
ser
seu
funcionamento).
A
utilização
de
módulos
já
prontos
dentro
de
uma
architecture
se
assemelha
à
instanciação
de
um
objeto
em
uma
linguagem
Orientada
a
Objetos:
especifica-‐se
o
tipo
do
objeto
(sua
Entity),
escolhe-‐se
um
nome
e
mapeia-‐se
suas
entradas
e
saídas
(semelhante
ao
construtor
de
classes
em
Java).
Dentro
da
architecture
utilizamos
sinais
(signals)
para
intercomunicar
módulos.
É
aplicável
um
paralelo
com
as
variáveis
de
um
programa
em
Java.
Comentários
são
feitos
utilizando-‐se
um
“-‐-‐”,
por
exemplo:
-‐-‐
Isso
é
um
comentário
e
não
será
utilizado
na
síntese
8
Segue
um
exemplo
básico:
uma
porta
lógica
AND:
1. -‐-‐
importando
std_logic
da
biblioteca
IEEE
2. library
IEEE;
3. use
IEEE.std_logic_1164.all;
4.
5. -‐-‐
essa
é
a
entidade
(entity)
6. entity
ANDGATE
is
7.
port
(
8.
I1
:
in
std_logic;
9.
I2
:
in
std_logic;
10.
O
:
out
std_logic);
11. end
entity
ANDGATE;
12.
13. -‐-‐
essa
é
a
arquitetura
comportamental
(architecture)
14. architecture
behavioral
of
ANDGATE
is
15. begin
16.
O
<=
I1
and
I2;
17. end
architecture
behavioral;
I1 I1
I2 ANDGATE
O
9
Agora,
podemos
analisar
o
divisor
de
freqüência
clk_div:
10
substituído
em
todos
os
lugares
que
aparece
no
código
por
4.
Trata-‐se
de
uma
constante.
Dentro
da
architecture,
vemos
um
process,
que
é
como
uma
função
em
C.
Todo
processo
leva
uma
lista
de
sensibilidade,
que
no
caso
é
(clk_in).
Isso
indica
que
sempre
que
clk_in
for
atualizado,
o
process
será
executado.
Há,
também,
4
signals:
2
contadores
e
2
temporários
que
são
mapeados
às
saídas
do
bloco,
como
indicam
as
linhas:
11
Agora,
podemos
analisar
o
outro
módulo,
base_tempo,
que
utiliza
o
módulo
clk_div
para
dividir
a
frequência
do
sinal
de
entrada
clk.
Vale
ressaltar
o
fato
de
que
um
DCM
(Digital
Clock
Manager
foi
necessário,
voltaremos
a
falar
sobre
ele
na
sessão
5):
59. library
IEEE;
60. use
IEEE.STD_LOGIC_1164.ALL;
61. use
ieee.numeric_std.ALL;
62. library
UNISIM;
63. use
UNISIM.Vcomponents.ALL;
64.
65. entity
base_tempo
is
66.
generic
(n:
integer
:=
2);
67.
port
(clk
:
in
std_logic;
68.
clk_out
:
out
std_logic;
69.
clk_out_2
:
out
std_logic;
70.
locked
:
out
std_logic);
71. attribute
LOC
:
string
;
72. attribute
LOC
of
clk
:
signal
is
"E12";
73. attribute
LOC
of
locked
:
signal
is
"W21";
74. attribute
LOC
of
clk_out
:
signal
is
"Y22";
75. attribute
LOC
of
clk_out_2
:
signal
is
"Y18";
76. end
entity;
77.
78.
79. architecture
estrutural
of
base_tempo
is
80. component
clk_div
81.
port
(clk_in
:
in
std_logic;
82.
div
:
out
std_logic;
83.
div2
:
out
std_logic);
84. end
component;
85.
86. COMPONENT
dcm1
87. PORT(CLKIN_IN
:
IN
std_logic;
88.
CLKFX_OUT
:
OUT
std_logic;
89.
CLKIN_IBUFG_OUT
:
OUT
std_logic;
90.
CLK0_OUT
:
OUT
std_logic;
91.
LOCKED_OUT
:
OUT
std_logic);
92. END
COMPONENT;
93.
94. signal
clk_int
:
std_logic;
95.
96.
97.
98.
99.
12
100.begin
101.clk_divider
:
clk_div
port
map
102.
(clk_in
=>
clk_int,
103.
div
=>
clk_out,
104.
div2
=>
clk_out_2);
105.
106.Inst_dcm1
:
dcm1
PORT
MAP
(
107.
CLKIN_IN
=>
clk,
108.
CLKFX_OUT
=>
clk_int,
109.
CLKIN_IBUFG_OUT
=>
open,
110.
CLK0_OUT
=>
open,
111.
LOCKED_OUT
=>
locked);
112.end
estrutural;
13
No
caso,
utilizamos
um
sinal
interno
clk_int,
que
serve
como
saída
do
dcm1.
Não
podemos
utilizar
diretamente
o
clock
da
placa
(50mHz),
pois
há
problemas
como
capacitâncias
parasitas
que
prejudicariam
o
funcionamento
do
circuito.
De
fato,
resolvemos
esse
problema
através
do
dcm1,
que
coloca
uma
frequência
menor
em
clk_int
para
que
essa
seja
utilizada
como
entrada
para
o
clk_div.
As
saídas
do
clk_div
são
intuitivamente
mapeadas
às
saídas
clk_out
e
clk_out_2
da
base_tempo.
Acreditamos
que
a
esse
ponto,
o
leitor
já
adquiriu
certa
noção
de
código
VHDL
e
de
seu
funcionamento,
sendo
capaz
de
continuar
por
si
só
utilizando
referências
online
para
funções
mais
complexas.
14
5.
Simulando
um
projeto
Completados
os
códigos
VHDL,
podemos
realizar
simulações
e
visualizar
seu
diagrama
RTL
através
do
ISE.
Vale
lembrar
que
podemos
ver
erros
de
sintaxe
em
tempo
real
na
aba
“Errors”,
basta
um
“CTRL
+
s”
para
salvar
o
código
e
a
janela
será
atualizada
com
os
erros
encontrados:
15
Feito
isso,
basta
um
duplo-‐clique
em
“Synthesize
-‐
XST”.
Espere
alguns
instantes
e
verifique
o
log
de
erros
para
saber
se
a
sintetização
foi
feita
com
sucesso.
Para
visualizar
o
esquemático
RTL,
basta
expandir
“Synthesize
-‐
XST”,
um
dupo-‐clique
em
“View
RTL
Schematic”
e
selecionar
“Start
with
a
schematic
of
the
top-‐
level
block”
no
diálogo
que
será
aberto.
16
“Simulate
Behavioral
Model”
(a
simulação
propriamente
dita).
17
Agora,
podemos
forçar
um
valor
no
clock
de
forma
a
observar
a
saída
do
circuito
(que
se
trata
de
um
clk_div).
Devemos
clicar
com
o
botão
direito
na
variável
desejada
e
selecionar
“Force
clock”.
Isso
abrirá
uma
janela
com
diversas
caixas
a
serem
preenchidas:
“Value
Radix”
-‐
Tipo
de
clock:
binário,
ASCII,
Decimal
etc
“Leading
Edge
Value”
-‐
Valor
inicial
de
clock
“Trailing
Edge
Value”
-‐
Valor
final
de
clock
“Starting
at
Time
Offset”
-‐
Quando
o
clock
começa
“Cancel
After
Time
Offset”
-‐
Quando
o
clock
termina
“Duty
Cycle
(%)”
-‐
Razão
entre
Leading
Edge
e
Trailing
Edge
“Period”
-‐
Auto-‐explicativo
50mHz.
18
Agora,
devemos
programar
por
quanto
tempo
a
simulação
será
executada.
Basta
preencher
a
caixa
de
texto
na
barra
de
ícones
e
então
clicar
na
setá
para
a
esquerda
(apagando
a
última
simulação).
Feito
isso,
devemos
clicar
no
botão
de
play
com
uma
ampulheta
e
na
terceira
lupa
(com
um
X)
para
ajustar
a
escala
dos
gráficos
ao
tamanho
da
janela.
19
Outra
forma
de
impor
valores
de
clock
e
de
certas
entradas
é
utilizar
um
TestBench.
Para
tanto,
devemos
selecionar
a
“Implementation
View”
em
“Design
>
Hierarchy”,
clicar
com
o
botão
direito
sobre
o
módulo
principal,
ir
em
“New
>
Source
>
TestBench”.
Devemos
dar
um
nome
ao
TestBench
(normalmente
adicionando-‐se
o
sufixo
_tb
ao
nome
do
componente
original)
e
ao
confirmar
seremos
levado
à
janela
de
seu
código
fonte
(o
código
exemplo
foi
usado
em
um
debouncer,
que
será
descrito
na
última
sessão):
118.LIBRARY
ieee;
119.USE
ieee.std_logic_1164.ALL;
120.
121.ENTITY
debouncer2_tb
IS
122.END
debouncer2_tb;
123.
124.ARCHITECTURE
behavior
OF
debouncer2_tb
IS
125.
126.
COMPONENT
debouncer2
127.
PORT(
128.
Clk
:
IN
std_logic;
129.
Key
:
IN
std_logic;
130.
pulse
:
OUT
std_logic
131.
);
132.
END
COMPONENT;
133.
134.
135.
-‐-‐Inputs
136.
signal
Clk
:
std_logic
:=
'0';
137.
signal
Key
:
std_logic
:=
'0';
138.
139.
-‐-‐Outputs
140.
signal
pulse
:
std_logic;
141.
142.
-‐-‐
Clock
period
definitions
143.
constant
Clk_period
:
time
:=
10
ms;
144.
145.BEGIN
146.
147.
-‐-‐
Instantiate
the
Unit
Under
Test
(UUT)
148.
uut:
debouncer2
PORT
MAP
(
149.
Clk
=>
Clk,
20
150.
Key
=>
Key,
151.
pulse
=>
pulse
152.
);
153.
154.
-‐-‐
Clock
process
definitions
155.
Clk_process
:process
156.
begin
157.
Clk
<=
'0';
158.
wait
for
Clk_period/2;
159.
Clk
<=
'1';
160.
wait
for
Clk_period/2;
161.
end
process;
162.
163.
164.
-‐-‐
Stimulus
process
165.
stim_proc:
process
166.
begin
167.
Key
<=
'0';
168.
wait
for
Clk_period;
169.
Key
<=
'1';
170.
wait
for
Clk_period
*
6;
171.
Key
<=
'0';
172.
wait
for
Clk_period
*
4;
173.
Key
<=
'1';
174.
wait
for
Clk_period
*
4;
175.
Key
<=
'0';
176.
wait;
177.
end
process;
178.
179.END;
21
palavra
reservada
wait
para
definir
os
atrasos
entre
as
mudanças
de
valores
(que
também
podem
ser
definidas).
Com
o
TestBench
feito,
basta
simulá-‐lo
no
lugar
do
componente
original
e
teremos
o
processo
automatizado,
sem
necessidade
de
forçar
clocks
ou
coisas
do
tipo.
22
6.
Criando
um
DCM
A
criação
de
um
DCM
consiste
nos
seguintes
passos:
-‐ Selecionar
o
“Implementation
View”
em
“Design
>
Hierarchy”
-‐ Clicar
com
o
botão
direito
no
projeto
e
selecionar
New
Source
-‐ Busque
por
DCM
na
barra
de
pesquisa
e
selecione
Single
DCM_SP
conforme
a
seguinte
imagem:
-‐ Dê
um
nome
diferente
de
dcm,
tal
como
dcm1
ou
dcm2,
e
clique
em
Finish
-‐ Feito
isso,
você
será
levado
à
janela
Xilinx
Clocking
Window
-‐ Nessa
janela
é
possível
selecionar
os
mais
variados
parâmetros
para
o
clock
que
o
DCM
transformará.
23
Selecione
conforme
as
exigências
de
seu
projeto
(como
multiplicar/dividir
o
clock)
-‐ Clique
em
Next,
selecione
“Use
Global
Buffers
for
all
Selected
Clock
Outputs”
-‐ Clique
em
Next,
selecione
“Show
all
Modifiable
Outputs”
e
clique
em
Finish
24
-‐ O
DCM
está
criado,
agora
basta
utilizar
o
código
para
o
componente
de
DCM
como
mostrado
na
sessão
4.
25
7.
Implementando
um
projeto
na
FPGA
Caso
os
sinais
da
entity
do
componente
já
estejam
mapeados
para
partes
da
FPGA,
como
mostrado
na
sessão
4,
você
está
pronto
para
implementar
o
código
na
placa.
É
importante,
obviamente,
que
a
placa
esteja
ligada
ao
PC
pela
interface
USB
e
esteja
devidamente
alimentada.
Em
primeiro
lugar,
devemos
escolher
a
“Implementation
View”
em
“Design
>
Hierarchy”,
feito
isso,
clique
uma
vez
sobre
o
módulo
principal
do
seu
projeto
e
clique
duas
vezes
sobre
“Configure
Target
Device”.
A
janela
do
iMPACT
será
aberta.
Clique
duas
vezes
em
“Boundary
Scan”
e
clique
com
o
botão
direito
no
espaço
em
branco
e
selecione
“Initialize
Chain”.
Na
primeira
miniatura
da
FPGA,
carregue
o
arquivo
.bit
que
correponde
ao
seu
projeto.
Deixei
a
segunda
em
“bypass”.
Clique
com
o
botão
direito
sobre
a
primeira
miniatura
e
clique
em
“Program
FPGA
Only”.
O
programa
deve
estar
carregado
na
placa.
Observe
as
partes
para
as
quais
os
sinais
foram
mapeados.
26
8.
Exemplos
de
código
Debouncer:
180.LIBRARY
ieee;
181.USE
ieee.STD_LOGIC_1164.all;
182.USE
ieee.STD_LOGIC_UNSIGNED.all;
183.
184.ENTITY
debouncer2
IS
185.
PORT
(Clk
:
IN
STD_LOGIC;
186.
Key
:
IN
STD_LOGIC;
187.
pulse
:
OUT
STD_LOGIC);
188.END
debouncer2;
189.
190.ARCHITECTURE
shift_register
OF
debouncer2
IS
191.SIGNAL
SHIFT_KEY
:
STD_LOGIC_VECTOR(3
DOWNTO
0)
:=
"1111";
192.
193.BEGIN
194.PROCESS
195.
BEGIN
196.
197.
WAIT
UNTIL
Clk'EVENT
AND
Clk
=
'1';
198.
199.
SHIFT_KEY(2
DOWNTO
0)
<=
SHIFT_KEY(3
DOWNTO
1);
200.
SHIFT_KEY(3)
<=
NOT
Key;
201.
202.
IF
SHIFT_KEY(3
DOWNTO
0)="0000"
THEN
PULSE
<=
'1';
203.
ELSE
PULSE
<=
'0';
204.
END
IF;
205.
206.END
PROCESS;
207.END
shift_register;
27
A
forma
de
atualizar
o
valor
do
registrador
é
ir
colocando
not
key
no
lado
direito
do
vetor
de
bits
do
registrador.
Se
por
4
clocks
seguidos,
o
valor
de
key
amostrado
estiver
em
1,
o
registrador
estará
no
estado
“0000”
e
pulse
valerá
1,
caso
contrário
pulse
valerá
0.
Isso
faz
sentido
pois
evita
que
a
saída
seja
atualizada
durante
o
transiente
da
vibração
da
chave,
fazendo
com
que
ela
só
seja
ativada
algum
tempo
depois
(o
suficiente
para
que
a
trepidação
termine).
Logo,
haverá
um
atraso
muito
pequeno
(porém
detectável
em
osciloscópio)
na
resposta
da
chave.
28
A
curva
mais
baixa
é
key
e
a
mais
alta
é
not
pulse,
vemos,
portanto,
que
pulse
só
vai
a
1
algum
tempo
depois
de
key
ter
ido
a
1.
Esse
é
o
tempo
do
transiente
de
vibração.
Referências:
An
ISE
Tutorial
-‐
Luiz
Rennó
Projeto
Debouncer
-‐
Camila
Simões
da
Costa
Cunha
Vasconcellos,
Henrique
Duarte
Faria,
Patrick
Svaiter,
Paulo
Roberto
Yamasaki
Catunda
Relatório
de
Sistemas
Digitais:
Projeto
Base
de
Tempo
-‐
Michael
D.
Barreto
e
Silva,
Luiz
Carlos,
Gabriela
Dantas
29