Страница 22 из 33 Первая ... 12202122232432 ... Последняя
Показано с 421 по 440 из 647

Тема: Проектируем цифровой фильтр для ЦАП 2

  1. #1 Показать/скрыть первое сообщение.
    Завсегдатай
    Автор темы
    Аватар для dortonyan
    Регистрация
    03.06.2009
    Адрес
    BLR
    Возраст
    38
    Сообщений
    3,306

    По умолчанию Проектируем цифровой фильтр для ЦАП 2

    В продолжение ветки open source проект универсального цифрового фильтра.
    Данный проект имел своей целью сделать цапострой на параллельных конверторах более доступным, т.к. интегральные ЦФ для параллельных ЦАП купить достаточно сложно и дорого.

    Особенности фильтра, выгодно отличающие его от интегральных аналогов, доступных в продаже:
    - поддержка х32 оверсемплинга,
    - автопереключение кратности интерполяции в зав-ти от входной ДЧ
    - поддержка конвейерного вывода данных
    - совместимость с большим кол-вом параллельных ЦАП-ов, в том числе SPI
    - 55Дб ослабление на частоте Найквиста
    - конфигурация режимов ЦФ выполняется внешними пинами, не требуя внешнего конфигурационного MCU
    - невысокая стоимость

    Фильтр писался под плисины в QFP-100 корпусах (латтис и алльтеру), но при желании проект несложно портировать и на любую другую плисину.
    В проекте не используются выделенные умножители и описание блоков памяти выполнено универсальным верилоговским стилем.

    Описание в стиле ДШ на агл. языке смотри в файле DF1_1_0_0.pdf
    Прошивки сделаны под плисины в 100-пиновых выводных корпусах: LCMXO2-2000 и EP1C3T100 - DF1_firmware.zip.
    Исходники написаны на верилоге: DF1_source.zip.
    Для гибкости проекта в него введен файл конфигурации, в котором можно менять параметры ЦФ и выбирать условную компиляцию под плисину lattice config_lattice.zip, или altera - config_altera.zip. Данный файл конфигурации дополняет исходники для компиляции проекта.
    Латтисы удобны меньшим потреблением и встроенной флешью. А циклоны - тем что их проще купить (полно на ибее).
    При этом плисины Lattice желательно выбирать с грейдом скорости выше единицы. Самый медленный ZE-1 в принципе тоже работает, но при повышенных температурах, или при просадках питания - не гарантированно.
    Так же во вложении смотри литературу по цифровой арифметике.

    Информация по тестам данного проекта вживую:

    Все модули и режимы (под латтис и под альтеру) отлаживались и проверялись во симуляторе Quartus. Для lattice fpga тайминги отдельно проверялись и оптимизировались в ide diamond.
    Так же, обе конфигурации (под латтис и под альтеру) проверялись в живую на моем ЦАПе на LCMXO2-7000ZE-1, но в ограниченном режиме. Т.е. проверено все, что позволила схемотехника моего ЦАП.
    Что проверено из основного функционала:
    - АЧХ фильтра на частоте Найквиста при входной частоте дискретизации 44,1кГц в режиме lp_mode = 0 и lp_mode = 1.
    - Работа на разном максимальном оверсемплинге: от х4 до х32.
    - Автоматическое переключение оверсемплинга при повышении входной частоты дискретизации до 384кГц.
    - Автоматическое переключение в режим байпасса.
    - Отработка переполнения (цифровой клипп на меандре и на звуковой фонограмме).
    - Индикация входной ЧД, байпасса и клиппа.
    - Вывод данных на битклоке разной скорости (от clk/4 до clk/1).
    - Смена скважности сигнала деглитчера.
    - Работа входного аттенюатора (как логикой во входном модуле, так и коэффициентами).
    - Работа дизеринга и ноизшейпинга округления данных на выходе.

    Что не проверено (проверено только в симуляторе):
    - Работа с тактовой частотой 768Fs.
    - Разные режимы вывода данных (SPI_MODE), в частности не проверена работа конвейерного вывода данных и вывод с непрерывным битклоком.
    - Не проверен вывод данных с SPI заголовками.
    - Кроме того, допускаю наличие описок и в описании (режимов работы и пинов конфигурации очень много). Поэтому версию проекта озаглавлена как alpha.
    [свернуть]


    Описание общей архитектуры ядра фильтра DF1:


    Для максимальной экономии ресурсов fpga фильтр использует х2 каскады симметричных фазолинейных FIR фильтров-интерполяторов.
    - х2 каскады снижают требуемы ресурсы для фильтрации, а так же делают удобным механизм смены кратности оверсемплинга.
    - Фазолинейность означает симметрию импульсной хар-ки относительно центрального пика.
    - Симметричность означает, что используется FIR четного порядка (это значит с нечетным числом коэф-тов, т.е. с одним центральным коэффициентом в максимуме).

    Всего в своем составе фильтр содержит 5 каскадов х2 интерполяторов, которые позволяют развивать максимальную кратность оверсемплинга 2^5 = х32.
    Каждый х2 каскад интерполятора имеет свой fifo буфер данных для расчета свертки фильтра. Итого, в составе фильтра всего 5 fifo буферов интерполяторов. Плюс, фильтр имеет отдельной fifo буфер для хранения результата расчета последнего х2 каскада.

    На каждый входной семпл х2 интерполятор рассчитывает два новых семпла.
    Входные данные всегда добавляются в fifo первого каскада. Результат расчета свертки первого каскада (два новых семпла) записывается в fifo будет 2-го каскада. Второй каскад для каждого нового семпла так же рассчитывает пару новых и результат (всего четыре новых семпла) добавляет в fifo 3-го каскада. И так далее...
    Последний 5-ый каскад для входных 16-ти семплов рассчитывает новые 32 семпла и помещает результат в fifo выходного буфера. Из выходного fifo буфера данные с заданной выходной частотой дискретизации извлекаются и передаются на выход.

    При снижении кратности оверсемплинга выходной fifo буфер принимает данные не с 5-го каскада, а из одного из предыдущих.
    Например, при кратности х8, входные данные добавляются в fifo 1-го х2 каскада. Далее, результат (два семпла) - добавляются в fifo 2-го каскада. Результат 2-го (4 семпла) добавляются в fifo 3-го каскада. И в конце - результат 3-го каскада (8 семплов) добавляются в выходной fifo буфер.

    Для экономии ресурсов fpga все каскады фильтра для расчета новых семплов используют общий арифметический блок (по одному на каждый канал) и общих блок ОЗУ. Поэтому расчет новых семплов каждого каскада выполняется последовательно (по очереди).
    Модули MAC, работают в конвейерном режиме, т.е. результат на выходе мака появляется через несколько тактов после загрузки последнего семпла данных на входе. Данное обстоятельство создает коллизию при последовательном обсчете каскадов от первого к последнему, т.к. расчет свертки следующего каскада будет начинаться раньше, чем завершится расчет семплов предыдущего каскада. Данную коллизию можно устранить просто добавляя паузы ожидания на выгрузку конвейера маков, но в таком случае упадет производительность блока арифметики.
    Поэтому, для устранения данной коллизии используется другой метод - обсчет каскадов выполняется в обратном порядке (от последнего к первому).
    Т.е. в режиме х32 оверсемплинга при загрузке нового семпла в fifo 1-го каскада, конечный автомат сначала запускает 5-ый х2 каскад и рассчитывает 32 новых семпла, которые записываются в выходной fifo буфер. Затем - второй х2 каскад, котоый записывает 16 новых семплов в fifo 5-го каскада и т.д.

    Т.к. fifo буферы размещены в общей ОЗУ, то данный блок поделен на сектора. Всего 6 рабочих секторов: 5 для fifo интерполяторов и один для выходного буфера.
    Для упрощения арифметики адресации размеры буферов fifo выбраны кратными 2^N (адрес такого буфера при переполнении автоматом переходит на начало).

    Т.к. при интерполяции промежуточные семплы прореживаются нулями, то объем fifo буфера интерполятора можно задавать вдвое меньше кол-ва отводов фильтра.
    Для первого каскада (самого длинного) выделена глубина fifo 128 семплов. Поэтому максимальная длина фильтра для данного буфера составляет 256 отводов. Максимальная длина симметричного фазолинейного фильтра при этом будет 253 (увеличить можно только на 4 отвода, тогда получится 257, что не поместится в буфере).
    Для остальных каскадов, а так же для выходного буфера глубина fifo задана 64 семпла.
    Общий блок ОЗУ имеет объем 512 семплов. Поэтому в нем занято 128 + 64 + 64 + 64 + 64 на фильтры и еще 64 на выходной буфер. Всего 448 семплов. Еще 64 слова памяти остаются не использованы.

    Адресация к блокам fifo внутри общего блока ОЗУ организована через смещения: старшие биты адреса задают адрес fifo буфера, а младшие - позицию внутри данного fifo буфера.
    [свернуть]


    Mac_Wx9

    Модуль Mac_Wx9 - собственно тот модуль который выполняет умножение с накоплением входных отсчетов из fifo на коэффициенты из блока памяти coef_rom. По результату моделирования фильтров в матлабе выяснено, что для заданных хар-к фильтра оптимальная разрядность коэффициентов составляет порядка 26..28 бит.
    Исходя из тактовой частоты 1024Fs выбрано максимально допустимое кол-во тактов умножителя на одно умножение: 3 такта. Это значит, что каждые три такта на входы умножителя подается новый семпл данных и новый коэффициент. При этом, на каждом такте выполняется умножение на 1/3 слова коэффициентов.
    Исходя из этого, разрядность коэф-тов выбрана 27 бит, как удобная с точки зрения построения умножителя (делится на три), так и с точки зрения достаточной точности вычислений. Так же 27 бит коэффициенты хорошо ложатся в выделенные блоки памяти, разрядность которых кратна 9 разрядам.
    Поэтому для данного проекта коэффициенты предварительно разбираются на 9 бит слова (для этого написана консольная утилита, которая из матлабовского файла коэффициентов создает верилоговский файл с коэффициентами в нужном формате).
    Для максимальной производительности арифметики модуль mac выполняет умножения без пропусков тактов (каждые три такта - новое умножение), пока не будут обсчитаны все х2 каскады фильтра.
    Также для оптимизации арифметики используется свойство симметрии коэффициентов фильтра. Если используются фазолинейный фильтр четного порядка, то в расчете каждого семпла выполняется умножение одного и того же коэффициента на два разных семпла данных.
    Это обстоятельство позволяет в свертке заменить выражение d1*c + d2*c выражением (d1 + d2)*c, вдвое сокращая кол-во умножений. Но в то же время, такая арифметика требует чтения двух семплов на каждое умножение (каждый семпл читается за один такт clk).
    Т.к. умножение выполняется за 3 такта, а чтение данных - за 2, то каждый 3-ий такт ОЗУ доступно для чтения результата из выходного буфера fifo.
    Учитывая кол-во тактов умножителя, синхронизация разных модулей фильтра осуществляется посредством счетчика syncnt внутри модуля DF1_FIR_CORE, который постоянно считает по циклу от нуля до двух.
    [свернуть]


    data_write

    Записью данных в fifo буфер управляет модуль data_write. Данный модуль принимает сигналы на запись данных от входного модуля sai_input (когда приняты данные SAI_input модуля) и от мака mac_control (когда на выходе мака готов очередной семпл).
    Для максимальной производительности арифметики мак работает без остановок, поэтому если оба сигнала приходят одновременно, то мак имеет более высокий приоритет (данные от модуля SAI_input запишутся после записи нового семпла из мака).
    Позиции актуальных адресов fifo хранятся в регистрах-счетчиках: currpos_st1...currpos_st6. При записи каждого нового семпла в буфер выполняется инкремент соответствующего счетчика.
    При этом, если выполняется запись данных от входного модуля, то data_write генерирует сигнал start_mac -> write_fir_start, который запускает конечный автомат управляющий арифметикой fir фильтра.
    [свернуть]


    init_adr data_adr

    Стартует алгоритм арифметики с модуля init_adr, который подготавливает данные для инициализации автомата генерации адресов интерполяторов (data_adr):
    - длина первого lenth1 и второго lenth2 прохода фильтра для данного каскада фильтра
    - кол-во повторов прохода: repeatnum
    - номер каскада, с которого начинается старт арифметики. Для х32 режима это 5-ый каскад, для х16 - 4-ый и т.д.
    - текущую позицию буфера fifo для данного каскада: curr_pos
    - номер текущего каскада х2 интерполятора: stage_num
    Модуль data_adr принимает инициализирующие значения от init_adr и генерирует адреса для заданного каскада фильтра (для расчета свертки х2 интерполятора). Так же модуль data_adr инициализирует генератор адресов коэффициентов coef_adr.
    По завершении генерации адресов data_adr генерирует сигнал next_stage обратно в модуль init_adr.
    Приняв этот сигнал init_adr готовит на свой выход данные инициализации для расчета следующего х2 каскада интерполятора.
    Обмен сигналами между модулями повторяется, пока не будут обсчитаны все каскады фильтра.
    [свернуть]


    data_read

    Модуль data_read является промежуточным модулем между fir фильтром и модулем вывода данных. По сигналу out_load от модуля SAI_output, модуль data_read запускает алгоритм чтения данных из выходного fifo буфера.
    Для этого, модуль data_read анализирует значение счетчика syncnt, и в момент когда ОЗУ свободна (нет чтения данных для мака) - выполняет чтение из буфера. Данные в новом семпле округляются с ноизшейпингом и проверяются на переполнение.
    [свернуть]


    coef_control


    Коэффициенты DF1 рассчитывались в matlab r2013b -> FDA tool -> FIR
    Для первого каскада (для самой низкой входной частоты дискретизации 44,1/48кГц) использован простой fir фильтр максимальной длины с Equiripple оптимизацией с повышенным ослаблением на частоте Найквиста. Для остальных каскадов использованы half-band фильтры.
    При повышении входной частоты дискретизации производительность фильтра пропорционально снижается, поэтому для первого каскада добавлены дополнительные наборы коэффициентов более коротких полуполосных фильтров.
    Управление наборами коэффициентов в зависимости от входной и выходной ЧД, а так же от режима lp_mode описано в файле coef_control внутри которого вызывается модуль rom_coef_control.
    Заголовок файла rom_coef_control содержит описание расчета максимального кол-ва тактов умножения для соотношения входной и выходной ЧД, исходя из которого выбирается набор коэффициентов для первого каскада интерполятора фильтра.
    [свернуть]


    Коэффициенты

    DF1 использует схему знакового умножителя в дополнительных кодах. Поэтому коэффициенты в ROM фильтра так же описаны в дополнительных кодах разрядностью 27бит (по три 9 бит слова на каждый коэффициент).
    Фактически свертка fir фильтра состоит из суммы частных (т.е. делений). Однако, т.к. арифметика деления сложнее умножений, то для замены частных значений произведениями коэффициенты переводятся в дробные значения. Т.е. выражение d/4 заменяется выражением d*0.25.
    Поэтому значения коэффициентов нормированы к единице: старший разряд дополнительного кода кодирует знак, в следующем разряде - единица, остальное дробная часть.
    Для 8 бит кода +1 выглядит так 0х40, минус один - 0хС0 (в отличие от целого числа, где минус единица это 0хFF).
    Но, если самый большой положительный коэффициент фильтра имеет значение меньше единицы, то второй бит слева всегда равен нулю. А значит можно увеличить разрядность коэффициентов на один бит без переполнения разрядной сетки.
    Matlab по умолчанию выполняет данную операцию автоматически, для максимального использования разрядной сетки коэффициентов: задает numerator range 0.5. Это значит что вес следующего разряда после знака не единица, а 0.5.
    Но в случае полуполосного фильтра максимальный (центральный) коэффициент равен единице. Поэтому matlab задает для него numerator range 1.
    Если ЦФ использует в своем составе оба типа фильтра (полуполосный и обычный), то при таком расчете получается разница размерностей коэффициентов, что не допустимо. Возникает проблема выравнивания размерностей.
    Способы решения данной проблемы:
    1. Использовать для коэффициентов неполуполосного фильтра диапазон 1 (но ухудшится точность для данного фильтра на один разряд).
    2. Задать для полуполосного фильтра размерность 0.5. Тогда matlab увеличит разрядность коэффициентов на бит, а для центрального отсчета единицу 0x40 заменит значением вдвое большим - 0x7F, чтобы получить единицу, но не выйти за пределы разрядной сетки. Но такое значение получается не ровно вдвое больше, а с погрешностью в -1LSB. К тому же, большое кол-во единиц в слове коэффициента означает большое кол-во суммирований в умножителе, что хуже с точки зрения потребления и помех.
    3. Решение использованное в DF1. Для максимального использования разрядной сетки диапазон для всех типов фильтра задается 0.5. А для полуполосного фильтра значение центрального коэф-та задается вдвое меньшим, т.е. вместо единицы - 0.5, чтобы не выйти из разрядной сетки.
    Как описано выше, умножитель имеет предварительный сумматор для суммирования двух семплов перед умножением на коэффициент. Чтобы компенсировать вдвое меньший центральный коэффициент для полуполосного фильтра значение семпла данных суммируется само с собой, что эквивалентно умножению на два. Т.е. выражение d*1 заменяется выражением (d+d)*0.5.
    Таким образом выполняется максимальное использование разрядной сетки коэффициентов с минимальным кол-вом суммирований и почти без дополнительных затрат логики.
    [свернуть]


    Конфигурация проекта


    Конфигурация проекта под разные FPGA реализуется через файл config.v, который содержит настройки условной компиляции.

    Выбор стиля описания логики. Нужен для оптимизации логики под fpga lattice или под альтеру.
    //`define LOGIC_STYLE_ALTERA
    `define LOGIC_STYLE_LATTICE

    // define RAM block zise for selected device - Выбор размера выделенных блоков памяти. Используется для оптимизации расхода блоков памяти.
    //`define BLOCK_RAM_SIZE_4K
    `define BLOCK_RAM_SIZE_9K

    // define FIR bus resolution (in bits). Valid values: from 26 to 36. - Выбор разрядности шины данных. Задает разрядность шины с учетом запаса в 1 бит на переполнение. Значение 31 бит означает разрядность данных на входе 30 бит.
    `define BUS_WIDTH 31 // Must be lower or equal ACC_WIDTH !!!!!
    Данное значение разрядности можно понижать, но для исключения накопления ошибок округления рекомендуется при этом включать дизеринг мака.

    // define accumulator bus resolution (in bits). Valid values: from 32 to 42. - Выбор разрядности аккумулятора. Разрядность так же можно понижать, но с включением дизеринга.
    `define ACC_WIDTH 37 // Must be grater or equal BUS_WIDTH !!!!!

    // MAC dithering signed random value length in bits. Valid values: from 2 to 8 - разрядность дизеринга при округдении в маке. Нуль - означает выключен.
    // Zero value switch dithering off.
    `define MAC_DITH_WIDTH 0

    // Enable dedicated FPGA multipplier - Включает описание умножителей для подключения выделенных блоков умножения, при их наличии в выбранной FPGA.
    //`define MULT_DEDICATED_ENA

    // select attenuate module: input (logic based), or coefficient (coef_ROM based) - Выбор построения входного аттенюатора: коэффициентами или входным аттенюатором.
    `define INPUT_ATT_ENA
    //`define COEF_ATT_ENA
    Аттенюация коэффициентами расходует дополнительные блоки памяти на коэффициенты (в 4 раза больше), но экономит эчейки, т.к. не использует логику на входном аттенюаторе.
    Аттенюатор во входном модуле предпочтительнее с точки зрения точности арифметики, т.к. Аттенюация коэффициентами, хоть и не значительно, но понижает разрядность коэффициентов (пропорционально уровню ослабления).

    // Input attenuator dithering signed random value length in bits. Valid values: from 2 to 8 - Задает уровень дизеринга во входном аттенюаторе. Используется при включении аттенюатора и пониженной разрядности шины данных. Нуль - значит выключен.
    // Zero value switch dithering off.
    `define ATT_DITH_WIDTH 0
    [свернуть]
    Вложения Вложения
    Последний раз редактировалось dortonyan; 15.11.2021 в 12:28.

  2. #421
    Завсегдатай Аватар для Nikkov
    Регистрация
    01.11.2005
    Адрес
    Омск, Сибирь
    Возраст
    51
    Сообщений
    1,364

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    Цитата Сообщение от tomtit Посмотреть сообщение
    Для Bulk протокола этот механизм подстройки не нужен. Это пакетно-ориентированный протокол без потерь данных.
    То есть, если нет запроса, следующий пакет не пошлют.
    Так ведь Bulk не гарантирует скорость передачи, в отличии от изохронного протокола, поэтому на стороне приемника надо будет иметь достаточно большой буфер. А так есть в инете нечто подобное.
    Электроника наука слабоизученная (c)
    Неизвестный специалист антенного хозяйства по поводу периодического пропадания сигнала в коллективной антенне

  3. #422
    Завсегдатай Аватар для l3VGV
    Регистрация
    02.05.2009
    Адрес
    Псков
    Возраст
    42
    Сообщений
    1,016

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    Цитата Сообщение от tomtit Посмотреть сообщение
    Но идея про плагин мне не понятна.
    Я разработал несколько устройств с этим протоколом, но всегда приходилось использовать специально написанный драйвер. Bulk стандартно используется ОC только для подключения масс-памяти(диски и флэш карты). Действительно, это самый простой и правильный метод обмена данными, если хватает скорости.
    А драйвер что делал? Я полагаю использовать WinUSB и писать прямо в девайс. Я так со своим осцилоскопом делал. Нормально работало!

    ---------- Сообщение добавлено 09:03 ---------- Предыдущее сообщение было 09:01 ----------

    Цитата Сообщение от Nikkov Посмотреть сообщение
    Так ведь Bulk не гарантирует скорость передачи, в отличии от изохронного протокола, поэтому на стороне приемника надо будет иметь достаточно большой буфер.
    Если на этот корневой концентратор ничего другого не вешать, то нормально будет.

    "Большой" буфер это сколько? 5-10кб я думаю хватит с запасом, даже с учетом дабл-буфера.

  4. #423
    Завсегдатай Аватар для sia_2
    Регистрация
    18.07.2005
    Сообщений
    4,010

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2


    Offтопик:
    Именно Bulk Stream и дает как максимальное использование пропускной способности канала, так и гарантию достоверности передач, в отличие от изохронного. На USB 2.0 у меня ниже 20 МБайт/с
    не было, несмотря на умеренный размер блоков, типично 30...35. Естественно, DLL своя. Естественно, поток произвольный, как угодно синхронизируемый, максимальное мертвое время 250 мкс.

  5. #424
    Завсегдатай Аватар для Meta|_
    Регистрация
    08.03.2005
    Адрес
    Северная Голландия
    Возраст
    40
    Сообщений
    1,995

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    Цитата Сообщение от sia_2 Посмотреть сообщение
    Именно Bulk Stream и дает как максимальное использование пропускной способности канала, так и гарантию достоверности передач, в отличие от изохронного.
    ЕМНИП, изохронный позволяет резервировать полосу, в отличие от bulk, что может быть полезно когда несколько устройств конкурируют за шину. Но если заранее думать что и куда подключать, то на bulk, конечно, можно сделать лучше
    ∇·D = ρ
    ∇·B = 0
    ∇xE = – ∂B/∂t
    ∇xH = j + ∂D/∂t
    © J. C. Maxwell, O. Heaviside

  6. #425
    Завсегдатай Аватар для Nikkov
    Регистрация
    01.11.2005
    Адрес
    Омск, Сибирь
    Возраст
    51
    Сообщений
    1,364

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2


    Offтопик:
    Цитата Сообщение от Meta|_ Посмотреть сообщение
    ЕМНИП, изохронный позволяет резервировать полосу, в отличие от bulk
    Да я писал именно про это. Понятно, что с учетом запаса по скорости в bulk-е это не слишком большое ограничение, хватало бы только буфера на приемной стороне. Основная проблема в нестандартности такого решения, т.е. сделать нормальный системный аудио-драйвер будет сильно сложнее самого устройства, поэтому либо ASIO+WinUSB/libusb и работа только с тем софтом, что его поддерживает, либо вообще плагин под конкретный плеер.

    Электроника наука слабоизученная (c)
    Неизвестный специалист антенного хозяйства по поводу периодического пропадания сигнала в коллективной антенне

  7. #426
    Частый гость Аватар для карабас123
    Регистрация
    31.12.2007
    Адрес
    Ижевск
    Возраст
    59
    Сообщений
    114

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    И таки да. Делал такой аудио вход выход. Программа под винду самописная, ft232h, хай спид, со стороны девайса fpga циклон3. Внешняя память sram, 8*512 k

  8. #427
    Новичок Аватар для kardanium
    Регистрация
    01.12.2018
    Адрес
    Молдавия
    Сообщений
    10

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    О, тема. У меня проект-долгострой по схожей теме на ПЛИС.
    48кГц 24 бит -> I2S -> Овевремплер (384к) -> Нойзшейпинг -> Сигма-Дельта (9 бит) -> ШИМ модулятор (полумост, с контролем мертвого времени и аварийной защитой)
    Все узлы сделаны, за исключением нормального оверсемплера. Уперся в то, что с 48кГц сделать нормальное оверсемплирование не так просто.
    Из-за слабого оверсемплинга, побороть шум квантования не удалось. Когда созрею, возьмусь за поиск оптимального алгоритма и попробую сделать автомат на ПЛИС. Возможно, попробую разобраться в Вашем оверсемплере и реализую похожий на CyII (у него аппаратные умножители есть)
    Входной битрейт выбран таким низким, потому что более высокие битрейты микроконтроллеру STM32F407 (стоящему между АЦП PCM1802 и ПЛИС) будет тяжко обрабатывать, если навесить на поток десяток каналов эквалайзера. В итоговый проект пойдет что-то помощнее, из серии STM32H7xx, но пока у меня их нет, а ЦАП нужно сделать.
    Пока все налаживается на Cyclone II (EP2C5T144C8N). ШИМ модулятор разогнал до 200мГц и получил 9 бит на частоте 384кГц.
    Последний раз редактировалось kardanium; 06.01.2023 в 22:58.

  9. #428
    Завсегдатай
    Автор темы
    Аватар для dortonyan
    Регистрация
    03.06.2009
    Адрес
    BLR
    Возраст
    38
    Сообщений
    3,306

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    На контроллере мастерить ЦФ при разрядности данных и коэф-тов выше 16 бит нецелесообразно. Модулятор тем более.
    Пробовал на PIC32MZ сделать максимально простой однобитный модулятор 3-го порядка. При тактовой 200МГц и оверсемплинге модулятора х64 быстродействия проца хватает максимум на 1 канал, и то с ухищрениями, типа переложения ряда функций на DMA.
    В общем ПЛИС - наше все.
    Разбираться с потрохами моего ЦФ нет смысла. Код не особо читабельный. Проще использовать модуль ядра (DF1_fir_core), у которого на входе и выходе параллельные шины данных. А модули ввода и вывода - использовать свои.
    В соседней ветке я уже приводил пример, как прикрутить модулятор к моему ЦФ.

  10. #429
    Новичок Аватар для kardanium
    Регистрация
    01.12.2018
    Адрес
    Молдавия
    Сообщений
    10

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    Благодарю.
    На МК у меня только пользовательская эквализация, регулирование громкости, баланса, сведение в моно (если нужно) и парочка дополнительных фильтров.
    STM32F407 справляется с 32-битным потоком 48кГц на ура. Причем, в стерео. В качестве фильтров использую БИХ в виде биквадратных фильтров. Расчет их коэффициентов производится там же, но только в момент перестройки. И это я еще неоптимально произвожу свертку. Там можно еще оптимизировать алгоритмы вычислений. У ядра ARM Cortex-M4 есть инструкции MAC, инструкции насыщения и прочий DSP функционал. Но преобразование в поток 384кГц он уже не вытягивает. Точнее, если сильно заморочиться, то выжать можно, но это уже нецелесообразно. Потому для преобразования и модуляции решено было использовать ПЛИС. Проект как бы и академический тоже. У меня ранее небыло задач под ПЛИС и вдруг появилась возможность их освоить. Я узнал, что сложную логику работы можно тоже построить на конечном автомате (как и в программах для ЦПУ), что такое асинхронный дизайн, временной анализ и прочее. С DSP было то же самое, сейчас хотя-бы базовые вещи знаю, вроде "что такое дискретный сигнал и каковы его особенности, что такое импульсная характеристика, какие типы цифровых фильтров бывают, как производится свертка сигналов, как оценивается фильтр, какие методы расчетов бывают и их особенности и т.д."
    Свой проект я тоже планирую открыть, но только после того, как получу вменяемые результаты. Это будет цифровой усилитель, но не Hi-End качества. Дай бог получить хотя-бы Hi-Fi начального уровня. Ладно, это оффтопик.

    Хотелось бы прояснить некоторые вещи по поводу Вашего проекта.
    Как я понял, Ваш апсемпллер является каскадным, где каждый каскад увеличивает частоту дискретизации в два раза, но апсемплер построен так, что для всех каскадов используются одни и те же вычислительные ресурсы.
    Каскад построен на фазолинейном КИХ фильтре четного порядка.
    Соответственно вопрос. Коэффициенты для всех каскадов одни и те же?
    Просто, если я правильно понимаю теорию дискретных сигналов, при использовании импульсной характеристики, расчитанной для одной частоты дискретизации, при использовании ее с сигналом другой частоты, большая часть характеристик фильтра сохраняется, только АЧХ его сдвигается по спектру вверх или вниз, кратно частоте дискретизации.

    Я строил свой КИХ на 128 коэффициентов. Получился удачным (вычисляет очень быстро, не просит много ресурсов ПЛИС, но создает задержку на четыре выборки), но его реализация не подходит для апсемплинга. Там нужна оптимизация из-за нулевых выборок. И я использовал один фильтр, что приводило к плохой интерполяции. Причем, чем выше частота, тем хуже была интерполяция. С 14 кГц начинали вылезать небольшие "провалы" в сигнале между ненулевыми выборками, что усиливало шум и приводило к нежелательным гармоникам. Но как я понял сейчас, нужна поэтапная обработка, с увеличением частоты дискретизации в два раза на каждом этапе.

  11. #430
    Завсегдатай
    Автор темы
    Аватар для dortonyan
    Регистрация
    03.06.2009
    Адрес
    BLR
    Возраст
    38
    Сообщений
    3,306

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    Цитата Сообщение от kardanium Посмотреть сообщение
    Как я понял, Ваш апсемпллер является каскадным, где каждый каскад увеличивает частоту дискретизации в два раза, но апсемплер построен так, что для всех каскадов используются одни и те же вычислительные ресурсы.
    Примерно так. Для каждого канала используется по одному модулю MAC, которые обсчитывает х2 апсемплеры по очереди.

    Цитата Сообщение от kardanium Посмотреть сообщение
    Соответственно вопрос. Коэффициенты для всех каскадов одни и те же?
    Нет конечно, так нерационально. Для каждого каскада задаются свои коэф-ты, с одинаковой полосой пропускания 20кГц (для самой первой ступени 19,5кГц). Причем для первой ступени используются 4 разных набора коэф-тов, в зав-ти от соотношения входной и выходной частот семплирования.

    Цитата Сообщение от kardanium Посмотреть сообщение
    Но как я понял сейчас, нужна поэтапная обработка, с увеличением частоты дискретизации в два раза на каждом этапе.
    Вообще не обязательно, можно делать и однопроходной фильтр.
    В моем проекте каскадирование используется для оптимизации, т.к. позволяет сэкономить на кол-ве отводов фильтра (на кол-ве умножений) ценой повышения разрядности шины данных. Если для однопроходного достаточно 24бита, то для каскадного надо минимум 30..32.
    Либо нужно добавлять дизер при округлении из аккумулятора, тогда можно разрядность опускать и ниже 24-х бит. Но дизеринг - это тоже дополнительные ресурсы, поэтому иногда проще повысить разрядность. Файл конфигурации в моем проекте позволяет пробовать разные варианты разрядностей (в некоторых пределах).

    Вообще, для первоначального ознакомления рекомендую начать с первой ветки, а так же с ветки под дельта-сигмы. Там много интересного по теме и вообще.

  12. #431
    Новичок Аватар для kardanium
    Регистрация
    01.12.2018
    Адрес
    Молдавия
    Сообщений
    10

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    Спасибо за ответы, займусь изучением вопроса для начала.

  13. #432
    Новичок Аватар для Montix
    Регистрация
    09.01.2022
    Сообщений
    37

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    Я пытаюсь использовать цифровой фильтр по дифференциальной конфигурации (четыре ЦАП), описанной dortonyan. Теперь думаю, как выбрать правильную топологию.

    Первый вопрос, который возникает, нужно ли вставлять так называемый FAN-OUT Buffer между ПЛИС и ЦАП? Причина в том, что от одного порта ПЛИС одновременно управляются четыре ЦАП (сигналы bck1, wck1, ltch1). Каждый порт ЦАП имеет входную емкость примерно 5 пФ. А так один порт ПЛИС возбуждает сразу суммарную емкость 20 пФ, что значительно округляет импульсный сигнал и ограничивает максимальное быстродействие SPI.

    Топология такова, что ПЛИС подключается через I2S к процессору, который подключен к USB на компьютере. ПЛИС и ЦАП имеют собственный источник питания. По этой причине я хочу использовать цифровой изолятор TI ISO для шумоподавления. Следующий вопрос: размещать ли ISO между процессором и ПЛИС или между ПЛИС и ЦАП? Для того, чтобы подавить возможные помехи от ПЛИС. ISO в основном имеет задержку (propagation delay), и у каждого есть +/- немного другая задержка. Но если после каждого ЦАП будет использоваться деглитчер, управляемый общим сигналом, то отдельные дифференциальные выходы должны быть синхронными (без взаимного смещения).

    Пожалуйста, помогите выбрать правильную топологию.

  14. #433
    Завсегдатай
    Автор темы
    Аватар для dortonyan
    Регистрация
    03.06.2009
    Адрес
    BLR
    Возраст
    38
    Сообщений
    3,306

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    Цитата Сообщение от Montix Посмотреть сообщение
    Каждый порт ЦАП имеет входную емкость примерно 5 пФ. А так один порт ПЛИС возбуждает сразу суммарную емкость 20 пФ, что значительно округляет импульсный сигнал и ограничивает максимальное быстродействие SPI.
    20 пик для порта плис - ерунда. Больше влиять будут последовательные резисторы в сигналах. На вскидку номинал можно использовать порядка 47 ом.
    Но распараллелить сигнал на разные порты может иметь смысл для улучшения трассировки.

    Цитата Сообщение от Montix Посмотреть сообщение
    Топология такова, что ПЛИС подключается через I2S к процессору, который подключен к USB на компьютере. ПЛИС и ЦАП имеют собственный источник питания. По этой причине я хочу использовать цифровой изолятор TI ISO для шумоподавления. Следующий вопрос: размещать ли ISO между процессором и ПЛИС или между ПЛИС и ЦАП? Для того, чтобы подавить возможные помехи от ПЛИС. ISO в основном имеет задержку (propagation delay), и у каждого есть +/- немного другая задержка. Но если после каждого ЦАП будет использоваться деглитчер, управляемый общим сигналом, то отдельные дифференциальные выходы должны быть синхронными (без взаимного смещения).
    Изолятор нужен для развязки от ЮСБ. Поэтому ставить развязку между плис и ЦАП имеет смысл только если плис запитана от USB.
    Задержка изолятора ни на что не влияет, т.к. она примерно одинаковая для всех сигналов.
    Если в схеме используется деглитчер, то сигнал "dg" нужно реклочить, вне зависимости от того, где используется изолятор. Задержка реклока учтена в таймингах выходных сигналов.

  15. #434
    Новичок Аватар для kardanium
    Регистрация
    01.12.2018
    Адрес
    Молдавия
    Сообщений
    10

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    Мысли по поводу своего проекта.
    В общем, оверсемплер решено строить на КИХ фильтре.
    Мне нужно увеличить частоту семплирования с 48кГц до 384кГц. Это получается в восемь раз. Других комбинаций пока не рассматриваю.
    Соответственно, между каждой входной выборкой, вставляется еще семь нулевых выборок и все это заталкивается в фильтр.
    Для того, чтобы сигнал нормально восстановился, нужен фильтр с полосой пропускания до 24кГц, и полосой подавления от 24кГц.
    Такой фильтр потребует бесконечное количество коэффициентов. Но звуковой диапазон до 20кГц, а частота Найквиста - 24кГц, соответственно,
    нужно уложить полосу перехода между 20 и 24 кГц.
    Для частоты семплирования 384кГц по расчетам выходит от 512 до 1024 коэффициента, в зависимости от
    требуемого уровня подавления и требуемой равномерности в полосе пропускания.
    Чтобы решить в лоб для наихудшего сценария (1024 коэффициента), нужно выполнить 1024 MAC операции по каждому запросу DS модулятора.
    Если постараться выполнять операцию за такт (пусть даже и конвейером за несколько тактов), то получается 384000 * 1024 + N = 393,216 + N МГц, что для второго Циклона серии C8 уже совсем много. Не вытянет по быстродействию. Однако, вставленные семь пустых выборок никак на результат не влияют, значит их нужно исключить.
    Идея следующая:
    Выборка с I2S записывается в кольцевой буфер, размерностью 128 слов и запускается вычисление первой выходной выборки.
    С кольцевого буфера последовательно читаются выборки и подаются на первый вход MAC.
    С ROM памяти, где хранятся коэффициенты, читаются каждый восьмой коэффициент, начиная с первого и подаются на второй вход MAC.
    По окончанию всех умножений и суммирований, результат фиксируется на выходе, а MAC сбрасывается.
    По поступлению запроса на следующую выборку от DS модулятора, вычисление запускается повторно, однако, коэффициенты читаются начиная со второго.
    При следующем запросе, коэффициенты уже будут читаться, начиная с третьего. И так далее.
    Таким образом, как бы двигаем не данные нулевыми выборками, а коэффициенты. Если на выход поставить FIFO, то можно не ждать запроса и вычислить все восемь выходных выборок подряд.
    Количество операций сократилось в восемь раз. 384000 * 128 + N = 49,152 + N МГц, что уже приемлемо и можно даже использовать 32-битные коэффициенты.
    Написал конвейеризированный модуль MAC в операндами 24 и 32 бита и 56-битным результатом. Quartus пообещал, что он заработает на частотах до 130-140 МГц,
    что вполне даже с двухкратным запасом. На выходных буду делать новый оверсемплер, о результатах сообщу.

  16. #435
    Завсегдатай
    Автор темы
    Аватар для dortonyan
    Регистрация
    03.06.2009
    Адрес
    BLR
    Возраст
    38
    Сообщений
    3,306

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    Цитата Сообщение от kardanium Посмотреть сообщение
    Но звуковой диапазон до 20кГц, а частота Найквиста - 24кГц, соответственно,
    нужно уложить полосу перехода между 20 и 24 кГц.
    Лучше рассчитывать на частоту семплирования в сетке 44,1кГц. Т.е. переходную полосу от 20 до 22,05кГц. Тогда для обеих сеток в полосе пропускания будет помещаться вся звуковая полоса (не ниже 20к).

    Цитата Сообщение от kardanium Посмотреть сообщение
    Если постараться выполнять операцию за такт (пусть даже и конвейером за несколько тактов), то получается 384000 * 1024 + N = 393,216 + N МГц, что для второго Циклона серии C8 уже совсем много. Не вытянет по быстродействию. Однако, вставленные семь пустых выборок никак на результат не влияют, значит их нужно исключить.
    Да, нулевые отсчеты можно опустить, тогда кол-во умножений в 8 раз ниже. Плюс можно использовать симметрию коэффициентов фазолинейного фильтра четного порядка. Тогда кол-во умножений еще вдвое меньше, но с предварительным суммированием. Логика чтения данных при этом конечно посложнее будет.
    Делать полное ослабление на на частоте Найквиста тоже не обязательно, в кач-ве компромисса можно задавить на 50..70дБ, что еще сэкономит ресурсов.
    32 бит коэф-ты оверкилл. Я вот думаю наоборот урезать с 27 до 24.
    Разрядность аккумулятора тоже можно урезать. Для однопроходного фильтра при 24-х битных данных на выходе достаточно порядка 32-х бит.

  17. #436
    Новичок Аватар для kardanium
    Регистрация
    01.12.2018
    Адрес
    Молдавия
    Сообщений
    10

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    Для 44,1 нужно втиснуть переход в еще более узкую полосу, хотя думаю, что для моего мощного фильтра это не будет большой проблемой.
    Я задавал подавление до 120 дБ. Такой уровень просит разрядность коэффициентов повыше.
    Из 56 бит результата 31 младших битов все равно нужно отбросить, так как это дробная часть, которая по итогу не нужна.
    Следующие 24 бита забираются в качестве результата и все остальное свыше - тоже отбрасывается. Еще как я понял, КИХ фильтр при оверсемплинге снижает выходной уровень сигнала. Можно в принципе задать усиление в полосе пропускания, но тогда под целую часть нужно будет выделить дополнительные биты, отобрав их у дробной части, либо добавив дополнительные. Еще одна причина, почему 32 бита - использованные аппаратные умножители будут задействованы полностью. Там что 24х24, что 24х32 - особо на расход ресурсов и быстродействие не влияют. То есть влияют, но незначительно. По этому можно не стесняться разрядностью.

    На счет использования симметрии ИХ подумаю.
    Это получается, фильтр четного порядка с нечетным количеством коэффициентов.
    В принципе можно сделать реверс счетчика адреса ROM, переключая второй операнд его сумматора с +1 на -1 согласно состояниям управляющего конечного автомата. В принципе, не сильно усложнится логика.

    Впрочем, у меня все это пока на стадии макетирования и проверки, что задумка в принципе реализуема. Потом уже буду оптимизировать в плане ресурсов и дорабатывать в плане универсальности и всеядности форматов входных потоков данных.
    В принципе, конечная цель - некий аналог чипа TAS5508, но двухканальный и без лишних наворотов.
    Последний раз редактировалось kardanium; 20.01.2023 в 22:56.

  18. #437
    Завсегдатай
    Автор темы
    Аватар для dortonyan
    Регистрация
    03.06.2009
    Адрес
    BLR
    Возраст
    38
    Сообщений
    3,306

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    Цитата Сообщение от kardanium Посмотреть сообщение
    Я задавал подавление до 120 дБ. Такой уровень просит разрядность коэффициентов повыше.
    Ну я считаю в матлабе. Там 24 бита хватает примерно до 125дБ.

    Цитата Сообщение от kardanium Посмотреть сообщение
    Еще как я понял, КИХ фильтр при оверсемплинге снижает выходной уровень сигнала. Можно в принципе задать усиление в полосе пропускания, но тогда под целую часть нужно будет выделить дополнительные биты, отобрав их у дробной части, либо добавив дополнительные.
    Уровень зависит от коэф-тов. Если коэф-ты рассчитываются не единичное усиление, то ослабления не будет.
    А дробная часть - в данном случае это условность для нормирования к единице. Аппаратная арифметика здесь целочисленная.

    Цитата Сообщение от kardanium Посмотреть сообщение
    Еще одна причина, почему 32 бита - использованные аппаратные умножители будут задействованы полностью. Там что 24х24, что 24х32 - особо на расход ресурсов и быстродействие не влияют. То есть влияют, но незначительно. По этому можно не стесняться разрядностью.
    Согласен, экономия незначительная, разве что на блоках памяти коэф-тов.

    Цитата Сообщение от kardanium Посмотреть сообщение
    Это получается, фильтр четного порядка с нечетным количеством коэффициентов.
    Да, тогда относительно центрального отсчета коэф-ты получаются симметричными, а значит два разных семпла умножаются на один и тот же коэф. Поэтому можно два умножения заменить на одно, просуммировав предварительно семплы (в особо крутых плисинах такие сумматоры уже встроены в DSP блоки). Я в своей публикации в заглавном посте описал такую арифметику для х2 интерполятора. Правда сходу не соображу - получится ли оно на х8 интерполяторе, но вроде должно.

    Цитата Сообщение от kardanium Посмотреть сообщение
    В принципе можно сделать реверс счетчика адреса ROM, переключая второй операнд его сумматора с +1 на -1 согласно состояниям управляющего конечного автомата. В принципе, не сильно усложнится логика.
    Да, у меня что-то такое и сделано: два счетчика считающих в разные стороны от нуля. А далее эти значения суммируются с начальным смещением, которое инкрементируется при записи в фифо буфер нового семпла.
    Кстати, такое чтение данных затрачивает два такта, а значит умножение тоже можно делать за два такта, сэкономив на ресурсах умножения (в моем проекте умножение за 3 такта).

    Цитата Сообщение от kardanium Посмотреть сообщение
    Впрочем, у меня все это пока на стадии макетирования и проверки, что задумка в принципе реализуема. Потом уже буду оптимизировать в плане ресурсов и дорабатывать в плане универсальности и всеядности форматов входных потоков данных.
    Самая лучшая оптимизация - это разбивка на х2 каскады (как в моем проекте). Т.к. однопроходной фильтр при оверсемплинге выше х8 получается слишком длинный. Но тогда логика адресации данных еще больше усложняется.

  19. #438
    Новичок Аватар для kardanium
    Регистрация
    01.12.2018
    Адрес
    Молдавия
    Сообщений
    10

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    Да, я имел в виду на счет коэффициентов, когда говорил об усилении в полосе пропускания.
    На счет экономии блоков памяти - в Циклоне 2 они по 4 килобита с шириной данных до 36 бит (включая биты четности). Конфигурация что 24х128, что 32х128 все равно забирает один блок. Ширина данных выше 18 бит ограничивает только полноценный двухпортовый интерфейс с двумя портами для записи и чтения. Но мне такой вариант не потребуется.
    В моем случае сокращение разрядности может дать выигрыш разве что в быстродействии, но пока и имеющейся производительности хватает.
    Пока сделаю так, как задумал, но в будущем вернусь к каскадной реализации с каскадами х2, так как она более гибкая. Мне еще DS модулятор нужно будет отлаживать. Вариантов модуляторов тоже несколько:
    * Классика в виде дельта-сумматора и интегратора.
    * Каскады CRFB, CRFF, CIFB или CIFF
    * Дельта сумматор + Квантователь по уровню + Обратная связь ошибки квантования через фильтр малого порядка.

    Последний вариант довольно интересный. Он намного проще, чем CRFB, сложнее классики, но я им умудрялся очень даже неплохо давить шум квантования. Конечно, весь слышимый шум не придавил, так как оверсемплинг был кривой, но он показал наилучшие результаты по сравнению с классикой. И он же довольно гибкий в плане перестройки.
    CRFB не делал, так как он имеет высокую вычислительную сложность, но пробовал готовый модуль (который сожрал прилично ресурсов). Тоже можно получить хорошие результаты, но нигде не нашел вменяемых гайдов по расчету и настройке его коэффициентов.

    Но перед этим нужно решить вопрос корректного оверсемплинга.

  20. #439
    Старый знакомый Аватар для tomtit
    Регистрация
    23.06.2009
    Адрес
    пгт.Торонтовка
    Возраст
    65
    Сообщений
    955

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    Цитата Сообщение от kardanium Посмотреть сообщение
    Да, я имел в виду на счет коэффициентов, когда говорил об усилении в полосе пропускания.
    На счет экономии блоков памяти - в Циклоне 2 они по 4 килобита с шириной данных до 36 бит (включая биты четности). Конфигурация что 24х128, что 32х128 все равно забирает один блок. Ширина данных выше 18 бит ограничивает только полноценный двухпортовый интерфейс с двумя портами для записи и чтения. Но мне такой вариант не потребуется.
    В моем случае сокращение разрядности может дать выигрыш разве что в быстродействии, но пока и имеющейся производительности хватает.
    Пока сделаю так, как задумал, но в будущем вернусь к каскадной реализации с каскадами х2, так как она более гибкая. Мне еще DS модулятор нужно будет отлаживать. Вариантов модуляторов тоже несколько:
    * Классика в виде дельта-сумматора и интегратора.
    * Каскады CRFB, CRFF, CIFB или CIFF
    * Дельта сумматор + Квантователь по уровню + Обратная связь ошибки квантования через фильтр малого порядка.

    Последний вариант довольно интересный. Он намного проще, чем CRFB, сложнее классики, но я им умудрялся очень даже неплохо давить шум квантования. Конечно, весь слышимый шум не придавил, так как оверсемплинг был кривой, но он показал наилучшие результаты по сравнению с классикой. И он же довольно гибкий в плане перестройки.
    CRFB не делал, так как он имеет высокую вычислительную сложность, но пробовал готовый модуль (который сожрал прилично ресурсов). Тоже можно получить хорошие результаты, но нигде не нашел вменяемых гайдов по расчету и настройке его коэффициентов.

    Но перед этим нужно решить вопрос корректного оверсемплинга.
    Ваш последний вариант называется дельта-модулятором второго порядка. Как мне помнится, они были известны ещё при царе Горохе. Чисто аналоговый вариант широко известен как знаменитый UCD Бруно Путзейса.
    Я делал такой в прошлом году на маленьком Латтисе для управления током магнитной 3Д антенны.
    0.1% THD делается легко, но и только.

  21. #440
    Старый знакомый Аватар для tomtit
    Регистрация
    23.06.2009
    Адрес
    пгт.Торонтовка
    Возраст
    65
    Сообщений
    955

    По умолчанию Re: Проектируем цифровой фильтр для ЦАП 2

    Проверил на днях очень простой цифровой регулятор громкости. Оказалось, что работает не хуже чем аналоговый. Идея такая, таковая частота ФПГА намного выше, чем частота дискретизации, поэтому расчёт можно сделать последовательно, каждый такт получая громкость меньше на одну ступеньку. А затем, просто запомнить результат на нужном шаге и вывести его на выход. Для диапазона регулировки 0..-75дБ достаточно 64 шагов с умножением на 7/8 на каждом шаге. Такое умножение делается одним вычитанием сдвинутой вправо на 3 бита исходной величины из самой себя. Регулировка автоматически получается обратно-логарифмической с шагом 1.16дБ. Симуляция показала, что всё работает идеально. Становятся архаизмом потенциометры и релейные регуляторы. На спектре нет никаких артефактов. Интерфейс к энкодеру можно сделать на той же ПЛИС.
    Последний раз редактировалось tomtit; 26.05.2023 в 20:32.

Страница 22 из 33 Первая ... 12202122232432 ... Последняя

Социальные закладки

Социальные закладки

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •