Jump to content

    

alexkis

Участник
  • Content Count

    8
  • Joined

  • Last visited

Community Reputation

0 Обычный

Recent Profile Visitors

433 profile views
  1. Да, я это понимаю, и где это возможно - использую CIC фильтры. Но использовать его тоже не во всех случаях возможно. Если мне нужно получать сигнал с промежуточных фильтров каскада, например, то использовать CIC не выйдет, встает вопрос как регулировать скейл без участия пользователя.
  2. Видимо я не совсем так Вас понял сначала. На самом деле я так и делаю в проектах где нужно получить узкую полосу и нет необходимости получать сигнал с выводов промежуточных фильтров. Этот пример с одинаковыми коэффициентами - удобное приближение для описания проблемы со скалированием / масштабированием.
  3. Спасибо, рассмотрю вариант использования этой утилиты. Есть рекомендации как их эффективно подобрать и почему не стоит так делать?
  4. Доброго времени суток! Хочу разобраться как правильно рассчитать скейл (scale) между фильтрами каскада для получения сигнала лучшего качества на выходе каскада. В текущем приближении каскад это цепочка half-band фильтров-дециматоров (децимация на 2). Разрядность входного сигнала s равна 16, разрядность коэффициентов фильтра coe - 18, коэффициенты одинаковы для каждого фильтра в каскаде. Полная разрядность выхода фильтра рассчитывается по следующему принципу: ceil(log2(sum(abs(coe)))) + bw_s, где bw_s - разрядность входа на которую рассчитан фильтр. После каждой пары децимирующих фильтров (децимации на 4) увеличиваю разрядность относительно входа на 1 (rule of thumb), или bw_s + log2(DF)/2, где DF фактор децимации. Выход фильтра усекается от полной разрядности фильтра (с округлением), после фильтра стоит скейлер, с помощью которого можно отступить от Most Significant Bit (MSB) вправо при усечении, по следующему принципу: По умолчанию вся цепочка содержит scale = 0. Для одного фильтра можно рассчитать такую входную последовательность для которой на выходе можно будет увидеть максимально возможное число. Для этого подается последовательность, где на месте положительного коэффициента стоит -(2^(bw_s - 1) - 0), а на месте отрицательного (2^(bw_s - 1) - 1), или наоборот. Код (matlab): N = 2^20; s = zeros(N, 1); s(coe > 0) = -(2^(bw_s - 1) - 0); s(coe < 0) = (2^(bw_s - 1) - 1); Так же можно рассчитать минимум и максимум сигнала на выходе: function [Y, bw] = get_fout_max( coe, X ) X_min = X(1, 1); X_max = X(1, 2); G_p = sum(coe(coe > 0)); G_m = sum(coe(coe < 0)); Y_min = G_p * X_min + G_m * X_max; Y_max = G_p * X_max + G_m * X_min; Y = [Y_min, Y_max]; bw = log2(max(abs(Y))) + 1; Где X - вектор [минимума, максимума] входа фильтра. Получается что существует такая последовательность где на первом фильтре каскада я увижу максимальное доступное число и выход нельзя масштабировать скейлером. Но существует ли такая последовательность где я увижу максимальное число для второго фильтра (с учетом выхода первого), третьего (с учетом выхода первого и второго) и т.п. Хочу понять каким образом можно рассчитать сдвиги от MSB (на втором рисунке) для каждого из фильтров, с учетом того какие последовательности возможны на выходах предыдущих фильтров. Пример фильтрации каскадом в приложении - cascade_example.zip (код matlab, скрипт cascade_bw.m). Там же теоретический расчет - если брать минимум и максимум амплитуды выхода предыдущего каскада для расчета амплитуд текущего (cascade_bw_theory.m). Этот метод не подходит потому что он предполагает что на выходе предыдущего фильтра возможна такая последовательность. Буду признателен за любую помощь. Спасибо!
  5. Спасибо за ответы! Дизеринг, судя по модели, помогает, но не значительно и немного поднимает уровень шума (некоторые палки чуть уменьшают уровень или скрываются за шумом). Попробую реализовать в железе.
  6. Т.е. чем меньше фильтров в каскаде, тем меньше ошибка? Для своей децимации в 16000 я использую каскад 5 -> 2 -> 2 -> 200 -> 4, FIR -> FIR -> FIR -> CIC -> FIR (компенсатор). Но на выходе в 16 бит все равно вижу спуры. Могу попробовать сделать схему 5 -> 4 -> 200 -> 4. Получается чтобы избавиться от спур необходимо увеличить разрядность выхода? И это единственный верный метод? PS. Чтобы окончательно прояснить, на появление спур влияет количество фильтров в каскаде? Или все же суммарная децимация, т.е. если взять теоретический единственный фильтр дециматор на 16000 то выхода 16 бит будет для него не достаточно, необходим выход в 23 бита чтобы убрать спуры? Спасибо.
  7. Буквально каждые пару фильтров? Имеется ввиду конкретный пример с децимацией по 2, как я понял. В реальном проекте используется солянка разных фильтров в каскаде, например - 5 -> 4 -> 200 -> 4. И необходимое число разрядов между каскадами складывается из фактора децимации до каждого следующего фильтра? Если я сделаю в этом примере (с децимацией по 2) между каскадов разрядность 23, а не 18 как сейчас, то на выходе я могу усекать разрядность до 16 или все равно необходимо брать разрядность 23 и на выходе? Откуда берется этот необходимый рост разрядности? Судя по MatLab модели нельзя на выходе брать разрядность 16 на выходе, даже если между каскадами разрядность 23 сохранять. В примере с MatLab модели используется усечение с round, артефакты есть. Попробую в железе сделать уточненное округление (оно больше похоже на round, чем текущее округление к ближайшему целому). Возможно дрожание по частотам от округления? PSS. Извините за поток вопросов.
  8. Добрый день! Есть проект в котором необходимо произвести децимацию сигнала вплоть до 16000. Столкнулся с тем что с определенного момента вижу артефакты в сигнале, хочу понять откуда они / их природу и можно ли с этим что-нибудь сделать. Объясню подробнее на упрощенном примере: Есть необходимость децимировать сигнал с частотой дискретизации 96 МГц в 2^11 раз. Т.е. необходимо 11 фильтров с фактором децимации 2 (для того чтобы можно было посмотреть где начинают появляться артефакты). Вход - 16 бит, внутренняя разрядность между каскадами - 18, коэффициенты фильтров - 18, выход каскада - 16. Так же производится скалирование между каскадами (усиление сигнала сдвигом к младшим разрядам выхода фильтра при усечении, при этом откидываются дублирующие знаковые биты). Matlab модель каскада: df_2_firs.zip Спектр входного сигнала (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); Надеюсь Вы прольете мне свет на этот вопрос. Спасибо!