Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: расчет БИХ фильтров в fdatool
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Вопросы системного уровня проектирования
shf_05
написал прогу для реализации 32бит фильтра на ADSP2191
в fdatool спроектировал БИХ фильтр, отквантовал до 32бит,
необходимо получить все коэф матрицы SOS в формате 1,31 и привести коэффициент G к 1 для всех секций.
делаю как в справке по fdatool, но коэф не хочет приравниваться к 1.

помогите подогнать коэффициенты или подскажите, как рачсчитать в какой-л др проге
Tue
Очень может быть, что коэффициент на выходе из секции Матлаб рассчитал равным единице, а разрядность этого коэффициента выставлена таким образом, что единицу представить не может. Посмотрите на выходной масштабирующий коэффициент секций.
shf_05
Цитата(Tue @ May 5 2008, 20:12) *
Очень может быть, что коэффициент на выходе из секции Матлаб рассчитал равным единице, а разрядность этого коэффициента выставлена таким образом, что единицу представить не может. Посмотрите на выходной масштабирующий коэффициент секций.

посмотрел- выходной коэф секций как раз не хочет быть равен одному, в примере как раз он тождественно равен 1. Я делаю все как в примере по fdatool, тока у меня версия 3,0 может быть дело в этом?
Tue
Дело в разрядности выходного коэффициента секции. Обычно Матлаб выставляет для входного и выходного коэффициентов секции одну и ту же разрядность. Допустим выставил sfix16_En15 - означает число со знаком, 16 бит на всё число, 15 бит - на дробную часть, следовательно остается один бит на знак, а на целую часть не остается ничего. Отсюда и ошибка. Пусть N - полное число бит, FL - число бит справа после запятой (дробная часть) и если число со знаком, тогда диапзон чисел, которые вы можете представить такой:
-2^(N-FL-1) <= число <= +2^(N-FL)-1 - 2(-FL)
Следовательно, чтобы исправить эту ошибку отнимите от дробной части один бит и добавьте его к целой части, т.о. у вас получится разрядность sfix16_En14 - число со знаком, 16 бит на все число, 14 бит на дробную часть, один бит на знак и как раз один бит на целую часть, чтобы единица представлялась корректно. Такой трюк в общем случае конечно чуть снизит точность представления дробной части коэффициента, но поскольку он у вас равен "1" и никакой дробной части не содержит, то никакой потери в точности вы не получите. К сожалению в FDAtool поменять разрядность какого-либо конкретного коэффициента секции не представляется возможным, поэтому чтобы этого добиться - надо реализовать (RealizeMDL) его в Симулинк в виде основных элементов (Build model using basic elements) и уже в Симулинке вручную поменять разрядность нужного коэффициента. Можно даже вообще убрать коэффциент на выходе из секции, который точно равен "1", оставив лишь блок преобразования типа, конвертирующий в нужную разрядность выхода секции, т.о. вы избавитесь от лишнего умножителя.
shf_05
попробовал ваш совет, получил, что часть коэффициентов больше 1, что и следовало ижидать.
я хотел получить коэффициенты a,b в формате 1,31 с коэф масштабирования, четко равному 1 (т .е его можно исключить). в примере по fdatool есть такое решение (там создается фильтр с коэф 1,16 и без масштабир оэф при этом АЧХ Q фильтра довольно четко совпадает с АЧХ неквант фильтра) , ноо когда я ставлю все настройки как там, результат не тот- коэф масштабир никак не хочет быть 1.
Tue
Честно говоря, я совсем не в курсе с каким примером вы работаете. В том, что часть коэффициентов больше 1 нет ничего криминального, главное понимать что происходит. Вы хорошо подумали, перед тем как использовать именно БИХ-фильтр ? Посчитать коэффициенты фильтра - это еще полбеды, главное добиться его нормальной работы в системе. Если да, то давайте разберемся более подробно. Приведите данные для рассчета вашего фильтра, какие где разрядности выставляете.
shf_05
насчет необходимости БИХ фильтра я уверен (ФЧХ не важна, необходим минимальный порядок фильтра). сейчас использую 16 разрядные БИХ фильтры, расчитанные с помощью qedesign v 1.0 (ужасно!!, но что дали старшие коллеги), я скачал v6.3.4, применил кряк, описанный на форуме http://www.telesys.ru/wwwboards/mcontrol/4...es/225467.shtml приводит ктому, что qued2000.exe не запускается.
понадобилось использовать 32 разрядную линию задержки (при 16 разр слишком малый динамич диапазон фильтра). Вобщем, решил рассчитать коэф в матлабе, расчитал необх фильтр примерно из 4-5 секций 2-го порядка, отквантовал до 32 бит, пусть коэф тоже будут точнее.
Для упрощения реализации и сниж вычислений на DSP секции второго порядка не должны содержать масштабирующих коэффициентов, линия задержки 32 битная. Полагаю такая реализация фильтра имеет право на существование.
для приведения вектора G (масштаб коэф на вых каждой секции) к 1, использую опцию Edit->Reodering->Highest SNR.
Для понимания происходящего прикрепляю файл
Tue
Да, попробовал сам - действительно один из коэффициентов не хочет приравниваться единице. То, что я писал выше про фиксированную точку - справедливо, когда коэффициент равен единице, а при переводе в фикс. точку уже не единица. Почему при масштабировании он изначально не равен единице - непонятно. Может баг, а может фича smile.gif По поводу 32 бит для представления коэффициентов вы не погорячились ? Конечно из-за рекурсивности БИХ требует меньше коэффциентов, задержек и прочего, но есть методы, позволяющие проектировать достаточно эффективные КИХ, которые гораздо проще и в анализе влияния фикс. точки, и в реализации. Поскольку вы собираетесь реализовывать свой фильтр на процессоре, то надо будет еще выбрать структуру фильтра таким образом, чтобы вычислительная эффективность не падала из-за сложных методов обращения к памяти данных/коэффициентов.
shf_05
Цитата(Tue @ Jun 7 2008, 13:32) *
Да, попробовал сам - действительно один из коэффициентов не хочет приравниваться единице. То, что я писал выше про фиксированную точку - справедливо, когда коэффициент равен единице, а при переводе в фикс. точку уже не единица. Почему при масштабировании он изначально не равен единице - непонятно. Может баг, а может фича smile.gif По поводу 32 бит для представления коэффициентов вы не погорячились ? Конечно из-за рекурсивности БИХ требует меньше коэффциентов, задержек и прочего, но есть методы, позволяющие проектировать достаточно эффективные КИХ, которые гораздо проще и в анализе влияния фикс. точки, и в реализации. Поскольку вы собираетесь реализовывать свой фильтр на процессоре, то надо будет еще выбрать структуру фильтра таким образом, чтобы вычислительная эффективность не падала из-за сложных методов обращения к памяти данных/коэффициентов.


