реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Подсчет числа одинаковых разрядов двоичного числа, ищется комбинаторная реализация
glock17
сообщение Apr 28 2006, 06:41
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 163
Регистрация: 3-09-04
Пользователь №: 586



help.gif
Задача следующая:

имеется 32-х разрядное число. Нужно вычислить, сколько у этого числа последовательных нулей или единиц, начиная со старшего разряда. Поясню на примере 8-разрядного числа:

0001xxxx или 1110xxxx дают результат 2 (3 одинаковых соседних бита в старших разрядах)
10xxxxxx или 01xxxxxx дают результат 0 (одинаковых соседних битов нет)
0000001x или 1111110x дают результат 5 (6 одинаковых соседних битов в старших разрядах)

x означает, что значение этих битов уже не имеет значения.

Задача тривиальна, если вычисления завязать на клок и строить внутри процесса (код пишется на Верилоге). Однако ищется возможность реализации на комбинационной логике (вопрос быстродействия стоит остро).

Буду благодарен за любые конструктивные идеи. cheers.gif
Go to the top of the page
 
+Quote Post
sazh
сообщение Apr 28 2006, 07:15
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 435
Регистрация: 6-10-04
Из: Петербург
Пользователь №: 804



А можно посмотреть на этот код?
Go to the top of the page
 
+Quote Post
Postoroniy_V
сообщение Apr 28 2006, 07:28
Сообщение #3


МедвеД Инженер I
****

Группа: Свой
Сообщений: 816
Регистрация: 21-10-04
Пользователь №: 951



Цитата(glock17 @ Apr 28 2006, 10:41) *
help.gif
Задача следующая:

имеется 32-х разрядное число. Нужно вычислить, сколько у этого числа последовательных нулей или единиц, начиная со старшего разряда. Поясню на примере 8-разрядного числа:

0001xxxx или 1110xxxx дают результат 2 (3 одинаковых соседних бита в старших разрядах)
10xxxxxx или 01xxxxxx дают результат 0 (одинаковых соседних битов нет)
0000001x или 1111110x дают результат 5 (6 одинаковых соседних битов в старших разрядах)

x означает, что значение этих битов уже не имеет значения.

Задача тривиальна, если вычисления завязать на клок и строить внутри процесса (код пишется на Верилоге). Однако ищется возможность реализации на комбинационной логике (вопрос быстродействия стоит остро).

Буду благодарен за любые конструктивные идеи. cheers.gif

если всё упирается в быстродействие, тогда делаете таблично(ROM)
адрес это ваши 0001xxxx и т.д.
а на выходе уже получаете "ответ" за 1 такт

а комбинационой логикой врядли получится быстрее


--------------------
Cogito ergo sum
Go to the top of the page
 
+Quote Post
glock17
сообщение Apr 28 2006, 07:55
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 163
Регистрация: 3-09-04
Пользователь №: 586



Цитата
А можно посмотреть на этот код?


Какой код? Если этот
Цитата
Задача тривиальна, если вычисления завязать на клок и строить внутри процесса (код пишется на Верилоге).
, то я его даже не писал, там никаких трудностей нет.
Этот вариант написан на C, перевести его в верилог не проблема(будет время - переведу).
Цитата
int16 L32_exp(int32 x)
{
int16 exp = 0;

if (!x)
return 0;

while ((x ^ (x << 1)) > 0)
{
x <<= 1;
exp++;
}
return (exp);
}


Но фишка в том, что такой вариант не катит.
Go to the top of the page
 
+Quote Post
glock17
сообщение Apr 28 2006, 08:10
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 163
Регистрация: 3-09-04
Пользователь №: 586



Цитата
если всё упирается в быстродействие, тогда делаете таблично(ROM)
адрес это ваши 0001xxxx и т.д.
а на выходе уже получаете "ответ" за 1 такт

а комбинационой логикой врядли получится быстрее


Думал уже... Это какой же ROM нужен, чтобы таким макаром 32-х битное число обработать... sad.gif
Проблема в том, что эта процедура - мизерная часть офигенно развесистого алгоритма, который пишется для создания ASIC на его базе, поэтому затраты по площади (так же, как и быстродействие) - основные проблемы.
Я уже попробовал минимизировать аналогичную функцию для 8-битного числа - результат впечатляет biggrin.gif
С 32-битным даже пробовать не буду.
Похоже, вариантов всего два - попытаться вообще исключить эту гнусную процедуру из алгоритма или все таки делать ее синхронно.
Go to the top of the page
 
+Quote Post
lelik
сообщение Apr 28 2006, 08:14
Сообщение #6


Участник
*

Группа: Свой
Сообщений: 51
Регистрация: 6-07-04
Пользователь №: 270



