Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Артефакты в сигнале при децимации
Форум разработчиков электроники ELECTRONIX.ru > Цифровая обработка сигналов - ЦОС (DSP) > Алгоритмы ЦОС (DSP)
alexkis
Добрый день! Есть проект в котором необходимо произвести децимацию сигнала вплоть до 16000. Столкнулся с тем что с определенного момента вижу артефакты в сигнале, хочу понять откуда они / их природу и можно ли с этим что-нибудь сделать. Объясню подробнее на упрощенном примере:

Есть необходимость децимировать сигнал с частотой дискретизации 96 МГц в 2^11 раз. Т.е. необходимо 11 фильтров с фактором децимации 2 (для того чтобы можно было посмотреть где начинают появляться артефакты).
Вход - 16 бит, внутренняя разрядность между каскадами - 18, коэффициенты фильтров - 18, выход каскада - 16. Так же производится скалирование между каскадами (усиление сигнала сдвигом к младшим разрядам выхода фильтра при усечении, при этом откидываются дублирующие знаковые биты).
Matlab модель каскада: Нажмите для просмотра прикрепленного файла

Спектр входного сигнала (16 бит):
Нажмите для просмотра прикрепленного файла

При этом наблюдаю некоторые артефакты / составляющие в сигнале которых не ожидаю на выходе каскада (выход 16 бит)
Нажмите для просмотра прикрепленного файла
Под артефактами я имею ввиду этот "лес палок" над шумом. Уровень палок меняется.

Если выход сделать 18 бит, то спектр будет похож на то что ожидаю увидеть:
Нажмите для просмотра прикрепленного файла

При этом эти артефакты появляются начиная с 9 фильтра (в 16 битном представлении выхода), выходы фильтров 8 и 9 соответственно:
Нажмите для просмотра прикрепленного файла Нажмите для просмотра прикрепленного файла

Так же собрал проект в железе с этими фильтрами на ядрах Xilinx (+ добавил DDС на входе). В качестве округления при переходе между фильтрами каскада использовал округление к ближайшему целому (когда добавляется старший из отбрасываемых разрядов, модель я смотрел и с таким округлением, по сути ничего не меняется).
При подаче мощного сигнала (5 дБм) с генератора, на выходе каскада, подстраиваясь скейлерами получаю следующий сигнал (16 бит):
Нажмите для просмотра прикрепленного файла
Т.е. сигнал такой каким я его ожидаю, но если не изменяя скейлеров уйти ниже по мощности (например с 5 дБм на -50 дБм на генераторе):
Нажмите для просмотра прикрепленного файла
Правда тут артефакты начинают появляться начиная с 8 фильтра.

При этом этот же сигнал в представлении 18 бит выглядит ожидаемо:
Нажмите для просмотра прикрепленного файла

Еще вопрос в том почему здесь палки похоже что стоят на тех же частотах, но не статичны и, судя по всему, перемещаются по частотам?
Нажмите для просмотра прикрепленного файла

Структурная схема каскада в железе:
Нажмите для просмотра прикрепленного файла

PS: если в модели подавать на вход не зашумленный сигнал, то эти палки будет отлично видно (16-битный выход последнего (11) фильтра в каскаде):
Нажмите для просмотра прикрепленного файла
Получается что это спуры от синусоиды, которые частично закрывает шум?
Если смотреть на выход предпоследнего фильтра (10) в 16 битном виде:
Нажмите для просмотра прикрепленного файла
Получается что они идут не со входа? Если построить спектр синусоиды (той же частоты что и на входе каскада и с частотой сэмплирования выхода фильтра) без awgn, то получится примерно такая же картина по спурам как и на выходах фильтров:
Код
Fs = 96e+6/2^11;
N = 2^14;
Fc = 15e+3;

t = 0:1/Fs:(N - 1)/Fs;
sig = complex(cos(2*pi*Fc*t), sin(2*pi*Fc*t)).';
% sig = awgn(sig, 65);
sig = sig / max(max(abs(real(sig))), max(abs(imag(sig))));
sig = round(sig * (2^(16 - 1) - 1));

data = sig;
figure(4); periodogram(data, blackmanharris(size(data, 1)), 'centered', 2^(nextpow2(size(data, 1))+1), Fs);


Нажмите для просмотра прикрепленного файла

Надеюсь Вы прольете мне свет на этот вопрос.
Спасибо!
blackfin
Цитата(alexkis @ Aug 6 2018, 13:50) *
Структурная схема каскада в железе:
...

На мой взгляд, точность промежуточных вычислений недостаточна.

После каждой пары децимирующих фильтров разрядность вычислений должна увеличиваться на один бит. То есть, после децимации на 16000 разрядность семплов на выходе должна быть:

