Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Дробные параметры в Верилоге
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Языки проектирования на ПЛИС (FPGA)
Kluwert
Коллеги,
что-то не могу сообразить как решить такую простую задачку. Есть простой модуль, который задаёт следующие друг за другом временные интервалы. Он работает на некоторой тактовой частоте. Соответственно, по ТЗ временные интервалы заданы в миллисекундах. Можно, конечно, пересчитать длительность интервалов в число на выходе счётчика на данной тактовой частоте и успокоиться. Но как-то это не изящно: изменилась тактовая частота, или временнАя диаграмма - садись за калькулятор и пересчитывай.
А как бы вот так сделать, что бы время и тактовая частота задавалась в параметрах модуля сразу в мсек и МГц, соответственно, а в модуле автоматом пересчитывалось в такты счётчика?
blackfin
localparam max_cntr = $rtoi(frequency * interval) ;
Kluwert
Цитата(blackfin @ Nov 20 2017, 11:28) *
localparam max_cntr = $rtoi(frequency * interval) ;

Спасибо, но, увы:
Error (10174): Verilog HDL Unsupported Feature error at encodersimitation.v(26): system function "$rtoi" is not supported for synthesis
RobFPGA
Приветствую!

Цитата(Kluwert @ Nov 20 2017, 12:05) *
Спасибо, но, увы:
Error (10174): Verilog HDL Unsupported Feature error at encodersimitation.v(26): system function "$rtoi" is not supported for synthesis


Можно просто max_cntr = (frequency * interval);
Обычно синтезатор сам округлит результат умножения до целого. Поворчав warning-ом для причия что "... мол округляю...".

В зависимости от синтезатора и поддерживаемой версии Verilog можно и так: integer'(frequency * interval) чтоб не ворчал;

Удачи! Rob.
Kluwert
Цитата(RobFPGA @ Nov 20 2017, 12:27) *
Можно просто max_cntr = (frequency * interval);
Обычно синтезатор сам округлит результат умножения до целого. Поворчав warning-ом для причия что "... мол округляю...".

Увы, тоже мимо. Округлять синтезатор Квартуса не захотел: сообщил, что с real variable data type он работать не намерен. Единственным пока решением проблемы оказалось установка в модуль подмодулей FP-умножения и округления до целых. Когда на входе постоянные, то компайлер этот огромный умножитель несколько упрощает, но, всё равно всё настолько громоздким становится, что, похоже, калькулятор - самое простое решение sad.gif
RobFPGA
Приветствую!

Цитата(Kluwert @ Nov 20 2017, 14:02) *
Увы, тоже мимо. Округлять синтезатор Квартуса не захотел: сообщил, что с real variable data type он работать не намерен. Единственным пока решением проблемы оказалось установка в модуль подмодулей FP-умножения и округления до целых. Когда на входе постоянные, то компайлер этот огромный умножитель несколько упрощает, но, всё равно всё настолько громоздким становится, что, похоже, калькулятор - самое простое решение sad.gif


Можете привести тут часть кода на которую ругается Qu?

Удачи! Rob.
Tosha1984
Можо в лоб если точность не критична.
Помножьте параметр на 10 в требуемой степени, чтоб сделать целым.
Осуществите все требуемые арифметические операции с целыми числами.
У полученного результата отбросьте требуемое количество младших битов (ну то есть если умножали на 10 - отбросьте 3).
Результат будет с точностью до степени 2. Ну и логики конечно возможно немеренно уйдет на такое.
iosifk
Цитата(Tosha1984 @ Nov 20 2017, 15:32) *
Результат будет с точностью до степени 2. Ну и логики конечно возможно немеренно уйдет на такое.

У ТС речь идет о "localparam", который вычисляется по формуле. И при чем тут "логики немеренно уйдет"? Ведь сама формула - не синтезируется...
Tosha1984
Цитата(iosifk @ Nov 20 2017, 15:43) *
У ТС речь идет о "localparam", который вычисляется по формуле. И при чем тут "логики немеренно уйдет"? Ведь сама формула - не синтезируется...