Если данные идут последовательно, то можно использовать счётчик.
Сбрасывать его когда последующий бит не равен предыдущему.
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 28 2006, 08:26
Сообщение #7


Вечный ламер
******

Группа: Модераторы
Сообщений: 7 248
Регистрация: 18-03-05
Из: Томск
Пользователь №: 3 453



Цитата(glock17 @ Apr 28 2006, 01:41) *
help.gif
Задача следующая:

имеется 32-х разрядное число. Нужно вычислить, сколько у этого числа последовательных нулей или единиц, начиная со старшего разряда. Поясню на примере 8-разрядного числа:

0001xxxx или 1110xxxx дают результат 2 (3 одинаковых соседних бита в старших разрядах)
10xxxxxx или 01xxxxxx дают результат 0 (одинаковых соседних битов нет)
0000001x или 1111110x дают результат 5 (6 одинаковых соседних битов в старших разрядах)

x означает, что значение этих битов уже не имеет значения.

Задача тривиальна, если вычисления завязать на клок и строить внутри процесса (код пишется на Верилоге). Однако ищется возможность реализации на комбинационной логике (вопрос быстродействия стоит остро).

Буду благодарен за любые конструктивные идеи. cheers.gif


поток нужен ?
или мона и ждайт ?


--------------------
Go to the top of the page
 
+Quote Post
RobFPGA
сообщение Apr 28 2006, 09:10
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 214
Регистрация: 23-12-04
Пользователь №: 1 643



Приветствую!

У меня вот этот вариант работает для VirtexII-5 с частотой >140 МГц
(только положительные чисела -ищется цепочка 0)

Успехов! Rob.

function [WHE-1:0] GetExpU;
input [WHI-1:0] N; //входное число с разряднотью WHI (у меня 48)
input integer M; //максимальная длинна иследуемого куска (у меня 26)
integer k,rz;
begin
rz=0;
k=WHI-1;
while(~N[k] && k>(WHI-1-M))
begin
k=k-1;
rz=rz+1;
end
GetExpU=rz;//WHI-1-k;
end
endfunction

always @(posedge clk)
rExp<=GetExpU(Din,(WHI-WHF));
Go to the top of the page
 
+Quote Post
sazh
сообщение Apr 28 2006, 09:33
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 435
Регистрация: 6-10-04
Из: Петербург
Пользователь №: 804



module comp32
(
input [31:0] in,
output [4:0] out
);


reg temp;
integer temp_a;

integer i;

always @(in) begin
temp=1;
temp_a=0;
for (i=31; i>0; i=i-1) begin
if (in[i] != in[i-1]) temp = 0;
if ((in[i] == in[i-1]) & temp) temp_a = temp_a+1; end
end
assign out = temp_a[4:0];

endmodule
Go to the top of the page
 
+Quote Post
Gate
сообщение Apr 28 2006, 09:34
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 859
Регистрация: 7-04-05
Из: Санкт-Петербург
Пользователь №: 3 943



glock17,
любые верилоговские конструкции, не стоящие под always @(edge signal), синтезируются в комбинаторную логику. Ваша задача элементарна:
integer i, result;
i=30;
while ((a[31]==a[i]) && (i>=0)) i=i-1;
result=30-i;
м.б. сделал ошибку, но принцип должен быть понятен.


--------------------
"Человек - это существо, которое охотнее всего рассуждает о том, в чем меньше всего разбирается." (с) С.Лем
Go to the top of the page
 
+Quote Post
sazh
сообщение Apr 28 2006, 10:01
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 435
Регистрация: 6-10-04
Из: Петербург
Пользователь №: 804



To Gate
В вашем примере неправильно будет интерпитироваться код все нули. Числа 31 не получить.
Go to the top of the page
 
+Quote Post
Magnum
сообщение Apr 28 2006, 10:08
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 214
Регистрация: 26-05-05
Пользователь №: 5 397



To Gate:
Это последовательный путь.. А надо параллельный, т.е. за 1 такт, тут задача на мой взгляд решается просто: Ставим 62 компаратора на (2,3,4..32 разряда), которые будут сравнивать наше слово с константами типа 11, 111, 1111,.... и т.д. 00, 000,0000... и т.д. соответсвтвенно цепляем на них старшие разряды шины и сравниваем со всеми одновременно выход будет работать по двоично-десятичной логике.

Сообщение отредактировал Magnum - Apr 28 2006, 10:09
Go to the top of the page
 
+Quote Post
sazh
сообщение Apr 28 2006, 10:20
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 435
Регистрация: 6-10-04
Из: Петербург
Пользователь №: 804



Причем тут последовательный или параллельный. И то и другое за один такт. Другое дело как это одной строчкой оформить. А то о чем вы говорите, что case это уже дело рук.
Go to the top of the page
 