для меня важны не линии задержки и связанные с ними затраты памяти, а задержка в смысле групповой задержки (критична для моего приложения) фильтра- при БИХ фильтрации получаем тот же спад АЧХ при меньшем порядке фильтра => при меньшей задержке.
насчет эффективности программы- написана на асме требует конечно в 3 раза больше вычислит затрат, чем при одинарной точности, но приходится идти на это- надо динамич диапазон
фильтр состоит из секций второго порядка, программа готова, даже проверял ее работу- фильтрует как надо, одна проблема- расчет коэф.
Tue
Чтож, похоже по поводу единичного полного коэффициента я вам помочь не могу. Попробуйте поиграться со структурами фильтра, там где можно обойтись без масштабирования (например прямая форма 1)
shf_05
Цитата(Tue @ Jun 16 2008, 12:16) *
Чтож, похоже по поводу единичного полного коэффициента я вам помочь не могу. Попробуйте поиграться со структурами фильтра, там где можно обойтись без масштабирования (например прямая форма 1)

реализовывать фильтр по схеме, отличной от каскадной из секций второго порядка на проце с фиксированой запятой я стараюсь избегать- как правило ничего хорошего не выходит- большие погрешности в квантовании коэф-в фильтра и как следствие неудовлетворительные хар-ки
я думаю попоробовать fdattol 4, которя есть в матлаб 2007, матлаб есть только жаль ключа нету к нему.
Tue
А каков порядок получается у вашего фильтра ? Обычно да, стараются реализовывать фильтр каскадно из секций 2-го порядка, но вы же радеете за динамический диапазон, а в таких случаях масштабирование нежелательно. Кстати прямая форма 1 обладает вообщем-то меньшим шумом округления, чем каскадные формы. Попробуйте сделать в прямой форме 1, проанализируйте в матлабе и подберите нужную разрядность для сумматора, чтобы не происходило переполнений (в демках по переводу фильтров в фикс. точку очень здорово все расписано). И все-таки 32 бит для квантования коэффициентов - это наверное через чур. Кол-во бит для представления коэфф-тов и элементов задержек вообщем случае не связаны.
shf_05
Цитата(Tue @ Jun 18 2008, 03:51) *
Кол-во бит для представления коэфф-тов и элементов задержек вообщем случае не связаны.