16 + 10*lg(16000)/6 = 16 + 7 = 23 бита.
andyp
Цитата(alexkis @ Aug 6 2018, 13:50) *
Надеюсь Вы прольете мне свет на этот вопрос.
Спасибо!


ИМХО Недофильтрованная ошибка округления предыдущего каскада заворачивается в полезную полосу при каждой децимации.
alexkis
Цитата(blackfin @ Aug 6 2018, 14:20) *
На мой взгляд, точность промежуточных вычислений недостаточна.

После каждой пары децимирующих фильтров разрядность вычислений должна увеличиваться на один бит. То есть, после децимации на 16000 разрядность семплов на выходе должна быть:

16 + 10*lg(16000)/6 = 16 + 7 = 23 бита.

Буквально каждые пару фильтров? Имеется ввиду конкретный пример с децимацией по 2, как я понял. В реальном проекте используется солянка разных фильтров в каскаде, например - 5 -> 4 -> 200 -> 4. И необходимое число разрядов между каскадами складывается из фактора децимации до каждого следующего фильтра? Если я сделаю в этом примере (с децимацией по 2) между каскадов разрядность 23, а не 18 как сейчас, то на выходе я могу усекать разрядность до 16 или все равно необходимо брать разрядность 23 и на выходе? Откуда берется этот необходимый рост разрядности?

Судя по MatLab модели нельзя на выходе брать разрядность 16 на выходе, даже если между каскадами разрядность 23 сохранять.
Цитата(andyp @ Aug 6 2018, 17:24) *
ИМХО Недофильтрованная ошибка округления предыдущего каскада заворачивается в полезную полосу при каждой децимации.

В примере с MatLab модели используется усечение с round, артефакты есть. Попробую в железе сделать уточненное округление (оно больше похоже на round, чем текущее округление к ближайшему целому). Возможно дрожание по частотам от округления?

PSS. Извините за поток вопросов.
andyp
Цитата(alexkis @ Aug 6 2018, 18:45) *
В примере с MatLab модели используется усечение с round, артефакты есть. Попробую в железе сделать уточненное округление (оно больше похоже на round, чем текущее округление к ближайшему целому). Возможно дрожание по частотам от округления?

PSS. Извините за поток вопросов.


У ошибки округления спектр линейчатый так как сигнал, который округляется, периодический. Тип усечения-округления (варианты round, floor, ceil, это всё) будет влиять только на высоту спуров.
Сами спуры всё равно появятся на кратных входному колебанию частотах. Дальше они будут заворачиваться от новой частоты дискретизации от стадии к стадии, что еще разных гармоник даст.
Я бы первые стадии в виде пары каскадов CIC с фактором децимации раз в 16-32-64 (в зависимости от требуемой выходной полосы) делал , чтобы не иметь ошибок округления при каждой децимации в 2 раза.
blackfin
Цитата(alexkis @ Aug 6 2018, 18:45) *
Откуда берется этот необходимый рост разрядности?

Рост разрядности возникает в результате увеличения отношения С/Ш на выходе фильтра. Децимирующий фильтр обычно сужает полосу входного сигнала в число раз равное коэффициенту децимации. Как следствие, в той же самой пропорции уменьшается мощность белого шума на выходе дециматора. В вашем случае каждая пара дециматоров с суммарным коэффициентом децимации равным 4 будет уменьшать полосу белого шума в 4 раза. Мощность полезного сигнала при этом остается неизменной. В результате, отношение С/Ш после децимации на 4 увеличится на 6 дБ, то есть, на один разряд.
alexkis
Цитата(andyp @ Aug 6 2018, 20:20) *
У ошибки округления спектр линейчатый так как сигнал, который округляется, периодический. Тип усечения-округления (варианты round, floor, ceil, это всё) будет влиять только на высоту спуров.
Сами спуры всё равно появятся на кратных входному колебанию частотах. Дальше они будут заворачиваться от новой частоты дискретизации от стадии к стадии, что еще разных гармоник даст.
Я бы первые стадии в виде пары каскадов CIC с фактором децимации раз в 16-32-64 (в зависимости от требуемой выходной полосы) делал , чтобы не иметь ошибок округления при каждой децимации в 2 раза.

Т.е. чем меньше фильтров в каскаде, тем меньше ошибка? Для своей децимации в 16000 я использую каскад 5 -> 2 -> 2 -> 200 -> 4, FIR -> FIR -> FIR -> CIC -> FIR (компенсатор). Но на выходе в 16 бит все равно вижу спуры. Могу попробовать сделать схему 5 -> 4 -> 200 -> 4.