+Quote Post
Gate
сообщение Apr 28 2006, 10:37
Сообщение #14


Знающий
****

Группа: Свой
Сообщений: 859
Регистрация: 7-04-05
Из: Санкт-Петербург
Пользователь №: 3 943



Цитата(sazh @ Apr 28 2006, 14:01) *
To Gate
В вашем примере неправильно будет интерпитироваться код все нули. Числа 31 не получить.

При числе, состоящем из всех 1 или 0, выход из цикла произойдет с i=-1, result=31. Что неверно?Проблема только в вычислении a[-1] (синтезатор может и не ругнуться) - ну тогда надо индекс сдвинуть на +1 или переписать условие цикла. Впрочем, пускай глок проверяет, принцип ему три человека рассказали.


--------------------
"Человек - это существо, которое охотнее всего рассуждает о том, в чем меньше всего разбирается." (с) С.Лем
Go to the top of the page
 
+Quote Post
id_gene
сообщение Apr 29 2006, 10:08
Сообщение #15


carpe manana
***

Группа: Свой
Сообщений: 321
Регистрация: 2-06-05
Пользователь №: 5 659



Цитата(sazh @ Apr 28 2006, 14:01) *
To Gate
В вашем примере неправильно будет интерпитироваться код все нули. Числа 31 не получить.

в исходном коде стоит
if (!x)
return 0;
Go to the top of the page
 
+Quote Post
sazh
сообщение Apr 29 2006, 19:31
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 2 435
Регистрация: 6-10-04
Из: Петербург
Пользователь №: 804



Уважаемый id_gene. Дело в том, что я не программист. И хотя текст этот понимаю, в железе освоил только FO, а вот условие в while ну никак осилить не могу. Ошибку выдает. Может Вы мне поможете. Написать пару формул.
Go to the top of the page
 
+Quote Post
DS
сообщение Apr 29 2006, 20:27
Сообщение #17


Гуру
******

Группа: СуперМодераторы
Сообщений: 3 096
Регистрация: 16-01-06
Из: Москва
Пользователь №: 13 250



По моему делается из 31 элемента XOR, который сводит 0 к 1 в соотвествии с первым разрядом и приоритетного шифратора. Как его сделать, написано в любой книжке по цифровой логике. Чтобы не делать многовходовых функций, он каскадируется.



Если полагаться, что компилятор Вам такую штуку придумает по поведенческому описанию, то в ней может оказаться тысяч сто вентилей smile.gif


--------------------
Не бойтесь тюрьмы, не бойтесь сумы, не бойтесь мора и глада, а бойтесь единственно только того, кто скажет - "Я знаю как надо". А. Галич.
Go to the top of the page
 
+Quote Post
Chudik
сообщение Apr 30 2006, 18:02
Сообщение #18


Частый гость
**

Группа: Свой
Сообщений: 197
Регистрация: 31-03-06
Пользователь №: 15 676



Я тоже, почитав ответы, пришёл к выводу об использовании XOR. Можно каскадированием, как предложил DS_, но при этом, имхо, это будет последовательное сравнение, т.е. тратим время.
Я бы, возможно, сделал примерно так:

Код
if (!(^data[31:0])) cnt = 31;
else if (!(^data[31:1])) cnt = 30;
else if (!(^data[31:2])) cnt = 29;
...
else if (!(^data[31:30])) cnt = 1;
else cnt=0