я имел ввиду, если коэф 32 разрядные, то и накопитель имеетсмысл делать 32 ращзрядным.
ну это вовсе не заморочка.

насчет формы 1, то попробую конечно, хотя я пробовал изменить форму с каскадной на DFF1 прямо в fdatool, сразу исказилась АЧХ фильтра, так что я сразу ее отмел, может я поспешил с этим решением?
параметры примерно такие ФНЧ, Fs=8000Hz, полоса 500Гц, может 100Гц, или до 2000Гц (всякие разные), порядок от 5-го до 12-го.
Tue
Странный подход. Выберите структуру фильтра. Создайте фильтр в двойной точности. Отквантуйте коэффициенты фильтра минимальным количеством бит, необходимым для того, чтобы АЧХ совпадала с исходным (неквантованным фильтром). Убедитесь в устойчивости фильтра, при необходимости увеличьте разрядность коэффициентов. Задайте входную/выходную и прочие разрядности. Создайте входной вектор, прогоните через фильтр, посмотрите где происходят переполнения (очень хороший туториал по переводу БИХ-фильтров в фикс. точку показан в демке "Floating-Point to Fixed-Point Conversion of IIR Filters"). Если и дальше хотите нормально создавать/анализировать цифровые фильтры лучше сразу привыкайте пользоваться функциями Filter Design Toolbox.

По поводу:
Цитата(shf_05 @ Jun 18 2008, 09:31) *
я имел ввиду, если коэф 32 разрядные, то и накопитель имеетсмысл делать 32 ращзрядным.
ну это вовсе не заморочка.
не совсем понятно. Разрядность коэффициентов в конечном итоге определяет то, насколько АЧХ квантованного фильтра будет похожа на исходную и 32 бита - это явный перебор. Если у вас коэффициенты 32 разрядные, то это еще не значит что накопитель у вас будет 32 разрядным. При разрядности входного слова, скажем, 16 бит у вас только умножитель должен быть (32+16) бит, а накопитель еще больше (+4/6 бит). В вашем процессоре есть умножители и накопители такой разрядности ? Конечно это все справедливо, если вы хотите округлять/усекать разрядность только на выходе секции/фильтра, а не в процессе промежуточных вычислений для минимизации шума квантования

По поводу:
Цитата(shf_05 @ Jun 18 2008, 09:31) *
насчет формы 1, то попробую конечно, хотя я пробовал изменить форму с каскадной на DFF1 прямо в fdatool, сразу исказилась АЧХ фильтра, так что я сразу ее отмел, может я поспешил с этим решением?
Вы создайте одну спецификацию фильтра, а потом по этой спецификации создайте разные объекты фильтров с разными структурами. Анализ покажет какая подходит вам лучше.
shf_05
Цитата(Tue @ Jun 18 2008, 13:49) *
По поводу:
Вы создайте одну спецификацию фильтра, а потом по этой спецификации создайте разные объекты фильтров с разными структурами. Анализ покажет какая подходит вам лучше.


1. спасибо я Вас понял,
2. не смог найти эту демку

