VHDL: usando o operador '*' ao implementar multiplicadores no design

10

Os FPGAs atuais construíram blocos DSP, os FPGAs mais recentes ainda construíram unidades de ponto flutuante compatíveis com IEEE-754.

É possível criar uma entidade / módulo DSP usando uma GUI depois de selecionar os parâmetros necessários e instancia-lo no design.

Quando precisamos fazer esse microgerenciamento em um projeto de instalação de blocos DSP reais e quando inserimos um operador '*' no código e deixamos a ferramenta de síntese lidar com os detalhes de baixo nível? Qual é melhor?

Existem muitos tipos diferentes de algoritmos de multiplicação quando se trata de multiplicação binária. Como agora construímos blocos DSP em silício e até multiplicadores de ponto flutuante, isso significa que todos esses algoritmos não se tornaram obsoletos.

quantum231
fonte
Qual FPGA possui FPUs compatíveis com 754 na malha?
Martin Thompson

Respostas:

6

Eu já fiz isso algumas vezes.

Geralmente, as ferramentas de design escolhem entre uma implementação de malha e uma fatia DSP com base nas configurações de síntese.

Por exemplo, para o Xilinx ISE, nas configurações do processo de síntese, Opções HDL, existe uma configuração "-use_dsp48" com as opções: Auto, AutoMax, Sim, Não. Como você pode imaginar, isso controla o quanto as ferramentas tentam colocar Fatias DSP. Certa vez, tive um problema em que multipliquei um número inteiro por 3, o que inferiu uma fatia do DSP - exceto que eu já estava inferindo manualmente cada fatia do DSP no chip, então o sintetizador falhou! Alterei a configuração para Não, porque já estava usando todas as fatias de DSP.

Essa é provavelmente uma boa regra geral (eu acabei de inventar): se o seu design tiver clock de menos de 50 MHz e você provavelmente usará menos de 50% das fatias DSP no chip, basta usar o operadores *, + e -. isso inferirá fatias DSP sem registros de pipeline. Isso realmente limita a velocidade máxima. (Eu não tenho ideia do que acontece quando você usa a divisão)

No entanto, se parecer que você executará as fatias mais próximas da velocidade máxima da fatia DSP (333 MHz para Spartan 6, velocidade normal). Você usará todas as fatias, deduzi-las manualmente .

Nesse caso, você tem duas opções.

Opção 1: use manualmente o modelo de instanciação DSP bruto. Opção 2: use um bloco IP do Xilinx Core Generator. (Eu usaria essa opção. Ao mesmo tempo, você aprenderá tudo sobre a geração principal, o que ajudará no futuro)

Antes de fazer qualquer um destes, leia as primeiras duas páginas do guia do usuário da fatia DSP. No caso do Spartan 6, (DSP48A1), esse seria o documento Xilinx UG389: http://www.xilinx.com/support/documentation/user_guides/ug389.pdf

Considere a opção Gerador de núcleo primeiro. Normalmente, crio um projeto de teste no Core Generator para a parte em que estou trabalhando, onde crio qualquer número de blocos de IP apenas para aprender o sistema. Então, quando estiver pronto para adicionar um ao meu design no ISE, clique com o botão direito do mouse na Hierarquia de Design, clique em nova fonte e selecione "IP (Gerador de Núcleo e Assistente de Arquitetura)" para que eu possa editar e regenerar o bloco diretamente do meu projeto.

Na geração Core, dê uma olhada nos diferentes blocos de IP que você pode escolher - existem algumas dezenas, a maioria delas muito legais.

O Multiplier Core é o que você deve procurar primeiro. Confira todas as páginas e clique no botão de folha de dados. As partes importantes são as larguras de bits inteiros, os estágios do pipeline (latência) e quaisquer sinais de controle. Isso produz o bloco mais simples possível removendo todas as portas que você não precisa.

Quando eu estava criando um filtro IIR de 5 por 3 pedidos no ano passado, tive que usar o modelo de instanciação manual, pois estava criando uma implementação muito personalizada, com 2 fatias de DSP com freqüência 4x mais rápida que a taxa de amostragem. Foi uma dor total.

Marcus10110
fonte
13

Se você quiser multiplicar dois números e eles se adequarem ao bloco DSP, o *operador deve inferir um bloco DSP. Caso contrário, envie a ferramenta de síntese de volta :)

No entanto, tirar proveito das combinações mais complexas da funcionalidade DSP geralmente requer uma instanciação direta do bloco e a configuração de seus parâmetros. Exemplos de coisas que podem não ser bem mapeadas por inferência (usando o Xilinx DSP48E1 como exemplo):

  • Uso de pré-somador
  • Uso do pós-acumulador
  • Uso do detector de padrões
  • Uso da unidade lógica

