nabbla (nabbla1) wrote,
nabbla
nabbla1

Categories:

ФНЧ БИХ на ЭРИ ОП

То есть, Фильтр Низкой Частоты с Бесконечной Импульсной Характеристикой на ЭлектроРадиоИзделиях Отечественного Производства :)

Итак, в прошлый раз мы обнаружили, что насыщенный синий цвет во входном аналоговом сигнале убивает нам синхронизацию, поскольку яркостная составляющая мала, а цветоразностная - огромная, вот сигнал и заходит в "область синхроимпульсов".

Вообще-то проблема известная, и в Datasheet на микросхему LM1881 (наверное, самый популярный селектор синхроимпульсов в мире) в схеме применения указана опциональная RC-цепочка на входе:


И в тексте пояснение: она как раз спасёт от слишком интенсивной цветовой составляющей, а также улучшит работу при наличии теплового шума.

Поэтому одно из самых простых решений - выполнить эту RC-цепочку в цифровом виде, а это как раз и есть БИХ-фильтр...


Собственно, все линейные цифровые фильтры подразделяются на КИХ (конечная импульсная характеристика) и БИХ.

КИХ не обладают рекурсией, выход зависит только от последних N входных отсчётов, взятых с определёнными коэффициентами. Они очень легко рассчитываются: по сути если знаешь импульсную характеристику, то знаешь и коэффициенты, ведь они и есть h(0), h(τ), h(2τ) и так далее, τ-интервал между отсчётами. Очень легко строятся "симметричные" фильтры, которые применённые к изображению оставляют его части "на своих местах", не вызывая, к примеру смещения вправо. Но огромный недостаток КИХ-фильтров - их ГРОМОЗДКОСТЬ! В нашем случае, мы хотим сделать нечто, отдалённо напоминающее RC-цепочку с постоянной времени 320 нс. Это 8 тактов по 40 нс. Импульсная характеристика RC-цепочки - экспонента, и на 320 нс она падает в e≈2,7 раз. Чтобы совсем резко её не обрубать, хочется взять удвоенное время, 640 нс, что потребует хранить в памяти 16 последних отсчётов, и каждый такт ПРОВОДИТЬ 16 умножений и 15 сложений, чтобы получить выходной отсчёт! По крайней мере, так выходит, если действовать в лоб.

БИХ называют ещё рекурсивными фильтрами, поскольку очередной выходной отсчёт вычисляется не только через входные, но и через предыдущие выходные отсчёты. Собственно, самый простой БИХ-фильтр, который и промоделировал бы нашу RC-цепочку, выглядит так:



где α - число от 0 до 1, выражающее постоянную времени. При α=1 фильтр попросту пропускает сигнал "насквозь" без изменений, а чем ближе α к нулю - тем больше будет становиться постоянная времени. И в любом случае, если на вход подать постоянное значение, на выходе рано или поздно установится оно же, т.е коэффициент передачи на низких частотах стремится к единице. Ровно такое же поведение имеет интегрирующая RC-цепочка.

Поскольку в ПЛИС серии 5576, которую нам хотелось бы применить, нет аппаратных перемножителей (в 5578 они появляются в каких-то невероятных количествах, но питание 1,2 и 2,5 вольта меня бесят, когда всё остальное работает от 1,8 и 3,3 вольт), хочется получить формулу, которая не содержит умножений.

Если нам не нужна какая-то совершенно конкретная постоянная времени, можно выбрать её из ряда α=2-m, и тогда формула сведётся к:



Такое исполнить на ПЛИС уже довольно легко: требуется 2 сумматора, а деление на 2m сводится к "переставлению проводов", т.е вообще БЕСПЛАТНО.

Увы, сумматоры на данной ПЛИС - сами по себе довольно медленные устройства, и два сумматора подряд, которые должны сработать за один такт, приводят к предельной тактовой частоте всего 30 МГц. В принципе, нас бы это устроило, мы пока на 25 МГц сидим, но когда-то мне казалось абсолютно необходимым оцифровывать этот сигнал на 33 МГц как минимум, и тогда мы снова не проходили по таймингам.

И мне подумалось: а так ли уж страшно, если мы добавим ещё одну задержку в такт:


Тогда получается очень шустрый модуль:

//implement  Q <= Q + ((D - Q) >> level)
//so bigger level means lower frequency

//but because our fpga is slow and cannot implement 2 additions in 1 clock,
//we instead implement
// Q[t] = Q[t-1] + ((D[t-2] - Q[t-2]) >> level)
// we completely forgot how to deal with z-transform...
// is it stable or not...
// seems it is :)
// we've remembered at last.

module IIR_LPF (input clk, input [7:0] D, output [7:0] Q);

parameter level = 2;

reg [7 + level : 0] Qfull = 1'b0;

wire [7:0] subRes;
wire subCout;

lpm_add_sub Sub (	.dataa (D),
			.datab (Qfull[7 + level : level]),
			.result(subRes),
			.cout (subCout));