3. странно, может я не так делаю, задаю необходимые хар-ки фильтра в fdatool, конвертирую в фильтр стр-ры DFF1, задаю квантование 32 бита, (формат 1.31 !!!) в итоге фильтр 9-го порядка нестабильный и АЧХ его искажается, конечно, если задать режим "best prec. fraqt. length", то этого может и не будет, но формат представления в проце 1,16 можно расширить до 1,31 (конечно там можно поупражняться с ПТ, но это не решение((( ).

Вы рекомендуете пользоваться преимущественно пакетом filter design, он дает больше возможностей, чем fdatool?
Tue
1. Пожалуйста, всегда рад помочь.
2. Вот демки, которые есть у меня в матлабе. Посмотрите эту и эту демки
3. Действительно странно. Наверное я вас недопонимаю. Вы конвертируете фильтр в DFF1 уже после квантования фильтра, построенного со структурой по умолчанию (кажется df2sos) ? Возможно после перевода в другую структуру матлаб пересчитывает коэффициенты фильтра и заданная ранее разрядность уже неоптимальна для них, отсюда неустойчивость и неудовлетворительная АЧХ. АЧХ там выводится, основываясь на коэффициентах. Соответственно структура фильтра ни при чем. Структура фильтра будет влиять уже в процессе фильтрации (переполнения, предельные циклы и прочие неприятности рекурсивности в фикс. точке)

Пользоваться функциями filter design toolbox намного удобнее, быстрее и понятнее
shf_05
Спасибо еще раз, внимательно изучу демки.
До этого работал с фильтрами с ПТ, жить было легко, использовал не более 5-6 команд из filter design.

чтобы Вам было понятно- вот как делааю фильтры сейчас:
1. запускаю fdattol
2. параметры фильтра fs=8000 Fpass=600 Fstop=800 Apass=1 Astop=30 min oder Butterworth (или др. тип)
3. file->convert to single section
4. file->convert structure-> DFF1
5. quantize coefs
6. fixed point (16 или даже 32 разряда для коэф-в)
7. отображение АЧХ исходного фильтра и вантованного не совпадают, фильтр нестабилен (stable NO)

насколько я помню из курса ЦОС- каскадный фильт тем и лучше, что его коэф-ты ближе к 1, чем у однокаскадного, поэтому ошибки окургления его коэф-в (не рез-в вычисления!) ок-т менее пагубное воздействие на его хар-ки, так ли это?

PS: буду лучше изучать filter design, (хватит пользоваться fdattol? она не дает всех возможностей, доступных для filter design?), хотел легко и быстро получить результат- коэф-ты, но без труда...)))
Tue
Цитата(shf_05 @ Jun 22 2008, 13:55) *
насколько я помню из курса ЦОС- каскадный фильт тем и лучше, что его коэф-ты ближе к 1, чем у однокаскадного, поэтому ошибки окургления его коэф-в (не рез-в вычисления!) ок-т менее пагубное воздействие на его хар-ки, так ли это?
Да, я где-то это тоже читал. Вообщем-то это правильно. Тут имеется ввиду, что если коэффициент по модулю превышает единицу, то приходится выделять для него под целую часть целый бит, что нерационально. Лучше отдать его дробной части, чтобы поточнее представить нули/полюса фильтра. Поэтому лучше привести все коэффициенты к диапазону [-1; 1].
Цитата(shf_05 @ Jun 22 2008, 13:55) *
PS: буду лучше изучать filter design, (хватит пользоваться fdattol? она не дает всех возможностей, доступных для filter design?), хотел легко и быстро получить результат- коэф-ты, но без труда...)))
FDATool - это просто GUI для функций пакета filter design toolbox, в нем вполне можно работать, но как вы увидите в демках и в моем примере ниже, использование функций напрямую без GUI развязывает руки и можно проводить всесторонний анализ. Ниже привожу матлабовский скрипт, который рассчитывает по вашей спецификации фильтр, переводит его в фикс. точку, проводит анализ на переполнения:
Код
% All frequency values are in Hz.
Fs = 8000;  % Sampling Frequency

Fpass = 600;         % Passband Frequency
Fstop = 800;         % Stopband Frequency
Apass = 1;           % Passband Ripple (dB)
Astop = 30;          % Stopband Attenuation (dB)
match = 'passband';  % Band to match exactly

% Construct an FDESIGN object and call its BUTTER method.
h  = fdesign.lowpass(Fpass, Fstop, Apass, Astop, Fs);

% по умолчанию создается фильтр со структурой "прямая форма 2" в виде
% каскадно соединенных секций 2 порядка Hdf2sos:
Hdf2sos = design(h, 'butter', 'MatchExactly', match);

% создаем копию объекта фильтра:
Hdf1 = copy(Hdf2sos);
% и меняем структуру на df1:
Hdf1 = convert(Hdf1,'df1');
fvtool(Hdf2sos,Hdf1)
legend ('DF2SOS','DF1')
% в двойной точности АЧХ фильтров с разными структурами совершенно
% одинаковы.


% Переводим фильтр в фикс. точку
Hd.Arithmetic = 'fixed';
Hdf1.Arithmetic = 'fixed';

