Estou tentando começar com o DSP na minha placa Spartan-3. Fiz uma placa AC97 com um chip de uma placa-mãe antiga e, até agora, consegui fazer o ADC, multiplicar as amostras por um número <1 (diminuir o volume) e depois o DAC.
Agora eu gostaria de fazer algumas coisas básicas de DSP, como um filtro passa-baixo, passa-alto etc. Mas estou realmente confuso sobre a representação numérica (números inteiros? Ponto fixo? Q0.15? Estouro ou saturação?).
Eu só quero um código de exemplo de um filtro simples real para começar. Sem alta eficiência, rápido ou algo assim. Apenas o filtro teórico implementado em VHDL.
Estive pesquisando, mas apenas encontro fórmulas teóricas - entendo isso, o que não entendo é como processar as amostras de áudio assinadas de 16 bits e 48KHz que estou recebendo do ADC. Eu tenho usado essas bibliotecas: http://www.vhdl.org/fphdl/ . Se eu multiplicar minhas amostras por 0,5, 0,25, etc., posso ouvir a diferença. Mas um filtro maior me dá apenas ruído.
Obrigado.
Respostas:
Parece que você precisa descobrir os aspectos do DSP primeiro e, em seguida, fazer uma implementação no FPGA.
Em relação aos tipos de dados, você pode usar números inteiros muito bem.
Aqui está um código de exemplo para você começar. Observe que faltam muitos problemas do mundo real (por exemplo, redefinição, gerenciamento de estouro) - mas espero que seja instrutivo:
fonte
O filtro FIR passa-baixo mais simples que você pode experimentar é y (n) = x (n) + x (n-1). Você pode implementar isso facilmente no VHDL. Abaixo está um diagrama de blocos muito simples do hardware que você deseja implementar.
De acordo com a fórmula, você precisa das amostras atuais e anteriores do ADC para obter a saída apropriada. O que você deve fazer é travar as amostras ADC recebidas na borda descendente do relógio e executar os cálculos apropriados na borda ascendente para obter a saída apropriada. Como você está adicionando dois valores de 16 bits, é possível que você tenha uma resposta de 17 bits. Você deve armazenar a entrada em registradores de 17 bits e usar um somador de 17 bits. Sua saída, no entanto, serão os 16 bits inferiores da resposta. O código pode parecer algo assim, mas não posso garantir que funcione completamente, pois ainda não o testei e muito menos o sintetizei.
Como você pode ver, você pode usar essa ideia geral para adicionar fórmulas mais complicadas, como aquelas com coeficientes. Fórmulas mais complicadas, como os filtros IIR, podem exigir o uso de variáveis para corrigir a lógica do algoritmo. Finalmente, uma maneira fácil de contornar os filtros que têm números reais como coeficientes é encontrar um fator de escala para que todos os números acabem o mais próximo possível de números inteiros. Seu resultado final terá que ser reduzido novamente pelo mesmo fator para obter o resultado correto.
Espero que isso possa ser útil para você e ajudá-lo a fazer a bola rolar.
* Isso foi editado para que a trava de dados e a saída saiam em processos separados. Também usando tipos assinados em vez de std_logic_vector. Estou assumindo que sua entrada ADC será um sinal std_logic_vector.
fonte
Outro trecho de código simples (apenas a coragem). Observe que não escrevi o VHDL diretamente, usei o MyHDL para gerar o VHDL.
Esta é uma implementação direta. Exigirá multiplicadores. A síntese deste circuito, direcionada para um Altera Cyclone III, não usou multiplicadores explícitos, mas exigiu 350 elementos lógicos.
Este é um filtro FIR pequeno e terá a seguinte resposta (não tão boa), mas deve ser útil como exemplo.
Além disso, tenho alguns exemplos, aqui e aqui , que podem ser úteis.
Além disso, sua pergunta parece perguntar: "o que é a representação de ponto fixo apropriada?" Freqüentemente, ao implementar funções DSP, a representação de ponto fixo é usada, porque simplifica a análise dos filtros. Como mencionado, o ponto fixo é apenas arthimético inteiro. A implementação real está simplesmente trabalhando com números inteiros, mas nossa representação recebida é fracionária.
Geralmente, surgem problemas ao converter de número inteiro de implementação (ponto fixo) para / para o ponto flutuante de design.
Não sei até que ponto os tipos de ponto fixo e ponto flutuante VHDL são suportados. Eles funcionarão bem em simulação, mas não sei se sintetizarão com a maioria das ferramentas de síntese. Eu criei uma pergunta separada para isso.
fonte
O OpenCores possui vários exemplos de DSP, IIR e FIR, incluindo o BiQuad. Você precisará se registrar para baixar os arquivos.
editar
Entendo o comentário de Kortuk sobre links mortos e, de fato, se o link para o OpenCores morrer, a resposta se tornará inútil. Estou bastante confiante de que isso não vai acontecer; meu link é genérico e só morrerá se o domínio completo do OpenCores desaparecer.
Tentei procurar alguns exemplos que eu poderia usar para esta resposta, mas eles são muito longos para serem representados aqui. Portanto, seguirei meu conselho de me registrar no site (tive que me mudar para Nova York, porque minha cidade natal não foi aceita) e dar uma olhada no código apresentado lá.
fonte
Tentei implementar scripts para implementação automática de filtros IIR, onde é possível definir se o design deve ser o mais rápido possível (para que cada multiplicação seja realizada com multiplicador dedicado) ou o menor possível (para que cada multiplicador seja reutilizado).
As fontes foram publicadas em alt.sources como "Implementação comportamental, mas sintetizável, de filtros IIR em VHDL" (você também pode encontrá-lo no arquivo do google: https://groups.google.com/group/alt.sources/msg/c8cf038b9b8ceeec ? dmode = origem )
As postagens no alt.sources estão no formato "shar", então você precisa salvar a mensagem como texto e descompactá-la (com o utilitário "unshar") para obter as fontes.
fonte
Que tal agora? https://github.com/MauererM/VIIRF
Ele implementa um filtro IIR baseado em biquad (SOS, seções de segunda ordem) que cuida da implementação de ponto fixo. Ele também possui scripts Python para design e verificação do filtro. Ele não usa construções FPGA específicas do fornecedor e você pode escolher a troca entre o uso em alta e a baixa área.
fonte