Цитата(blackfin @ Aug 6 2018, 20:34) *
Рост разрядности возникает в результате увеличения отношения С/Ш на выходе фильтра. Децимирующий фильтр обычно сужает полосу входного сигнала в число раз равное коэффициенту децимации. Как следствие, в той же самой пропорции уменьшается мощность белого шума на выходе дециматора. В вашем случае каждая пара дециматоров с суммарным коэффициентом децимации равным 4 будет уменьшать полосу белого шума в 4 раза. Мощность полезного сигнала при этом остается неизменной. В результате, отношение С/Ш после децимации на 4 увеличится на 6 дБ, то есть, на один разряд.

Получается чтобы избавиться от спур необходимо увеличить разрядность выхода? И это единственный верный метод?

PS. Чтобы окончательно прояснить, на появление спур влияет количество фильтров в каскаде? Или все же суммарная децимация, т.е. если взять теоретический единственный фильтр дециматор на 16000 то выхода 16 бит будет для него не достаточно, необходим выход в 23 бита чтобы убрать спуры?

Спасибо.
Fat Robot
Именно так. Заворачиваются и суммируются конструктивно.

Цитата(andyp @ Aug 6 2018, 18:24) *
ИМХО Недофильтрованная ошибка округления предыдущего каскада заворачивается в полезную полосу при каждой децимации.


alexkis,

Попробуйте выключить шум на входе и поменять частоту входного сигнала c 15kHz на 14.9kHz. Вы увидите, что в выходном сигнале сосредоточенные компоненты отсутствуют, а вместо них - шум, более-менее равномерный в полосе. Незначительное изменение частоты привело к тому, что спуры "рассыпались", т.к. не выполнилось условие их конструктивного сложения.

Спуры будут для входных частот, которым кратна частота отсчетов. Сказываться они будут тем сильнее, чем выше коэффициент децимации (больше наложений и, как следствие, потенциально больше суммирований).
Единственный способ избавиться от их влияния - это постоянно держать их под шумом, не давать им высунуться, увеличивая динамический диапазон вычислителей в каскадах.
blackfin
Цитата(alexkis @ Aug 6 2018, 23:11) *
Получается чтобы избавиться от спур необходимо увеличить разрядность выхода? И это единственный верный метод?

На мой взгляд, да. Если вы хотите, чтобы спуры были ниже несущей на SNRC децибел, разрядность выхода должна быть не меньше SNRC/6 бит.
andyp
Цитата(alexkis @ Aug 6 2018, 23:11) *
Т.е. чем меньше фильтров в каскаде, тем меньше ошибка? Для своей децимации в 16000 я использую каскад 5 -> 2 -> 2 -> 200 -> 4, FIR -> FIR -> FIR -> CIC -> FIR (компенсатор). Но на выходе в 16 бит все равно вижу спуры. Могу попробовать сделать схему 5 -> 4 -> 200 -> 4.


У нелинейных искажений в дециматорах две причины
1. Заворачивание спектра (folding)
2. Усечение разрядности

Со вторым, очевидно, чем меньше усекаете, тем лучше. Что касается первого, то тут все решается дизайном цепочки. Я обычно сначала использую CIC без компенсации. В моих приложениях мне становится недостаточно подавления имиджей до того, как завал АЧХ становится проблемой.
CIC иногда разбиваю на два каскада, когда не хочется сильно раздувать разрядность аккумуляторов на высокой частоте дискретизации. При этом получаю немного больше проблем с причиной 2, конечно.
После CIC ставлю в зависимости от приложения разные варианты FIR дециматоров. Так как частота дискретизации уже низкая, то можно себе позволить более широкие шины между каскадами и реже усекать разрядность.

Точные значения факторов децимации, тип и каскадная структура FIR дециматора определяется требованиями к общему фактору децимации, ширине рабочей полосы и допустимому уровню нелинейных искажений в полосе.
petrov
Попробуйте другие варианты округления, с прибавлением некоррелированного с сигналом шума, например младшие разряды просто отбрасываем, а к оставшемуся прибавляем однобитную псевдослучайную последовательность.

Цитата(andyp @ Aug 7 2018, 18:58) *
У нелинейных искажений в дециматорах две причины
1. Заворачивание спектра (folding)


Это линейные искажения.
alexkis
Спасибо за ответы!

Цитата(petrov @ Aug 8 2018, 10:58) *
младшие разряды просто отбрасываем, а к оставшемуся прибавляем однобитную псевдослучайную последовательность


Дизеринг, судя по модели, помогает, но не значительно и немного поднимает уровень шума (некоторые палки чуть уменьшают уровень или скрываются за шумом). Попробую реализовать в железе.
petrov
Цитата(alexkis @ Aug 8 2018, 17:33) *
Дизеринг, судя по модели, помогает, но не значительно и немного поднимает уровень шума (некоторые палки чуть уменьшают уровень или скрываются за шумом). Попробую реализовать в железе.


Ну это так, дерьмовенький вариант, совсем правильно надо с генератора шума с треугольным распределением прибавлять до округления, работает хорошо, именно убирает палки, а не скрывает за шумом.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.