Jump to content
    

"Пропорциональный сумматор" на VHDL

Есть 2 целых числа одинаковой разрядности, обозначим их X и Y. Также есть некий вещественный коэффициент K от 0 до 1 включительно. Как наиболее простым способом синтезировать на VHDL модуль, который посчитает следующую целую сумму S = K * X + (1 - K) * Y ?

Понятно, что можно задействовать аппаратные умножители 2 шт., делитель и т. п. А нет ли простого алгоритма ?

Share this post


Link to post
Share on other sites

Если раскрыть скобки и сгруппировать по К, то можно обойтись одним умножителем и двумя сумматорам.

Share this post


Link to post
Share on other sites

Если раскрыть скобки и сгруппировать по К, то можно обойтись одним умножителем и двумя сумматорам.

S = Y + K * (X - Y)

Да, так, безусловно, лучше.

Теперь ещё понять бы, как задать целое K таким образом, чтобы обойтись без деления (точнее, заменить его сдвигом). Например, если в качестве K использовать 4-битное число, то оно принимает значения от 0 до 15. Тогда в итоге сумму придётся делить на 15, и нужен делитель. Чтобы делить в итоге на 16 (сдвиг вправо на 4 бита), нужно, чтобы K было от 0 до 16, то есть отводить под K уже 5 бит, что неэкономно. Замкнутый круг какой-то...

Share this post


Link to post
Share on other sites

S = Y + K * (X - Y)

Да, так, безусловно, лучше.

Теперь ещё понять бы, как задать целое K таким образом, чтобы обойтись без деления (точнее, заменить его сдвигом). Например, если в качестве K использовать 4-битное число, то оно принимает значения от 0 до 15. Тогда в итоге сумму придётся делить на 15, и нужен делитель. Чтобы делить в итоге на 16 (сдвиг вправо на 4 бита), нужно, чтобы K было от 0 до 16, то есть отводить под K уже 5 бит, что неэкономно. Замкнутый круг какой-то...

Не стоит забывать, что реально принимает значение К=0...1.

Если мы представляем К как целое, тогда при К=16 (т.е К=1), выражение будет

S=X

и ничего делить не нужно.

Поэтому смело отдавайте К 4 бита.

Share this post


Link to post
Share on other sites

Если К константа то умножение заменяется на несколько сумматоров и у резульата отбрасывается несколько младших бит для приведения к диапазону 0-1, т.е. делим. Если не константа, то ставьте настоящий умножитель.

Share this post


Link to post
Share on other sites

Не стоит забывать, что реально принимает значение К=0...1.

Если мы представляем К как целое, тогда при К=16 (т.е К=1), выражение будет

S=X

и ничего делить не нужно.

Поэтому смело отдавайте К 4 бита.

На K тогда нужно отвести 5 бит. Хотя будет только одно единственное значение K, для которого нужен пятый бит - значение 16. Но 4 бит мало.

Но лишний бит на представление K обойдётся гораздо дешевле чем честное деление на 15.

Share this post


Link to post
Share on other sites

Я такую формулу вычислял 30 лет назад. Это было такое текущее усреднение. При этом число К записывал в ПЗУ по адресу - номеру итерации усреднения.

Share this post


Link to post
Share on other sites

S = Y + K * (X - Y)

Да, так, безусловно, лучше.

Теперь ещё понять бы, как задать целое K таким образом, чтобы обойтись без деления (точнее, заменить его сдвигом). Например, если в качестве K использовать 4-битное число, то оно принимает значения от 0 до 15. Тогда в итоге сумму придётся делить на 15, и нужен делитель. Чтобы делить в итоге на 16 (сдвиг вправо на 4 бита), нужно, чтобы K было от 0 до 16, то есть отводить под K уже 5 бит, что неэкономно. Замкнутый круг какой-то...

Я так понимаю что для начала нужно определиться что такое К. Т.е. для 4 разрядов это может быть:

1) .bbbb, что является числом от 0 до 0,9375,

