Jump to content

    
alexkis

Расчет скейла между фильтрами каскада

Recommended Posts

Доброго времени суток!

 

Хочу разобраться как правильно рассчитать скейл (scale) между фильтрами каскада для получения сигнала лучшего качества на выходе каскада.

 

В текущем приближении каскад это цепочка half-band фильтров-дециматоров (децимация на 2). Разрядность входного сигнала s равна 16, разрядность коэффициентов фильтра coe - 18, коэффициенты одинаковы для каждого фильтра в каскаде.

111.thumb.JPG.3f799fd34a11ab3892a508a7b8edfa1f.JPG

Полная разрядность выхода фильтра рассчитывается по следующему принципу: ceil(log2(sum(abs(coe)))) + bw_s, где bw_s - разрядность входа на которую рассчитан фильтр.

После каждой пары децимирующих фильтров (децимации на 4) увеличиваю разрядность относительно входа на 1 (rule of thumb), или bw_s + log2(DF)/2, где DF фактор децимации.

Выход фильтра усекается от полной разрядности фильтра (с округлением), после фильтра стоит скейлер, с помощью которого можно отступить от Most Significant Bit (MSB) вправо при усечении, по следующему принципу:

222.thumb.JPG.75eaca1d694f240194fc2ed0304c7971.JPG

По умолчанию вся цепочка содержит 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). Этот метод не подходит потому что он предполагает что на выходе предыдущего фильтра возможна такая последовательность.

 

Буду признателен за любую помощь.

Спасибо!

Share this post


Link to post
Share on other sites

В Матлабе есть fixed-point-tool, там ваша модель в зависимости от входных данных автоматически масштабируется под fixed-point с лучшими параметрами. 

youtube matlab fixed-point-tool

Share this post


Link to post
Share on other sites
1 hour ago, Skryppy said:

В Матлабе есть fixed-point-tool, там ваша модель в зависимости от входных данных автоматически масштабируется под fixed-point с лучшими параметрами. 

youtube matlab fixed-point-tool

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

1 hour ago, FatRobot said:

это не очень умно

Есть рекомендации как их эффективно подобрать и почему не стоит так делать?

Share this post


Link to post
Share on other sites

Рекомендация простая: построить АЧХ всего каскада в диапазоне от 0 до Fsi/2  (Fsi - частота отсчетов на входе), и посмотреть, как АЧХ отдельных фильтров влияет на результирующую АЧХ.

Скорее всего окажется, что

фильтр #0 может содержать 7-11 коэффициентов, включая нулевые,  

фильтр #1 может содержать 11-15 коэффициентов, включая нулевые,

и т.д. 

и только фильтр #5, работающий на относительно низкой частоте Fsi/64 имеет существенный порядок

 

Можно посмотреть, как подобная задача решена здесь.

 

1 hour ago, alexkis said:

Есть рекомендации как их эффективно подобрать и почему не стоит так делать?

Share this post


Link to post
Share on other sites
8 hours ago, FatRobot said:

Рекомендация простая: построить АЧХ всего каскада в диапазоне от 0 до Fsi/2  (Fsi - частота отсчетов на входе), и посмотреть, как АЧХ отдельных фильтров влияет на результирующую АЧХ.

Скорее всего окажется, что

фильтр #0 может содержать 7-11 коэффициентов, включая нулевые,  

фильтр #1 может содержать 11-15 коэффициентов, включая нулевые,

и т.д. 

и только фильтр #5, работающий на относительно низкой частоте Fsi/64 имеет существенный порядок

 

Можно посмотреть, как подобная задача решена здесь.

 

Видимо я не совсем так Вас понял сначала. На самом деле я так и делаю в проектах где нужно получить узкую полосу и нет необходимости получать сигнал с выводов промежуточных фильтров. 

 

Этот пример с одинаковыми коэффициентами - удобное приближение для описания проблемы со скалированием / масштабированием.

Edited by alexkis

Share this post


Link to post
Share on other sites

Несколько замечаний:

1. Методологическое. Вы то исходите из предельно возможного отклика (Ваше: ceil(log2(sum(abs(coe)))) + bw_s), то начинаете играть в статистику (Ваше: После каждой пары децимирующих фильтров (децимации на 4) увеличиваю разрядность относительно входа на 1 (rule of thumb), или bw_s + log2(DF)/2)

То есть то Вы берёте предельный случай для входного сигнала, то уповаете на усреднённый, причём получаемый при белом спектре.

А если на входе просто константа? Никакого одного бита на четырёхкратную децимацию в таком случае нет.

2. По поводу фильтров с одинаковыми коэффициентами. Если это связано с простотой реализации, в особенности, если речь об аппаратной реализации в FPGA/ASIC, то рассмотрите CIC фильтр. Это и дешевле, и качественнее. Предложенная Вами схема весьма скверно давит внеполосный спектр.

Edited by dragonfly

Share this post


Link to post
Share on other sites
32 minutes ago, dragonfly said:

2. По поводу фильтров с одинаковыми коэффициентами. Если это связано с простотой реализации, в особенности, если речь об аппаратной реализации в FPGA/ASIC, то рассмотрите CIC фильтр. Это и дешевле, и качественнее. Предложенная Вами схема весьма скверно давит внеполосный спектр.

 

Да, я это понимаю, и где это возможно - использую CIC фильтры. Но использовать его тоже не во всех случаях возможно. Если мне нужно получать сигнал с промежуточных фильтров каскада, например, то использовать CIC не выйдет, встает вопрос как регулировать скейл без участия пользователя.

Edited by alexkis

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.