Como obter um design FPGA que definitivamente funcione em hardware real

9

Acabei de começar a aprender design de lógica digital com FPGAs e tenho construído muitos projetos. Na maioria das vezes (já que sou meio noob), tenho um design que simula perfeitamente (simulação comportamental), mas não é sintetizado adequadamente.

Portanto, minha pergunta é "quais são as etapas de design que posso incorporar no meu fluxo de trabalho, que garantirão que eu tenha um design funcional que funcione corretamente no meu FPGA?"

Eu tenho duas áreas principais em que espero aconselhar, mas isso é absolutamente baseado em um ponto de vista muito restrito para iniciantes, e mais são bem-vindos:

  • O que todas as etapas (visualização do esquema RTL, simulação pós-síntese, ...) devem ser realizadas para a melhor prática.
  • O que todas as coisas devo ter em mente ao projetar minha lógica (digamos FSM ou circuitos seqüenciais) para evitar resultados inesperados.

Estou usando um pacote Xilinx Spartan 6 FPGA e Xilinx ISE Design para o meu trabalho.

ironstein
fonte
1
Que tipo de problemas você encontra com a síntese? Você alcança um alto nível de cobertura na simulação?
Pjc50 02/03
@ pjc50 Não entendi a pergunta. O que você quer dizer com "alto nível de cobertura em simulação"?
ironstein
1
Você tem um banco de testes ou estímulo para conduzir a simulação. As ferramentas de cobertura informam quanto do design está sendo realmente exercido pelo teste, como uma porcentagem. Se esse número for muito baixo, seu testbench é inadequado e você não está testando alguns casos que podem surgir em uso real.
Pjc50 02/03
@ pjc50 que é realmente um conselho muito bom. Qual é o equivalente disso no Xilinx ISE design suite?
ironstein
1
Vale notar: sintetiza e "definitivamente funciona em hardware real" são diferentes níveis de rigor. Existem padrões que podemos seguir para garantir que sintetize. No entanto, quando se trata de fazê-lo funcionar com hardware real, com certeza, é preciso lembrar a máxima da simulação: "Todos os modelos estão errados; alguns são úteis".
Cort Ammon 02/02

Respostas:

13

Em um local em que trabalhei, havia dois campos de designers de FPGA. Um campo que chamei de simular, simular, simular ou é dividido em cubos. O outro campo era sobre design.

Os caras em cubos usavam um simulador como o modelsim; eles apresentavam um design inicial através de métodos de codificação e \ ou blocos no conjunto de design. Em seguida, eles simulavam e encontravam as coisas que não funcionavam, depois mudavam o código. Esse processo foi repetido várias vezes até que eles apresentassem um design que funcionasse.

O campo de design (que eu preferia) projetaria a forma de onda em papel (ou papel digital como visio), exatamente o que era necessário. Em seguida, crie um diagrama lógico. Este é um processo de auto-documentação. Em seguida, o diagrama foi convertido em código (o código e o diagrama eram 1: 1, se havia algo no diagrama, havia um processo para ele no código). Em seguida, foi simulada, e a forma de onda da simulação foi comparada com a forma de onda projetada no papel e esperava-se que fosse a mesma.

Acabei fazendo as duas coisas, às vezes entrava no modo s em cubos e não era muito divertido. Descobri que às vezes perdi de vista meu objetivo. Por exemplo, eu mudaria um estado em uma máquina de estado, e a mudança seria reduzida para o próximo estado, então eu teria que consertar isso. Acabei passando mais tempo do que pensando sobre isso.

Em que campo você prefere estar? Acho que precisa haver um design rigoroso, fazer o que funciona para você, mas acho que quanto mais detalhado e rigoroso você estiver no design, menos problemas você terá a longo prazo. Dei alguns exemplos do que é possível, eles podem não se encaixar na estrutura organizacional do seu local de trabalho. A razão pela qual os detalhes do projeto e o planejamento cuidadoso são tão úteis, é que o força a pensar no que está fazendo. Isso facilita a depuração. Desenvolva um fluxo de trabalho de design que permita que isso aconteça. Além disso, familiarize-se com as ferramentas de simulação e escreva boas bancas de teste que testarão todas as condições que o dispositivo simulado pode enfrentar. É claro que isso precisa ser equilibrado com o tempo. Por exemplo, escreva o código ADC HDL que simulará o dispositivo em suas simulações.