defparam
	Sub.lpm_direction = "SUB",
	Sub.lpm_hint = "ONE_INPUT_IS_CONSTANT=NO,CIN_USED=NO",
	Sub.lpm_representation = "UNSIGNED",
	Sub.lpm_type = "LPM_ADD_SUB",
	Sub.lpm_width = 8 + level;
	
reg [7:0] rSubRes = 1'b0;
reg rSubCout = 1'b0;

always @(posedge clk) begin
	rSubRes <= subRes;
	rSubCout <= ~subCout;
	Qfull <= Qfull + {{level{rSubCout}}, rSubRes};
end

assign Q = Qfull[7 + level : level];

endmodule


Название расшифровывается как Infinite Impulse Response - Low-Pass Filter, в общем тот же ФНЧ БИХ.

Такая штуковина синтезируется в 37 ЛЭ и имеет предельную частоту 99 МГц (!!!)

Исполнение очень "низкоуровневое" - ширина первого сумматора (вычитатора?) всегда 8 бит, в смысле что совпадает с шириной наших отсчётов. Знак результата "расширяется" до полной ширины регистра, который чуть крупнее, чтобы не потерять точности. Видно, что модуль я писал очень давно: боялся в верилоговских файлах писать по-русски, т.к при копипасте из Quartus оно превращалось в тарабарщину (позже обнаружил, что если открывать их в каком-нибудь Notepad++, то всё там в порядке), и параметризовать всё и вся ещё не насобачился. Сегодня я бы написал не 7:0, а DataWidth-1:0, вдруг захочется с 8-битных отсчётов на 12-битные перейти, или того хуже, 24-битные для нашей с братом звуковой драндулетины :)

Но остаётся вопрос: а устойчива ли такая схема? Вдруг дополнительная задержка может в каких-то специфических условиях привести к самовозбуду?

Чтобы ответить на этот вопрос, нужно провести Z-преобразование. Вещь это очень простая: в рекуррентном соотношении меняем x[k-a] на z-ax, и точно так же y[k-a] на z-ay (здесь a - некоторое число). То есть, умножение на z-1 соответствует задержке сигнала на 1 такт. Получаем следующее выражение:







Коэффициент передачи фильтра:


Дальше я вечно начинаю путаться, что нам нужно: нули или полюса, и где оно должно лежать, ВНУТРИ единичной окружности или ВНЕ её? (сбивают с толку все эти отрицательные степени)

Ход размышлений примерно таков: КИХ-фильтры имеют коэффициент передачи a0+a1z-1+a2z-2+..., и они заведомо устойчивы, какие бы коэффициенты не стояли. Из-за стоящих повсюду z-1 у нас повсюду возникает полюс z=0, и мы плевать на него хотели! А нолей и вовсе нет, разве что z стремящийся к бесконечности. Но в БИХ-фильтрах, вроде нашего, тоже возможен один-единственный ноль при z стремится к бесконечности, так что это не показатель.

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

Давайте это и сделаем, найдём полюса:





(для m > 1. Но применять данный фильтр при m=1 не имеет особого смысла, т.к можно использовать куда более простой, y[k]=(x[k-1]+y[k-1])/2)



Очевидно, что





Чтобы определить положение второго полюса, воспользуемся неравенством


при x > 0

Получаем:




Оба полюса лежат внутри единичного круга, что доказывает: наш БИХ-фильтр стабилен!



Такой вот экскурс в цифровую обработку сигналов! А то ковыряться с ПЛИС и не поставить туда ни одного фильтра - деньги на ветер!
Tags: ПЛИС, математика, программки, работа, странные девайсы
Subscribe

  • Быстрее, меньше, точнее!

    Начинаем тестировать новую процедуру арктангенса. Сначала на симуляции. Получаем дамп памяти: Переписываем числа в таблицу: Первая половина…

  • atan1 "на четырёх умножениях" на ассемблере

    Немножко подправил таблицу результатов для первого алгоритма. В этот раз вместо "правильных углов" 0°, 12°, 24° и т.д (те, которые я ХОТЕЛ взять для…

  • Тестируем atan1 на QuatCore

    Пора уже перебираться на "железо" потихоньку. Решил начать с самого первого алгоритма, поскольку он уже был написан на ассемблере. В программу внёс…

  • Формулы приведения, что б их... (и atan на ТРЁХ умножениях)

    Формулу арктангенса на 4 умножениях ещё немножко оптимизировал с помощью алгоритма Ремеза: Ошибка уменьшилась с 4,9 до 4,65 угловой секунды, и…

  • Алгоритм Ремеза в экселе

    Вот и до него руки дошли, причина станет ясна в следующем посте. Изучать чужие библиотеки было лениво (в том же BOOSTе сам чёрт ногу сломит), писать…

  • atan на ЧЕТЫРЁХ умножениях

    Мишка такой человек — ему обязательно надо, чтоб от всего была польза. Когда у него бывают лишние деньги, он идёт в магазин и покупает какую-нибудь…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 5 comments