Комментарии 17
2 порядок больше подходит для звена БИХ фильтра. Сколько варнингов у такого описания? Еще, что бросилось в глаза: если стоит условный оператор, то условия перечисляются через логическое и/или (&& ||). А вообще классно, было интересно читать!
0
Спасибо. Вылитает 16 варнингов, причем 2 относятся к тому что не используется объявленная переменная outsum, 4 к тому, что не дал внутримодульные названия мегафункциям. Это самые критичные вроде, остальные — мелочь какая-то. Насчет условного оператора, вы правы конечно, но я во всех проектах использую подобную запись, и, кажется, никаких проблем с этим не возникало. Может быть стоит начать писать правильно, мало ли где выплавит. А что вы имели ввиду по поводу звена БИХ фильтра? Нашел фразу:«БИХ-фильтры обычно реализуются с помощью звеньев второго порядка, которые называются биквадратными фильтрами». Но вроде бы эти биквадратные формы используются для упрощений расчетов фильтров больших порядков, определения нулей и полюсов фильтров. Влияет ли это на конечную реализацию устройства, например в Verilog? Всегда казалось что для повышения порядка, достаточно добавить дополнительные слагаемые в конечное разностное уравнение.
0
А посмотрите в проекте этот сумматор: COUNT[5:0] + 1. Просто интересно, скольки он разрядный. Просто «1» по дефолту int и преображается в 32 разряда, поэтому сумматор может получится страшным, а может и нет, если оптимизацию пройдет.
Лично один раз спотыкался об & и && по части интерфейсов, теперь стараюсь следить.
И да, большие БИХ фильтры можно строить звеньями, что облегчает анализ этих фильтров. Это эквивалентно последовательному включению фильтров меньшего порядка, что реализацию, в принципе, не меняет.
Лично один раз спотыкался об & и && по части интерфейсов, теперь стараюсь следить.
И да, большие БИХ фильтры можно строить звеньями, что облегчает анализ этих фильтров. Это эквивалентно последовательному включению фильтров меньшего порядка, что реализацию, в принципе, не меняет.
0
Не могу не запостить этот баян:
0
Спасибо, учту…
0
Вы не принимайте близко к сердцу, я с благими намерениями :)
0
хм…
а это у Вас вообще-то работает? пробовали ли в железе или симулировали?
Что-то меня смущает несколько моментов.
1) похоже все операции делаются над положительными числами, это так? Не вижу signed reg или $signed… Если все числа положительны, то на выходе будет все возрастающее число — посмотрите на свою структуру: сложение многих положительных компонентов дает большее число и с каждой новой входящей выборкой число на выходе будет увеличиваться…
2) вы как-то смело используете для всех переменных 32х битные регистры. При этом вообще-то при перемножении двух 32х битных чисел получится 64х битное число, ведь так? Почему Вы пренебрегаете этим?
3) и как оно синтезируется для ПЛИС? для какой конкретно ПЛИС? операция умножения довольно расточительная функция и занимает много места, если только не используются встроенные умножители
3)
а это у Вас вообще-то работает? пробовали ли в железе или симулировали?
Что-то меня смущает несколько моментов.
1) похоже все операции делаются над положительными числами, это так? Не вижу signed reg или $signed… Если все числа положительны, то на выходе будет все возрастающее число — посмотрите на свою структуру: сложение многих положительных компонентов дает большее число и с каждой новой входящей выборкой число на выходе будет увеличиваться…
2) вы как-то смело используете для всех переменных 32х битные регистры. При этом вообще-то при перемножении двух 32х битных чисел получится 64х битное число, ведь так? Почему Вы пренебрегаете этим?
3) и как оно синтезируется для ПЛИС? для какой конкретно ПЛИС? операция умножения довольно расточительная функция и занимает много места, если только не используются встроенные умножители
3)
+1
Да, все хорошо работает в железе.
1) Дело в том что при вычислениях используется формат числа с плавающей запятой. Я указал в пояснениях к модулю, что функция int18_to_float32 преобразует числа к этому виду.Вот ознакомьтесь пожалуйста Число одинарной точности.Старший бит этой 32-х битной структуры как раз и отвечает за знак числа. И числа конечно же не все положительные. Переменные С0… С2, заведомо умножены на -1, т.е. они отрицательные.
2) Все правильно, если бы это были целые числа, то так бы оно и было. Но я использую числа с плавающей запятой, поэтому результат остается 32-х разрядный.
3)Конкретно в этом проекте я использую Cyclone III EP3C25Q240C8.Там есть встроенные умножители. У меня там 4 таких фильтра и еще процессор Nios II, места на все хватает.
1) Дело в том что при вычислениях используется формат числа с плавающей запятой. Я указал в пояснениях к модулю, что функция int18_to_float32 преобразует числа к этому виду.Вот ознакомьтесь пожалуйста Число одинарной точности.Старший бит этой 32-х битной структуры как раз и отвечает за знак числа. И числа конечно же не все положительные. Переменные С0… С2, заведомо умножены на -1, т.е. они отрицательные.
2) Все правильно, если бы это были целые числа, то так бы оно и было. Но я использую числа с плавающей запятой, поэтому результат остается 32-х разрядный.
3)Конкретно в этом проекте я использую Cyclone III EP3C25Q240C8.Там есть встроенные умножители. У меня там 4 таких фильтра и еще процессор Nios II, места на все хватает.
0
Вот пара моментов, которые прям бросились в глаза:
1) Входы-выходы объявляются в заголовке модуля обычно. Вы объявляете регистры и цепи в процессе их появления в тексте. Мелочь, конечно, но для меня странно выглядит.
2) Для каждого блока always используете один оператор. Почему не в операторных скобках в одном блоке always?
3) У вас все повторяющиеся условия ( которые отрабатывают счетчик) можно свести в один case ( автомат получится). Вы это делаете, чтоб синтезировалась обработка условий через enable в триггерах вместо мультиплексора, которым реализуется автомат? Насколько это эффективнее?
4) Я бы параметризовал многие вещи. Для гибкости. Вдруг пригодится.
5) На какой частоте все работает? Имеется в виду оценка Тime quest'а.
Извините, если несуразные вопросы. Стаж у самого чуть больше года. Может я что-то важное упускаю?
Eщё нескромный вопрос. Не пробовали генерировать фильтр из матлаба?
1) Входы-выходы объявляются в заголовке модуля обычно. Вы объявляете регистры и цепи в процессе их появления в тексте. Мелочь, конечно, но для меня странно выглядит.
2) Для каждого блока always используете один оператор. Почему не в операторных скобках в одном блоке always?
3) У вас все повторяющиеся условия ( которые отрабатывают счетчик) можно свести в один case ( автомат получится). Вы это делаете, чтоб синтезировалась обработка условий через enable в триггерах вместо мультиплексора, которым реализуется автомат? Насколько это эффективнее?
4) Я бы параметризовал многие вещи. Для гибкости. Вдруг пригодится.
5) На какой частоте все работает? Имеется в виду оценка Тime quest'а.
Извините, если несуразные вопросы. Стаж у самого чуть больше года. Может я что-то важное упускаю?
Eщё нескромный вопрос. Не пробовали генерировать фильтр из матлаба?
0
1) Мне так удобнее ориентироваться в программе. Когда простыня на несколько экранов я ищу нужное мне место по объявлениям регистров.
2) Ну тут много причин:
a)Ключевое слово always указывает на процесс. Процесс — это такой кусок кода, внутри которого все операции выполняются ПОСЛЕДОВАТЕЛЬНО. Зачем мне ограничиваться, выстраивая последовательные расчеты, если я могу выполнять их ПАРАЛЛЕЛЬНО.
b)Эти процессы зачастую тактируются по-разному. Если в этой маленькой программе этого нет (везде одна частота), то есть проекты, в которых условия срабатывания в разных процессах разные. Поэтому я привык разграничивать различные по смыслу процессы.
3)Это такой же мультиплексор, не важно как его задавать, case-ом или if-ом. Реализация не вентильно-тригерном уровне не меняется. В case вроде бы нельзя задать выбор по диапазону, а только по конкретному значению, как в if, а раз смысл одинаковый, а функциональности больше у if, я пользуюсь обычно if. Хотя иногда, когда много условий, могу использовать и case.
4)Да, можно было бы. А то какой-то говнокод получается:)
5)По данным Тime quest'а максимальное значение частоты mhz_clk = 63.4MHz, но эта частота определяется частотой дискритизации АЦП. В моем проекте это 600кГц, поэтому mhz_clk я выбрал 30МГц.
С матлабом пока дела не имел, но начинаю к нему приглядываться. Скоро опять будет проект, где нужно будет синтезировать фильтр по заданной АЧХ, причем весьма сложной. Без матлаба видимо не обойтись…
2) Ну тут много причин:
a)Ключевое слово always указывает на процесс. Процесс — это такой кусок кода, внутри которого все операции выполняются ПОСЛЕДОВАТЕЛЬНО. Зачем мне ограничиваться, выстраивая последовательные расчеты, если я могу выполнять их ПАРАЛЛЕЛЬНО.
b)Эти процессы зачастую тактируются по-разному. Если в этой маленькой программе этого нет (везде одна частота), то есть проекты, в которых условия срабатывания в разных процессах разные. Поэтому я привык разграничивать различные по смыслу процессы.
3)Это такой же мультиплексор, не важно как его задавать, case-ом или if-ом. Реализация не вентильно-тригерном уровне не меняется. В case вроде бы нельзя задать выбор по диапазону, а только по конкретному значению, как в if, а раз смысл одинаковый, а функциональности больше у if, я пользуюсь обычно if. Хотя иногда, когда много условий, могу использовать и case.
4)Да, можно было бы. А то какой-то говнокод получается:)
5)По данным Тime quest'а максимальное значение частоты mhz_clk = 63.4MHz, но эта частота определяется частотой дискритизации АЦП. В моем проекте это 600кГц, поэтому mhz_clk я выбрал 30МГц.
С матлабом пока дела не имел, но начинаю к нему приглядываться. Скоро опять будет проект, где нужно будет синтезировать фильтр по заданной АЧХ, причем весьма сложной. Без матлаба видимо не обойтись…
0
1) Вы работаете один? Я работаю в команде и стилистика, хоть и на словах, но имеется и обсуждается.
2) а) Например блок
Always @(posedge clk)
begin
a=x+y;
b=q+g;
c=n+m;
end
Все присвоения в таком случае сработают параллельно.
5) Маловата частота конечно для такой плис, но если запас в 2 раза, то проблем нет.
Matlab, кстати, очень рекомендую. Весь ЦОС всегда полностью моделирую, но вот генерацией HDL кода пока не занялся.
2) а) Например блок
Always @(posedge clk)
begin
a=x+y;
b=q+g;
c=n+m;
end
Все присвоения в таком случае сработают параллельно.
5) Маловата частота конечно для такой плис, но если запас в 2 раза, то проблем нет.
Matlab, кстати, очень рекомендую. Весь ЦОС всегда полностью моделирую, но вот генерацией HDL кода пока не занялся.
0
1) Нет, не один, но у нас все также пишут:)
2)Нет, последовательно. Это можно сделать параллельно, если вместо begin...end использовать fork...join. Либо можно еще ускорить процесс присвоения регистра. Дело в том, что операция установки регистра занимает определенное время. Можно использовать неблокирующее присваивание(a<=x+y;b<=q+g), при котором перескок на следующую операцию идет сразу после того, как регистр начнет устанавливаться.
2)Нет, последовательно. Это можно сделать параллельно, если вместо begin...end использовать fork...join. Либо можно еще ускорить процесс присвоения регистра. Дело в том, что операция установки регистра занимает определенное время. Можно использовать неблокирующее присваивание(a<=x+y;b<=q+g), при котором перескок на следующую операцию идет сразу после того, как регистр начнет устанавливаться.
0
Я делал фильтры из fdatool в matlab, получааетсся очень громоздко и нечитабельно. Именно по этой причине я и написал этот пост, где брал из матлаба коэффициента фильтра, а все умножения с накоплением делал сам. Когда доделал фильтр сравнил результаты: дизайн из матлаба не влез в Cyclone2 не помню какую, мой дизайн занял 1% кристалла, аккуратно разложив сдвиговый регистр и коэффициенты в ram, которой было более чем достаточно
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Реализация на Verilog цифрового БИХ-фильтра