E especialmente combinações dos itens acima.

As ferramentas de síntese ainda não são boas o suficiente para mapear combinações completamente arbitrárias de lógica e aritmética da maneira mais eficiente possível.

Martin Thompson
fonte
4

Se houver blocos DSP presentes, você deve usá-los se puder, porque será mais eficiente do que usar LUTs para fazer a mesma coisa. A menos que você não precise de uma multiplicação de alto desempenho, nesse caso, você deve implementar, digamos, um somador em pipeline e um registro de turnos para economizar espaço.

No entanto, gostaria de inferir blocos DSP antes de ir para as ferramentas da GUI. O manual Xilinx XST possui 'recebimentos' de HDL para instanciar blocos DSP com verilog puro / VHDL. Basicamente, se você adicionar registros suficientes antes e / ou depois dos multiplicadores, o XST usará um bloco DSP para implementar a operação automaticamente. Você pode verificar nos logs de síntese para ver se está inferindo os blocos DSP corretamente. Presumo que Altera tenha algo parecido.

Aliás, eu estava pensando sobre isso há alguns minutos, pois atualmente estou trabalhando em uma implementação de twister de Mersenne que usa apenas um multiplicador para a semente inicial. Minha implementação de primeira passagem não atende ao tempo, mas a funcionalidade está correta. O XST também coloca a operação de multiplicação em blocos DSP, no entanto, não é otimizada e, portanto, roda cerca da metade da velocidade que eu gostaria. Provavelmente vou reimplementar a multiplicação usando uma técnica de troca e adição que terá 32x o número de ciclos de clock, mas não exigirá mais um multiplicador de hardware.

alex.forencich
fonte
Por que deveria falhar o tempo ao usar o multiplicador de hardware?
precisa saber é o seguinte
A multiplicação sem pipeline de 32 bits por 32 bits leva mais de 8 ns, aparentemente.
Alex.forencich 17/09/14
hmm eu vejo, não considerou isso. Portanto, os blocos DSP não são canalizados. Eu me pergunto como exatamente eles implementam a multiplicação. É um multiplicador paralelo realmente difícil?
Quantum231
Eu acho que pode ser configurado para funcionar de algumas maneiras diferentes. De acordo com o manual do XST, a adição de registros suficientes na entrada e na saída permitirá que o XST use um multiplicador em pipeline em uma fatia DSP48. No meu caso, havia apenas um registro de saída e nenhum registro de entrada, portanto, não foi possível tirar proveito disso. Como isso era apenas para inicialização (semeando o PRNG), substitui a multiplicação paralela por um multiplicador serial de bits para economizar na utilização de recursos.
alex.forencich
2

Depende de quanto de otimização você precisa e de quanto portátil deve ser o seu design. É um pouco como o software, otimizando usando um pouco de montagem ou deixando o compilador escolher as instruções. Você também pode ter algumas trocas de tamanho / velocidade para não poder pagar um multiplicador combinatório de precisão dupla.

Eu não sabia lá onde multiplicadores FP conectados em FPGAs.

Um operador de multiplicação compatível com IEEE P754, adequado para uma CPU, envolve mais do que um multiplicador grande: você precisa adicionar os expoentes, alterar as formas anormais, gerenciar infinitos e alguns sinalizadores praticamente inúteis (inexato, subfluxo ...)

TEMLIB
fonte
Os FPGAs de última geração, como a série Altera 10, têm multiplicadores de ponto flutuante compatíveis com IEEE-754 no próprio hardware! Eu ainda não tive oportunidade de usá-los.
quantum231
Se construímos blocos DSP, o FPGA deve usá-los em vez do multiplicador combinatório ou usar outro algoritmo que, por exemplo, usa o bloco de memória, certo?
Quantum231
2

Li este documento http://www2.warwick.ac.uk/fac/sci/eng/staff/saf/papers/fpl2014-ronak.pdf :

Embora as funções que se encaixam em um único bloco DSP possam ser sintetizadas com eficiência a partir de código RTL em pipeline, descobrimos que funções mais complexas que exigem vários blocos DSP sofrem com menor desempenho. Uma descrição RTL padrão de uma função matemática pode ser fortemente canalizada, por exemplo, após cada operação, no entanto, uma vez que essa tubulação pode não levar em conta a estrutura e os estágios internos do bloco DSP, o projeto sintetizado resultante pode exibir desempenho abaixo do padrão, pois os blocos DSP são combinados de uma maneira que não lhes permita executar a toda velocidade.

Eu gostaria de encontrar a fonte de suas ferramentas para verificar suas descobertas.

hlide
fonte