Como estruturar projetos em FPGA e VHDL

projetos em FPGA e VHDL
Este post faz parte da série Como estruturar projetos em FPGA e VHDL. Leia também os outros posts da série:

Introdução

 

É muito comum vermos muita gente que trabalha com FPGA afirmar que “entende” da coisa para vermos várias barbeiragens, coisas verdadeiramente amadoras, na concepção de sistemas mais complexos de lógica programável. Porém, apesar de ser um tema que desperta muita curiosidade, pouca gente segue trabalhando com isso. Por que? Complexidade.

 

Vejo muita gente entrar, começar a mexer com FPGA e em seguida concluir que “é muito difícil” ou desanimar por fazer coisas que “na simulação funciona” mas, na prática, não. E digo além: se alguém depende do Signal Tap, ChipScope e ou outras ferramentas para por um projeto de FPGA para funcionar, é porque alguma coisa está errada. Que me desculpem os fabricantes e amantes dessas técnicas/ferramentas: elas devem ser acessórios. Em 10 anos trabalhando com FPGA, acho que nunca usei um Chipscope na vida, e olha que já fiz alguns sistemas bem grandes...

 

Existem algumas regras e alguns conceitos muito básicos que interferem de maneira muito dura e pesada no projeto de sistemas em FPGA. Ao longo desta série, pretendo pretensiosamente (redundâncias, coisa de quem trabalha com FPGA há muito tempo) apresentar uma maneira de fazer os projetos nascerem certos e que a simulação, de fato, reflita aquilo que está no chip.

 

Além disso, tem a questão de custo. Bons projetos vão usar chips menores e usar mais da capacidade de um chip. Dependendo como o sistema é construído, um projeto funciona bem em um FPGA apenas porque este está com 50% de ocupação e pode falhar miseravelmente se for transferido para um dispositivo menor, em que a ocupação esteja alta (entre 80 e 90%). E quanto menor for o FPGA usado, menor o custo. Eu desconheço qualquer empresa hoje que não se importe com custos...

 

Esses conceitos normalmente fizeram a abertura da maioria dos manuais de boas práticas de FPGA que eu já escrevi ao longo dos anos. Creio que me ajudaram e ajudaram vários colegas ou pessoas que eu treinei a desenvolver suas habilidades e conseguir, com bastante facilidade e sem a necessidade de bruxarias, construir coisas muito complexas em FPGA. Porém, eu preciso ser redundante (redundância da redundância: coisa de quem trabalha com FPGA há muito tempo) e explicar alguns conceitos básicos.

 

 

Aspectos Básicos

 

O Clock

 

O clock é um sinal sagrado. Quando bem feito, a única linha de relógio que um desenvolvedor em FPGA deve enxergar, repetida em todos os blocos funcionais, é: 

 

Nada mais. E isso será válido para o projeto inteiro, para todos os IPs e para tudo o que for feito em FPGA. Não se faz lógica com o relógio, não se usa ele para dividir taxa e jamais em qualquer circunstância esse relógio terá outra fonte senão os recursos de relógio global do FPGA.

 

Nem será flip-flops, nem luts, nem pinos. Será apenas dos recursos globais.

 

Você até pode dispensar o uso dos recursos de relógio para clocks baixos, porém, em situações em que o FPGA estiver muito cheio, haverá alto fator sorte. E eu não creio que desenvolvedores possam depender da sorte. Por que? Veja a figura.

 

 

fpga-logica 

Sistemas síncronos (que são 99% dos sistemas que um desenvolvedor fará em FPGA) obedecem a algumas regrinhas físicas de tempo de propagação, tempo de set e tempo de hold. Veja o que são na figura abaixo.

 

 

fpga-set-hold-time 

O clock máximo, caso o clock seja perfeitamente distribuído, é:

 

Período = Tpropagação da lógica + TSET + THOLD

 

E como sabemos:

 

Fmax = 1/período

 

Hold normalmente é zero. Set é minúsculo. Porém, em FPGA, o tempo de propagação pode ser enorme. Entra todo o roteamento do FPGA, por exemplo, atraso das luts e etc. E se não forem usados os recursos globais de relógio, a figura muda.

 fpga-logica-sem-recursos-globais

 

 

Como o clock passará a percorrer o mesmo caminho que a lógica, é possível que o clock atrase mais que o sinal. O timing fica:

 

fpga-set-hold-time-sem-recursos-globais

 

 

Algum desavisado pode achar isso bom, pois o sinal está mais estável quando o clock chega. Não é bem verdade. Na verdade, nessa figura, por exemplo, o clock máximo cai, pois não se tem mais todo um período de relógio para acomodar o sinal, tem-se apenas 75% deste tempo. Então, a conta de período mínimo seguro fica:

 

Período = Tpropagação do relógio + Tpropagação da lógica + TSET + THOLD

 

 E como sabemos, se o período aumenta, a frequência cai...

 

Para os puristas, sim, há um tempo de propagação do relógio mesmo nos recursos globais, porém, isso não fará diferença nem mesmo em sistemas que estejam tirando o último suco do FPGA. Enquanto o atraso do relógio for menor que o atraso da lógica, tudo bem; e isso é garantido ao usar recursos globais de relógio.

 

Um parênteses antes de terminar sobre relógios: quando não se respeita essa frequência máxima, acontece algo que se chama de “metaestabilidade”. Ela é a grande culpada pelos sistemas em simulação serem tão diferentes dos sistemas “na prática”. Você vai querer ler mais sobre isso aqui, tem muito material no Google ou nos sites dos fabricantes de FPGA.

 

Enables

 

Para poder gerar diferentes taxas, já que o relógio mestre é intocável, como fazer?

 