fvtool(Hdf2sos,Hdf1)
legend ('DF2SOS Fixed-point','DF1 Fixed-point')
% На графике видно, что 16 бит для представления коэффициентов, выставляемые
% по умолчанию, явно недостаточно для фильтра со структурой "прямая форма 1" (DF1)


% пробуем увеличить разрядность коэффициентов, чтобы АЧХ пришла в норму
Hdf1.CoeffWordLength = 32;
fvtool(Hdf1)
legend ('DF1 Fixed-point')
% видимо 32-х бит вполне достаточно.

%%
% задаем входную разрядность
Hdf1.InputWordLength=16; % длина всего входного слова
Hdf1.InputFracLength=14; % число бит справа от запятой (дробная часть)

% создаем входной вектор из 3000 случайных значений в диапазоне входной
% разрядности фильтра. Этот вектор будем использовать для анализа фильтра
% на переполнения, которые могут возникать в процессе работы:
rand('state',5);
q = quantizer([Hdf1.InputWordLength,Hdf1.InputFracLength],'RoundMode','convergent');
xq = randquant(q,3000,1);
x = fi(xq,true,Hdf1.InputWordLength,Hdf1.InputFracLength);
% входной вектор готов к использованию.

fipref('LoggingMode', 'on', 'DataTypeOverride', 'ScaledDoubles');

% пропускаем через созданный фильтр входной вектор.
filter(Hdf1,x);
fipref('LoggingMode', 'off', 'DataTypeOverride', 'ForceOff');
qreport(Hdf1)
% из таблицы видно, что диапазон выходного сигнала немного не втискивается в
% установленный диапазон выходного слова

%%
% проводим автомасштабирование фильтра, чтобы устранить эту неприятность.
autoscale(Hdf1,x);
% Hdf1f.ScaleValueFracLength=Hdf1f.CoeffWordLength-2;
fipref('LoggingMode', 'on', 'DataTypeOverride', 'ForceOff');
% Вновь фильтруем:
filter(Hdf1,x);
fipref('LoggingMode', 'off');
qreport(Hdf1)

% Всё, фильтр готов. Дальше можно проанализировать его на шумы, вносимые
% округлением в полосе пропускания (да и в любой другой полосе), но это уже в
% след. серии :)

Если наберете команду info(Hdf1,'long'), то просто ужаснетесь от размеров умножителей и аккумулятора. Этот ужас вызван неадекватной разрядностью коэффициентов. Поэтому и применяют секции 2-го порядка. Если хотите использовать прямую форму 1, то лучше конечно, когда порядок фильтра гораздо меньше. При таком порядке, который у фильтра в примере "df1" - нецелесообразна. Я тут много наговорил, а вам ведь нужно все-таки сделать фильтр. Мой вам совет - забейте на пример в хелпе матлаба и на то, что у вас там не единица. Просто сделайте фильтр как в примере выше, но соответственно со структурой DF2SOS. Внимательно отмасштабируйте его по соответствующей норме, задайте ограничения на единице (unit) на масщтабирующие множители, проанализируйте. Можно также создавать фильтр не по Баттерворту, а например с использованием эллиптических функций. "Elliptic filter" - порядок фильтра как правило меньше чем у Баттерворта. Правда за все приходится платить, в данном случае пульсации в полосе пропускания. Вообщем экспериментируйте.
Tue
Блин, долго искал как можно отредактировать сообщение - не нашел. Обнаружил небольшую опечатку. Там где
Цитата
% Переводим фильтр в фикс. точку
Hd.Arithmetic = 'fixed';
Hdf1.Arithmetic = 'fixed';
Вместо Hd должно быть Hdf2sos
shf_05
Цитата(Tue @ Jun 23 2008, 01:59) *
Блин, долго искал как можно отредактировать сообщение - не нашел. Обнаружил небольшую опечатку. Там где
Вместо Hd должно быть Hdf2sos


Весьма благодарю за Вашу помощь.
если не секрет, то какая версия filter design toolbox у Вас?
Tue
Version 4.3 (R2008a)
shf_05
Цитата(Tue @ Jun 24 2008, 01:46) *
Version 4.3 (R2008a)


Вы бы очень помогли, если бы ответили на http://electronix.ru/forum/index.php?showtopic=49111
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.