Младшие биты, которые лишние - тоже будут участвовать в арифметических операциях.
То есть если домножили скажем на 1000 - появляется 10 битов которые надо туда-сюда таскать по RTL, а в конечном итоге отбросить.
Я так делал когда-то давно когда писал преобразование цвета из одной системы в другую (например RGB -> HSB). Там коэффициенты были как раз дробные и передавались параметрами. Далее я их формулами в теле делал целыми (домножал) что естественно не синтезировалось, потом непосредственно в верилоге все это перемножал/суммировал, а потом отбрасывал младшие биты. В итоге получалась гора логики, которая влияла на 1-2 младших бита в конечном результате - то есть она не была оптимизирована при синтезе, но по сути являлась балластом.
blackfin
Цитата(Kluwert @ Nov 20 2017, 14:02) *
Увы, тоже мимо. Округлять синтезатор Квартуса не захотел: сообщил, что с real variable data type он работать не намерен.

Тогда так:

localparam integer max_cntr = frequency * interval;
ViKo
Переведите мегагерцы в наносекунды и делите свои миллисекунды на наносекунды.
Kluwert
Цитата(iosifk @ Nov 20 2017, 15:43) *
У ТС речь идет о "localparam", который вычисляется по формуле. И при чем тут "логики немеренно уйдет"? Ведь сама формула - не синтезируется...

Иосиф прав, во-первых, синтезироваться-то ничего и не должно, это - постоянные.
Во-вторых, аппроксимировать деление на степени 10 делением на степени 2 - это как-то уж совсем грубо.
Но, ваша идея мне подсказала, походу самый оптимальный путь: время не в мкс, а в нс.

Т.е., как-то так:
parameter F_CLK_MHZ = 230;
parameter T_PULSE_NS = 275300;

`define COUNTER_MAX (F_CLK*T_PULSE_NS/1000)

Проверил, Квартус прожевал, вроде работает. Но всё-таки осадочек остался: почему нельзя было хотя бы для постоянных реализовать функцию $rtoi я не понимаю.
blackfin
Цитата(Kluwert @ Nov 20 2017, 16:41) *
Но всё-таки осадочек остался: почему нельзя было хотя бы для постоянных реализовать функцию $rtoi я не понимаю.

Так проверьте еще через параметр: пост #10.
Kluwert
Цитата(blackfin @ Nov 20 2017, 16:46) *
Так проверьте еще через параметр: пост #10.

Сорри, коллега, не заметил ваш пост. Слушайте, да, похоже работает и ваш способ похоже лучший на данный момент!Спасибо! Вот ведь меня на define'ах заклинило sm.gif
blackfin
Цитата(Kluwert @ Nov 20 2017, 17:19) *
Слушайте, да, похоже работает и ваш способ похоже лучший на данный момент! Спасибо!

Это не мой способ. Это способ RobFPGA. Его и благодарите.. biggrin.gif
RobFPGA
Приветствую!

Цитата(blackfin @ Nov 20 2017, 17:24) *
Это не мой способ. Это способ RobFPGA. Его и благодарите.. biggrin.gif

Ну так как я забыл написать localparam то чесно поделим благодарность пополам sm.gif .

Есть еще вариант если нужно присваивать константу wire|logic - обернуть вычисление в функцию которая возвращает integer.
Только вот для успешного синтеза в выражении real значения там могут быть только литеральными константами.
И не должно быть промежуточных real variable.
например
Код
function integer ms_n(input integer ms);
   return (FREQ_Hz * 0.001 * ms);
endfunction

И опят же надо проверять в конкретном синтезаторе. А то у меня была эпопея когда "...return integer'(...)" в Vivado для всех отрицательных значений real выражения в скобках всегда выдавал -1. А просто "...return (...)" работал правильно.

Удачи! Rob.
Kluwert
Цитата(RobFPGA @ Nov 20 2017, 19:19) *
И опят же надо проверять в конкретном синтезаторе. А то у меня была эпопея когда "...return integer'(...)" в Vivado для всех отрицательных значений real выражения в скобках всегда выдавал -1. А просто "...return (...)" работал правильно.

А позвольте полюбопытствовать. Я по смыслу понимаю, что конструкция integer' - это приведение типа к целому. Но, перерыл IEEE'шный стандарт Верилога-2001(ieee_std_1364_2001) ничего такого не нашёл. Это какая-то узко-Vivado'вская фича, или я просто не нашёл?
blackfin
Цитата(Kluwert @ Nov 21 2017, 11:24) *
Но, перерыл IEEE'шный стандарт Верилога-2001(ieee_std_1364_2001) ничего такого не нашёл. Это какая-то узко-Vivado'вская фича, или я просто не нашёл?

Это фича SystemVerilog'a.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.