Enables. Semáforos. Chame como quiser. Eu sempre usei enables pois era assim chamado o sinal que habilitava (ou não) os antigos 7474, o famoso TTL Flip-Flop D.

 

Todo o bloco deve fazer uso de enables. Toda a transferência interna de taxas, fifos (exceto fifos de borda, como veremos a seguir) devem ser todas referenciadas a um relógio mestre superior a maior taxa de transferência instantânea.

 

Em HDL, o desenvolvedor deve ver:

 

E só.

 

Em outras palavras: o clock mestre deve ser o mesmo para o projeto inteiro, sendo as diferentes taxas geradas por sinais de enable. Veja a figura:

 

fpga-fifo

 

 

O relógio mestre desta fifo pode ser 20MHz. Porém, a taxa de transferência de dados pode ser 2Mbps. Quem irá determinar a taxa é o sinal de enable.

 

fpga-clock

 

 

Em situações extremas, de taxas muito alta para que o relógio mestre possa ser muitas vezes maior que a maior taxa, pode-se, por exemplo, usar um relógio mestre ligeiramente maior que a maior taxa. Neste caso, o sinal de enable passaria a maior parte do tempo ativo, sendo esporadicamente desligado para acomodar a taxa.

 

fpga-set-hold-time-clock-mestre

 

 

Se o relógio mestre é intocável, o Enable sofre todo o pênalti. Dá para abusar do coitado. Dá para anular um pulso, forçar um pulso, enfim, toda a lógica que seria feita no clock mestre pode (e deve) ser feita com toda segurança nos sinais de enable.

 

 

Gerando Sinais de Enable

 

Referência Lenta Assíncrona

 

Entende-se como referência lenta qualquer sinal que seja em torno de 4x menor que o relógio mestre. Para fazer isso com segurança, mesmo, se ele for menor a partir de 8x o relógio mestre.

 

O jeito mais fácil para gerar um sinal de enable é dividindo o relógio mestre com um contador. Este artigo sobre PWM explica isso bem. Porém, a saída dele é um clock; queremos um enable. Como fazer? Detectar borda. Veja o exemplo de um relógio lento e um relógio rápido. E veja também o pulso que acompanha a borda deste relógio lento. É isso que queremos.

 

projetos em FPGA
Clock

 

Para isso, basta uma lut e dois FFD. Eu prefiro criar isso em um bloco, pois meus sistemas sempre usaram e abusaram da construção abaixo:

 

projetos em FPGA
Block

 

 

Ou em pseudo HDL: 

 

Simples. Se precisar usar uma fonte externa assíncrona ao relógio mestre, basta sincronizar o sinal antes. Dá para fazer isso com 2 FFD:

 

projetos em FPGA
Fonte assíncrona

 

 

Eu costumo construir um arsenal destes blocos e deixar eles à mão. Coloco detector de borda de subida, descida, subida e descida, encadeador de enables...

 

Referência Rápida Assíncrona

 

E os tais clocks grandões, que são 90% do clock mestre? É, nestes casos não dá para usar os detectores de borda. Nem os sincronizadores. Mas há um jeito de fazer: fifos assíncronas.

 

Fifos assíncronas são fifos que possuem um contador Gray internamente. Porém não necessariamente um contador Gray, pois este é muito chato de fazer. O que se faz é usar um contador normal, converter para Gray, cruzar o domínio de relógio e retornar para o contador normal.

 

Veja a figura:

 

projetos em FPGA
Contador Gray

 

 

Uma vez que se esteja no domínio de relógio desejado, basta usar a própria indicação da fifo para gerar enables (full e empty). Existem várias formas de fazer isso, desde fazer lógica entre o estado e um gerador de taxa (que estará sob a forma de pulsos de enables, claro) como fazer que sempre que a fifo estiver cheia, o enable é 1. Se vazia, o enable é ‘0’. Não é o mais elegante, mas está tecnicamente muito correto: e elegância em FPGA vem com o tempo...

 

Referências Derivadas do Clock Mestre

 

Deixei por último. O porquê? Para encerrar esta seção com algo bem fácil. Referências síncronas podem ser usadas diretamente nos mesmos detectores de borda usados para a referência assíncrona, independente da taxa. Qualquer coisa que tenha sido gerada por lógica, no caso, por algum tipo de máquina de estados, temporizada a partir do relógio mestre, pode passar por um detetor de borda e ser usado como enable.

 

 

No próximo artigo

 

Modelos de organização de projeto e conceitos de IP Core.

Outros artigos da série

Como estruturar projetos em FPGA e VHDL - Parte 2 >>
Este post faz da série Como estruturar projetos em FPGA e VHDL. Leia também os outros posts da série:
NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Ricardo Tafas
Ricardo F. Tafas Jr é Engenheiro Eletricista pela UFRGS com ênfase em Sistemas Digitais e mestre em Engenharia Elétrica pela PUC com ênfase em Gestão de Sistemas de Telecomunicações. É também escritor e autor do livro Autodesenvolvimento para Desenvolvedores. Possui +10 anos de experiência na gestão de P&D e de times de engenharia e +13 anos no desenvolvimento de sistemas embarcados. Seus maiores interesses são aplicação de RH Estratégico, Gestão de Inovação e Tecnologia Embarcada como diferenciais competitivos e também em Sistemas Digitais de alto desempenho em FPGA. Atualmente, é editor e escreve para o "Repositório” (https://www.repositorio.blog), é membro do editorial do Embarcados (https://embarcados.com.br) e é Especialista em Gestão de P&D e Inovação pela Repo Dinâmica - Aceleradora de Produtos.

1
Deixe um comentário

avatar
 
1 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Rogerio Moreira Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Rogerio Moreira
Visitante
Rogerio Moreira

Excelente! Parabéns, Tafas .