или, если хочется короче:
Код
   for(i=0; i<32; i=i+1)
       if(!(^data[31:i])
          begin
               cnt = 31 - i;
               break;
          end


всё это, естественно, под always @(data)

Сообщение отредактировал Chudik - Apr 30 2006, 18:05
Go to the top of the page
 
+Quote Post
DS
сообщение Apr 30 2006, 18:24
Сообщение #19


Гуру
******

Группа: СуперМодераторы
Сообщений: 3 096
Регистрация: 16-01-06
Из: Москва
Пользователь №: 13 250



А как Вы думаете, что построится по Вашим IF ? Это и будет приоритетный шифратор. Собрать 16 входов физически нельзя, и поскольку компилятор не понимает сущности задачи, он его нарежет произволльным образом и либо вентилей получится больше чем надо, либо логических уровней.А скорее всего вообще будет построен коммутатор на 32 входа, который вектора от 0 до 31 на выход пропускает.

Лучше об этом самому подумать. А то потом возникает удивление, почему в микросхеме площади не хватает.


--------------------
Не бойтесь тюрьмы, не бойтесь сумы, не бойтесь мора и глада, а бойтесь единственно только того, кто скажет - "Я знаю как надо". А. Галич.
Go to the top of the page
 
+Quote Post
Gate
сообщение Apr 30 2006, 18:24
Сообщение #20


Знающий
****

Группа: Свой
Сообщений: 859
Регистрация: 7-04-05
Из: Санкт-Петербург
Пользователь №: 3 943



Цитата(Chudik @ Apr 30 2006, 22:02) *
Я тоже, почитав ответы, пришёл к выводу об использовании XOR. Можно каскадированием, как предложил DS_, но при этом, имхо, это будет последовательное сравнение, т.е. тратим время.
Я бы, возможно, сделал примерно так:

Код
if (!(^data[31:0])) cnt = 31;
else if (!(^data[31:1])) cnt = 30;
else if (!(^data[31:2])) cnt = 29;
...
else if (!(^data[31:30])) cnt = 1;
else cnt=0


или, если хочется короче:
Код
   for(i=0; i<32; i=i+1)
       if(!(^data[31:i])
          begin
               cnt = 31 - i;
               break;
          end


всё это, естественно, под always @(data)

Код неверен, т.к. поразрядный ксор будет выдавать парити.


--------------------
"Человек - это существо, которое охотнее всего рассуждает о том, в чем меньше всего разбирается." (с) С.Лем
Go to the top of the page
 
+Quote Post
glock17
сообщение May 1 2006, 00:58
Сообщение #21


Частый гость
**

Группа: Свой
Сообщений: 163
Регистрация: 3-09-04
Пользователь №: 586



Всем откликнувшимся - большое спасибо!
Проблема на предварительном уровне решена.
Докладываю результаты проверки smile.gif :
- конструкция, предложенная sazh, заработала без проблем, так что беру её на карандашик (sazh, отдельное спасибо)
- кроме того, есть собственный вариант (после отладки опубликую).
- все остальные варианты пока досконально не ковырял (я пишу "досконально", потому что сразу они не заработали, каждый нуждается в доделках (на что пока не было времени), хотя идеи практически везде правильные). Единственное замечание из личного опыта: использование конструкции while допустимо при создании функционального кода, при синтезе лучше такой конструкции избегать, так как часто это выливается в неоправданное расходование ресурсов.

Окончательный вариант пока не выбран, точку в этом деле поставим после синтеза (жду, когда заработает FTP, что бы сразу использовать синтезатор, указанный заказчиком). Вариант sazh намного компактнее нашего по коду, однако насчет компактности при синтезе я пока не уверен.

Тем не менее, тема пока не закрыта, поэтому дальнейшие предложения приветствуются.

Еще раз спасибо всем участникам дискуссии. a14.gif
Go to the top of the page
 
+Quote Post
Chudik
сообщение May 1 2006, 01:10
Сообщение #22


Частый гость
**

Группа: Свой
Сообщений: 197
Регистрация: 31-03-06
Пользователь №: 15 676



Цитата(DS_ @ Apr 30 2006, 11:24) *
А как Вы думаете, что построится по Вашим IF ? Это и будет приоритетный шифратор.
Лучше об этом самому подумать. А то потом возникает удивление, почему в микросхеме площади не хватает.

Да я как-то и не спорю с этим wink.gif. Насколько я понимаю, эти IF выродятся именно в то, что я написал чуть выше. Только более короткая форма в программе. Собственно, вопрос в том, что автору топика важнее: время или количечство занимаемого силикона. Если второе, то можно просто сдвигать и счимтать количество одинаковых битов. Если важнее первое, то приоритетный шифратор - вот он smile.gif

Цитата(Gate @ Apr 30 2006, 11:24) *
Код неверен, т.к. поразрядный ксор будет выдавать парити.

Да, пожалуй. Он хорошо работает с лидирущими нулями. С нечётным количеством лидирующих единиц приведёт к неправильному результату. Значит, к сожалению придётся ставить поразрядные & и |. Какая неприятность.... wacko.gif
Go to the top of the page
 
+Quote Post
sazh
сообщение May 2 2006, 06:48
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 2 435
Регистрация: 6-10-04
Из: Петербург
Пользователь №: 804



А разве мой первый вариант это разве не XOR в связке с преоритетным шифратором?. Другое дело : при таком описании синтезатор сумматоры задействовал. так можно и без сумматоров. А можно и с клоком на конвейере. А лучше синтезатора (ручками) приоритетный шифратор все равно не сделаете.
module comp32p
(
input [31:0] in,
output [4:0] out
);


reg temp;
integer temp_a;

integer i;

always @(in) begin
temp=1;
temp_a=31;
for (i=31; i>0; i=i-1) begin
if ((in[31] != in[i-1]) & temp) begin
temp_a = 31-i;
temp = 0;end end
end
assign out = temp_a[4:0];

endmodule
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 20:51
Рейтинг@Mail.ru


Страница сгенерированна за 0.01612 секунд с 7
ELECTRONIX ©2004-2016