Просто FIR интерполятор - вещь достаточно банальная, а вот оптимизация ресурсов - задача более интересная.
Поэтому новая ветка про оптимизацию. Предлагаю пообсуждать решения по оптимизации арифметики на FPGA и MCU для аудио ЦОС.
Предыдущий проект со ссылками на другие ветки здесь.
С появлением недорогих FPGA GoWin оптимизация вроде как особо и не нужна. Но в наших (отечественных) реалиях ассортимент и стоимость микросхем могут быть не самые лучшие.
Ну а кроме того, у меня уже давно были мысли уместить ЦФ в LCMXO2-1200, т.к. это недорогая FPGA со встроенной флешью и в компактном исполнении: QFN-32 5x5mm. Что так же послужило поводом для нового проекта и стало целевой задачей при разработке.
Несколько лет назад я прикидывал, что туда поместится только что-то совсем простое, вроде SM5842. Однако с опытом работы в верилоге получилось ужать арифметику настолько, что даже в такой скромный чип помещается нормальный полноценный апсемплер с шейпером.
Кое что из стандартных приемов оптимизации уже описывал в проекте DF1.
Теперь дополнил подробнее (документ во вложении ниже).
Отдельно добавлю, что изначально мысль ужать ресурсы возникла из того обстоятельства, что в DF2 для первой ступени х2 интерполятора использовались каскады с максимально широкой полосой пропускания (максимально узкой переходной полосой). Сделал я это по аналогии со старыми микросхемами ЦФ, типа SM5847.
Но потом подумал - а собственно нафига?
В интегральных ЦФ первая ступень для любой входной частоты семплирования сделана максимально широкополосной чисто из соображений экономии: тупо используется одна и та же логика, просто на разной частоте.
А на FPGA ситуация обратная: максимальная частота тактирования лимитирована, а добавить несколько наборов коэффициентов для разной входной частоты семплирования - не проблема.
Частоты выше 20кГц все равно не слышно, поэтому переходную полосу можно сделать более пологой (сделать полосу пропускания для всех входных частот семплирования в районе 20кГц).
Это не только укорачивает импульсную хар-ку фильтра, сохраняя преимущества Hi-Res контента, но и потенциально упрощает фильтрацию в аналоге: чем шире полоса пропускания, тем шире и ее отражение на частоте семплирования.
А если так, то кол-во тактов, необходимых для обсчета фильтра резко уменьшается. На столько, что при тактировании частотой 1024Fs можно успеть обсчитать оба канала по очереди, что и стало основным нововведением в проекте DF3E. Т.е. в данном ЦФ блок многоступенчатого FIR апсемплера запускается вдвое чаще, чем в DF2.
Правда одного сужения полосы первой ступени интерполятора оказалось недостаточно для поочередной обработки каналов.
Поэтому для DF3E проекта были так же оптимизированы полуполосные каскады интерполяторов (сокращены до минимума). Из-за этого боковые лепестки в полосе задержания получились повыше, чем в DF2 проекте, но только на частотах кратных 705кГц, где они легко дофильтровываются аналоговым ФНЧ.
Еще немного тактов удалось сэкономить оптимизацией алгоритма умножения центрального отвода полуполосных каскадов. В DF2 это умножение, как и остальные, выполнялось за два такта, а в DF3E - за один.
Для упрощения модуля приема пакетов SPI обработка выполняется сразу по приему данных одного канала: приняли левый - запустили обработку, приняли правый - запустили обработку.
Данное обстоятельство накладывает ограничение на SPI фрейм, в котором сигнал LRCK обязан иметь скважность 50%. Но я еще не сталкивался со случаями, когда данное условие не выполняется.
Кроме того, обработка в остальных блоках так же выполнена последовательной, что позволило серьезно сэкономить еще и на шейпере и дополнительных амсемплерах. Кто пользовал DF2 сразу почувствует разницу.
Другое важное нововведение: добавлено округление с дизером в маке, что позволило уменьшить разрядность шины данных до 22 бит, а так же - сделало входной аттенюатор фактически беспотерьным даже при малой разхрядности шины данных, и его теперь можно использовать как качественный цифровой РГ.
Округление с дизером было и в самом первом проекте DF1, но теперь оно выполнено более аккуратно.
Дизеры для мака и для округления выходных данных выполнены на LFSR со сдвигом на 16 тактов перед выборкой. Если использовать сдвиг на 2^N тактов, то длина генерации последовательности до повтора получается такая же, как и при сдвиге на один такт (т.к. 2^N всегда некратно максимальной длине последовательности LFSR).
Так же, в ходе экспериментов с округлением на сигналах малой разрядности выяснил, что амплитуда дизера должна быть не менее +/-1 LSB, иначе получается модуляция шума, хотя на спектре следов квантования не видно.
Для округления данных на выходе добавлена опция дизера с треугольным распределением. Шум которого на 3дБ ниже, чем с прямоугольным. Однако это имеет значение только для округления без шейпера.
Наличие даже самого простого шейпера 1-го порядка исключает модуляцию шума и можно использовать самый простой шум с равномерным распределением минимальной амплитуды: +/-0.5LSB.
Схему отработки переполнения наоборот упростил: убрал дополнительный аттенюатор перед шейпером.
Теперь аттенюация отдана на откуп пользователю проекта, который должен сам решать - на сколько ослабить сигнал в случае вывода данных малой разрядности с шейпингом.
Ну и отдельно стоит упомянуть про такую вещь, как асинхронное тактирование ядра в DF3E. Для этого выделен отдельный порт "CCLK".
Типовая тактовая частота для данного проекта 1024Fs.
Однако, в случае отсутствия тактовых генераторов на такую частоту, можно применить например 512Fs генераторы, а ядро фильтра (а так же ядро DSD дециматора) затактировать любой произвольной частотой, не обязательно кратной 1024Fs (например от встроенного в FPGA генератора).
Это не только позволяет сохранить производительность при низкой частоте тактовых генераторов, но и при необходимости - поднять тактовую частоту и увеличить длину фильтров.
Подняв частоту вдвое получим производительность DF2 (если конечно позволит быстродействие выбранной плисины).
В архиве проект DF3E с исходниками, как обычно в альфа версии, т.к. протестировать весь накрученный функционал слишком трудоемко.
В файле с примерами приведено два проекта:
1. Вывода на параллельный ЦАП с возможность приема DSD битстрима.
2. Вывод данных с соневского модулятора дифференциальными битстримами на PCM179x в моно-включении в режиме DSD.
Помимо исходников в архиве есть графики частотных хар-к в разных режимах (включая хар-ки DSD дециматоров), диаграммы управляющих сигналов и данных, а так же доработанная утилита (и ее исходник) для преобразования коэф-тов, сгенерированным в матлабе.
Модули вывода SAI_OUTPUT взяты с проекта DF2 с чисто косметическими доработками, поэтому его описание не делал.
Социальные закладки