Escolar Documentos
Profissional Documentos
Cultura Documentos
Apostila - Lógica Programável Ranhel Rev 6
Apostila - Lógica Programável Ranhel Rev 6
Julho – 2015.
Prof. João Ranhel
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 1
Introdução
Esta é uma apostila para introduzir dispositivos programáveis aos alunos de iniciação em Eletrônica Digital
(na UFPE: Técnicas Digitais). Acredito, e as evidências de mercado/indústria apontam isso, que circuitos
integrados discretos são o passado. A questão é: como ensinar aos iniciantes em circuitos digitais que os
dispositivos lógicos programáveis (CPLDs, FPGAs e os SoCs) podem ser compreendidos com a mesma
facilidade que os circuitos da geração anterior?
A primeira coisa é tomar contato logo de cara com os circuitos. A segunda é isolar o objeto de estudo,
tirando-o do contexto dos kits de desenvolvimento que algumas empresas vendem, que são caros e trazem
muitos recursos (displays, LCDs, chaves e botões, saída VGA, conversores A/D e D/A, entrada e saída de
áudio, memória, etc.). São recursos desejáveis para quem desenvolve sistemas digitais mais avançados.
Para o aluno que está começando aprender portas, blocos lógicos combinacionais e circuitos sequenciais,
ter muito recurso na placa pode intimidar, pode criar ruído onde não precisa existir algum.
Acredito que ensinar lógica programável diretamente no objeto a ser programado (CPLD e FPGA) é muito
mais construtivo. Por isso, sou adepto das placas de FPGA e CPLD mínimas. Elas possuem apenas os
circuitos integrados básicos para alimentação do chip, cristais osciladores, memória de configuração
(embora dispensável), e os conectores ligados direto nos pinos do circuito integrado.
A burocracia brasileira dificulta a compra de pequenos dispositivos. Um kit mínimo custa menos de US$ 40
nos sites de venda pela Internet. Muitos alunos podem comprar um kit assim. O desenvolvimento desse
aluno, tendo o kit para trabalhar, é superior ao daquele que só faz as práticas e daqueles que só aprendem
na teoria. Acreditando que estudantes devem ter acesso a esse material, solicitei a alguns alunos que
ajudassem a criar os kits na UFPE. O resultado foi a confecção de placas de alta qualidade. A ideia é que o
resultado desse desenvolvimento seja hardware livre (Hardware_Livre_UFPE) e por isso disponibilizamos os
esquemas dos projetos. Os arquivos desenvolvidos no CAD Eagle estão livres para quem quiser. A pessoa
pode escolher uma empresa que confeccione as placas de circuito impresso (PCBs) e o custo de produção
de cada PCB tem sido entre 1 e 2 dólares sem componentes. Escolhemos um CI FPGA que custa menos de
US 12. As listas de materiais estão disponíveis, portanto, o aluno pode montar sua própria FPGA e as placas
básicas de entrada e saída. Além disso, alunos já desenvolveram outros módulos que são agregadas ao
sistema como os shields do Arduino (aliás, uma placa desenvolvida por aluno agrega Arduino ao sistema).
Dessa forma, agora temos nossos kits minimalistas para aprendizado de eletrônica digital em dispositivos
lógicos programáveis. Aos alunos pioneiros que ajudaram no projeto (Jéssica Ribeiro, André Moraes, João
Henrique CC Albuquerque, Dierson Antônio Silva, Samuel Sobral dos Santos, José Rodrigues O Neto)
devemos nossos sinceros agradecimentos. Eles fizeram os kits se tornarem realidade.
Ensinar “descrição” (ou “configuração”) de hardware logo no primeiro contato com eletrônica digital pode
parecer improdutivo ou demasiado complexo, afinal, o aluno tem que aprender uma linguagem. A prática
tem mostrado que não. Ensinamos aos alunos que começamos por montar “tabelas” verdade. Em seguida,
extraímos das tabelas “equações” booleanas, ou seja, leis matemáticas. Equações são apenas outra forma
(mais abstrata) de representação das tabelas. Depois vem simplificação algébrica, e então ensinamos a
transformar equações em “diagramas”. Portas e blocos lógicos desenhados em circuitos eletrônicos são
apenas outra forma de representação das tabelas e equações. Se, logo de início, mostramos aos alunos que
existe outra forma de representar a mesma coisa, a “descrição” na forma de texto, o aluno aprende sem o
salto entre a forma “antiga” de criar projetos em eletrônica digital e a forma “nova”.
A apostila é um texto guia sobre dispositivos programáveis, VHDL, e o uso dos kits desenvolvidos no Depto.
de Eletrônica e Sistemas (DES) da UFPE. Um livro para aprofundar nesses assuntos é imprescindível.
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 2
Lógica Programável
Dispositivos Lógicos Programáveis (PLDs – programmable logic devices) são componentes eletrônicos
utilizados para construir sistemas digitais. Introduzidos na década de 1980, estes circuitos surgiram para
atender a grande demanda crescente na complexidade dos sistemas digitais, demandas de diminuição e
simplificação das placas de circuito impresso (PCBs), de consumo de energia, de velocidade de operação,
entre outras. Ao contrário de um circuito integrado (CI) discreto com portas ou blocos lógicos, cuja função é
fixa, um PLD tem uma função indefinida quando é fabricado. Em geral, o usuário/criador do sistema digital
é que programa um PLD determinando sua funcionalidade.
Alternativa aos circuitos programáveis são os circuitos cuja função é destinada a um propósito específico,
denominados ASICs (application-specific integrated circuit - ou circuitos integrados de aplicação específica).
Estes CIs são geralmente mais velozes, otimizados com relação ao consumo de energia, geralmente mais
baratos quando fabricados aos milhões, e suas funções são definidas na fabricação. Geralmente, ASICs não
necessitam de muitos componentes externos porque sua alta densidade permite absorver grande parte dos
subsistemas, que são implementados dentro dos próprios chips. Os problemas com ASICs são: seu
desenvolvimento é caro e demorado, não podem ser reprogramados; portanto, sua função e/ou vida útil
fica dependente do tempo de existência do produto ao que foi destinado.
Em contrapartida, os PLDs são flexíveis e podem ser reutilizados, garantindo ao produto vida útil maior
porque novas versões dos sistemas digitais podem ser programadas com seu uso, apesar de custarem mais
que os ASICs, de consumirem um pouco mais de energia em geral, e de não atingirem as velocidades de
operação mais altas que os concorrentes ASICs. Em comparação com outras tecnologias de circuitos
integrados digitais (por exemplo, circuitos discretos – hoje obsoletos), os dispositivos de lógica programável
apresentam um ciclo de projeto menor e custos reduzidos.
Os PLDs podem, atualmente, ser classificados em dois tipos de circuitos: CPLDs (complex programmable
logic device) e FPGAs (Field Programmable Logic Arrays). As CPLDs são mais simples que as FPGAs e são
utilizadas para implementação de sistemas ou circuitos lógicos de complexidade intermediária, são
reconfiguráveis e sua configuração é não volátil. As FPGAs permitem implementar sistemas lógicos de
grande complexidade em função de possuírem blocos lógicos mais complexos (explicado adiante), sistemas
de roteamento em maior escala, sistemas de distribuições de sinais globais como clock e reset, circuitos
aritméticos e DPS com multiplicadores, somadores, etc; e principalmente, blocos de memória interna –
inclusive memória RAM de porta dupla (dual-port RAM). Existem FPGAs com configuração não volátil, mas
a maioria utiliza memória RAM estática que é volátil. Portanto, uma característica marcante das FPGAs é
que elas precisam ser reconfiguradas cada vez que são desligadas. Essa reconfiguração pode ser feita de
várias maneiras diferentes: automaticamente após o reset pela FPGA que lê os bits de reconfiguração numa
memória externa, por um microprocessador externo, ou via uma porta especial chamada JTAG.
Vamos trabalhar com os CIs FPGA da Altera. Portanto, vamos explicar o que há dentro de uma família de
FPGAs especificas chamada CYCLONE II.
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 3
Um arranjo lógico programável consiste em circuitos que possuem estrutura interna baseada em um
conjunto deportas AND-OR (o conjunto de portas AND e OR são chamados de arranjos) que podem ser
ligados ou desligados para se obter, geralmente, SOMA DE PRODUTOS. As entradas desse circuito são
ligadas às portas AND (formando produtos: P = A•B•C ... •Z) e as saídas das portas AND são conectadas às
entradas das portas OR (realizando a soma: X = P1 + P2 + ... + PN), que são as saídas do circuito.
É possível fazer lógica programável em memórias ROM. Antes das PLD's serem inventadas, as memórias
ROM foram utilizadas para implementar lógica combinatória. Considere uma ROM com m entradas (Linhas
de endereço) e n saídas (bits de dados). Quando usadas como memória, cada ROM contém 2n palavras de
n-bits. Considere que as entradas são ligadas não a um endereço m-bits mas a m sinais lógicos
independentes; teremos em tese 2m funções booleanas possíveis desses sinais. Por exemplo, suponha que
m=3 = {A,B,C}. Podemos ter as seguintes combinações (endereços):
Contudo, a estrutura da ROM permite apenas n destas funções sejam obtidas nos pinos de saída. Ou seja,
se escolhermos o bit D0 como saída, podemos gravar a ROM para gerar em D0 uma soma de qualquer dos
produtos acima, basta gravar um bit ‘1’ na posição equivalente ao termo da equação desejado. Como
temos n saídas (digamos 8 bits) então teremos n (8) funções lógicas possíveis, uma em cada pino de saída
de dados (D0, D1, D2, D3, D4, D5, D6, D7). Um exemplo em D0 poderia ser gravar: {1 + 0 + 0 + 1 + 1 + 0 + 0 + 0}
que significa que no bit D0 teríamos a função:
A ROM torna-se equivalente a n de circuitos lógicos paralelos, cada qual gerando sua função lógica
independente de m entradas. Pode-se utilizar ROM (PROMs, EPROMs, EEPROMs) para esse fim para gerar
qualquer função lógica combinacional com m entradas, o que tornando o dispositivo lógico disponível para
aplicações variadas. O inconveniente é que as ROMs ficam com grande parte de seu circuito sem utilização,
são mais lentas que os circuitos convencionais, consomem mais energia, não permitem implementação de
lógica sequencial; portanto implementar lógica programável em ROM é ineficiente. A noção de
programação de memória ROM como PLD é mostrada na figura 1.
Fig. 1: Uma ROM vista como dispositivo programável (img modificada da internet).
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 4
Na década de 1970 começaram a surgir os circuitos programáveis específicos. A ideia principal era atender
uma demanda de engenharia que precisava de lógica combinacional programável para diminuição dos
espaços utilizados em PCBs. Datas marcantes e as principais tecnologias introduzidas foram:
Fig. 2: arranjo típico de um PLA: tanto a matriz AND quanto a matriz OR são programáveis (img internet).
Este tipo de circuito era particularmente difícil de ser programado devido ao fato de o projetista ter que
escolher a programação tanto dos termos de produto quanto da soma. Para melhor utilizar os Cis isso
requeria dos projetistas realizar simplificações dos circuitos desejados, o que resultava em pouca economia
de tempo de projeto.
No exemplo da Fig. 2 vemos como devem ser programadas as conexões tanto na matriz AND quanto na
matriz OR para se obter cada uma das 6 funções de saída.
A MMI introduziu um dispositivo diferente das PLAs em 1978, com uma arquitetura mais simples porque
omitia a matriz programável OR, ou seja, a matriz OR já vem configurada. Isto tornava os componentes
mais rápidos, menores e mais baratos, e o projetista deveria optar pelo tipo de arranjo de saída que
desejava. As PALs também possuíam flip-flops (ver Fig. 3) incorporados às matrizes OR, que podiam ser
programados para criar máquinas sequenciais e máquinas de estados finitos (FSM) mais facilmente.
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 5
Em certo sentido a PAL desmistifica o processo de construção de sistemas digitais porque um software de
design convertia equações booleanas de engenharia em padrões de queima ou não de fusíveis necessários
para programar o componente. Os componentes PAL rapidamente se tornaram populares.
Fig. 3: circuito do PAL PLUS 16R4 da Philips: a matriz AND é programávem e a matriz OR é fixa. Note-se a presença de
flip-flops, apropriados para criação de FSM (imagem manual Philips).
Com o sucesso das PALs, a Lattice semiconductor em 1985 expandiu a ideia criando os GAL, que tem as
mesmas propriedades lógicas das PAL mas podem ser apagadas e reprogramadas. Estes circuitos se
mostraram úteis no estágio de prototipagem de um projecto, quando alguns erros lógicos podem surgir. As
GAL podem ser programadas e reprogramadas usando um programador PAL ou usando uma técnica de um
circuito embutido em alguns chips. Um componente similar, o PEEL (programmable electrically erasable
logic), foi produzido pela ICT.1
Atualmente estes circuitos e técnicas de criação de sistemas lógicos programáveis foram substituídos pelos
novos dispositivos que surgiram a partir dos anos 1980, baseados em blocos lógicos programáveis.
1
Fonte: http://pt.wikipedia.org/wiki/Dispositivo_l%C3%B3gico_program%C3%A1vel (17/09/2014)
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 6
A Altera chama Elementos Lógicos (LE – Logic Elements) as estruturas que compõem a nova base de
dispositivos programáveis, mais genéricas e versáteis que as tradicionais matrizes de AND-OR dos arranjos
lógicos programáveis.
Fig. 4: Multiplexador de 2 entradas, e uma Look-up Table (LUT) de 2 entradas. As saídas do MUX na LUT são definidas
pelas variáveis de entrada A e B, e os registrador de deslocamento armazena os bits.
O principal componente introduzido neste tipo de tecnologia é o conceito de LUT (Look-up Table). Uma LUT
é composta de um multiplexador (figura 4) associado geralmente a um registrador de deslocamento cujos
bits de sua saída paralelizada são aplicados ao MUX. Assim, a saída F do multiplex é selecionada em função
das entradas (A e B – no exemplo). Se um determinado termo da função está ativo ou não é uma questão
de ligar (1) ou desligar (0) o bit de dado respectivo nos flip-flops do registrador.
Por exemplo, no esquema da figura 4, para obter a equação precisamos gravar os bits
“1001” nos flip-flops. Para obter a função (função XOR) precisamos gravar os bits “0110” nos
flip-flops do registrador ( ).
Associado às LUTs colocam-se algumas entradas adicionais e um ou dois flip-flops do tipo D para reter
dados, ou seja, para permitir criação de lógica sequencial. A esse conjunto a Altera dá o nome de Logical
Elements (LE), ou elementos lógicos, como pode ser visto na figura 5. Outro nome comum para esse bloco é
Configurable Logic Block (CLB).
Fig. 5: Esquemático de um bloco lógico configurável composto de uma LUT, um flip-flop e um multiplex de saída.
A complexidade dos elementos lógicos varia de tecnologia para tecnologia, e de fabricante para fabricante.
É comum construir elementos lógicos com 4, com 5 ou com 6 entradas nos multiplexadores. Isso depende
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 7
da família de elementos lógicos programáveis onde serão utilizados. A figura 6 mostra um elemento lógico
configurável de uma CPLD da Altera.
Fig. 6: Elemento Lógico (LE) configurável numa CPLD Altera. Nos dispositivos mais complexos como FPGA, os LEs
possuem entradas em cascatas para operações aritméticas e outras funções (imagem manual Altera).
Embora exista CPLDs com matrizes de portas AND e OR associadas a elementos lógicos (LUT), é uma
tendência que os circuitos, mesmo CPLDs, sejam feitos com elementos lógicos como os descritos acima.
PALs e GALs são construídos em tamanhos pequenos, ou seja, com relativamente poucos componentes
configuráveis. São apropriados para criação de circuitos lógicos de baixa complexidade, e são equivalentes
a algumas centenas de portas lógicas. Para sistemas lógicos maiores pode-se usar Complex PLD ou CPLDs.
CPLDs contém o equivalente a várias PALs que podem ser interligadas dentro de um único chip por meio de
barramentos programáveis. Dentro de um chip CPLD temos centenas ou milhares de elementos lógicos
programáveis podem ser interligados por barramentos de interconexão dentro do chip. CPLDs podem
assim substituir milhares de portas lógicas e/ou blocos lógicos vendidos em CIs discretos.
Alguns CPLDs mais antigos podem ser configurados/programados usando o programador PAL ou
programador universal, mas este método torna-se inconveniente para CIs com centenas de pinos. Assim,
surgiu outro método de programação que consiste em soldar o componente à PCB, ligar um cabo serial que
transfere dados de configuração a partir de um PC, e programar (configurar é a melhor palavra) o CI na
própria PCB junto com os outros componentes. O CPLD contém um circuito que decodifica os dados seriais
e configura o chip. Cada fabricante começou a usar um nome proprietário para o sistema de configuração
dos chips que usam essa metodologia; por exemplo, a Lattice chamou (ISP) "In-system Programming" (ou
programação no sistema), termo que ainda é utilizado.
Contudo, o método mais comum de gravação é o JTAG, que discutiremos adiante. Note que foi falado que
o CPLD é programado via cabo serial, esta é a razão por termos utilizado um registrador de deslocamento
na representação dos bits de configuração da LUT na Fig. 4. Na verdade, todos os bits de configuração de
um CPLD ou FPGA (tanto os das LUTs quanto os que configuram os barramentos de interconexões) são
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 8
A Fig. 7 ilustra como é um diagrama de blocos com a configuração interna de um CPLD da Altera.
Fig. 7: Diagrama de blocos de um CPLD Altera (MAX V). Cada Bloco Lógico (LAB) é formado de vários elementos lógicos
programáveis (Les). Um barramento interconecta blocos lógicos. Os blocos IOE mostram os circuitos que
interconectam cada bloco com os pinos de entrada e saída do circuito integrado (img manual Altera).
Os CPLDs modernos são muito utilizados para fazer pontes entre barramentos (bus-bridge), quando há
diferenças entre tipos de barramentos num sistema. Podem ainda ser utilizados para fornecer lógica
complementar para FPGAs.
Fig. 8: kit EPM240 Altera MAX II CPLD. O kit custa ~ US$ 18,00. Baseado no CPLD EPM240 possui: 240 elementos
lógicos LEs, 192 macro células, 80 pinos I/O, opera até 340 MHz (foto da internet).
Atualmente (09/2014) é possível comprar uma placa (kit) de desenvolvimento CPLD em sites da internet
por menos de US$20, como a placa da figura 8. Estes kits facilitam o uso dos CPLDs porque já vem com toda
a parte de alimentação e regulação de tensão, filtros, entrada de programação JTAG e cristal oscilador
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 9
instalados na placa. Os pinos de entrada e saída (I/O) disponíveis para os usuários estão conectados a
barras de pinos, facilitando o acesso ao usuário. Por esse motivo, são bons para criar protótipos rápidos.
FPGAs são circuitos integrados reprogramáveis que usam conjuntos de elementos lógicos (LEs, como
descritos anteriormente) como unidades básicas de construção de blocos programáveis. Cada fabricante dá
um nome ao seu conjunto de elementos lógicos, assim, podemos encontrar “blocos lógicos programáveis”
(PLBs ou Programmable Logic Blocks) ou Logic Array Blocks (LABs), e assim por diante. Para se ter uma
ideia, na família Cyclone IV da Altera, cada LAB possui:
■ 16 LEs
■ LAB control signals
■ LE carry chains
■ Register chains
■ Local interconnect
Apenas por essa pequena descrição dá para perceber que o que diferencia FPGAs de CPLDs é a
complexidade da construção dos elementos programáveis. À isso associam-se a integração em grande
escala permitindo que um chip possua milhares e até milhões de elementos lógicos (fig. 5). A fig. 9 ilustra
como estão estruturadas as FPGAs da família Cyclone II da Altera.
Fig. 9: Organização interna das matrizes de blocos lógicos (LAB) na Cyclone II da Altera. Cada LAB contém 16
elementos lógicos (Fig. 6) interconectados localmente. Entre LABs vizinhos há um barramento de interconexão local.
Para interconectar LABs distantes, há uma estrutura de barramentos de interconexão formando uma matriz (array)
com barramentos para colunas e linhas que formam a matriz de interconexões (img manual Altera).
Além de possuirem as estruturas de blocos lógicos programáveis, as FPGAs possuem também subsistemas
ou blocos lógicos dedicados. Por exemplo:
• Sistema de gerenciamento de clock – dedicado para gerenciar sinais vários sinais de clock (relógios do
sistema), sinais de reset e enable global, etc. Para isso, os blocos dos FGPAs avançados possuem PLLs
(Phase Locked Loop) que permitem multiplicar e dividir o clock de entrada gerando duty-cicles variados.
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 10
• Advanced I/O support – que permite gerar sinais diferenciais de alta velocidade nas saídas (para
transceptores diferenciais), ou permitem controlar os vários níveis de tensão (Single-ended I/O standard
support, including 2.5-V and 1.8-V, SSTL class I and II, 1.8-V and 1.5-V HSTL class I and II, 3.3-V PCI and PCI-X
1.0, 3.3-, 2.5-, 1.8-, and 1.5-V LVCMOS, and 3.3-, 2.5-, and 1.8-V LVTTL).
• Bloco de memória RAM – internamente os chips FPGAs possuem atualmente RAM estática de alta
velocidade, alguns com dual-port RAM.
É possível comprar um kit FPGA atualmente (Fig. 10) por valores como ~US$ 30,00 (09/2014). Um circuito
integrado FPGA hoje, com 6.000 LEs pode custar em torno de US$ 12,00; apesar de haver CIs FPGA
especializados que custam até US$ 20.000,00 ou mais.
Fig. 10: Placa (kit) FPGA CoreEP4CE6 Cyclone IV Altera. A placa é feita par prover alimentação ao FPGA, sinal de clock e
acesso aos pinos do JTAG usados para configurar o chip. Os pinos e entrada e saída da FPGA ficam todos disponíveis
para o usuário (foto do site DX na internet).
Uma tendência também é embutir microprocessadores nas FPGAs, criando os chamados SoC (System on
Chips). Esse tipo de componente permite aproveitar o melhor dos dois mundos: a flexibilidade de rodar
software nos microprocessadores, dentro de uma FPGA que permite processamento em hardware.
Com dispositivos tão complexos, fica evidente a necessidade de utilização de uma ferramenta apropriada
para configurá-los. Um FPGA pode chegar a ter milhões de bits que precisam ser ligados ou desligados,
basicamente para três fins: implementar a lógica desejada nos LEs, configurar o roteamente e as
interconexões locais ou na matriz geral do chip, ou preencher os bits dos blocos de memória interna do
chip. Assim, um FPGA pode facilmente alcançar milhões de bits necessários para configurá-lo. Por esse
motivo, usa-se FFs tipo D em cada bit, e os dados de configuração são introduzidos no chip cada vez que o
FPGA é religado.
Cada bit interno pode representar um fio que o usuário precisaria ligar num protoboard, ou uma trilha a ser
feita na PCB. Só para dar um exemplo, se uma FPGA tem 2 milhões de bits internos para configuração, e o
usuário gastasse 1 segundo para ligar cada bit, ele levaria ~556 horas contínuas para liga-los; ou ~ 23 dias
contínuos. Fica evidente a necessidade da assistência de um computador para realizar tal tarefa. Para isso
foram desenvolvidos as ferramentas Electronic Design Automation (EDA ou ECAD), que fazem a
“automação do projeto eletrônico”. O programa EDA da Altera, onde o usuário descreve o hardware de seu
projeto é o QUARTUS II.
O usuário pode configurar esses chips para implementar funcionalidades complexas e personalizadas em
hardware. Para isso, ele deverá descrever o hardware desejado utilizando uma linguagem de descrição de
hardware (HDL – Hardware Description Language), que são introduzidas no QUARTUS. As duas linguagens
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 11
mais conhecidas para descrição de hardware são VERILOG e VHDL, na qual serão baseadas nossas práticas
descritas adiante.
Já da década de 1970 o projeto das PCBs se tornaram complexo o bastante para causar um embaraço para
a indústria eletrônica: como testar cada placa produzida? Com os circuitos integrados crescendo em
complexidade o número de trilhas da placas aumentavam. Mais ainda, surgiram PCBs com vários layers e as
trilhas ficavam ‘escondidas’ e sem pontos de acesso para serem testadas. Posteriormente surgiram CIs
cujos pinos (e as trilhas) ficavam escondidos em baixo dos CIs (os BGAs ou ball gate arrays). Para resolver o
problema o IEEE criou um grupo que ficou conhecido como Joint Test Action Group, que criou um padrão
denominado IEEE 1149.1, que define uma ferramenta para testes de placas, conhecido também como
Standard Test Access Port e Boundary-Scan Architecture.
A imagem 11 mostra como o padrão IEEE 1149.1 insere no chip a capacidade de funcionar na cadeia de CIs
com arquitetura boundary-scan. Estes chips possuem em cada pino do CI um sistema de chaveamento que
permite desconectar a lógica interna do CI, portanto temos os núcleos lógicos do CI desconectados do
mundo externo; assim como desconectar as trilhas externas da lógica interna, portanto, uma trilha da placa
pode ser isolada. O boundary-scan permite excitar tanto a lógica interna do chip (com as trilhas
desconectadas) quanto as trilhas externas (com as lógicas internas dos chips desconectadas). Para isso os
CIs com JTAG possuem pinos adicionais dedicados, e são interconectados em cadeia. Assim, é possível
deslocar os bits da cadeia de forma que podemos ‘ler’ como está cada pino isolado de cada CI da cadeia.
Fig. 11: Chip com o boundary-scan architecture (ou JTAG). Estes chips possuem em cada pino do CI um sistema de
chaveamento que pode desconectar a lógica interna, pode desconectar as trilhas externas, e permite excitar tanto a
lógica interna quanto as trilhas externas. Os chips são interconectados em cadeia.
Dessa forma, podemos excitar uma trilha e verificar se o sinal chega apenas nos pinos aos quais ela está
ligada, verificando se há rompimento ou curto nas trilhas.
Por outro lado, se podemos desconectar os CIs e podemos excitá-los internamente, podemos então usar o
boundary-scan para dois outros propósitos: gravar bits dentro do chip e verificar o status desses bits; ou
seja, podemos configurar ou programar os chips. Por outro lado, se podemos ler os bits dentro do chip
então podemos usar o JTAG como ferramenta de depuração (debugging). A figura 12 mostra uma placa de
circuito impresso com alguns CIs com e outros sem JTAG, e a forma como a cadeia é ligada.
Os pinos JTAG do chip tem nomes definidos: TDI (test data input), TCK (test clock), TMS (test mode select) e
TDO (test data output). Para fazer a cadeia, conectam-se os pinos em paralelo exceto TDI/TDO que são
ligados em série. O pino TDI1 do 1º chip (por onde entram os dados da cadeia) está ligado no terminal JTAG.
O pino TDO1 do 1º chip é ligado ao TDI2 do 2º chip na cadeia, e seu TDO2 é ligado ao TDI do chip seguinte e
assim por diante, até que TDO do último chip se conecta ao terminal JTAG (figura 12).
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 12
Fig. 12: Placa de circuito impresso (PCB) com um terminal JTAG de acesso externo. Note como os CIs são ligados em
cadeia, com o TDOn de cada chip conectado ao TDIn+1 do chip seguinte. Os outros sinais são ligados em paralelo em
todos os CIs. Isso forma a cadeia boundary-scan que permite testar a placa, programá-la, e debugar projetos.
Vamos utilizar o terminal JTAG da placa para programar/configurar a placa FGPA, por isso precisamos de
um cabo ou adaptador serial que converta a saída do PC para a entrada JTAG da placa. O adaptador chama
USB-Blaster (figura 13). Este adaptador vem com dois cabos: um que se conecta à USB do PC e ao conversor
de níveis, e um flat-cable JTAG (10 pinos) que conecta o conversor ao conector JTAG da placa.
Fig. 13: Adaptador JTAG da Altera (USB-Blaster): O cabo preto é conectado a uma saída USB do PC e ao conversor de
níveis. O cabo chato (flat-cable) é conectado no conversor e no terminal JTAG da placa (foto da internet).
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 13
Como já foi dito, existem duas linguagens de descrição de hardware mais utilizadas atualmente: Verilog e
VHDL. Vamos utilizar a última por entender que ela está mais próxima do projetista de hardware, embora
Verilog também seja uma linguagem eficiente que é bastante utilizada na indústria eletrônica.
Criar um projeto em HDL segue um ciclo de desenvolvimento. Primeiro o projetista cria um projeto e
descreve o circuito usando VHDL. Durante o processo o projetista pode verificar sintaxe, etc e garantir que
cada arquivo de código gerado está descrito corretamente. Geralmente, cada arquivo VHDL descreve um
circuito, um bloco lógico, um sistema. Se achar interessante a metáfora, pense nestes arquivos como se
fossem um circuito integrado que você compraria numa loja para integrar ao seu sistema. Um arquivo deve
descrever como esses vários arquivos VHDL estão interligados – que é o arquivo que descreve a estrutura
global do projeto.
O fluxo de projeto pode ser visto na figura 14. Após descrever em VHDL os blocos que fazem parte do
sistema (fig. 14 System Design) o usuário pode verificar a funcionalidade do projeto (bloco no canto
superior direito: Functional Simulation, Design Rule Checking e RTL View, onde se pode ver graficamente
os blocos no nível de transferência de registradores, ou RTL).
Em seguida, o usuário deve impor as restrições ao projeto, ou seja, deve configurar quais pinos físicos do CI
receberá os sinais que na descrição de hardware foram tratados por nomes. Pode ainda fazer análises de
performance aproximada e consumo, ambas baseadas em simulação (Fig 14 – I/O Assignment & Analysis).
Na sequência o usuário deve fazer a síntese propriamente dita (RTL Synthesis). O programa Quartus rotear
as funções desejadas dentro do dispositivo escolhido (Place & Route Process). O programa vai gerar um
arquivo que é uma fileira de bits ‘1’s e ‘0’s respeitando o que é descrito (a função que deve ser executada)
associada aos pinos físicos do FPGA. Nesse momento fazemos a gravação do arquivo configurador no
dispositivo.
Fig. 14: Fluxo de criação de um projeto em HDL (retirado manual Quartus II)
Projetistas já em estágio avançados podem editar os locais a distribuição de funções na planta do chip (Chip
Editor), mas podem também analisar por meio de simulações as áreas de dissipação de energia na FPGA de
forma mais realística, assim como a temporização dos sinais de forma estimada, porém mais realista. Para
isso, usam-se ferramentas de simulação (Power Analyis, Board-Level Timing, etc, quadro à direita inferior
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 14
na fig. 14). Esses procedimentos são avançados e não serão vistos na apostila. Pode-se ainda utilizar o JTAG
e outras ferramentas de software para DEBUGAR seu hardware já na placa (Fig. 14 In-System Verification).
Esse é o processo normal de criação de um projeto utilizando uma linguagem HDL e uma ferramenta EDA.
Agora, vamos analisar como se faz a descrição de hardware.
VHDL foi originalmente proposta pelo Depto de Defesa americano (DARPA) e depois foi transferida para o
IEEE (Institute of Electrical and Electronics Engineers) que a padronizou. A linguagem é formalmente
conhecida como IEEE 1076, ratificada em 1987, depois revisada em 1993, pequenas alterações foram
introduzidas em 2000 e 2002, e por último, em setembro de 2008 foi aprovado pelo REVCOM a mais
recente versão, IEEE 1076-2008.
A ideia inicial da linguagem de descrição de hardware era padronizar a forma de descrever os circuitos
lógicos de milhares de placas de diversos fornecedores do DARPA, em substituição aos desenhos dos
circuitos; assim, seria possível passar a descrição de uma placa de um fornecedor para outro fornecedor
com mais facilidade. Em seguida, observou-se que a linguagem de descrição do hardware também serve
para simulações, para testar se o circuito opera da forma que se espera. Portanto, um HDL serve também
para simular funcionamento dos circuitos, o que não é objeto desta apostila.
Depois, ferramentas foram criadas para sintetizar circuitos em CPLDs e FPGAs. Sintetizar significa
transformar a descrição dos circuitos em conexões dentro dos CIs de lógica programável, de forma que o
comportamento e as funcionalidades descritas na linguagem se tornem efetivamente circuitos de hardware
dentro dos chips. Nós vamos trabalhar com esta perspectiva.
Vantagens Desvantagens
Projeto independente da tecnologia; Hardware gerado é menos otimizado;
Facilidade na atualização dos projetos; Simulações mais lentas que implementações
Intercâmbio de projetos entre equipes de Dificuldade em encontrar pessoal treinado para
desenvolvedores lidar com a linguagem;
Reconfiguração parcial e dinâmica;
Reduz tempo de projeto e custo;
Elimina erros de baixo nível;
Simplifica a documentação
Aumento da performance
Toda linguagem tem um conjunto de regras (chamada sintaxe) que permite a um compilador,
interpretador e/ou sintetizador verificar se não há ambiguidades ou descrições incongruentes. Vamos
então analisar quais os conjuntos de sintaxes básicos de VHDL.
Lembre-se de uma coisa primordial: quando você está trabalhando em um HDL você não está
PROGRAMANDO, no sentido de fazer um programa em C ou assembly, você está DESCREVENDO
um hardware. Portanto, saiba primeiro o que você quer fazer no hardware.
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 15
• Inserimos comentários em VHDL utilizando dois sinais ‘--‘; depois desses sinais podemos escrever
qualquer coisa que o compilador ignora (até o próximo ENTER);
• Como outras linguagens, um enunciado, comando, declaração em VHDL termina com ‘;’
• VHDL só reconhece os caracteres 1...9 e as letras A-Z ou a-z e ainda o caractere underline ‘_’. Um
identificador (variável, uma porta, ou nome de um sinal) tem que começar com uma letra. Identificadores
não podem também terminar com 2 ‘_´nem ter dois underlines seguidos.
c <= b; -- esta linha de comando é exatamente igual à anterior, porque C é igual a c para VHDL
end df_Interruptor_3_IN;
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 16
As 10 primeiras linhas desse código começam com “--“, ou seja o que vem na frente é comentário, é para
descrever o projeto e será desconsiderado na hora da sintetização. Depois vem as declarações
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
Essa parte do código diz para o compilador/sintetizador quais bibliotecas a serem utilizadas na descrição e
quais funções, componentes ou blocos da bibliotecas serão usados. No caso, usamos todos (all). Depois
vemos a descrição da ENTITY, que é a interface do projeto:
entity Interruptor_3_IN is
-- estas são as portas que conectam a entidade ao mundo externo
Port ( CHV : in STD_LOGIC_VECTOR (2 downto 0);
LED : out STD_LOGIC);
end Interruptor_3_IN;
A descrição da caixa preta começa com a palavra-chave entity, então vem o nome do circuito
“Interruptor_3_IN”. Nunca use caracteres com acentos nem espaços nos nomes, e procure usar nomes
que signifiquem o que o circuito faz. Depois vem a palavra-chave is. A descrição dessa caixa preta só
termina com a palavra-chave end, seguida do nome da entidade e ponto e vírgula ‘;’.
No meio da definição da entidade há um bloco (Port) de descrição das portas que entram ou saem da caixa
preta. No exemplo, há um sinal de entrada chamado CHV que é um vetor (um barramento) de 3 bits; quer
dizer, há três sinais/fios chamado CHV que entram na caixa (CHV(2), CHV(1) e CHV(0)). Depois do nome do
sinal vem : in que determina que são fios/sinais de entrada. O tipo do sinal (STD_LOGIC_VECTOR) diz que se
trata de um vetor, e a abrangência (2 downto 0) diz que o vetor tem o bit mais significativo com o index 2,
e o menos significativo com o index 0.
No bloco (Port) também está descrito que existe uma porta chamada LED que é um sinal de saída (: out) e
que é um sinal lógico padrão (STD_LOGIC), ou seja, um fio único por onde o sinal sai da entidade.
A caixa preta descrita acima pode ser representada pelo seguinte diagrama de bloco:
CVH(2)
CVH(0)
Em seguida no código surge a descrição do que existe dentro dessa caixa preta chamada. O início da
descrição da arquitetura do circuito começa com a palavra-chave architecture.
end df_Interruptor_3_IN;
Literalmente, a primeira linha quer dizer: “a arquitetura cujo nome é df_Interruptor_3_IN da caixa preta
chamada Interruptor_3_IN é”. O nome df_Interruptor_3_IN é o nome da arquitetura, você pode
utilizar o nome que quiser, respeitando as regras descritas acima.
A descrição da arquitetura começa com a palavra-chave begin e termina com a palavra-chave end, seguida
do nome da arquitetura e de ponto e vírgula ‘;’. No meio há uma atribuição, um comando que diz: LED
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 17
recebe o sinal da saída de (<=) uma porta XOR, cujos sinais de entrada são CHV(0) XOR CHV(1) XOR CHV(2). O
circuito completo descrito no código acima pode ser representado assim:
CVH(2)
CVH(1) LED
CVH(0)
Em VHDL devemos sempre lembrar que os blocos que estamos descrevendo acontecem em paralelo.
Existem três diferentes estilos ou abordagens para programação em VHDL: fluxo de dados (data flow),
descrição de estruturas (structure) e ainda descrição de comportamento (behavior).
Fluxos de dados são descritos geralmente por meio do operador “<=”, que especifica diretamente as
relações entre sinais. Podemos pensar que o equivalente seria lógica combinacional, ou seja, as saídas
dependem apenas das entradas que são usadas como operadores. Note-se que neste estilo de
programação o projetista descreve o circuito lógico como se estivesse detalhando graficamente. O
projetista tem que descrever as conexões e as operações que ocorrem entre os sinais.
Estruturas são necessárias para conectar hierarquicamente os vários blocos de um sistema digital. Assim, o
estilo estrutural é necessário para compor o bloco lógico hierárquico de maior importância no projeto.
Comportamento é um estilo mais abstrato de descrição de hardware. Neste estilo o projetista apenas diz
como o circuito deve se comportar, sem se importar com “como” estão conectados os elementos lógicos
que executam aquelas funções. Sabemos que o estilo behavioral está sendo utilizado porque a descrição de
comportamento é marcada pelo uso de processos.
Um processo (process) é caracterizado pela palavra-chave process seguido de uma lista de sinais que
disparam aquele processo. Veja o seguinte exemplo:
ARCHITECTURE arq_detecta OF detecta IS
begin
process(clk,sensor_1)
begin
if(rising_edge(clk) and sensor_1='1') then
led <= '1';
else
led <= '0';
end if;
end process;
end arq_detecta;
Dentro dessa arquitetura aparece um processo, descrito a partir da palavra-chave process(). Dentro dos
parênteses está indicado que dois sinais disparam este processo: o sinal clk e o sinal sensor_1. A descrição
do comportamento do circuito começa depois do begin dentro do processo e termina em end process;.
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 18
Dentro temos uma estrutura if (alguma condição) then, que termina em end if; e que tem uma alternativa
else no meio. O que é testado (alguma condição) é testado em relação a ser uma verdade booleana; por
exemplo, if (x or 1) then, sempre resultará 1, portanto sempre será executado. Já if (x and y and 0) then,
nunca será executado porque uma AND com entrada zero resulta zero, portanto, neste caso o else seria
executado.
O teste do if do exemplo acima é sobre ter ocorrido o evento de subida do sinal de clock (rising_edge(clk) e
(and) se o sinal do sensor_1 está em nível lógico ‘1’. Se isso ocorrer então a primeira parte do if é
executada e o else será ignorado, portanto, o sinal led assume o valor ‘1’.
Caso contrário, se o sinal sensor_1 estiver em ‘0’, o bloco do if será ignorado e o bloco dentro do else será
executado, fazendo o sinal led ser igual a ‘0’.
Toda vez que o ocorrer um evento (uma variação) no sinal de clk ou no sinal sensor_1 este processo será
executado e estas condições serão testadas.
Tenha em mente que em VHDL os processos acontecem em paralelo, assim, a descrição de hardware pode
ter vários processos mas, fisicamente no CI eles ocorrem em paralelo.
Mais detalhes da linguagem VHDL deve ser buscada nos livros que descrevem detalhes da linguagem. Um
livro indicado é Free Range VHDL Book - Free Range Factory, que pode ser baixado do site:
http://www.freerangefactory.org/dl/free_range_vhdl.pdf
A seguir, vamos descrever uma série de práticas para consolidar o aprendizado dos diversos.
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 19
1.3 Placa de FPGA: criada e montada aqui no DES da UFPE, a placa de FPGA é baseada no
circuito integrado CYCLONE IV da empresa Altera.
A alimentação das placas FPGA pode ser utilizados para qualquer função que você
feita de duas formas: pelo próprio conector desejar.
mini-USB (preferível), ou por meio de dois A placa FPGA também tem 4 saídas de 3,3V
pinos de entrada (+V), e neste caso, que podem ser utilizadas para alimentar as
certifique-se da polaridade da conexão. No placas básicas de entrada e saída.
conector mini-USB a tensão de entrada é
+5V e os reguladores internos tratam de
baixar para os valores corretos. Se utilizar os
pinos de entrada, certifique-se de que é uma
tensão estabilizada de +5V.
Cada um desses pinos de I/O está conectado a um pino da FPGA, portanto é menos maleável
que nosso kit, contudo é mais prático, porque não precisamos usar flat-cables. Dessa forma, ao
escolher uma chave ou um LED ou display, certifique-se de que a pinagem está de acordo com o
manual da placa (reproduzido a seguir).
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 27
end df_Pratica_01;
-- -------------------------------------------------------------------------------------
----------
Como Interligar as placas:
3 – Escolha o conector que desejar na FPGA. Conecte o flat cable tanto na FPGA quanto nas
placas de Entrada/Saída sempre com os cabos voltados para fora das placas.
Dois modos de ligar as placas Entrada e Saída na FPGA (lembre-se de configurar os pinos no
PIN PLANNER)
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 31
----------------------------------------------------------------------------------
-- Company: UFPE
-- Engineer: João Ranhel
--
-- Create Date: 09/04/2016
-- Design Name: Práticas de Técnicas Digitais
-- Module Name: Circuito ENCODER 8 inputs para BCD
--
-- Descrição:
-- Circuito que apresenta a estrutura WITH SELECT e o conceito de LOGIC_VECTOR
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Encoder_8IN_BCD_Prior is
-- estas são as portas NA FORMA DE VETORES que conectam essa entidade ao mundo externo
Port ( I : in STD_LOGIC_VECTOR(7 downto 0);
D : out STD_LOGIC_VECTOR(3 downto 0));
end Encoder_8IN_BCD_Prior;
with I select
D(3 downto 0) <=
"1000" when "11111111", -- a boia #8 está ativa, sai BCD = 8
"0111" when "01111111", -- a boia #8 está desativada e #7 ativa, BCD = 7
"0110" when "00111111", -- # 6 com prioridade
"0101" when "00011111", -- # 5
"0100" when "00001111", -- # 4
"0011" when "00000111", -- # 3
"0010" when "00000011", -- # 2
"0001" when "00000001", -- # 1
"0000" when others; -- se nenhuma boia está ativa
end df_Encoder_8IN_BCD_Prior;
-- -----------------------------------------------------------------------------------------------
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 33
----------------------------------------------------------------------------------
-- Company: UFPE
-- Engineer: João Ranhel
--
-- Create Date: 08/17/2013
-- Design Name: Práticas de Técnicas Digitais
-- Module Name: Comparador de 1 bit - dataflow
--
-- Descrição:
-- Módulo comparador de 1 BIT de A com 1 bit de B
-- que será usado como COMPONENTE num comparador de 4 bits
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
end df_Igual_1bit;
-- ------------------------------------------------------------------------------
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 35
----------------------------------------------------------------------------------
-- Company: UFPE
-- Engineer: João Ranhel
--
-- Create Date: 08/17/2013
-- Design Name: Práticas de Técnicas Digitais
-- Module Name: Comparador de 4 bits - Estrutural + dataflow
--
-- Descrição:
-- Este módulo é a ESTRUTURA principal de um comparador de 4 bits
-- criado a partir do componente 'Igual_1bit' que compara o bit A com B
-- (obs: este é um exemplo didático de como se monta estrutura com componentes
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- uma porta AND une os 4 sinais de X(0...3) porque A=B apenas quando todos forem =1
(AND)
A_igual_B <= X(0) and X(1) and X(2) and X(3);
end str_Comparador_4_bits;
-- OBS: O MESMO RESULTADO se obtém com o circuito descrito abaixo apenas com dataflow:
-- OBS: O MESMO RESULTADO se obtém também com o código seguinte, que descreve FIG 1.
-- architecture str_cmp4_bits of Compara_4_bits is
-- signal X : std_logic_vector (3 downto 0);
-- begin
-- X(0) <= A(0) xor B(0); -- o sinal X(0) recebe o resultado de A(0)
xnor B(0)
-- X(1) <= A(1) xor B(1);
-- X(2) <= A(2) xor B(2);
-- X(3) <= A(3) xor B(3);
-- A_igual_B <= X(0) nor X(1) nor X(2) nor X(3);
-- end str_cmp4_bits
-- --------------------------------------------------------------------------------
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 36
entity Soma_Sub_1Bit is
Port ( A, B, Te, M : in STD_LOGIC;
S, Ts : out STD_LOGIC);
end Soma_Sub_1Bit;
-----.---------..---------..---------..---------..---------..---------..---------.------
-- Company: UFPE
-- Engineer: João Ranhel
-- Create Date: 08/17/2013
-- Module Name: Somador e Subtrator Completo 4-Bits - Structural + dataflow
-- Descrição:
-- Este módulo soma/subtrai 4 bits de A com B, dependendo do valor da entrada M.
-- Se M=0 soma, se M=1 subtrai. O resultado sai em S(3...0) e Carry_Out em Ts.
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- ---------------------------------------------------------------------
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 38
-- conversão para 7-seg ANODO COMUM-dataflow (pode ser copiado em outros projs)
with numBCD select
sseg(6 downto 0) <=
"1000000" when "0000", -- alg 0 decimal, anodo comum
"1111001" when "0001", -- 1
"0100100" when "0010", -- 2
"0110000" when "0011", -- 3
"0011001" when "0100", -- 4
"0010010" when "0101", -- 5
"0000010" when "0110", -- 6
"1111000" when "0111", -- 7
"0000000" when "1000", -- 8
"0010000" when "1001", -- 9
"0001000" when "1010", -- A (hexa) anodo comum
"0000011" when "1011", -- B
"1000110" when "1100", -- C
"0100001" when "1101", -- D
"0000110" when "1110", -- E
"0001110" when "1111", -- F
"1111111" when others;
-- conversão para 7-seg CÁTODO COMUM-dataflow (pode ser copiado em outros projs)
-- with numBCD select
-- sseg(6 downto 0) <=
-- "0111111" when "0000", -- alg 0 decimal, anodo comum
-- "0000110" when "0001", -- 1
-- "1011011" when "0010", -- 2
-- "1001111" when "0011", -- 3
-- "1100110" when "0100", -- 4
-- "1101101" when "0101", -- 5
-- "1111101" when "0110", -- 6
-- "0000111" when "0111", -- 7
-- "1111111" when "1000", -- 8
-- "1101111" when "1001", -- 9
-- "1110111" when "1010", -- A (hexa) anodo comum
-- "1111100" when "1011", -- B
-- "0111001" when "1100", -- C
-- "1011110" when "1101", -- D
-- "1111001" when "1110", -- E
-- "1110001" when "1111", -- F
-- "0000000" when others;
end df_Decoder_7seg;
-- -------------------------------------------------------------------------
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 40
O código acima pode ser reutilizado em vários projetos. Reutilizando o projeto do somador ficará assim:
Obs: escolha uma chave deslizante do KIT DE2-115 da placa para ser o MODE. No kit UFPE escolha um dos
botões de pulsador. Ligue TS-OUT em um LED para verificar quando ocorre overflow.
-- arquitetura que descreve por dataflow o circuito que soma e/ou subtrai 1 bit
architecture df_Soma_Sub_1Bit of Soma_Sub_1Bit is
begin
-- aqui começa a descrição em dataflow dos circuitos
S <= A xor B xor Te;
Ts <= (B and Te) or ((M xor A) and (B or Te));
end df_Soma_Sub_1Bit;
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 41
-----.---------..---------..---------..---------..---------..---------..---------.------
-- Company: UFPE
-- Engineer: João Ranhel
-- Create Date: 08/17/2013
-- Design Name: Práticas de Técnicas Digitais
-- Module Name: Somador e Subtrator Completo 4-Bits - Structural + dataflow
-- Descrição:
-- Este módulo soma/subtrai 4 bits de A com B, dependendo do valor da entrada M.
-- Se M=0 soma, se M=1 subtrai. O resultado sai em S(3...0) e Carry_Out em Ts.
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
end st_Somador_Subtrator_4bits;
-- ---------------------------------------------------------------------
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 42
end bh_Registrador;
-- começo da arquitetura
begin
-- este procedimento conecta as saídas dos FFs r_conta com as saídas Q da entidade
Q <= STD_LOGIC_VECTOR(r_conta); -- Q(i) converte vetor em saída(pinos)
-- este procedimento gera um pulso '1' quando o último número (2**N-1) é atingido
max_out <= '1' when r_conta=(2**N-1) else '0';
end bh_Binary_Counter;
-- OBS: neste código, o número de BITS do contador (ou seja, o número de FFs) é definido
-- por você, no GENERIC (default = 4) e pode ser mudado na hora de instanciar esse
-- componente, em outra estrutura, usando generic map ( N => 10 ), por exemplo.
I. Experimento e Simulação
II. Organização do Relatório
Considere o circuito da Fig. 1. O relatório deve ser organizado nos
seguintes tópicos (os títulos dos tópicos
não precisam ser necessariamente os
mesmos indicados) (sejam sintéticos, usem
200 palavras por tópico no máximo);
1) Resumo (Opcional): Deve conter um
breve resumo sobre o trabalho com os
principais resultados obtidos;
2) Introdução/Motivação: Deve conter
Fig. 1 – Contador decimal síncrono de 4-bits. uma breve introdução/motivação sobre
a prática, com objetivos e roteiros
Trata-se de um contador binário de 4 3) Fundamentação Teórica: Contém a
bits cujo clock está ligado aos FFs em teoria utilizada na prática. Uma breve
paralelo (contador síncrono). Note que descrição sobre o que faz o circuito (no
portas AND adicionais detectam caso o contador binário, contador de
quando o FF-C muda (quando a década, e divisor de frequência). Ou
contagem chega a 3) e quando o FF-D seja, explique de onde saiu o circuito
muda (quando chega a 7). inicial;
Este contador conta até 10 e reseta os
FFs quando a porta NAND tem 4) Metodologia: deve conter o arranjo
entradas = ‘1’. Portanto, depois do experimental, os métodos de medição
número 9, ao receber um clock, o e os resultados da
contador volta para “0000”. Por isso é simulação/experimentos;
chamado contador decimal binário. 5) Análise: deve conter a análise dos
O contador de módulo-M conta em resultados experimentais em
binário até o número M que você o comparação com os resultados teóricos
programar. e/ou simulados.
begin
-- este processo conta pulsos e memoriza em r_conta
mem_conta: process(clk,reset)
begin
if (reset='0') then -- reset assíncrono em ZERO
r_conta <= (others => '0'); -- zera todos os bits de r_conta
elsif rising_edge(clk) then -- sem reset, na subida de clk
r_conta <= r_proxi; -- memoriza proximo valor
end if;
end process mem_conta;
-- -----------------------------------------------------------------------
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 48
entity Display_4dig_7seg_mux is
Port ( clk, reset : in STD_LOGIC;
sseg : out STD_LOGIC_VECTOR (7 downto 0);
dig : out STD_LOGIC_VECTOR (3 downto 0));
end Display_4dig_7seg_mux;
begin
-- instanciar o componente divisor de frequência para 10 Hz...
clock_10Hz : entity work.clk_div(bh_clk_div)
generic map(N => 1600000) -- (Na Papilio, 32Mhz, N=1600000 -> clkout= 10Hz)
port map(CLKin => clk,
reset => reset,
CLKout => clk_10Hz);
-- instanciar 1o. contador de módulo M (unidade)
conta_Un : entity work.conta_mod_M(bhv_conta_mod_M)
generic map(N => 4, M => 10) -- N = 4 bits e M = 10 (modulo 10)
port map(clk => clk_10Hz,
reset => reset,
max => mx1,
q => cU);
-- instanciar 2o. contador de módulo M (dezena)
conta_Dz : entity work.conta_mod_M(bhv_conta_mod_M)
generic map(N => 4, M => 10) -- N = 4 bits e M = 10 (modulo 10)
port map(clk => mx1,
reset => reset,
max => mx2,
q => cD);
-- instanciar 3o. contador de módulo M (centena)
conta_Cn : entity work.conta_mod_M(bhv_conta_mod_M)
generic map(N => 4, M => 10) -- N = 4 bits e M = 10 (modulo 10)
port map(clk => mx2,
reset => reset,
max => mx3,
q => cC);
-- instanciar 4o. contador de módulo M (milhar)
conta_Ml : entity work.conta_mod_M(bhv_conta_mod_M)
generic map(N => 4, M => 10) -- N = 4 bits e M = 10 (modulo 10)
port map(clk => mx3,
reset => reset,
max => mx4,
q => cM);
-- instanciar o multiplex nesta estrutura
mux_4x_7s : entity work.Mux_4dig_7seg(bh_Mux_4dig_7seg)
port map(clk => clk,
reset => reset,
nU => cU,
nD => cD,
nC => cC,
nM => cM,
sseg => sseg,
dig => dig);
end st_Display_4dig_7seg_mux;
-- FIM da entidade principal --
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 50
----------------------------------------------------------------------------------
-- Company: UFPE
-- Engineer: João Ranhel
--
-- Create Date: 08/17/2013
-- Design Name: Práticas de Técnicas Digitais
-- Module Name: Multiplex de 4 dígitos e 7 segmentos
-- Descrição:
-- Este módulo pode ser utilizado em vários projetos que utilizem 4 nums c/ display 7 seg
-- entra 4 nums em nU...nM, sai o vetor dig "1110"=dig unidade e "0111"=milhar (ativo low)
-- sai sseg (7 downto 0) 0 LED "a" é o LSB, "g" = sseg(6), e ponto decimal em sseg(7).
-- O circuito apaga os leds zerados à esquerda (blanking em dígitos não significativos)
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- caixa preta: entra clock + 4 nums BCD e sai 7seg DP + sinal dígito da vez...
entity Mux_4dig_7seg is
Port ( clk, reset : in STD_LOGIC; -- sinal de clock
nU,nD,nC,nM : in STD_LOGIC_VECTOR (3 downto 0); -- nums BCD de 4 bits
sseg : out STD_LOGIC_VECTOR (7 downto 0); -- sinal 7 segmtos + dp
dig : out STD_LOGIC_VECTOR (3 downto 0)); -- seleção dígito na placa
end Mux_4dig_7seg;
-- começo da arquitetura
begin
-- instanciar o componente divisor de frequência para 10 Hz...
clock_varre : entity work.clk_div(bh_clk_div)
generic map(N => 132000) -- N = 132.000 faz o clk out ~ 120 Hz
port map(CLKin => clk,
reset => reset,
CLKout => clk_varre);
-- processo que ajusta o valor do dado digaux para un, dz, cn, milhar...
Ajst_digaux : process (dignxt) is
begin
case (dignxt) is
when "1110" => digaux <= nU; sseg(7) <= '1';
when "1101" => digaux <= nD; sseg(7) <= '0'; -- deixei o pto fixo na dezena!
when "1011" => digaux <= nC; sseg(7) <= '1';
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 51
----------------------------------------------------------------------------------
-- Company: UFPE
-- Engineer: João Ranhel
--
-- Create Date: 08/17/2013
-- Design Name: Práticas de Técnicas Digitais
-- Module Name: Divisor de clock - Behavioral
-- Descrição:
-- Módulo DIVISOR DE CLOCK por um valor N inteiro (CLKin é dividido por N).
-- (duty cycle=50%: a saída CLKout='1' por N/2 pulsos de CLKin; CLKout='0' durante N/2 pulsos)
-- Ajuste os generics N_varre e N_10Hz no início do módulo (na entity) p/ mudar f_varre e timer
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
----------------------------------------------------------------------------------
-- Company: UFPE
-- Engineer: João Ranhel
--
-- Create Date: 08/17/2013
-- Design Name: Práticas de Técnicas Digitais - PR_04B
-- Module Name: Contador de Módulo M - Behavioral
--
-- Descrição:
-- Este circuito é um contador de N bits de módulo M, ou seja
-- o contador conta de 0 até M (M tem que ser representável em N bits)
-- Os valores de N e M podem ser ajustados no GENERIC ou em GENERIC MAP...
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
begin -- da architecture
-- --------------------------------------------------------------------------
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 53
entity Display_4dig_7seg_mux is
Port ( clk, reset : in STD_LOGIC;
sseg1, sseg2, sseg3, sseg4 : out STD_LOGIC_VECTOR (6 downto 0));
end Display_4dig_7seg_mux;
begin
-- instanciar o componente divisor de frequência para 10 Hz...
clock_10Hz : entity work.clk_div(bh_clk_div)
generic map(N => 1600000) -- (Na Papilio, 32Mhz, N=1600000 -> clkout= 10Hz)
port map(CLKin => clk,
reset => reset,
CLKout => clk_10Hz);
-- instanciar 1o. contador de módulo M (unidade)
conta_Un : entity work.conta_mod_M(bhv_conta_mod_M)
generic map(N => 4, M => 10) -- N = 4 bits e M = 10 (modulo 10)
port map(clk => clk_10Hz,
reset => reset,
max => mx1,
q => cUn);
-- instanciar 2o. contador de módulo M (dezena)
conta_Dz : entity work.conta_mod_M(bhv_conta_mod_M)
generic map(N => 4, M => 10) -- N = 4 bits e M = 10 (modulo 10)
port map(clk => mx1,
reset => reset,
max => mx2,
q => cDz);
-- instanciar 3o. contador de módulo M (centena)
conta_Cn : entity work.conta_mod_M(bhv_conta_mod_M)
generic map(N => 4, M => 10) -- N = 4 bits e M = 10 (modulo 10)
port map(clk => mx2,
reset => reset,
max => mx3,
q => cCn);
-- instanciar 4o. contador de módulo M (milhar)
conta_Ml : entity work.conta_mod_M(bhv_conta_mod_M)
generic map(N => 4, M => 10) -- N = 4 bits e M = 10 (modulo 10)
port map(clk => mx3,
reset => reset,
max => mx4,
q => cMl);
-- instanciar o multiplex nesta estrutura
mux_4x_7s : entity work.Mux_4dig_7seg(bh_Mux_4dig_7seg)
port map(clk => clk,
reset => reset,
nUn => cUn,
nDz => cDz,
nCn => cCn,
nMl => cMl,
sseg => sseg,
dig => dig);
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 54
-- esta parte do circuito liga apenas UM dos displays por vez (time multiplex) ...
proc_mux_display: process(dig) is
begin
if dig="1110" then -- se estiver varrendo dig UN
sseg1 <= sseg;
else
sseg1 <= "1111111"; -- se não, apaga o display
end if;
if dig="1101" then -- se estiver varrendo dig UN
sseg2 <= sseg;
else
sseg2 <= "1111111"; -- se não, apaga o display
end if;
if dig="1011" then -- se estiver varrendo dig UN
sseg3 <= sseg;
else
sseg3 <= "1111111"; -- se não, apaga o display
end if;
if dig="0111" then -- se estiver varrendo dig UN
sseg4 <= sseg;
else
sseg4 <= "1111111"; -- se não, apaga o display
end if;
end process proc_mux_display;
end st_Display_4dig_7seg_mux;
-- FIM da entidade principal –
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 55
----------------------------------------------------------------------------------
-- Company: UFPE
-- Engineer: João Ranhel
--
-- Create Date: 08/17/2013
-- Design Name: Práticas de Técnicas Digitais
-- Module Name: Multiplex de 4 dígitos e 7 segmentos
-- Descrição:
-- Este módulo pode ser utilizado em vários projetos que utilizem 4 nums c/ display 7 seg
-- entra 4 nums em nU...nM, sai o vetor dig "1110"=dig unidade e "0111"=milhar (ativo low)
-- sai sseg (7 downto 0) 0 LED "a" é o LSB, "g" = sseg(6), e ponto decimal em sseg(7).
-- O circuito apaga os leds zerados à esquerda (blanking em dígitos não significativos)
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- caixa preta: entra clock + 4 nums BCD e sai 7seg DP + sinal dígito da vez...
entity Mux_4dig_7seg is
Port (clk, reset : in STD_LOGIC; -- sinal de clock e reset
nUn,nDz,nCn,nMl : in STD_LOGIC_VECTOR (3 downto 0); -- nums BCD de 4 bits
sseg : out STD_LOGIC_VECTOR (6 downto 0); -- sinal 7 segmtos
dig : out STD_LOGIC_VECTOR (3 downto 0)); -- seleção dígito na placa
end Mux_4dig_7seg;
-- começo da arquitetura
begin
-- instanciar o componente divisor de frequência para 10 Hz...
clock_varre : entity work.clk_div(bh_clk_div)
generic map(N => 200000) -- N = 200.000 faz o clk out ~ 125 Hz
port map(CLKin => clk,
reset => reset,
CLKout => clk_varre);
-- processo que ajusta o valor do dado digaux para un, dz, cn, milhar...
Ajst_digaux: process (dignxt) is
begin
case (dignxt) is
when "1110" => digaux <= nUn;
when "1101" => digaux <= nDz;
when "1011" => digaux <= nCn;
when "0111" => digaux <= nMl;
when others => digaux <= "1111";
end case;
end process Ajst_digaux ;
-- e ajusta a saída dig para selecionar o prox dígito a ser ligado
dig <= dignxt;
----------------------------------------------------------------------------------
-- Company: UFPE
-- Engineer: João Ranhel
-- Create Date: 08/17/2013
-- Design Name: Práticas de Técnicas Digitais
-- Module Name: Divisor de clock - Behavioral
-- Descrição:
-- Módulo DIVISOR DE CLOCK por um valor N inteiro (CLKin é dividido por N).
-- (duty cycle=50%: a saída CLKout='1' por N/2 pulsos de CLKin; CLKout='0' durante N/2 pulsos)
-- Ajuste os generics N_varre e N_10Hz no início do módulo (na entity) p/ mudar f_varre e timer
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
----------------------------------------------------------------------------------
-- Apostila: Dispositivos Lógicos Programáveis e VHDL - Prof. João Ranhel 58
----------------------------------------------------------------------------------
-- Company: UFPE
-- Engineer: João Ranhel
-- Create Date: 08/17/2013
-- Design Name: Práticas de Técnicas Digitais - PR_04B
-- Module Name: Contador de Módulo M - Behavioral
--
-- Descrição:
-- Este circuito é um contador de N bits de módulo M, ou seja
-- o contador conta de 0 até M (M tem que ser representável em N bits)
-- Os valores de N e M podem ser ajustados no GENERIC ou em GENERIC MAP...
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
begin -- da architecture
-- este processo conta pulsos e memoriza em r_conta
mem_conta: process(clk,reset)
begin
if (reset='0') then -- reset assíncrono em ZERO
r_conta <= (others => '0'); -- zera todos os bits de r_conta
elsif falling_edge(clk) then -- sem reset, na descida de clk
r_conta <= r_proxi; -- memoriza proximo valor
end if;
end process mem_conta;
-- próximo estado lógico
r_proxi <= (others=>'0') when r_conta>=(M-1) else r_conta+1;
-- gera o pulso max se chegou no maior valor do módulo M
pulso_out: process(r_conta)
begin
if r_conta=(M-1) then max <= '1'; else max <= '0'; end if;
end process pulso_out;
entity Display_8dig_7seg_serial is
Port (clk, reset : in STD_LOGIC;
DIO : out STD_LOGIC;
SCK : out STD_LOGIC;
RCK : out STD_LOGIC);
end Display_8dig_7seg_serial;
----------------------------------------------------------------------------------
-- Company: UFPE
-- Engineer: João Ranhel
--
-- Create Date: 08/17/2013
-- Design Name: Práticas de Técnicas Digitais
-- Module Name: MÓDULO MUX e FSM para - Structural + Behavioral + Dataflow
--
-- Descrição:
-- (este é apenas o módulo MUX que multiplexa e serializa dados para o 74HC595)
-- Este módulo pode ser utilizado em vários projetos que utilizem 8 nums c/ display 7 seg
-- entra 8 nums em n1...n8, sai o sinal de dados e um pulso de clock para serializa-lo.
-- O circuito apaga os leds zerados à esquerda (blanking em dígitos não significativos)
-- A frequencia de varredura é conseguida instanciando o clk_div p/ 2 KHz...
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- define uma variável do tipo vars de estado (usando type) com 35 estados E00...E34
type tipo_estado is (E00,E01,E02,E03,E04,E05,E06,E07,E08,E09,E10,E11,E12,E13,E14,E15,E16,
E17,E18,E19,E20,E21,E22,E23,E24,E25,E26,E27,E28,E29,E30,E31,E32,E33,E34);
-- define sinais internos da arquitetura
signal EsA, EsF : tipo_estado;
-- declara o uso do componente divisor de clock do sistema (usa 120 Hz para varredura)
signal clk_varre: STD_LOGIC; -- clock varredura (=4KHz, 500 vezes/display)
signal proxdig : STD_LOGIC_VECTOR (7 downto 0); -- sinaliza o prox dígito
signal sseg : STD_LOGIC_VECTOR (7 downto 0); -- valor do dado a ser serializado
signal val_aux : STD_LOGIC_VECTOR (3 downto 0); -- valor aux para conversão BCD-7seg
signal Reg_Out : STD_LOGIC_VECTOR (15 downto 0);-- reg p/ armazenar concatenação sseg &
proxdig
-- a cada pulso de clk_varre o circ seleciona e memoriza O PROXIMO dígito (display 7 seg)
prox_digito: process(clk_varre, reset)
begin
if (reset='0') then
proxdig <= "00000000";
elsif rising_edge(clk_varre) then
proxdig <= "00000001"; -- por default varre o dígito 1 apenas
val_aux <= n1; -- e mostra o número da unidade!
if proxdig = "00000001" then
-- blanking: se varre dig N1 e algum dos dígitos seguintes > 0, varre também N2
if (n8>"0000" or n7>"0000" or n6>"0000" or n5>"0000" or n4>"0000" or n3>"0000" or n2>"0000") then
proxdig <= "00000010"; -- passa a varrer o segundo dígito e memoriza proxdig
val_aux <= n2;
end if;
elsif proxdig = "00000010" then
-- blanking: se varre dig N2 e algum dos seguintes > 0, varre também N3
if (n8>"0000" or n7>"0000" or n6>"0000" or n5>"0000" or n4>"0000" or n3>"0000") then
proxdig <= "00000100"; -- passa a varrer o 3o dígito
val_aux <= n3;
end if;
elsif proxdig = "00000100" then
-- blanking: se varre dig N3 e algum dos seguintes > 0, varre também N4
if (n8>"0000" or n7>"0000" or n6>"0000" or n5>"0000" or n4>"0000") then
proxdig <= "00001000"; -- passa a varrer o 4o dígito
val_aux <= n4;
end if;
elsif proxdig = "00001000" then
-- blanking: se varre dig N4 e algum dos seguintes > 0, varre também N5
if (n8>"0000" or n7>"0000" or n6>"0000" or n5>"0000") then
proxdig <= "00010000"; -- passa a varrer o 5o dígito
val_aux <= n5;
end if;
elsif proxdig = "00010000" then
-- blanking: se varre dig N5 e algum dos seguintes > 0, varre também N6
if (n8>"0000" or n7>"0000" or n6>"0000") then
proxdig <= "00100000"; -- passa a varrer o 6o dígito
val_aux <= n6;
end if;
elsif proxdig = "00100000" then
-- blanking: se varre dig N6 e algum dos seguintes > 0, varre também N7
if (n8>"0000" or n7>"0000") then
proxdig <= "01000000"; -- passa a varrer o 7o dígito
val_aux <= n7;
end if;
elsif proxdig = "01000000" then
-- blanking: se varre dig N7 e algum dos seguintes > 0, varre também N8
if (n8>"0000") then
proxdig <= "10000000"; -- passa a varrer o 8o dígito
val_aux <= n8;
end if;
elsif proxdig = "10000000" then
proxdig <= "00000001"; -- inicia mostrando apenas o digito 1
val_aux <= n1;
end if;
end if;
end process prox_digito;
-- uma máquina de estados para enviar os dados serialmente para o 74HC595 da placa
sync_FSM_serial: process(clk, EsF, clk_varre)
begin
-- aqui acontece o processo síncrono, saída = prox estado (no clock) ou reset...
if (clk_varre = '0') then -- clk_varre faz o papel de RESET (='0' faz voltar para
E00)
EsA <= E00;
elsif (rising_edge(clk)) then -- SE clk_varre='1', CADA subida de clk
EsA <= EsF; -- assume prox estado
end if;
end process sync_FSM_serial;
comb_FSM_serial: process(EsA)
begin
rck <= '0'; -- STCP #12 HC595 storage register clk input
sck <= '0'; -- default sck='0' SHCP #11 HC595 shift register clk input
dout <= '0'; -- dout = '1'
case EsA is
-- no estado zero do contador cria o contador Reg_Out (concatena sseg & proxdig)
when E00 =>
Reg_Out <= sseg & proxdig; -- concatena os 16 bits do 'Reg_Out' a serem
enviados
EsF <= E01; -- ajusta o prox estado para E01
rck <= '1'; -- STCP #12 HC595 storage register clk input
when E01 =>
rck <= '0'; -- STCP #12 HC595 storage register clk input
EsF <= E02; -- prox estado
when E02 =>
dout <= Reg_Out(0); -- coloca o bit de dado na saída
sck <= '1'; -- levanta o pulso de clock p. HC595 copiar bit
EsF <= E03; -- prox estado
when E03 =>
sck <= '0'; -- baixa o pulso de clock p. HC595
EsF <= E04; -- prox estado
when E04 =>
dout <= Reg_Out(1); -- coloca o bit de dado na saída
sck <= '1'; -- levanta o pulso de clock p. HC595 copiar bit
EsF <= E05; -- prox estado
when E05 =>
sck <= '0'; -- baixa o pulso de clock p. HC595
EsF <= E06; -- prox estado
when E06 =>
dout <= Reg_Out(2); -- coloca o bit de dado na saída
sck <= '1'; -- levanta o pulso de clock p. HC595 copiar bit
EsF <= E07; -- prox estado
when E07 =>
sck <= '0'; -- baixa o pulso de clock p. HC595
EsF <= E08; -- prox estado
when E08 =>
dout <= Reg_Out(3); -- coloca o bit de dado na saída
sck <= '1'; -- levanta o pulso de clock p. HC595 copiar bit
EsF <= E09; -- prox estado
when E09 =>
sck <= '0'; -- baixa o pulso de clock p. HC595
EsF <= E10; -- prox estado
when E10 =>
dout <= Reg_Out(4); -- coloca o bit de dado na saída
sck <= '1'; -- levanta o pulso de clock p. HC595 copiar bit
EsF <= E11; -- prox estado
when E11 =>
sck <= '0'; -- baixa o pulso de clock p. HC595
EsF <= E12; -- prox estado
when E12 =>
dout <= Reg_Out(5); -- coloca o bit de dado na saída
sck <= '1'; -- levanta o pulso de clock p. HC595 copiar bit
EsF <= E13; -- prox estado
when E13 =>
sck <= '0'; -- baixa o pulso de clock p. HC595
EsF <= E14; -- prox estado
when E14 =>
dout <= Reg_Out(6); -- coloca o bit de dado na saída
sck <= '1'; -- levanta o pulso de clock p. HC595 copiar bit
EsF <= E15; -- prox estado
when E15 =>
sck <= '0'; -- baixa o pulso de clock p. HC595
EsF <= E16; -- prox estado
Dispositivos Lógicos Programáveis João Ranhel 64
----------------------------------------------------------------------------------
-- Company: UFPE
-- Engineer: João Ranhel
--
-- Create Date: 08/17/2013
-- Design Name: Práticas de Técnicas Digitais - PR_04B
-- Module Name: Contador de Módulo M - Behavioral
--
-- Descrição:
-- Este circuito é um contador de N bits de módulo M, ou seja
-- o contador conta de 0 até M (M tem que ser representável em N bits)
-- Os valores de N e M podem ser ajustados no GENERIC ou em GENERIC MAP...
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
begin -- da architecture