A ferramenta mais valiosa para ter no design de FPGA (na minha opinião) é um bom procedimento de teste que permitirá que você teste completamente seu design e execute-o em seus ritmos. Não se pode esperar que um projeto de FPGA "funcione" apenas, é necessário um esforço para garantir que todas as peças funcionem. Se você encontrar erros, volte à simulação e ao design e aprenda quais são as diferenças entre um FPGA e RTL simulados. Isso vem principalmente da experiência, mas se o design funciona em simulação, mas não em hardware, você precisa descobrir por que há uma diferença.

Algumas coisas importantes que aprendi:
1) Desinfetar suas entradas, o relógio e os circuitos de redefinição precisam estar limpos ou você pode obter a metastablidade propagando-se pelo seu sistema. Saiba o que é um sincronizador de classificação dupla. Existem muitas topologias diferentes para os circuitos de redefinição, sei como usá-los (há um ótimo artigo na Web, eu ainda não o tenho em mãos).
2) Obtenha os requisitos do design antecipadamente e, em seguida, faça o design em torno deles. Se as pessoas ao seu redor não fornecerem requisitos definidos, crie alguns por conta própria.
3) A caixa de ferramentas de ponto fixo da Matlab é ótima para simular sistemas de controle e aplicativos DSP, mas você pode não ter acesso a isso. É uma ótima maneira de provar um design antes de codificar.
4) O design vem primeiro, depois codifica e depois simula.
5) Fortemente digitado, também mantenha os nomes dos sinais consistentes nos esquemas PCB e HDL. (é também por isso que prefiro o VHDL ao verilog.

Voltage Spike
fonte
2
+1 para "s ao cubo" ou simulation3
Paebbels
Muito bom: ao "design rigoroso" eu acrescentaria "usando o sistema de tipos". Exemplo: um índice de matriz do tipo apropriado, como o intervalo da matriz, sem necessidade de testar a condição fora dos limites. Eu discordaria apenas de "forma de onda comparada com a forma de onda projetada no papel" ... a forma de onda projetada deve estar em VHDL nesse estágio (ou talvez lida em arquivo de texto) e o simulador deve realizar a comparação.
Brian Drummond
Também poderia ser feito dessa maneira, achei útil projetar uma forma de onda no papel, porque dava algo para comparar. Como uma forma de onda ADC, o tempo foi projetado e depois comparado com a saída modlesim, depois verificado fisicamente. Se a saída modelim estiver correta, compare-a com isso. O código foi fortemente digitado (esqueci de mencionar isso), mas isso é realmente importante. É por isso que eu prefiro VHDL do que verilog, existem menos atalhos que você pode usar. E isso torna o código muito mais legível.
Voltage Spike
sim. Na verdade, assim como outras áreas, como software ou hardware convencional, o ponto de partida é dividir o problema em blocos e depois se perguntar "como saberei quando esse bloco funciona". Então faça. Crie seu design bloco por bloco, depois junte os blocos e teste novamente se o que você recebe é o que é esperado. Às vezes, você pode perceber que, com um design melhor em nível de bloco, seria mais limpo ou mais fácil, então você volta atrás.
Danmcb 18/09/19
6

As principais coisas são:

  • Codificação cuidadosa para evitar estruturas não sintetizáveis
  • Minimize os níveis lógicos para melhorar o desempenho do tempo (simplifique a lógica entre os registros)
  • teste, teste, teste para garantir a correção funcional e verifique itens como registros não inicializados e fios desconectados
  • síntese e verifique os logs de síntese quanto a avisos, verifique se os avisos não indicam problemas (ou seja, o aviso de registro removido pode ser intencional (não usou uma saída do módulo) ou não-intencional (esqueceu de conectar a saída do módulo / erro de digitação / etc.))
  • mapeamento e verifique o relatório do mapa para obter os valores de utilização, verifique se o FPGA não está muito cheio
  • análise de local e rota e tempo, verifique se o seu design será executado na velocidade de clock necessária

Eu tive vários projetos bastante complexos funcionando corretamente (ou pelo menos na maior parte corretamente) no primeiro teste em um FPGA real, seguindo o acima. Não é necessário verificar o esquema RTL, isso é extremamente complicado e é uma completa perda de tempo para projetos grandes. Uma simulação pós-síntese seria muito mais útil.

alex.forencich
fonte
1
obrigado pela sua resposta rápida. Você poderia elaborar o segundo ponto (minimizar os níveis lógicos).
ironstein
5

Todo o seu código sintetizável precisa ser expressável como:

  • LUTs
  • Sandálias de dedo
  • Primitivas específicas do fornecedor

As primitivas específicas do fornecedor são instanciadas explicitamente ou geradas pelo assistente do fornecedor ou inferidas por padrões de codificação muito específicos, portanto, não deve haver ambiguidade.

No VHDL, por exemplo, você não pode usar wait forno código sintetizável. Para entender o porquê, tente expressar de forma determinística wait for 100 nsusando LUTs ou chinelos. Você não pode.

Isso não significa que você não pode implementá-lo configurando um contador com uma frequência de clock conhecida (com período que pode dividir 100 ns) e use sua contagem para saber quando o tempo acabou. Mas o mecanismo de síntese não criará esse esquema automaticamente. Você precisa ser explícito sobre a arquitetura em termos de lógica combinatória (gates / LUTs) e registros.

Portanto, o principal a ter em mente para gerar código sintetizável é ter uma imagem relativamente clara de como seu código se torna portas lógicas e chinelos. É isso mesmo.

apalopohapa
fonte
wait until rising_edge(clk);é certamente sintetizável, embora algumas ferramentas imponham restrições ao seu uso.
Brian Drummond
2

O primeiro passo mais óbvio é verificar os avisos.

As ferramentas Xilinx produzem arquivos de log que alertam sobre algo que pode não ser o que o codificador pretendia. Às vezes, isso é irritante, quando você tem montes de avisos sobre sinais não utilizados que você sabe perfeitamente que não são utilizados. Mas, às vezes, ele pega bugs genuínos. Se você é um novato, as chances de cometer um erro são significativamente maiores.

Então você precisa configurar restrições de tempo. Com que rapidez, após uma borda crescente no relógio A, é necessário definir a linha de dados B? Ou por quanto tempo a linha de dados B precisa ser mantida antes de uma borda decrescente no relógio A? As restrições de tempo permitem especificar tudo isso. Se você não tiver restrições de tempo, o compilador pode assumir que você não se importa particularmente e pode direcionar seus sinais para qualquer lugar. Se você tiver restrições de tempo, o compilador funcionará para garantir que seus sinais atendam a essas restrições, movendo o posicionamento. E se não puder atender às restrições de tempo, será emitido um aviso.

Se o seu problema é que as saídas não estão fazendo o que você espera, observe em detalhes os blocos de E / S. Cada pino de E / S possui um pouco de lógica associada e um flip-flop. A ordem na qual você especifica suas variáveis ​​lógicas e de estado no seu código pode não permitir que seu código se encaixe nessa arquitetura, para que você obtenha um atraso extra de onde quer que ele seja colocado. Os avisos sobre restrições de tempo informam se isso acontece (supondo que você configurou suas restrições de tempo), mas corrigi-lo exige que você compreenda o hardware e como o seu design será mapeado no hardware. Geralmente, esse é apenas um problema quando você começa a atingir altas taxas de clock, mas vale a pena mencionar.

Graham
fonte