sazh 8 6 апреля, 2010 Опубликовано 6 апреля, 2010 · Жалоба У меня есть нечто подобное на AHDL, мне нравится. Попробуйте еще на макросах типа 74163 с трюковыми входами. Каскадировать можно до бесконечности. Еще круче будет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 6 апреля, 2010 Опубликовано 6 апреля, 2010 · Жалоба Попробуйте еще на макросах типа 74163 с трюковыми входами. Каскадировать можно до бесконечности. Еще круче будет. Это - шутка? Гляньте, какая таблица истинности вышла: CI SI SO CO 0 0 0 0 0 1 1 0 1 0 0 1 1 1 1 1 т.е., CO повторяет CI, SO повторяет SI :) :) :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Builder 1 6 апреля, 2010 Опубликовано 6 апреля, 2010 · Жалоба Это - шутка? Да, я думаю это была шутка. Вы по моему занимаетесь пустой работой, главное - результат. Т.е. описываете задачу, описываете сколько нужно по времянке и всё. Я тоже помню, что в старые времена красиво было смотреть как софт на раскладке рисовал цепочки переносов, видно было где счётчики. Но как-то последнее время на это уже не обращаешь внимание: временка и ресурсы устраивают и ладненько. А в последнее время как-то всёравно стало, как оно там, пока не прижмёт. Да, что-то мне подсказывает, что такие примитивы как счётчик крайне редко получится сделать оптимальнее чем в LPM модулях сделано, времени потратите больше чем экономии будет, если будет экономия... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 6 апреля, 2010 Опубликовано 6 апреля, 2010 · Жалоба Да, я думаю это была шутка. Вы по моему занимаетесь пустой работой, главное - результат. Я думаю, работа редко бывает впустую. Вот, мы узнали, что CARRY_SUM это просто два повторителя (наверное). Счетчик, "выстроенный в шеренгу", имеет регулярную структуру, предсказуемое быстродействие, близкое к предельному, не зависимые от переукладки проекта. С вашего позволения, я еще немного "потрахаюсь". Если будет результат, доложу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 7 апреля, 2010 Опубликовано 7 апреля, 2010 · Жалоба Но не получаю желаемого (см. картинку). Где-то промахнулся. Поможите, люди добрые! что то счетчиком не пахнет %) тогда как в лоб видно что ква использует lpm_counter для данной архитектуры Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 7 апреля, 2010 Опубликовано 7 апреля, 2010 · Жалоба что то счетчиком не пахнет %) Не пахнет, потому что CARRY_SUM - это просто две цепи, одна ведет через мультиплексоры загрузки, синхронного сброса (зависит от архитектуры ПЛИС) к триггеру или еще куда подальше..., а вторая - цепь переноса, ведет ко входу переноса следующего ЛЭ. А не сумматор, как можно было бы подумать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 7 апреля, 2010 Опубликовано 7 апреля, 2010 · Жалоба Не пахнет, потому что CARRY_SUM - это просто две цепи, одна ведет через мультиплексоры загрузки, синхронного сброса (зависит от архитектуры ПЛИС) к триггеру, а вторая - цепь переноса, ведет ко входу переноса следующего ЛЭ. А не сумматор, как можно было бы подумать. а не пахнет потому что 1. это Technology Viewer: 2. вывод Pout не подключен к счетному выводу, как задумывалось, а сиди тупо на VCC 3. логика каждого бита порта Count не зависит от других битов, а зависит только от сигналов enable, reset_n, clock и своего собственного значения. Как ЭТО может быть счетчиком, в котором, при любом способе построения, старшие биты зависят от младших ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bogaev_roman 0 7 апреля, 2010 Опубликовано 7 апреля, 2010 · Жалоба Самый идеальный вариант - использовать мегафункцию, она специально заточена под структуру плисины. При написании а ля counter<=counter+1 после синтеза квартус делает сумматор, который оптимизирует далее до счетчика и который проигрывает первоначальному варианту по быстродействию (немного, издержки фиттера). Если делать на вентильном уровне, то квартус придет к тому же варианту что и с мегафункцией :) (проверял на небольшой разрядности). Если хотите, чтоб на флурплане было все в линеечку и максимально упаковано, то используйте мегафункцию (чтоб при фиттере в большом проекте не размазал, ограничте область). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 7 апреля, 2010 Опубликовано 7 апреля, 2010 · Жалоба Объясняю, что хотел сделать. Вот образец на AHDL. Для ACEX счетчик выстраивается ровненько, с цепями переноса из разряда в разряд и триггерами в тех же ЛЭ. Для Cyclone - уже нет. Хочу сделать подобное на Verilog. Title "Counter with Syncronous Reset"; %-- Library 2005 ViKo -------------------------- Counter with syncronous enable, load, reset direction - increment (default) or decrement carry-out - asyncronous, can be triggered outside Нельзя использовать слишком много индивидуальных загрузок и сбросов - не удастся разложить, не хватит каналов, можно вылететь из-за ошибки. Но можно использовать несколько сигналов для групп. %----------------------------------------------- Parameters ( Wid = 8, -- counter width Dir = "up" -- "down" or "up" ); ------------------------------------------------ Subdesign ViKoCount ( Clk : input; -- Clock Ena : input = Vcc; -- Enable (input_pulse) Dat[Wid-1..0] : input = Gnd; -- Data for load nLd[Wid-1..0] : input = Vcc; -- /Load nRes[Wid-1..0] : input = Vcc; -- /Reset Q[Wid-1..0] : output; -- Outputs P : output; -- Carry output ) ------------------------------------------------ Variable Ct[Wid-1..0] : dff; -- Counter cells Cy[Wid-1..0] : carry; -- Carry nodes ------------------------------------------------ Begin Ct[].clk = Clk; Ct0.d = ((Ct0 $ Ena) & nLd0 # Dat0 & !nLd0) & nRes0; if Dir == "down" generate Cy0 = !Ct0; -- & nRes0; else generate Cy0 = Ct0; -- & nRes0; end generate; for i in 1 to Wid-1 generate Ct[i].d = ((Ct[i] $ (Cy[i-1] & Ena)) & nLd[i] # Dat[i] & !nLd[i]) & nRes[i]; if Dir == "down" generate Cy[i] = !Ct[i] & Cy[i-1]; -- & nRes[i]; else generate Cy[i] = Ct[i] & Cy[i-1]; -- & nRes[i]; end generate; end generate; Q[] = Ct[]; P = Cy[Wid-1]; -- Out with glitch End; Самый идеальный вариант - использовать мегафункцию, она специально заточена под структуру плисины. ... Согласен. Попробую и это обязательно. Вот такой код работает. Но это только "полуфабрикат". module CountPrim #(parameter WIDTH = 4) ( input Reset_n, Clock, Enable, output [WIDTH-1:0] Count, output POut, input Down ); wire [WIDTH-1:0] Fb; // feedback wire [WIDTH-1:0] Lt; // lookUp table wire [WIDTH-1:0] Cr; // carry out CARRY_SUM Cy0 (.sin(!Fb[0]), .cin(Fb[0] ^ Down), .sout(Lt[0]), .cout(Cr[0])); DFFE Ff0 (.d(Lt[0]), .clk(Clock), .clrn(Reset_n), .prn(1), .ena(Enable), .q(Fb[0])); CARRY_SUM Cy1 (.sin(Fb[1] ^ Cr[0]), .cin((Fb[1] ^ Down) & Cr[0] ), .sout(Lt[1]), .cout(Cr[1])); DFFE Ff1 (.d(Lt[1]), .clk(Clock), .clrn(Reset_n), .prn(1), .ena(Enable), .q(Fb[1])); CARRY_SUM Cy2 (.sin(Fb[2] ^ Cr[1]), .cin((Fb[2] ^ Down) & Cr[1]), .sout(Lt[2]), .cout(Cr[2])); DFFE Ff2 (.d(Lt[2]), .clk(Clock), .clrn(Reset_n), .prn(1), .ena(Enable), .q(Fb[2])); CARRY_SUM Cy3 (.sin(Fb[3] ^ Cr[2]), .cin((Fb[3] ^ Down) & Cr[2]), .sout(Lt[3]), .cout(Cr[3])); DFFE Ff3 (.d(Lt[3]), .clk(Clock), .clrn(Reset_n), .prn(1), .ena(Enable), .q(Fb[3])); assign Count = Fb; assign POut = Cr[3]; endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 7 апреля, 2010 Опубликовано 7 апреля, 2010 · Жалоба По совету участников обратился к мегафункции LPM_COUNTER, с помощью Визарда создал Verilog модуль, который можно вставлять в свой проект, причем, кое-что можно и менять, например, разрядность. Раскладывается, как положено, быстродействие отличное. Большего мне не надо. Вот он какой, модуль. module MWLPM_Counter ( aclr, clk_en, clock, cnt_en, data, sload, cout, q); input aclr; input clk_en; input clock; input cnt_en; input [23:0] data; input sload; output cout; output [23:0] q; wire sub_wire0; wire [23:0] sub_wire1; wire cout = sub_wire0; wire [23:0] q = sub_wire1[7:0]; lpm_counter lpm_counter_component ( .sload (sload), .clk_en (clk_en), .aclr (aclr), .clock (clock), .data (data), .cnt_en (cnt_en), .cout (sub_wire0), .q (sub_wire1), .aload (1'b0), .aset (1'b0), .cin (1'b1), .eq (), .sclr (1'b0), .sset (1'b0), .updown (1'b1)); defparam lpm_counter_component.lpm_direction = "UP", lpm_counter_component.lpm_port_updown = "PORT_UNUSED", lpm_counter_component.lpm_type = "LPM_COUNTER", lpm_counter_component.lpm_width = 24; endmodule Обращается к lpm_counter. А тот представляет собой AHDL файл, который, я, собственно, и пытался "изобрести". Вывод такой - если хочешь качества - используй LPM, если все равно - пиши по-простому, на Verilog. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 65 8 апреля, 2010 Опубликовано 8 апреля, 2010 · Жалоба Вывод такой - если хочешь качества - используй LPM, если все равно - пиши по-простому, на Verilog. module slon ( input clk, output bit [63:0] cnt ); always_ff @(posedge clk) begin cnt <= cnt + 1; end endmodule Floorplan: Одна из ячеек (любая): Что я делаю не так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Builder 1 8 апреля, 2010 Опубликовано 8 апреля, 2010 · Жалоба Обращается к lpm_counter. А тот представляет собой AHDL файл, который, я, собственно, и пытался "изобрести". Вывод такой - если хочешь качества - используй LPM, если все равно - пиши по-простому, на Verilog. Во-во, и более того, обычно достаточно просто написать: a=a+1; и квартус автоматически подключит LPM. Единственный случай. который прихдит на ум, когда есть смысл попробовать ручками подключать, если сумматор по логике сложится с другой логике, и результат не ляжет на LPM. Но я например к таким экспериментам прихожу если не выполняются констрейны. Так что не придумываете себе забот лишних, больше чем их есть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 8 8 апреля, 2010 Опубликовано 8 апреля, 2010 · Жалоба Во-во, и более того, обычно достаточно просто написать: a=a+1; и квартус автоматически подключит LPM. LPM counter он только на ацексе подключает. Последний квартус его уже не поддерживает. У ацекса одна судьба - пакет max+II Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 8 апреля, 2010 Опубликовано 8 апреля, 2010 · Жалоба LPM counter он только на ацексе подключает. Последний квартус его уже не поддерживает. У ацекса одна судьба - пакет max+II Не знаю, как последний, а Quartus 9.0 тот модуль, что я показал, скушал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 8 апреля, 2010 Опубликовано 8 апреля, 2010 · Жалоба Что я делаю не так? теперь еще добавить alcr, clk_ena, sload, cnt_en как в сабжевом примере и посмотреть. очень занятные вещи видятся для разных семейств (причины уже обсуждали на этом форуме) %) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться