Organize sua Biblioteca em Lógica Programável

Lógica Programável
Este post faz parte da série Como estruturar projetos em FPGA e VHDL. Leia também os outros posts da série:

E só porque é há uma conclusão, é o fim? Na verdade, nos dois primeiros artigos fechamos a parte técnica e era importante concluir aquelas ideias. Agora começa a parte chata: a parte burocrática. Gerenciar conteúdo de Lógica Programável é tão importante quanto saber trabalhar tecnicamente com isso: se o time não for quase neurótico com relação a reuso, o time todo falha.

 

 

Produtividade é tudo em Lógica Programável

 

Em lógica programável, cada projeto é um projeto, cada roteamento é um roteamento e se o time inteiro não aderir ao modelo de projeto, um único core pode fazer lambança em um projeto inteiro. E o pior: esse core pode estar totalmente isolado dos elementos principais do sistema.

 

Reescrever ou ter que ajeitar via constantes de timing um projeto e a cada mudança ter que fazer isso novamente é maçante, cansativo. O pior é que depois de muito trabalho, fica frágil. Acredite: já vi projeto fracassar porque adicionaram mais um LED. Pior, o FPGA nem estava cheio.

 

Mas isso tudo foi resolvido caso as recomendações da parte 1 e parte 2 tenham sido seguidas. A esta altura do campeonato, se já está mexendo com FPGA, deve ter percebido que um core SPI, um GPIO e cores "genéricos" podem ser usados em inúmeros projetos distintos.

 

Mas e o trabalho de ter que revisitar projeto a projeto corrigindo o erro em um determinado core? Quando se corrige um erro em um determinado core, perde-se muita produtividade ter que ir, projeto a projeto, corrigindo isso. Pode-se cometer uma variedade tão grande de erros nesse processo que, se forem listados, acabam com este artigo.

 

Por outro lado, o modo "copia pasta daqui e cola lá" não é muito indicado, embora, não sei porquê, tem gente que goste. Normalmente isso acontece porque o sujeito é obrigado a "tunar" (ok, adaptar) o bloco para funcionar especificamente naquele projeto. Por que? Parte 1 e 2 não seguidas. Vou ser um pouco autoritário aqui: isso não é uma questão de gosto. É uma questão de certo ou errado.

 

Em Lógica Programável (que é o nome correto do "ramo"), produtividade e reuso andam de mãos dadas e abraçadas em um bom modelo de versionamento. E é este tripé que compõe uma biblioteca de lógica programável.

 

 

Versionamento

 

Nem vou discutir a necessidade disso. Costumo dizer que Lógica Programável não é nem software nem hardware. É um meio termo. Gerenciar conteúdo de Lógica Programável é exatamente o mesmo que gerenciar conteúdo de software. Esta série já diz tudo.

 

Porém, aqui, precisamos estudar uma estratégia de versionamento que colabore com a estrutura de projetos com SOCs.

 

O que será versionado?

 

Primeiro, versiona-se apenas conteúdo formal. Costumo dizer que há 3 tipos de conteúdo formal a serem versionados em projetos de Lógica Programável / FPGA. Em tempo: conteúdo formal deve ser entendido como código fonte. Segue:

  • Bibliotecas: contém elementos básicos de reuso de sistemas digitais, funções combinacionais, infraestrutura de barramento e etc;
  • Cores: blocos funcionais. Seria um conjunto de periféricos;
  • Projetos: contém os vários “cores” e bibliotecas, além de toda estrutura específica do dispositivo.

 

E essa é exatamente a ordem de dependência. Então, algumas regrinhas:

  • Uma biblioteca não poderá depender de algo que esteja dentro do core. Porém, pode haver dependência hierárquica (não recursiva, claro) entre bibliotecas;
  • Um core não pode depender de outro core, porém, pode depender de outra biblioteca. Se um código de um core será usado em outro, considere movê-lo para uma biblioteca;
  • Um projeto pode depender de cores e bibliotecas, mas não pode depender de outros projetos. Na verdade, cada projeto é um “SOC” diferente.

 

Como será versionado?

 

Cada um montará sua estrutura de pastas, diretórios ou como quiser chamar. Eu costumo gostar de ter um branch de desenvolvimento e branches de tags, meio a moda do antigo CVS. Conheço gente que prefere o contrário: a melhor versão estável estar no branch de desenvolvimento e toda adição ser feita por outras tags, sendo reincorporada ao branch principal quando estiver estável.

 

Seja como for, ponto é o seguinte: deve haver, de alguma forma, fotografias do código atual para ser usado pelos itens de hierarquia mais elevados.

 

Exemplo: uma biblioteca, quando atualizada, não pode gerar quebras nas versões atuais dos cores. Estes, por sua vez, não podem gerar quebras nas versões atuais de projeto. Um core pode usar uma versão antiga de biblioteca que o mantenha estável, sendo o mesmo válido para um projeto.

 

Porém, podem acontecer conflitos: um core “a” usa uma versão antiga de uma determinada biblioteca e outro, “b”, usa uma versão nova. Deve-se então planejar a atualização deste core “a”. E isso não vai afetar os demais projetos, que continuarão a usar a versão antiga do core “a”. Outro ponto interessante: a correção de um erro em um core ou biblioteca pode beneficiar todos os demais projetos, sendo necessário apenas agendar as atualizações.

 

