sazh 9 April 6, 2010 Posted April 6, 2010 · Report post У меня есть нечто подобное на AHDL, мне нравится. Попробуйте еще на макросах типа 74163 с трюковыми входами. Каскадировать можно до бесконечности. Еще круче будет. Quote Share this post Link to post Share on other sites More sharing options...
ViKo 1 April 6, 2010 Posted April 6, 2010 · Report post Попробуйте еще на макросах типа 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 :) :) :) Quote Share this post Link to post Share on other sites More sharing options...
Builder 1 April 6, 2010 Posted April 6, 2010 · Report post Это - шутка? Да, я думаю это была шутка. Вы по моему занимаетесь пустой работой, главное - результат. Т.е. описываете задачу, описываете сколько нужно по времянке и всё. Я тоже помню, что в старые времена красиво было смотреть как софт на раскладке рисовал цепочки переносов, видно было где счётчики. Но как-то последнее время на это уже не обращаешь внимание: временка и ресурсы устраивают и ладненько. А в последнее время как-то всёравно стало, как оно там, пока не прижмёт. Да, что-то мне подсказывает, что такие примитивы как счётчик крайне редко получится сделать оптимальнее чем в LPM модулях сделано, времени потратите больше чем экономии будет, если будет экономия... Quote Share this post Link to post Share on other sites More sharing options...
ViKo 1 April 6, 2010 Posted April 6, 2010 · Report post Да, я думаю это была шутка. Вы по моему занимаетесь пустой работой, главное - результат. Я думаю, работа редко бывает впустую. Вот, мы узнали, что CARRY_SUM это просто два повторителя (наверное). Счетчик, "выстроенный в шеренгу", имеет регулярную структуру, предсказуемое быстродействие, близкое к предельному, не зависимые от переукладки проекта. С вашего позволения, я еще немного "потрахаюсь". Если будет результат, доложу. Quote Share this post Link to post Share on other sites More sharing options...
des00 26 April 7, 2010 Posted April 7, 2010 · Report post Но не получаю желаемого (см. картинку). Где-то промахнулся. Поможите, люди добрые! что то счетчиком не пахнет %) тогда как в лоб видно что ква использует lpm_counter для данной архитектуры Quote Share this post Link to post Share on other sites More sharing options...
ViKo 1 April 7, 2010 Posted April 7, 2010 · Report post что то счетчиком не пахнет %) Не пахнет, потому что CARRY_SUM - это просто две цепи, одна ведет через мультиплексоры загрузки, синхронного сброса (зависит от архитектуры ПЛИС) к триггеру или еще куда подальше..., а вторая - цепь переноса, ведет ко входу переноса следующего ЛЭ. А не сумматор, как можно было бы подумать. Quote Share this post Link to post Share on other sites More sharing options...
des00 26 April 7, 2010 Posted April 7, 2010 · Report post Не пахнет, потому что CARRY_SUM - это просто две цепи, одна ведет через мультиплексоры загрузки, синхронного сброса (зависит от архитектуры ПЛИС) к триггеру, а вторая - цепь переноса, ведет ко входу переноса следующего ЛЭ. А не сумматор, как можно было бы подумать. а не пахнет потому что 1. это Technology Viewer: 2. вывод Pout не подключен к счетному выводу, как задумывалось, а сиди тупо на VCC 3. логика каждого бита порта Count не зависит от других битов, а зависит только от сигналов enable, reset_n, clock и своего собственного значения. Как ЭТО может быть счетчиком, в котором, при любом способе построения, старшие биты зависят от младших ? Quote Share this post Link to post Share on other sites More sharing options...
bogaev_roman 0 April 7, 2010 Posted April 7, 2010 · Report post Самый идеальный вариант - использовать мегафункцию, она специально заточена под структуру плисины. При написании а ля counter<=counter+1 после синтеза квартус делает сумматор, который оптимизирует далее до счетчика и который проигрывает первоначальному варианту по быстродействию (немного, издержки фиттера). Если делать на вентильном уровне, то квартус придет к тому же варианту что и с мегафункцией :) (проверял на небольшой разрядности). Если хотите, чтоб на флурплане было все в линеечку и максимально упаковано, то используйте мегафункцию (чтоб при фиттере в большом проекте не размазал, ограничте область). Quote Share this post Link to post Share on other sites More sharing options...
ViKo 1 April 7, 2010 Posted April 7, 2010 · Report post Объясняю, что хотел сделать. Вот образец на 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 Quote Share this post Link to post Share on other sites More sharing options...
ViKo 1 April 7, 2010 Posted April 7, 2010 · Report post По совету участников обратился к мегафункции 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. Quote Share this post Link to post Share on other sites More sharing options...
dxp 112 April 8, 2010 Posted April 8, 2010 · Report post Вывод такой - если хочешь качества - используй LPM, если все равно - пиши по-простому, на Verilog. module slon ( input clk, output bit [63:0] cnt ); always_ff @(posedge clk) begin cnt <= cnt + 1; end endmodule Floorplan: Одна из ячеек (любая): Что я делаю не так? Quote Share this post Link to post Share on other sites More sharing options...
Builder 1 April 8, 2010 Posted April 8, 2010 · Report post Обращается к lpm_counter. А тот представляет собой AHDL файл, который, я, собственно, и пытался "изобрести". Вывод такой - если хочешь качества - используй LPM, если все равно - пиши по-простому, на Verilog. Во-во, и более того, обычно достаточно просто написать: a=a+1; и квартус автоматически подключит LPM. Единственный случай. который прихдит на ум, когда есть смысл попробовать ручками подключать, если сумматор по логике сложится с другой логике, и результат не ляжет на LPM. Но я например к таким экспериментам прихожу если не выполняются констрейны. Так что не придумываете себе забот лишних, больше чем их есть. Quote Share this post Link to post Share on other sites More sharing options...
sazh 9 April 8, 2010 Posted April 8, 2010 · Report post Во-во, и более того, обычно достаточно просто написать: a=a+1; и квартус автоматически подключит LPM. LPM counter он только на ацексе подключает. Последний квартус его уже не поддерживает. У ацекса одна судьба - пакет max+II Quote Share this post Link to post Share on other sites More sharing options...
ViKo 1 April 8, 2010 Posted April 8, 2010 · Report post LPM counter он только на ацексе подключает. Последний квартус его уже не поддерживает. У ацекса одна судьба - пакет max+II Не знаю, как последний, а Quartus 9.0 тот модуль, что я показал, скушал. Quote Share this post Link to post Share on other sites More sharing options...
des00 26 April 8, 2010 Posted April 8, 2010 · Report post Что я делаю не так? теперь еще добавить alcr, clk_ena, sload, cnt_en как в сабжевом примере и посмотреть. очень занятные вещи видятся для разных семейств (причины уже обсуждали на этом форуме) %) Quote Share this post Link to post Share on other sites More sharing options...