alexkis 0 Posted January 26, 2021 · Report post Доброго времени суток! Хочу разобраться как правильно рассчитать скейл (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). Этот метод не подходит потому что он предполагает что на выходе предыдущего фильтра возможна такая последовательность. Буду признателен за любую помощь. Спасибо! Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Skryppy 0 Posted January 26, 2021 · Report post В Матлабе есть fixed-point-tool, там ваша модель в зависимости от входных данных автоматически масштабируется под fixed-point с лучшими параметрами. youtube matlab fixed-point-tool Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
FatRobot 0 Posted January 26, 2021 · Report post это не очень умно 4 hours ago, alexkis said: коэффициенты одинаковы для каждого фильтра в каскаде. Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
alexkis 0 Posted January 26, 2021 · Report post 1 hour ago, Skryppy said: В Матлабе есть fixed-point-tool, там ваша модель в зависимости от входных данных автоматически масштабируется под fixed-point с лучшими параметрами. youtube matlab fixed-point-tool Спасибо, рассмотрю вариант использования этой утилиты. 1 hour ago, FatRobot said: это не очень умно Есть рекомендации как их эффективно подобрать и почему не стоит так делать? Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
FatRobot 0 Posted January 26, 2021 · Report post Рекомендация простая: построить АЧХ всего каскада в диапазоне от 0 до Fsi/2 (Fsi - частота отсчетов на входе), и посмотреть, как АЧХ отдельных фильтров влияет на результирующую АЧХ. Скорее всего окажется, что фильтр #0 может содержать 7-11 коэффициентов, включая нулевые, фильтр #1 может содержать 11-15 коэффициентов, включая нулевые, и т.д. и только фильтр #5, работающий на относительно низкой частоте Fsi/64 имеет существенный порядок Можно посмотреть, как подобная задача решена здесь. 1 hour ago, alexkis said: Есть рекомендации как их эффективно подобрать и почему не стоит так делать? Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
alexkis 0 Posted January 27, 2021 (edited) · Report post 8 hours ago, FatRobot said: Рекомендация простая: построить АЧХ всего каскада в диапазоне от 0 до Fsi/2 (Fsi - частота отсчетов на входе), и посмотреть, как АЧХ отдельных фильтров влияет на результирующую АЧХ. Скорее всего окажется, что фильтр #0 может содержать 7-11 коэффициентов, включая нулевые, фильтр #1 может содержать 11-15 коэффициентов, включая нулевые, и т.д. и только фильтр #5, работающий на относительно низкой частоте Fsi/64 имеет существенный порядок Можно посмотреть, как подобная задача решена здесь. Видимо я не совсем так Вас понял сначала. На самом деле я так и делаю в проектах где нужно получить узкую полосу и нет необходимости получать сигнал с выводов промежуточных фильтров. Этот пример с одинаковыми коэффициентами - удобное приближение для описания проблемы со скалированием / масштабированием. Edited January 27, 2021 by alexkis Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
dragonfly 0 Posted January 27, 2021 (edited) · Report post Несколько замечаний: 1. Методологическое. Вы то исходите из предельно возможного отклика (Ваше: ceil(log2(sum(abs(coe)))) + bw_s), то начинаете играть в статистику (Ваше: После каждой пары децимирующих фильтров (децимации на 4) увеличиваю разрядность относительно входа на 1 (rule of thumb), или bw_s + log2(DF)/2) То есть то Вы берёте предельный случай для входного сигнала, то уповаете на усреднённый, причём получаемый при белом спектре. А если на входе просто константа? Никакого одного бита на четырёхкратную децимацию в таком случае нет. 2. По поводу фильтров с одинаковыми коэффициентами. Если это связано с простотой реализации, в особенности, если речь об аппаратной реализации в FPGA/ASIC, то рассмотрите CIC фильтр. Это и дешевле, и качественнее. Предложенная Вами схема весьма скверно давит внеполосный спектр. Edited January 27, 2021 by dragonfly Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
alexkis 0 Posted January 27, 2021 (edited) · Report post 32 minutes ago, dragonfly said: 2. По поводу фильтров с одинаковыми коэффициентами. Если это связано с простотой реализации, в особенности, если речь об аппаратной реализации в FPGA/ASIC, то рассмотрите CIC фильтр. Это и дешевле, и качественнее. Предложенная Вами схема весьма скверно давит внеполосный спектр. Да, я это понимаю, и где это возможно - использую CIC фильтры. Но использовать его тоже не во всех случаях возможно. Если мне нужно получать сигнал с промежуточных фильтров каскада, например, то использовать CIC не выйдет, встает вопрос как регулировать скейл без участия пользователя. Edited January 27, 2021 by alexkis Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...