2) если нужно точное значение 1, то b.bbb.

 

в первом случае сдвигаем на 4 разряда, во втором на три...

Для целого числа в любом случае придется выделить разряд слева от запятой.

Share this post


Link to post
Share on other sites

Я так понимаю что для начала нужно определиться что такое К.

K - это коэффициент от 0 до 1 включительно, т. е. [0;1]. При изменении K от 0 до 1 сумма S меняется от Y до X соответственно.

Под значение K отведено 4 бита, это значит, что K будет меняться от 0 до 15, соответственно, чтобы привести его к интервалу [0;1] необходимо всю сумму поделить на 15:

S = ( 15 * Y + K(целое) * (X - Y) )/15, где K [0;15].

Делитель на 15 на VHDL - это довольно затратный ресурс, и поскольку таких сумматоров нужно несколько, то они не помещаются в FPGA. В отличие от деления на 16, которое есть просто сдвиг вправо на 4 бита, что элементарно на программируемой логике. Но тогда коэффициент K уже должен быть в интервале [0;16] и ради одного значения 16 нужно отводить под него 5 бит.

Вот в чём проблема, и как её элегантно решить - я пока думаю и прошу совета бывалых.

 

Share this post


Link to post
Share on other sites

K - это коэффициент от 0 до 1 включительно, т. е. [0;1]. При изменении K от 0 до 1 сумма S меняется от Y до X соответственно.

Под значение K отведено 4 бита, это значит, что K будет меняться от 0 до 15, соответственно, чтобы привести его к интервалу [0;1] необходимо всю сумму поделить на 15:

S = ( 15 * Y + K(целое) * (X - Y) )/15, где K [0;15].

Делитель на 15 на VHDL - это довольно затратный ресурс, и поскольку таких сумматоров нужно несколько, то они не помещаются в FPGA. В отличие от деления на 16, которое есть просто сдвиг вправо на 4 бита, что элементарно на программируемой логике. Но тогда коэффициент K уже должен быть в интервале [0;16] и ради одного значения 16 нужно отводить под него 5 бит.

Вот в чём проблема, и как её элегантно решить - я пока думаю и прошу совета бывалых.

Так я и написал что если нужно 1 включительно, то без 1 разряда слева от запятой не обойтись. Или ставить делитель.

Share this post


Link to post
Share on other sites

Может быть, можно обойтись каким-нибудь табличным методом, если учесть, что разрядность X и Y всего 5 бит? Практикуется ли такое (замена деления таблицей) ?

Edited by gerber

Share this post


Link to post
Share on other sites

Но тогда коэффициент K уже должен быть в интервале [0;16] и ради одного значения 16 нужно отводить под него 5 бит.

Вот в чём проблема, и как её элегантно решить - я пока думаю и прошу совета бывалых.

В чем проблема 5 бит ? Нужно делать сумматоры, умножители на 5 бит? Либо же нужно иметь регистр на 5 бит для K ?

 

Может быть, можно обойтись каким-нибудь табличным методом, если учесть, что разрядность X и Y всего 5 бит? Практикуется ли такое (замена деления таблицей) ?

Конечно.

Но еще раз повторюсь. При К=0 и К = 16 ничего умножать и делить не надо.

При К=0

S=Y

При К=16

S=X

 

При остальных значениях К достаточно выделить на него 4 бита. Т.е все умножители и сумматоры будут работать только с младшими 4 битами К.

 

Share this post


Link to post
Share on other sites

При остальных значениях К достаточно выделить на него 4 бита. Т.е все умножители и сумматоры будут работать только с младшими 4 битами К.

Если 5-битовый умножитель не ложится в ПЛИС, то можно так попробовать:

S = K[4] ? X : (Y + K[3:0] * (X - Y));

Share this post


Link to post
Share on other sites

Если 5-битовый умножитель не ложится в ПЛИС, то можно так попробовать:

S = K[4] ? X : (Y + K[3:0] * (X - Y));

Мне думается, что Костян это же и сказал)

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...