Guardar Testbenches?

 

Eu já vi muita gente escrever testbenches e descartá-los. JAMAIS faça isso!!!

 

Os testbenches devem ser versionados com as bibliotecas, cores e projetos que eles exercitam. Isso vai ajudar desde fazer simulações com maior cobertura a permitir "night builds" nas bibliotecas.

 

O ideal é que cada elemento de biblioteca e cada core tenha seu próprio testbench. Pode parecer trabalhoso, mas receber, no início da manhã um report quentinho de quais cores ainda estão funcionando após o update de uma bliblioteca certamente vai salvar o time daquela situação em que "do nada, tudo parou de funcionar"...

 

 

Documentação

 

Esse ponto sempre gera muita discussão. Eu não sou muito chegado, pelo menos nessa filosofia de IP core, de misturar a documentação formal e funcional com a operacional. Eu costumo adotar um conceito para definir tipos documentação:

  • Documentação formal: o próprio código fonte, como já comentei. Ao ler ele e entender, você sabe o que ele faz, portanto, é auto-explicativo;
  • Funcional: normalmente o código pode não explicitar tudo. Para isso, para colocar as cadeias de raciocínio mais longas, coloca-se comentários no código;
  • Operacional: documento de quem será usuário de determinado bloco, sem importância como será usado.

 

A Documentação Formal e Funcional

 

Não vou aqui discutir a necessidade de um código fonte bem documentado. Nem regras de endentação e etc. Assumo que todo mundo gosta de ver um código fonte limpo, com variáveis bem nomeadas e comentários significativos...

 

Apenas saliento aqui alguns conceitos importantes:

  1. Adote um guia de codificação. Se não quer criar um, o do guia opencores é muito bom.
  2. O modo como o código se apresenta pode gerar resultados diferentes para o sintetizador. Escrever da maneira correta pode significar a diferença entre inferir um bloco dedicado do FPGA ou emular o mesmo com portas lógicas / flip-flops.
  3. Nem pense em armazenar como código os arquivos gerados pelos wizards das ferramentas. É caminho garantido para problemas.

 

A Documentação Operacional

 

A documentação formal e funcional ficam no código fonte para os desenvolvedores destes blocos. Porém, a operacional não é bom que fique no arquivo de HDL...

 

É comum alguém de software ser o "usuário" do SOC implementado em FPGA. É o desenvolvedor de software que vai configurar os dispositivos do FPGA e fazer com que o chip (o FPGA) passe a cumprir sua função no sistema embarcado. Para tal, ele precisará de uma documentação de uso. Um datasheet.

 

Basicamente, dá para pensar que não interessa ao programador como o SOC ARM que ele usa foi desenvolvido, interessa para ele as descrições de como as coisas funcionam e quais registros ele precisa acessar para por o bloco a fazer o que precisa ser feito. Não interessa para ele os macetes usados para aumentar o desempenho de uma memória, interessa para ele operar esta memória. E os blocos em FPGA deve seguir o mesmo raciocínio.

 

Além disso, eu particularmente acho chato pôr um desenvolvedor de software a baixar todo um conjunto de HDLs, abrir um código fonte e lá dentro olhar quais os registros que ele precisa. Minha recomendação é que, a cada novo “core”, o projetista faça literalmente um datasheet daquele bloco. Conforme a biblioteca evolui, o número de novos datasheets vai reduzindo, até o ponto em que, para a maioria dos projetos, apenas um ou outro datasheet seja necessário.

 

Este datasheet deve conter os mapas de registros, significado de cada bit de configuração e etc. Dependendo, o usuário do bloco pode até cogitar de colaborar com o colega desenvolvedor e criar exemplos ou alguns casos de uso, a partir do que aprendeu com o autor do bloco.

 

No caso, eu tenho uma grande tendência a gostar de Wikis para essa documentação operacional. Eu já usei e gosto do TracWiki, até porque ele integra um sistema de tickets. Porém, já documentei datasheets de blocos de Lógica Programável até em *.doc... Sem morrer por causa disso.

 

 

E agora?

 

Todas as ferramentas que apresentei nestes 3 artigos são extremamente básicas na organização de projetos de FPGA, porém, são conceitos dos quais pode-se construir muita coisa. Ao longo destes artigos, as várias referências que fiz incrementam esta ideia de uma equipe de FPGA produtiva.

 

Na Parte 1 tratamos do conceito do relógio. Na Parte 2 comentei que é preciso definir um barramento interno padrão e estruturar a coisa em cores, usando a filosofia de SOC. Também discuti uma abordagem bem primitiva, o modelo PC-PO, mas que ainda hoje é muito útil.

 

Na parte 3 é onde costumo separar os profissionais dos amadores: enquanto amadores não querem saber de produtividade, profissionais precisam e devem se preocupar com isso. Quem já passou horas depois do expediente tentando por para funcionar um sistema de lógica programável mal feito e gerenciado sabe muito bem do que estou falando...

 

Produtividade é tudo em FPGA e quem trabalha com isso sabe: a única saída para um código muito mal feito e muito mal gerenciado é o lixo. Cruel ver esforço, tempo e dinheiro desperdiçado assim...

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://www.embarcados.com.br) e é Especialista em Gestão de P&D e Inovação pela Repo Dinâmica - Aceleradora de Produtos.

Deixe um comentário

avatar
 
  Notificações  
Notificar