tAmega 0 5 сентября, 2010 Опубликовано 5 сентября, 2010 · Жалоба Попробовал на сумматорах, синтезатор выдает 14 уровней логики, и задержку 20.2ns то есть в район. Spartan3, VHDL, ISE. Затем поставил на входе сумматоров 8 ROM на 256x4, а затем три уровня сумматоров , выдало 13 уровней логики и 16.5ns После подумал, а если все сделать на ROM в четыре уровня, 8ROM 256x4 затем 4ROM 256x5 затем 2 ROM 1024x6 и наконец 1ROM 4096x7 В результате синтезатор выдал 5 уровней логики и 10.5 ns, это на Spartan3 (-5) Вполне возможно на быстрой версии Cyclone такой вариант получится на 125MHz, расход на все в районе 8Кb. Проверьте, может ошибаюсь, но должно получиться по моему. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Shtirlits 0 5 сентября, 2010 Опубликовано 5 сентября, 2010 · Жалоба Спасибо, воспользовался поводом запустить quartus. В данном случае трюки для программистов не могут пригодиться никак, просто впустую потраченное время на скачивание, поиск главы и чтение. Подсчет количества уровней логики - тоже тупое занятие, так как время уходит на interconnect. Вопросов по большой счету есть только два: - можно ли задачу обойти двумя-тремя тактами, другой микросхемой или меньшим количеством разрядов ? - сколько входных битов можно обработать одним LAB-ом ? Второй вопрос вызван тоже двумя вопросами, но поменьше: - как засунуть в один LAB два асинхронных двухбитных сумматора с входом carry_in и выходом carry_out ? - можно ли в принципе заставить quartus забить LAB как хочется автору и использовать carry chains ? Без этого больше 120MHz (slow model 85C) не выходит никак, quartus тупит со страшной силой, наверное только терпеливое тыкание его мордой в LogicLock может помочь. Суть подхода такова: - Определяю как действовать на первой стадии. В cyclone3 LUT 4-х входовой, однако, если пытаться подсчитывать количество единиц на 4 входах, то потребуется 3 LUT-а и соотношение количества информации на входе первой стадии и на выходе будет 4/3, так как количество битов с '1' может быть от 0 до 4, что в двоичной записи требует 3 бита. Если использовать LUT3, то для 3-х входов понадобится только 2 LUT-а, для вариантов 0..3 нужно только два бита, то есть соотношение 3/2, что немного лучше первого варианта. Хотя, на все 64-бита в первом случае получится 48 бит, во втором 44. Итого, на первой стадии из троек входов получаются пары битов с количеством единиц. Можно надеяться, что 12 входов одного LAB-а превратятся в 8 сигналов. Займет это преобрахование 8 LUT-ов. - На вторую стадию напрашивается сложение пары двойки битов. Так как сумматор 0..3+0..3 может дать в результате от 0 до 6, остается одно свободное состояние. Эту ситуацию можно исправить, если на вход CARRY сумматора подать еще один исходный сигнал. Каждый сумматор займет 2 LUT-а, старший бит суммы является CARRY_OUT. Мне это сделать пока не удалось, не умею я готовить quartus. Если получится, то к 12 входам добавится еще 2, а на выходе будут те же 2 раза по 3 бита. Займет вторая стадия 4 LUT-а с их CARRY-цепочками. Суммарное соотношение входной информации к выходной заметно улучшится. - Третья стадия имеет полное право поместиться в оставшиеся 4 LUT-а данного LAB-а, хотя мне кажется, что и трёх должно хватить. Итого, на входе 14 битов, на выходе 4 бита содержащих количество единиц. Чтобы этим хозяйством можно было сосчитать 64(70)-бит, понадобится 5 таких блоков и сумматор 5 раз по 4 бита на 4-ом уровне, он и поест все время. Вопрос: как же в исходном тексте в этом quartus-е управлять низкоуровневым синтезом, размещением внутри LAB-а, относительно соседних LAB-ов? Есть ли механизмы для создания макросов, вроде xilinx-овых RLOC? Неужели снова LogicLoc и констрейны?! На практике это безусловно не имеет никакого значения, так как ни инструменты, ни заказчики, ни разработчики в своей массе заточены для других задач. А даже если и заточены, чтобы все заработало как надо, нужны разместить входные и выходные регистры рядом с упомянутой кучкой LUT-ов. Там, где это требование легко выполняется, скорее всего и конвейер можно сделать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexPec 3 6 сентября, 2010 Опубликовано 6 сентября, 2010 · Жалоба ВСЕМ СПАСИБО! Теперь надобно решить, либо хитрить и считать все-таки на 125 МГц, либо логику переделывать. Поже все-таки логику переделывать. Судя по Вашим оценкам экспертов, если и будет на 125МГц работать, то с натягом, сильным, и ресурсов это как-то много займет. А мне как-то не нравится, когда с натягом работает. Я спокоен только когда 1,5 кратный запас . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SergeyF 0 8 сентября, 2010 Опубликовано 8 сентября, 2010 · Жалоба Судя по Вашим оценкам экспертов, если и будет на 125МГц работать, то с натягом, сильным, и ресурсов это как-то много займет. А мне как-то не нравится, когда с натягом работает. Я спокоен только когда 1,5 кратный запас . Вам же дали ссылки. Первая ссылка немного о другом, там поиск лидирующей единицы, а вторая как раз в тему. Там много вариантов. alexPec, уважаемый des00 был как всегда точен, тем было несколько, ищутся легко, вот пара на вскидку: Сумма единиц Есть ли стандартная функция Я из интереса проделал аналогичный эксперимент с CycloneIII. На медленной модели при 85С получилась частота 143,5МГц. По-моему, достаточный запас. И сама схема занимает всего 119 логических элементов (не учитывая входные регистры, без которых не посчитать тактовую частоту). module cnt64(clk,rst,din,cnt); input clk,rst; input [63:0] din; output reg [6:0] cnt; reg [63:0] dreg; reg [6:0] comb_cnt; wire [2:0] s[15:0]; reg [3:0] s0[7:0]; reg [4:0] s1[3:0]; reg [5:0] s2[1:0]; //ones in four bits function [2:0] cnt8; input [3:0] din; integer i; begin cnt8=0; for(i=0; i<=3; i=i+1) if (din[i]) cnt8=cnt8+1; end endfunction //registers always @(posedge clk or negedge rst) begin if (!rst) begin cnt<=0; dreg<=0; end else begin cnt<=comb_cnt; dreg<=din; end end //adder tree always @(*) begin //first level s0[0]=s[0]+s[1]; s0[1]=s[2]+s[3]; s0[2]=s[4]+s[5]; s0[3]=s[6]+s[7]; s0[4]=s[8]+s[9]; s0[5]=s[10]+s[11]; s0[6]=s[12]+s[13]; s0[7]=s[14]+s[15]; //second level s1[0]=s0[0]+s0[1]; s1[1]=s0[2]+s0[3]; s1[2]=s0[4]+s0[5]; s1[3]=s0[6]+s0[7]; //third level s2[0]=s1[0]+s1[1]; s2[1]=s1[2]+s1[3]; //fourth level comb_cnt=s2[0]+s2[1]; end //preadders genvar j; generate for(j=0; j<=15; j=j+1) begin : os assign s[j]=cnt8(dreg[j*4+:4]); end endgenerate endmodule P.S. При включении Fitter effort = Standard получается 156МГц, а при задействовании входных переносов в дереве сумматоров (как предложено в указанной выше теме) и избавления, таким образом, от одного сумматора первого уровня, комбинаторика получается еще на 7 элементов меньше и частота поднимается до 159МГц. Можно и дальше оптимизировать и искать варианты, но требования и так выполняются с запасом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Des333 0 9 сентября, 2010 Опубликовано 9 сентября, 2010 · Жалоба ...Я из интереса проделал аналогичный эксперимент с CycloneIII. На медленной модели при 85С получилась частота 143,5МГц. По-моему, достаточный запас... Так Вы проверяете на C6, а автор просил на С8. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SergeyF 0 9 сентября, 2010 Опубликовано 9 сентября, 2010 · Жалоба Так Вы проверяете на C6, а автор просил на С8. :) Вроде как сначала были неопровергнутые сомнения, что получится и на быстрой градации. :) На 6 и 7 градации получается. На EP3C5 даже на 8 градации модификация с разбросом 8 бит из 64-х по входам переноса в дереве сумматоров укладывается в 125МГц. Можно и дальше поколдовать с архитектурой и попробовать выжать на больших микросхемах. Но разница в стоимости между 7 и 8 градацией меня в данном случае не мотивирует. :) Могу лишь добавить в ответ на сомнения автора темы, что если Таймквест говорит, что в худшем случае на максимальной температуре будет работать, то работать будет и полуторакратный запас по частоте совсем ни к чему. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tAmega 0 10 сентября, 2010 Опубликовано 10 сентября, 2010 · Жалоба Все что я выше написал про реализацию на ROM оказалось полной чушью, прошу прощения у автора топика. Но зато попробовал изменить код представленный Sergey'F Загнал вышеприведенный код суммирования на Verilog, вот что выдал Synplify 9.6 (установки по умолчанию, я в нем не слишком пока ориентируюсь) EP3C5, FC256, -6 Requested Estimated Requested Estimated Clock Clock Starting Clock Frequency Frequency Period Period Slack Type Group ------------------------------------------------------------------------------------------------------------------------ cnt64|clk 160.6 MHz 136.5 MHz 6.227 7.325 -1.099 inferred Autoconstr_clkgroup_0 ================================================================================ То есть на -6 выдает частоту 136.5 MHz А затем я решил, просуммировать 64 единицы и выкинуть все массивы из кода вообще. В результате получились вот такие результаты (установки те же) EP3C5, FC256, -8 Requested Estimated Requested Estimated Clock Clock Starting Clock Frequency Frequency Period Period Slack Type Group ------------------------------------------------------------------------------------------------------------------------ top|clk 178.7 MHz 151.9 MHz 5.596 6.584 -0.988 inferred Autoconstr_clkgroup_0 =========================================================================== EP3C5, FC256, -6 Requested Estimated Requested Estimated Clock Clock Starting Clock Frequency Frequency Period Period Slack Type Group ------------------------------------------------------------------------------------------------------------------------ top|clk 237.7 MHz 202.1 MHz 4.206 4.949 -0.742 inferred Autoconstr_clkgroup_0 =========================================================================== На версии -8 влезаем в 150MHz, а на -6 можно работать до 200MHz Вот код на VHDL library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity top is port ( clk,rst : in std_logic; di : in std_logic_vector(63 downto 0); q : out std_logic_vector(6 downto 0) ); end top; architecture rtl of top is component add2 is port ( d : in std_logic_vector(63 downto 0); q : out std_logic_vector(6 downto 0)); end component; signal sdat : std_logic_vector (6 downto 0);--sdat_array; signal dreq : std_logic_vector (63 downto 0); begin ADD_21: add2 port map( d=>dreq, q=>sdat); process(clk) begin if(clk='1' and clk'event) then if(rst = '1') then dreq <= (others=>'0'); q <= (others=>'0'); else dreq <= di; q <= sdat;--comb_cnt; end if; end if; end process; end rtl; -- add 4-to-cnt8 preadder library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity add2 is port ( d : in std_logic_vector(63 downto 0); q : out std_logic_vector(6 downto 0)); end add2; architecture rtl of add2 is begin q <= conv_std_logic_vector( conv_integer(d(63)) + conv_integer(d(62)) + conv_integer(d(61)) + conv_integer(d(60)) + conv_integer(d(59)) + conv_integer(d(58)) + conv_integer(d(57)) + conv_integer(d(56)) + conv_integer(d(55)) + conv_integer(d(54)) + conv_integer(d(53)) + conv_integer(d(52)) + conv_integer(d(51)) + conv_integer(d(50)) + conv_integer(d(49)) + conv_integer(d(48)) + conv_integer(d(47)) + conv_integer(d(46)) + conv_integer(d(45)) + conv_integer(d(44)) + conv_integer(d(43)) + conv_integer(d(42)) + conv_integer(d(41)) + conv_integer(d(40)) + conv_integer(d(39)) + conv_integer(d(38)) + conv_integer(d(37)) + conv_integer(d(36)) + conv_integer(d(35)) + conv_integer(d(34)) + conv_integer(d(33)) + conv_integer(d(32)) + conv_integer(d(31)) + conv_integer(d(30)) + conv_integer(d(29)) + conv_integer(d(28)) + conv_integer(d(27)) + conv_integer(d(26)) + conv_integer(d(25)) + conv_integer(d(24)) + conv_integer(d(23)) + conv_integer(d(22)) + conv_integer(d(21)) + conv_integer(d(20)) + conv_integer(d(19)) + conv_integer(d(18)) + conv_integer(d(17)) + conv_integer(d(16)) + conv_integer(d(15)) + conv_integer(d(14)) + conv_integer(d(13)) + conv_integer(d(12)) + conv_integer(d(11)) + conv_integer(d(10)) + conv_integer(d(9)) + conv_integer(d(8)) + conv_integer(d(7)) + conv_integer(d(6)) + conv_integer(d(5)) + conv_integer(d(4)) + conv_integer(d(3)) + conv_integer(d(2)) + conv_integer(d(1)) + conv_integer(d(0)),7); end rtl; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Shtirlits 0 10 сентября, 2010 Опубликовано 10 сентября, 2010 · Жалоба А что говорит TimeQuest после размещения и разводки? Уверен, что на этой задаче Synplify выдает желаемое за действительное, половину времени сожрет интерконнект. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tAmega 0 10 сентября, 2010 Опубликовано 10 сентября, 2010 · Жалоба У меня нет Квартуса и возможности пока поставить нет. Согласен, Synplify тут возможно горячится. В ISE на Spartan3 лучшие результаты показывает дизайн где в preadder первые 4 бита вот так, как выше через конверсию целых чисел, а затем массивы. Для Cyclone надо смотреть, но путь оптимизации мне например ясен, подменять массивы сумматорами с входа по 4 или 8 или 16 бит, а остальное массивами. Какой из них покажет лучшие результаты тот и брать. Как поставлю Квартус, выложу свои результаты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Des333 0 10 сентября, 2010 Опубликовано 10 сентября, 2010 · Жалоба А что говорит TimeQuest после размещения и разводки? Уверен, что на этой задаче Synplify выдает желаемое за действительное, половину времени сожрет интерконнект. Если этот код скомпилить в Quartus'е, то для C8 получаем 78 МГц. :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tAmega 0 10 сентября, 2010 Опубликовано 10 сентября, 2010 · Жалоба Да, уж облажался я, так облажался :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Shtirlits 0 10 сентября, 2010 Опубликовано 10 сентября, 2010 · Жалоба Задача далеко за рамками обычного промышленного синтеза. Без учета архитектуры ячейки и интерконнекта получить результаты немногим лучше 100MHz трудно. Без использования архитектуро-зависимых примитивов больше 119 MHz получить не выходит, хотя есть ощущение, что quartus просто дурачится и можно сделать лучше. Описывать обычным языком VHDL или verilog и надеяться на хороший синтез не приходится, так как должен получиться вполне конкретный результат, а синтезатор не говорит, что именно программист сделал не так и почему синтезировалось так, а не эдак. Например, quartus сообщает, что проигнорировал буфер carry_sum, lut_output или cascade, но не говорит почему. Главное, как я считаю, заставить один LAB обрабатывать побольше входных сигналов, так как быстрый интерконнект LAB-а очень полезен, а забитый под завязку LAB по определению быстрее нескольких полупустых. Научите меня контролировать размещение LUT-ов в LAB-е и принудительно соединять LUT-ы через carry цепочки. Без этого не получается использовать ресурсы микросхемы для этой задачи. У Зайлингс в таких случаях задача решается применением низкоуровневых примитивов и атрибутов RLOC для указания относительного размещения ячеек. И хотя я сердцем больше люблю Альтеру, работаю чаще с Зайлингс. Так вот синтезатор последнего XST не пытается игнорировать мои команды, а если они противоречат возможностям микросхемы, то их не игнорирует, а останавливает синтез с внятным сообщением. Мои изыскания закончились следующим: 1) для кодирования количества единиц на N входах нужно log2(N+1) бит, так как считать нужно с нуля до N. Казалось бы, чем больше входов у LUT-а, тем выгоднее, но 4-х входовые LUT-ы оказываются совсем некудышными. 3 LUT-а на 4 входа и из 8-ми состояний только 5 полезных. Если применить 3-х входовые LUT-ы, то потребуется 2 LUT-а на 3 входа. А если учесть, что один 4-х входовой LUT в арифметическом режиме превращается в 2 LUT3, то и совсем интересно выходит. Все хорошо, если не учесть, что один из выходов - это CARRY ведущий вниз и только второй выход идет на быстрый интерконнект LAB-а и наружу. 2) Ну и замечательно, пусть один из выходов будет carry_out, его мы можем использовать в качестве carry_in младшего бита сумматора. Второй выход LUT-ов нижнего уровня подать на второй бит этого сумматора. Итого, получается 3 LUT-а на 5 входов. Не очень густо, но лучше, чем на 4. Старший бит результата выходит на carry, что с одной стороны плохо, а с другой полезно. Если ниже расположен младший бит сумматора следующего уровня, то полезно. 3) Выходы сумматоров первого уровня попадают на сумматоры второго уровня, у которых тоже есть пустой вход carry_in. На него можно подать дополнительный входной сигнал. То есть, если на нижнем уровне суммируется 5 сигналов, то на следующем 5+5+1=11. На втором уровне 11+11+1=23, и т.д. В общем, идею можно развить, вылизать и реализовать, но это требует усилий, в основном по борьбе с синтезатором и mapper-ом. Кстати, подозреваю, что использование synplify или другого синтезатора поможет для получения netlist с необходимыми буферами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SergeyF 0 10 сентября, 2010 Опубликовано 10 сентября, 2010 · Жалоба Задача далеко за рамками обычного промышленного синтеза. Без учета архитектуры ячейки и интерконнекта получить результаты немногим лучше 100MHz трудно. Ну это уже не смешно. Извините, Вы то, что я выше написал, читали? Повторюсь: QII 9.1, Таймквест, медленная модель, 85С. На любом Cyclone III градации 6 и 7, что я пробовал, укладывается в 125МГц. Код с разбрасыванием 8 бит из 64 по входам дерева сумматоров приводить не буду - это тривиально. Он ненамного быстрее того, что я привел. Самое быстрое, что я получил на нем - 159МГц. Это не значит, что нельзя сделать лучше - просто дальше нет интереса идти. И никаких LogicLock, архитектурно зависимых примитивов и т.д.. Чем и хороша Altera по сравнению с некоторыми другими производителями. :) По поводу идей: Четырехвходовые LUT на первом уровне как раз очень подходят. В отличие от предлагаемых Вами трехвходовых, они уменьшают глубину дерева сумматоров на один уровень и сами обрабатывают 4 бита в один слой логики, без переносов, которые, хоть и быстрые, но вносят задержку. Замечу, что синтезатор все синтезирует как написано без всяких примитивов - на первом уровне под каждую группу из 4 бит по 3 LUT, а далее складываем 16 (в случае с разбросом 8 бит - 14) таких сумм на 4 уровнях сумматоров. Кстати, если не разбрасывать, он очень четко делает первый уровень в нормальном режиме, а все следующие с цепями переноса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Des333 0 10 сентября, 2010 Опубликовано 10 сентября, 2010 · Жалоба У меня за мои суммарные час попыток на С8 выжать 125 МГц так и не удалось. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SergeyF 0 10 сентября, 2010 Опубликовано 10 сентября, 2010 · Жалоба У меня за мои суммарные час попыток на С8 выжать 125 МГц так и не удалось. :) Вот проект :). Компилировался в 9.1 без SP. cnt64.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться