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

 
 
5 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Счетчик на примитивах CARRY_SUM и DFFE
ViKo
сообщение Apr 6 2010, 12:09
Сообщение #1


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Quartus 9.0, Altera ACEX 1K. Пытаюсь создать счетчик, чтобы укладывался компактно в логические элементы. Для начала - фиксированного размера (с generate - свои проблемы). Как-то так:
Код
module CountPrim
#(parameter WIDTH = 4)
  (
  input Reset_n, Clock, Enable,
  output [WIDTH-1:0] Count,
  output POut
  );

  wire [WIDTH-1:0] Fb;    // feedback
  wire [WIDTH-1:0] Lt;    // look table
  wire [WIDTH-1:0] Cr;    // carry out

  CARRY_SUM Cy0 (.sin(Fb[0]), .cin(1),
        .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]), .cin(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]), .cin(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]), .cin(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

Но не получаю желаемого (см. картинку). Где-то промахнулся. Поможите, люди добрые!
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
Maverick
сообщение Apr 6 2010, 12:35
Сообщение #2


я только учусь...
******

Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839



Цитата(ViKo @ Apr 6 2010, 15:09) *
Quartus 9.0, Altera ACEX 1K. Пытаюсь создать счетчик, чтобы укладывался компактно в логические элементы. Для начала - фиксированного размера (с generate - свои проблемы).
Но не получаю желаемого (см. картинку). Где-то промахнулся. Поможите, люди добрые!


чем Вас не устраивает такое описание

Код
   reg [<upper>:0] <reg_name>;
  
   always @(posedge <clock> or posedge <reset>)
      if (<reset>)
         <reg_name> <= 0;
      else if (<clock_enable>)
         <reg_name> <= <reg_name> + 1;


готового счетчика?


--------------------
If it doesn't work in simulation, it won't work on the board.

"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 6 2010, 12:45
Сообщение #3


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Maverick @ Apr 6 2010, 15:35) *
чем Вас не устраивает такое описание
...
готового счетчика?

Не устраивает тем, что Quartus не объединяет в одном логическом элементе сумматор и триггер, а раскидывает, как захочет. На MAX+II на AHDL у меня счетчики выстраивались в линейку, с цепями переноса длиной в 24 элемента.
Go to the top of the page
 
+Quote Post
Builder
сообщение Apr 6 2010, 12:52
Сообщение #4


iBuilder©
****

Группа: Свой
Сообщений: 519
Регистрация: 14-07-04
Из: Минск
Пользователь №: 322



Цитата(ViKo @ Apr 6 2010, 15:45) *
Не устраивает тем, что Quartus не объединяет в одном логическом элементе сумматор и триггер, а раскидывает, как захочет. На MAX+II на AHDL у меня счетчики выстраивались в линейку, с цепями переноса длиной в 24 элемента.
Какую версию квартуса используете? Квартус достаточно умный для того, что-б использовать мегафункции, если только там код не сильно хитрый и не завязано на что-то ещё. Если что-то не получается, по моему проще использовать LPM функцию сложения, врятли получится написать оптимальнее чем в ней, особенно для общего случая.
Go to the top of the page
 
+Quote Post
Kuzmi4
сообщение Apr 6 2010, 12:54
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 3 304
Регистрация: 13-02-07
Из: 55°55′5″ 37°52′16″
Пользователь №: 25 329



Цитата(ViKo @ Apr 6 2010, 15:45) *
..раскидывает, как захочет...

Если во времянку вложились - вам не всё равно где и почему он их так расставил ??
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 6 2010, 12:57
Сообщение #6


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Kuzmi4 @ Apr 6 2010, 15:54) *
Если во времянку вложились - вам не всё равно где и почему он их так расставил ??

Предпочитаю идеальное решение. Жалко напрасно потраченных логических элементов.
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 6 2010, 13:02
Сообщение #7


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(ViKo @ Apr 6 2010, 19:45) *
Не устраивает тем, что Quartus не объединяет в одном логическом элементе сумматор и триггер, а раскидывает, как захочет. На MAX+II на AHDL у меня счетчики выстраивались в линейку, с цепями переноса длиной в 24 элемента.

У вас счетчик по скорости не укладывается или вам просто хочется, чтобы фиттер размещал ячейки рядом и обязательно переносы делал через carry chain'ы?


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 6 2010, 13:06
Сообщение #8


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(dxp @ Apr 6 2010, 16:02) *
У вас счетчик по скорости не укладывается или вам просто хочется, чтобы фиттер размещал ячейки рядом и обязательно переносы делал через carry chain'ы?

...Просто хочется smile.gif...
Просто счетчиков будет некоторое количество... остальное уже сказал.
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 6 2010, 13:08
Сообщение #9


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(ViKo @ Apr 6 2010, 19:57) *
Предпочитаю идеальное решение. Жалко напрасно потраченных логических элементов.

Перфекционизмом занимаетесь. smile.gif Просинтезируйте счетчик, который вам описали, и загляните в директорию db - с ненулевой вероятностью увидите там файл lpm_counter.tdf. smile.gif Который как раз весь из себя низкоуровневый и использует переносы "вручную".


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
iosifk
сообщение Apr 6 2010, 13:09
Сообщение #10


Гуру
******

Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(ViKo @ Apr 6 2010, 17:06) *
Просто счетчиков будет некоторое количество... остальное уже сказал.

Самый главный вопрос: все счетчики считают одновременно и на максимальной для чипа частоте?
Т.е решение "в лоб"???
Или можно сделать один счетчик и успевать им считать в нескольких каналах?


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
Kuzmi4
сообщение Apr 6 2010, 13:09
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 3 304
Регистрация: 13-02-07
Из: 55°55′5″ 37°52′16″
Пользователь №: 25 329



2 ViKo
пройдитесь по форуму - помнится des00 и SM поднимали такой вопрос (только там есчё модуль был числа, а потом "плюс"). Не совсем то, что вам нужно, но сумматор там как раз таким вот хитроумным методом и был организован, и даже вроде бы через generate-ы.
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 6 2010, 13:10
Сообщение #12


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(ViKo @ Apr 6 2010, 20:06) *
...Просто хочется smile.gif...
Просто счетчиков будет некоторое количество... остальное уже сказал.

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


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 6 2010, 13:20
Сообщение #13


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Счетчики разные, счетчиков - несколько (5-6), длинные.
Я могу написать Count = Count + 1, и все будет нормально.
Но хотелось бы получить конкретный ответ на свой вопрос. Что-то я напутал в CARRY_SUM.

Цитата(Kuzmi4 @ Apr 6 2010, 16:09) *
2 ViKo
пройдитесь по форуму - помнится des00 и SM поднимали такой вопрос (только там есчё модуль был числа, а потом "плюс"). Не совсем то, что вам нужно, но сумматор там как раз таким вот хитроумным методом и был организован, и даже вроде бы через generate-ы.

Смотрел, что-то видел. Но там не было CARRY_SUM.
Я понимаю так, что таблица истинности у него следующая:
Код
CI SI SO CO
0  0  0  0
0  1  1  0
1  0  1  0
1  1  0  1
Go to the top of the page
 
+Quote Post
Костян
сообщение Apr 6 2010, 13:45
Сообщение #14


Знающий
****

Группа: Свой
Сообщений: 740
Регистрация: 24-07-06
Из: Minsk
Пользователь №: 19 059



Цитата(ViKo @ Apr 6 2010, 11:57) *
Предпочитаю идеальное решение. Жалко напрасно потраченных логических элементов.

а почему не берете в расчет зря потраченное время на это решение?

Цитата(ViKo @ Apr 6 2010, 12:20) *
Я понимаю так, что таблица истинности у него следующая:
Код
CI SI SO CO
0  0  0  0
0  1  1  0
1  0  1  0
1  1  0  1

похоже на правду, если хотите удостовериться - сделайте тестбенч и подайте на вход CI SI (всего лишь четыре варианта)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 6 2010, 13:54
Сообщение #15


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Костян @ Apr 6 2010, 16:45) *
а почему не берете в расчет зря потраченное время на это решение?

похоже на правду, если хотите удостовериться - сделайте тестбенч и подайте на вход CI SI (всего лишь четыре варианта)

По первому - один раз набив шишек, можно потом клепать счетчики сколь угодно раз. У меня есть нечто подобное на AHDL, мне нравится. Сразу видно на Floorplan - вот они, мои счетчики smile.gif
По второму - попробую.
Go to the top of the page
 
+Quote Post
sazh
сообщение Apr 6 2010, 14:01
Сообщение #16


Гуру
******

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



Цитата(ViKo @ Apr 6 2010, 16:54) *
У меня есть нечто подобное на AHDL, мне нравится.


Попробуйте еще на макросах типа 74163 с трюковыми входами. Каскадировать можно до бесконечности. Еще круче будет.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 6 2010, 14:13
Сообщение #17


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(sazh @ Apr 6 2010, 17:01) *
Попробуйте еще на макросах типа 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
smile.gif smile.gif smile.gif
Go to the top of the page
 
+Quote Post
Builder
сообщение Apr 6 2010, 15:42
Сообщение #18


iBuilder©
****

Группа: Свой
Сообщений: 519
Регистрация: 14-07-04
Из: Минск
Пользователь №: 322



Цитата(ViKo @ Apr 6 2010, 17:13) *
Это - шутка?
Да, я думаю это была шутка.
Вы по моему занимаетесь пустой работой, главное - результат.
Т.е. описываете задачу, описываете сколько нужно по времянке и всё. Я тоже помню, что в старые времена красиво было смотреть как софт на раскладке рисовал цепочки переносов, видно было где счётчики. Но как-то последнее время на это уже не обращаешь внимание: временка и ресурсы устраивают и ладненько. А в последнее время как-то всёравно стало, как оно там, пока не прижмёт.

Да, что-то мне подсказывает, что такие примитивы как счётчик крайне редко получится сделать оптимальнее чем в LPM модулях сделано, времени потратите больше чем экономии будет, если будет экономия...
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 6 2010, 16:25
Сообщение #19


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Builder @ Apr 6 2010, 18:42) *
Да, я думаю это была шутка.
Вы по моему занимаетесь пустой работой, главное - результат.

Я думаю, работа редко бывает впустую. Вот, мы узнали, что CARRY_SUM это просто два повторителя (наверное).
Счетчик, "выстроенный в шеренгу", имеет регулярную структуру, предсказуемое быстродействие, близкое к предельному, не зависимые от переукладки проекта.
С вашего позволения, я еще немного "потрахаюсь". Если будет результат, доложу.
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 7 2010, 10:59
Сообщение #20


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

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



Цитата(ViKo @ Apr 6 2010, 07:24) *
Но не получаю желаемого (см. картинку). Где-то промахнулся. Поможите, люди добрые!

что то счетчиком не пахнет %)
Прикрепленное изображение

тогда как в лоб
Прикрепленное изображение

видно что ква использует lpm_counter для данной архитектуры


--------------------
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 7 2010, 11:17
Сообщение #21


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(des00 @ Apr 7 2010, 14:14) *
что то счетчиком не пахнет %)

Не пахнет, потому что CARRY_SUM - это просто две цепи, одна ведет через мультиплексоры загрузки, синхронного сброса (зависит от архитектуры ПЛИС) к триггеру или еще куда подальше..., а вторая - цепь переноса, ведет ко входу переноса следующего ЛЭ. А не сумматор, как можно было бы подумать.
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 7 2010, 11:22
Сообщение #22


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

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



Цитата(ViKo @ Apr 7 2010, 06:32) *
Не пахнет, потому что CARRY_SUM - это просто две цепи, одна ведет через мультиплексоры загрузки, синхронного сброса (зависит от архитектуры ПЛИС) к триггеру, а вторая - цепь переноса, ведет ко входу переноса следующего ЛЭ. А не сумматор, как можно было бы подумать.

а не пахнет потому что
1. это Technology Viewer:
2. вывод Pout не подключен к счетному выводу, как задумывалось, а сиди тупо на VCC
3. логика каждого бита порта Count не зависит от других битов, а зависит только от сигналов enable, reset_n, clock и своего собственного значения. Как ЭТО может быть счетчиком, в котором, при любом способе построения, старшие биты зависят от младших ?


--------------------
Go to the top of the page
 
+Quote Post
bogaev_roman
сообщение Apr 7 2010, 11:24
Сообщение #23


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

Группа: Свой
Сообщений: 1 088
Регистрация: 20-10-09
Из: Химки
Пользователь №: 53 082



Самый идеальный вариант - использовать мегафункцию, она специально заточена под структуру плисины.
При написании а ля counter<=counter+1 после синтеза квартус делает сумматор, который оптимизирует далее до счетчика и который проигрывает первоначальному варианту по быстродействию (немного, издержки фиттера).
Если делать на вентильном уровне, то квартус придет к тому же варианту что и с мегафункцией smile.gif (проверял на небольшой разрядности).
Если хотите, чтоб на флурплане было все в линеечку и максимально упаковано, то используйте мегафункцию (чтоб при фиттере в большом проекте не размазал, ограничте область).
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 7 2010, 11:52
Сообщение #24


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Объясняю, что хотел сделать. Вот образец на 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;


Цитата(bogaev_roman @ Apr 7 2010, 14:39) *
Самый идеальный вариант - использовать мегафункцию, она специально заточена под структуру плисины.
...

Согласен. Попробую и это обязательно.


Вот такой код работает. Но это только "полуфабрикат".
Код
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
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 7 2010, 13:36
Сообщение #25


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



По совету участников обратился к мегафункции 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.
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 8 2010, 04:38
Сообщение #26


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(ViKo @ Apr 7 2010, 20:51) *
Вывод такой - если хочешь качества - используй LPM, если все равно - пиши по-простому, на Verilog.

Код
module slon
(
    input            clk,                      
    output bit [63:0] cnt
);

always_ff @(posedge clk) begin
    cnt <= cnt + 1;
end

endmodule

Floorplan:
Прикрепленное изображение


Одна из ячеек (любая):
Прикрепленное изображение


Что я делаю не так?


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Builder
сообщение Apr 8 2010, 06:13
Сообщение #27


iBuilder©
****

Группа: Свой
Сообщений: 519
Регистрация: 14-07-04
Из: Минск
Пользователь №: 322



Цитата(ViKo @ Apr 7 2010, 16:51) *
Обращается к lpm_counter. А тот представляет собой AHDL файл, который, я, собственно, и пытался "изобрести".
Вывод такой - если хочешь качества - используй LPM, если все равно - пиши по-простому, на Verilog.
Во-во, и более того, обычно достаточно просто написать: a=a+1; и квартус автоматически подключит LPM.
Единственный случай. который прихдит на ум, когда есть смысл попробовать ручками подключать, если сумматор по логике сложится с другой логике, и результат не ляжет на LPM. Но я например к таким экспериментам прихожу если не выполняются констрейны.
Так что не придумываете себе забот лишних, больше чем их есть.
Go to the top of the page
 
+Quote Post
sazh
сообщение Apr 8 2010, 06:54
Сообщение #28


Гуру
******

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



Цитата(Builder @ Apr 8 2010, 09:28) *
Во-во, и более того, обычно достаточно просто написать: a=a+1; и квартус автоматически подключит LPM.


LPM counter он только на ацексе подключает. Последний квартус его уже не поддерживает.
У ацекса одна судьба - пакет max+II
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 8 2010, 07:51
Сообщение #29


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(sazh @ Apr 8 2010, 10:09) *
LPM counter он только на ацексе подключает. Последний квартус его уже не поддерживает.
У ацекса одна судьба - пакет max+II

Не знаю, как последний, а Quartus 9.0 тот модуль, что я показал, скушал.
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 8 2010, 07:56
Сообщение #30


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

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



Цитата(dxp @ Apr 7 2010, 22:53) *
Что я делаю не так?


теперь еще добавить alcr, clk_ena, sload, cnt_en как в сабжевом примере и посмотреть. очень занятные вещи видятся для разных семейств (причины уже обсуждали на этом форуме) %)


--------------------
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 8 2010, 08:32
Сообщение #31


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Ну, вот, к примеру.
Код
module CountDownReload
#(parameter PERIOD = 50000)
  (
  input Reset_n, Clock, Enable,
  output reg [WIDTH:0] Count
  );
  localparam WIDTH = NumBits(PERIOD-2);
  
  always @(negedge Reset_n, posedge Clock)
  if (!Reset_n)
    Count = 0;
  else
    if (Enable)
      if (Count[WIDTH])
        Count = Count - 1;
      else
        Count = (1 << WIDTH) | (PERIOD-2);
endmodule

Для ACEX получился в виде, как на картинке. Да, сумматор использует переносы, но триггеры черт знает где, выходы берутся с других мест.


А вот тот же код, разложенный в Cyclone III, 18 ЛЭ

Что сказать: Quartus + Cyclone = Сила!
Предыдущие семейства - в топку!
Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
sazh
сообщение Apr 8 2010, 08:43
Сообщение #32


Гуру
******

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



Цитата(ViKo @ Apr 8 2010, 11:47) *
Что сказать: Quartus + Cyclone = Сила!
Предыдущие семейства - в топку!


Добавлю, все на квартус 9.0. Ибо только он творит чудеса.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 8 2010, 08:46
Сообщение #33


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(sazh @ Apr 8 2010, 11:58) *
Добавлю, все на квартус 9.0. Ибо только он творит чудеса.

Неужто 9.1 хуже?
Или, снова... шутка? Смайлик поставьте.
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 8 2010, 08:50
Сообщение #34


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(des00 @ Apr 8 2010, 15:11) *
теперь еще добавить alcr, clk_ena, sload, cnt_en как в сабжевом примере и посмотреть. очень занятные вещи видятся для разных семейств (причины уже обсуждали на этом форуме) %)

Код
//------------------------------------------------------------------------------
module slon
(
    input            clk,
    input            rst,

    input            cnt_en,

    input      [63:0] data,
    input             load,
                    
    output bit [63:0] cnt
);

always_ff @(posedge clk, posedge rst) begin
    if(rst) begin
        cnt <= 0;
    end
    else begin
        if(cnt_en) begin
            if(load) begin
                cnt <= data;
            end
            else begin
                cnt <= cnt + 1;
            end
        end
    end
end

endmodule
//------------------------------------------------------------------------------

Прикрепленное изображение
Прикрепленное изображение


P.S. EP2C8F256I8 @ Quartus II 9.0 Build 235 06/17/2009 SJ Full Version, Service Pack Installed: 2


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 8 2010, 08:56
Сообщение #35


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



to dxp
Для ACEX попробуйте то же.

Сам попробовал smile.gif
Все ровненько, только я длину счетчика уменьшил до 32.
Значит, ваш пример недостаточно сложный.
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 8 2010, 11:41
Сообщение #36


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

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



Цитата(dxp @ Apr 8 2010, 03:05) *
P.S. EP2C8F256I8 @ Quartus II 9.0 Build 235 06/17/2009 SJ Full Version, Service Pack Installed: 2

я не зря перечислил нужные сигналы, посмотрите для начала на таблицу истинности lpm_counter потом сравните со своим кодом %)


--------------------
Go to the top of the page
 
+Quote Post
sazh
сообщение Apr 8 2010, 12:28
Сообщение #37


Гуру
******

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



Цитата(ViKo @ Apr 8 2010, 12:01) *
Неужто 9.1 хуже?
Или, снова... шутка? Смайлик поставьте.


Error (10207): Verilog HDL error at CountDownReload.v(7): can't resolve reference to object "NumBits"
Где он описан?
Да и приоритетность нарушаете:
The signal order is the same for all Altera device families, although as noted
previously, not all device families provide every signal. The following priority order is
observed:
1. Asynchronous Clear, aclr—highest priority
2. Preset, pre
3. Asynchronous Load, aload
4. Enable, ena
5. Synchronous Clear, sclr
6. Synchronous Load, sload
7. Data In, data—lowest priority
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 8 2010, 12:46
Сообщение #38


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(sazh @ Apr 8 2010, 15:43) *
Error (10207): Verilog HDL error at CountDownReload.v(7): can't resolve reference to object "NumBits"
Где он описан?
Да и приоритетность нарушаете:
...

Это - функция, в другом месте была
Код
/*!
***********************************************************************
* @brief    Calculate Number-of-Bits for Number
* @details    Вычисляет количество разрядов для представления числа
* @param    Number - число
* @return    NumBits - количество двоичных разрядов
***********************************************************************/
function integer NumBits (input integer Number);
begin
  NumBits = 0;
  while (Number)
  begin
    NumBits++;
    Number >>= 1;
  end
end
endfunction

Приоритетность нарушаю? unsure.gif
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 8 2010, 12:50
Сообщение #39


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(des00 @ Apr 8 2010, 18:56) *
я не зря перечислил нужные сигналы,

Цитата
теперь еще добавить alcr, clk_ena, sload, cnt_en

Код
module slon
(
    input            clk,
    input            rst,

    input            clk_en,
    input            cnt_en,

    input      [63:0] data,
    input             load,
                    
    output bit [63:0] cnt
);

always_ff @(posedge clk, posedge rst) begin
    if(rst) begin
        cnt <= 0;
    end
    else begin
        if(clk_en) begin
            if(load) begin
                cnt <= data;
            end
            else begin
                if(cnt_en) begin
                    cnt <= cnt + 1;
                end
            end
        end
    end
end

endmodule

Так?

Результат в смысле выстраивания счетчика в сгруппированном виде не изменился (скриншоты делать и слать лень).

Цитата(des00 @ Apr 8 2010, 18:56) *
посмотрите для начала на таблицу истинности lpm_counter потом сравните со своим кодом %)

lpm_counter может быть сконфигурирован очень разнообразно, начиная от первого моего примера и включая этот. Какую именно конфигурацию вы имеете в виду? И что в ней мешает синтезатору слепить счетчик в сгруппированных ячейках и с использованием быстрых переносов?


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 8 2010, 13:24
Сообщение #40


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(dxp @ Apr 8 2010, 16:05) *
Какую именно конфигурацию вы имеете в виду? И что в ней мешает синтезатору слепить счетчик в сгруппированных ячейках и с использованием быстрых переносов?

Если задействовать всё, что можно, в счетчике, то, может быть, "красивенько" уже не уложится.
Код
FUNCTION lpm_counter
                           (
                           -- INPUTS
                           data[LPM_WIDTH-1..0],
                           clock,
                           clk_en,
                           cnt_en,
                           updown,
                           cin,
                           aclr,
                           aset,
                           aconst,
                           aload,
                           sclr,
                           sset,
                           sconst,
                           sload
                           )

                           WITH
                           (
                           -- PARAMETERS
                           LPM_WIDTH,
                           LPM_DIRECTION,
                           LPM_MODULUS,
                           LPM_AVALUE,
                           LPM_SVALUE,
                           LPM_PORT_UPDOWN,
                           CARRY_CNT_EN,
                           LABWIDE_SCLR,
                           USE_NEW_VERSION
                           )

                           RETURNS
                           (
                           -- OUPUTS
                           q[LPM_WIDTH-1..0],
                           cout,
                           eq[15..0]%,
                           debug_out[6..0]%
                           );

Правда, я уже не совсем понимаю, зачем...
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 8 2010, 13:38
Сообщение #41


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

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



Цитата(dxp @ Apr 8 2010, 08:05) *
Результат в смысле выстраивания счетчика в сгруппированном виде не изменился (скриншоты делать и слать лень).


пример Viko MWLPM_Counter в посте №25 дает 26 плиток для третьего сыклона, ваш пример slon подрихтованный по разрядности + выход cout дает 50 плиток для того же сыклона.


--------------------
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 8 2010, 13:45
Сообщение #42


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(ViKo @ Apr 8 2010, 20:39) *
Правда, я уже не совсем понимаю, зачем...

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


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 8 2010, 13:59
Сообщение #43


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(des00 @ Apr 8 2010, 16:53) *
пример Viko MWLPM_Counter в посте №25 дает 26 плиток для третьего сыклона, ваш пример slon подрихтованный по разрядности + выход cout дает 50 плиток для того же сыклона.

Видимо, дело, в cout (которого нет у dxp). Потому что последний slon на 24 разряда дает те же 26 "плиток".
Приведите свой модуль.
Ой, нет - 24 "плитки", 26 было для ACEX.
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 8 2010, 14:05
Сообщение #44


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

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



Цитата(ViKo @ Apr 8 2010, 09:14) *
Приведите свой модуль.

как разберусь откуда берутся лишние плитки приведу %)


--------------------
Go to the top of the page
 
+Quote Post
bogaev_roman
сообщение Apr 8 2010, 14:46
Сообщение #45


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

Группа: Свой
Сообщений: 1 088
Регистрация: 20-10-09
Из: Химки
Пользователь №: 53 082



Загнал следующий код в квартус 9.1 под stratix iv с установками по умолчанию.

Код
module test_counter
(
input clk,
input rst,
output reg [15:0] cnt_out
);

always @(posedge clk or posedge rst)
    if (rst) cnt_out<=16'd0;
        else cnt_out<=cnt_out+16'd1;

endmodule

Проект размазался на флурплане по трем лабам и занял 20 лог ячеек, при этом раскидался в произвольном порядке.
К сожалению, вставить картинку так и не смог smile3046.gif
При использовании мегафункции все получилось ровно и красиво.

Поменял далее на циклон второй - красивая картиночка - все как положено. Непонятно... cranky.gif

Сообщение отредактировал bogaev_roman - Apr 8 2010, 14:52
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 8 2010, 17:25
Сообщение #46


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Хотел написать, что у меня сложилось впечатление, что Альтеровцы в Quartus намеренно душат семейства, не рекомендуемые к новым разработкам.
Но Stratix IV ??
Go to the top of the page
 
+Quote Post
sazh
сообщение Apr 8 2010, 18:06
Сообщение #47


Гуру
******

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



Цитата(ViKo @ Apr 8 2010, 16:01) *
Приоритетность нарушаю? unsure.gif


Ну накрутили. Снимаю шляпу.
Код
module CountDownReload
#(parameter PERIOD = 16)
  (
  input Reset_n, Clock, Enable,
  output reg [WIDTH:0] Count
  );
  localparam WIDTH = clogb2(PERIOD);

function integer clogb2 (input [31:0] value);
if (value < 2)              clogb2 = 1;
else                 begin
value = value - 1;
for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1)
value = value >> 1;
                     end
endfunction

  always @(negedge Reset_n, posedge Clock)
  if (!Reset_n)
       Count <= PERIOD-2;
  else
    if (Enable)
      if (Count[WIDTH])
        Count <= PERIOD-2;
      else
        Count <= Count - 1'b1;
endmodule
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 9 2010, 05:29
Сообщение #48


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

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



Цитата(ViKo @ Apr 8 2010, 08:14) *
Приведите свой модуль.


Цитата(des00 @ Apr 8 2010, 08:20) *
как разберусь откуда берутся лишние плитки приведу %)


и вот опять старый мега баг квартуса, с неумением работать с сигналом sload %)

немного подрихтованный slon
Код
module slon
(
    input            clk,
    input            rst,

    input            clk_en,
    input            cnt_en,

    input      [23:0] data,
    input             load,
                    
    output bit [23:0] cnt,
    output bit cout, cout2    
);

bit [24:0] cnt_reg;
wire [24:0] cnt_next = cnt_reg + 1'b1;

always_ff @(posedge clk, posedge rst) begin
    if(rst) begin
        cnt_reg <= 0;
    end
    else begin
        if(clk_en) begin
        
            if(load) begin
                cnt_reg <= {1'b0, data};
            end
            else begin
                if(cnt_en) begin
                    cnt_reg <= cnt_next;
                end
            end
        end
    end
end

assign cnt = cnt_reg[23:0];
assign cout = cnt_reg[24];
assign cout2 = cnt_next[24];

endmodule


51 плитка, стоит убрать cout2 или sload 26 плиток. Несмотря на то, что согласно "Figure 2–3. Cyclone III Family Devices LEs in Arithmetic Mode" снять сигнал переноса с последнего сумматора можно легко, ква делает для cout2, при наличии сигнала sload, отдельный сумматор. Мозгов ему в этом "крайне сложном" деле не хватает %) С MWLPM_Counter такого эффекта нет


--------------------
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 9 2010, 07:14
Сообщение #49


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

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



UPD. Ну так и есть, немного хендмейда и те же 26 плиток на третьем сыклоне %)

Код
wire [24:0] cnt_reg;
wire [24:0] cnt_next = cnt_reg + cnt_en;
wire [24:0] cnt_init = {1'b0, data};

genvar i;
generate
  for (i = 0; i < $size(cnt_reg); i++) begin : dff_gen
      dffeas
      dffeas
      (
        .clk    ( clk          ) ,
        .d      ( cnt_next [i] ) ,
        .ena    ( clk_en       ) ,
        .asdata ( cnt_init [i] ) ,
        .clrn   ( rst          ) ,
        .sload  ( load         ) ,
        .q      ( cnt_reg  [i] )
      );
  end
endgenerate

assign cnt = cnt_reg[23:0];
assign cout = cnt_reg[24];
assign cout2 = cnt_next[24];


Не любит ква сигнал sload, ох как не любит. Если мне память не изменяет, тянется это еще с 7 ой версии %)


--------------------
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 9 2010, 09:01
Сообщение #50


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(sazh @ Apr 8 2010, 21:21) *
Ну накрутили. Снимаю шляпу.

Хотел, чтобы загрузка в ACEX шла нулем, согласно архитектуре.
Ваш пример работает в Cyclone III быстрее. Наверное, потому, что в Циклон загрузка идет единицей sload .

to des00
Посмотрите на картинку для последнего slon'а.
По-моему, все проблемы в сигнале cnt_en, который, вообще говоря, хрен знает зачем нужен. Есть же clk_en.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 9 2010, 10:07
Сообщение #51


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

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



Цитата(ViKo @ Apr 9 2010, 03:16) *
Посмотрите на картинку для последнего slon'а.

я думал что вы уже поняли что квартусовскому RTL вьюверу не верю и им не пользуюсь. Только Technology mapper. %)

Цитата
По-моему, все проблемы в сигнале cnt_en, который, вообще говоря, хрен знает зачем нужен. Есть же clk_en.

Ну почему, нужна вещь в некоторых применениях. Да и в мегафункции lpm_counter он был с ее основания %)


--------------------
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 9 2010, 11:54
Сообщение #52


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Смотрю в картинку "Figure 2–5. Cyclone III Family Devices LEs in Arithmetic Mode" (у меня 2-5).
Не могу представить, как можно сделать сумматор для счетчика, и обходной путь, когда cnt_en запрещает счет, и выход переноса для следующего разряда.
Левый нижний мультиплексор сообще нарисован по-идиотски, что выбирает, чем выбирает?
Дальше-то просто - sload, data3, clock, ena.
Т.е., возможно, это не глюк, а суровая реальность.
P.S. Впрочем, и без cnt_en результат тот же sad.gif

Upd. Устройство ЛЭ лучше смотреть в Resource Property Editor (который выскакивает в Chip Planner) - там все видно, как надо.
День провозился с последним slon'ом, но так и не смог добиться того, что выдал des00 с использованием dffeas.
Хочется верить, что это не глюк, а какая-то логическая нестыковка между Verilog и Cyclone.
Вот и получается, что без примитивов перфект-качества не получить?
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 10 2010, 02:23
Сообщение #53


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

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



Цитата(ViKo @ Apr 9 2010, 06:09) *
Не могу представить, как можно сделать сумматор для счетчика, и обходной путь, когда cnt_en запрещает счет, и выход переноса для следующего разряда.

за счет цепей register bypass можно получить на тех же ресурсах комбинационный и регистровый выход сумматора. в lpm_counter cnt_en запрещает счет, но не запрещает формирование сигнала переноса.
Кодом его можно описать двояко :
1) как в приведенном мной коде (кстати в этом случае cout завязан на cnt_en)
2) сумматор сделать константным (развязав cout и cnt_en), но усложнив логику формирования сигнала ena типа так clk_ena & (sload | (~sload & cnt_en))

Цитата
Upd. Устройство ЛЭ лучше смотреть в Resource Property Editor (который выскакивает в Chip Planner) - там все видно, как надо.

мне даташита хватает %)

Цитата
Вот и получается, что без примитивов перфект-качества не получить?

вообще ква достаточно оптимально разводит, но вот сей эффект имеет место быть, когда я что-то делаю под альтеру, что должно использовать sload, я пишу два варианта и добавляю `ifdef __USE_ALTERA_MACRO__ %)

Цитата
Хочется верить, что это не глюк, а какая-то логическая нестыковка между Verilog и Cyclone.

Вот за что мне нравиться форум, что ответы порой находятся сами собой. Читая ваш вопрос, случайно открыл даташит на второй сыклон и сравнил с третьим. Вуаля. Во втором сыклоне в арифметическом режиме нет register bypass. А ква не хватает ума что бы поставить последний LE в цепочке в нормальный режим (в котором register bypass есть). Ребята с альтеры сэкономили, архитектуру чипа улучшили, а вот маппер похоже оставили от второго сыклона. Индусы блин %(
Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
 


--------------------
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 10 2010, 18:27
Сообщение #54


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Приколы продолжаются.
"Хэндмэйд" des00 отказался укладываться в ACEX1K (Auto device selected by fitter), наверное, каналов не хватило?
Код
Error: Cannot route source node "dff_gen[11].dffeas" of type logic cell to destination node "cnt[11]" of type I/O pin
Error: Cannot route source node "dff_gen[11].dffeas" of type logic cell to destination node "lpm_add_sub:Add0|addcore:adder|a_csnbuffer:result_node|cs_buffer[11]" of type logic cell
Error: Cannot route source node "dff_gen[24].dffeas" of type logic cell to destination node "cout" of type I/O pin
Error: Cannot route source node "dff_gen[24].dffeas" of type logic cell to destination node "lpm_add_sub:Add0|addcore:adder|unreg_res_node[24]" of type logic cell
Error: Cannot route source node "lpm_add_sub:Add0|addcore:adder|a_csnbuffer:result_node|cs_buffer[5]" of type logic cell to destination node "dff_gen[5].dffeas" of type logic cell
Error: Cannot route source node "lpm_add_sub:Add0|addcore:adder|a_csnbuffer:result_node|cs_buffer[7]" of type logic cell to destination node "dff_gen[7].dffeas" of type logic cell
Error: Can't find fit
Error: Quartus II Fitter was unsuccessful. 7 errors, 0 warnings

А в ACEX1K100 - влез.

Немного видоизмененный (и только с асинхронным выходом переноса) влез в удвоенное количество ЛЭ.
Код
module  CounterDFFEAS
#(parameter    WIDTH = 24)
  (
  input    Reset_n,
  input    Clock,
  input    Enable,
  input    Load,
  input    [WIDTH-1:0] Data,
  output    [WIDTH-1:0] CntOut,
  output    POut
  );
  
  wire    [WIDTH-1:0] Count;
  wire    [WIDTH:0] Next = Count + 1;
  
  genvar i;
  generate
    for (i=0; i<WIDTH; i++)
    begin : ffc
      dffeas  dffeas
      (
      .d (Next[i]),
      .clk (Clock),
      .clrn (Reset_n),
      .ena (Enable),
      .asdata (Data[i]),
      .sload (Load),
      .q (Count[i])
      );
    end
  endgenerate

  assign  CntOut = Count;
  assign  POut = Next[WIDTH];
endmodule

И только MWLPM_Counter, как уже говорилось, упаковался компактно.
Еще одна особенность - если длина счетчика небольшая (смотрел для приведенного выше счетчика при длине 4 на Cyclone III), то цепи переноса из разряда в разряд не используются.
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 11 2010, 05:32
Сообщение #55


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

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



Цитата(ViKo @ Apr 10 2010, 13:42) *
Приколы продолжаются.
"Хэндмэйд" des00 отказался укладываться в ACEX1K (Auto device selected by fitter), наверное, каналов не хватило?

у меня 9.0сп2 собрал без каких либо проблем

а так,
Код
wire [24:0] cnt_reg;
wire [24:0] cnt_next;
wire [24:0] carry_cnt;
wire [24:0] cnt_init = {1'b0, data};

genvar i;
generate
  for (i = 0; i < $size(cnt_reg); i++) begin : dff_gen

    carry_sum
    carry_sum
    (
      .sin  ( cnt_reg   [i]  ),
      .cin  ( (i == 0) ? 1'b1 : carry_cnt[i-1] ),
      .sout ( cnt_next  [i]  ),
      .cout ( carry_cnt [i]  )
    );

    dffeas
    dffeas
    (
      .clk    ( clk          ) ,
      .d      ( cnt_next [i] ) ,
      .ena    ( clk_en       ) ,
      .asdata ( cnt_init [i] ) ,
      .clrn   ( rst          ) ,
      .sload  ( load         ) ,
      .q      ( cnt_reg  [i] )
    );
  end
endgenerate

assign cnt = cnt_reg[23:0];
assign cout = cnt_reg[24];
assign cout2 = cnt_next[24];

даже уложился в 27 плиток для асекса (как MWLPM_Counter для него же), и в 1 у плитку для сыклонов %)

Цитата
Еще одна особенность - если длина счетчика небольшая (смотрел для приведенного выше счетчика при длине 4 на Cyclone III), то цепи переноса из разряда в разряд не используются.

это не удивительно и достаточно очевидно %)


--------------------
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 11 2010, 07:28
Сообщение #56


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(des00 @ Apr 11 2010, 08:47) *
у меня 9.0сп2 собрал без каких либо проблем

У меня 9.0 без СП, придется по-новее пошукать.

Цитата
а так,...

...не работает, потому что нет сумматора. Об этом я уже писал в начале.
Я уже было обрадовался - вот оно!
Похоже, остался еще шаг до цели smile.gif

Цитата
это не удивительно и достаточно очевидно %)

Точно! Где можно обойтись параллельным выполнением операции, последовательное не нужно.
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 11 2010, 07:45
Сообщение #57


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

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



Цитата(ViKo @ Apr 11 2010, 01:43) *
...не работает, потому что нет сумматора. Об этом я уже писал в начале.

а так
Код
    carry_sum
    carry_sum
    (
      .sin  ( cnt_reg   [i]  ),
      .cin  ( (i == 0) ? cnt_en : carry_cnt[i-1] ),
      .sout ( cnt_next  [i]  ),
      .cout ( carry_cnt [i]  )
    );

чем не сумматор %)))

ЗЫ. Те же 27 плиток %)

UPD. бугааа, повелся на поводу у людей, взято из файла altera_primitives.v

Код
module carry_sum (sin, cin, sout, cout);
    input sin;
    input cin;
    output sout;
    output cout;

    assign sout = sin;
    assign cout = cin;
endmodule

это не сумматор, это всего лишь указание использовать быстрые цепи переноса
Эскизы прикрепленных изображений
Прикрепленное изображение
 


--------------------
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 11 2010, 08:19
Сообщение #58


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(des00 @ Apr 11 2010, 11:00) *
это не сумматор, это всего лишь указание использовать быстрые цепи переноса

Ja-ja, naturlich! (как-то так smile.gif
Меня терзает предчувствие, что не упакуется сумматор с триггерами даже если между ними и забить CARRY_SUM.

Цитата(sazh @ Apr 8 2010, 10:09) *
У ацекса одна судьба - пакет max+II

Все больше склоняюсь к этому. Уже проверил, где там у меня MAXPlus+II инсталлятор smile.gif
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 11 2010, 08:26
Сообщение #59


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

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



Цитата(ViKo @ Apr 11 2010, 02:34) *
Ja-ja, naturlich! (как-то так smile.gif
Меня терзает предчувствие, что не упакуется сумматор с триггерами даже если между ними и забить CARRY_SUM.


Все больше склоняюсь к этому. Уже проверил, где там у меня MAXPlus+II инсталлятор smile.gif


так сумматор получили, теперь осталось только втолковать квартусу что все это ложиться в одну плитку в соответствии с режимом "Clearable Counter Mode" LE асекса указанного в даташите ACEX 1K Programmable Logic Device Family Data Sheet
Код
wire [1:0]  sum [0 : 24];

wire cnt_en_wire = cnt_en;

genvar i;
generate
  for (i = 0; i < $size(cnt_reg); i++) begin : dff_gen

    assign sum[i][0] = cnt_reg[i] ^ ((i == 0) ? cnt_en_wire : carry_cnt[i-1]);
    assign sum[i][1] = cnt_reg[i] & ((i == 0) ? cnt_en_wire : carry_cnt[i-1]);
    
    carry_sum
    carry_sum
    (
      .sin  ( sum[i][0]     ),
      .cin  ( sum[i][1]     ),
      .sout ( cnt_next  [i] ),
      .cout ( carry_cnt [i] )
    );


--------------------
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 11 2010, 13:19
Сообщение #60


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

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



Путем ковыряния даташита на асекс и квартуса у меня сложилось следующее понимание : альтеровцы как всегда всех ввели в заблуждение. Режим работы ячейки асекса Clearable Counter Mode
Цитата
The clearable counter mode is similar to the up/down counter mode, but it supports a synchronous clear instead of the up/down control. The clear function is substituted for the cascade-in signal in the up/down counter mode. Two 3-input LUTs are used; one generates the counter data, and the other generates the fast carry bit. Synchronous loading is provided by a 2-to-1 multiplexer. The output of this multiplexer is AND ed with a synchronous clear signal.

квартусу недоступен, он слишком туп для этого. Он ставит лют в арифметический регистр и sload в такой LE уже не ложиться, (см даташит на асекс). Помимо этого добавление к вышеуказанному коду сигнала sclr раздувает код до 74 плиток, хотя по даташиту это должно лечь в аппаратный AND в LE.

Вывод : Надо пользовать в таких тяжелых случаях мегафункцию и не париться %)


--------------------
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 11 2010, 13:36
Сообщение #61


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(des00 @ Apr 11 2010, 16:34) *
Вывод : Надо пользовать в таких тяжелых случаях мегафункцию и не париться %)

Но мегафункция-то работает! В Квартусе, на Verilog (ну, или AHDL, какая разница).
Смотришь в эту функцию lpm_counter.tdf - ничего не понимаешь smile.gif
Тоже, наверное, индусы писали smile.gif
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 11 2010, 13:39
Сообщение #62


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

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



Цитата(ViKo @ Apr 11 2010, 08:51) *
Но мегафункция-то работает! В Квартусе, на Verilog (ну, или AHDL, какая разница).

Если бы еще мегафункция не работала, то это бы вообще ни в какие ворота не лезло. Ведь по сути мегафункция это вставка RPM, а так разработчики синтезатора с языка Verilog сильно упростили себе задачу, положив два с половиной режима LE вместо 4-х %)


--------------------
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 11 2010, 13:44
Сообщение #63


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(des00 @ Apr 11 2010, 16:54) *
Если бы еще мегафункция не работала, то это бы вообще ни в какие ворота не лезло.

Вопрос принципиальный. Можно конвертировать из *.tdf в *.v (если б это что-то упростилоsmile.gif, синтезировать счетчик в упакованном виде. Что же не дает? Может быть, настройки какие-то хитрые есть, атрибуты?
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 11 2010, 13:49
Сообщение #64


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

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



Цитата(ViKo @ Apr 11 2010, 07:59) *
Вопрос принципиальный. Можно конвертировать из *.tdf в *.v (если б это что-то упростилоsmile.gif, синтезировать счетчик в упакованном виде. Что же не дает? Может быть, настройки какие-то хитрые есть, атрибуты?

не дает, то, что при синтезе tdf используется синтезатор с языка AHDL, а при синтезе с v синтезатор с языка Verilog. И далеко не факт что команда разработчиков обоих синтезаторов была одна и та же. Просто кто-то, в свое время, сильно схалявил, а команда тестеров вовремя эту халяву не заметила. Потом пошли сыклоны, вторые, третьи и как то всем стало не до асексов. Своего рода плевок в вечность (как в свое время с шиной ISA) %)


--------------------
Go to the top of the page
 
+Quote Post
sazh
сообщение Apr 11 2010, 14:48
Сообщение #65


Гуру
******

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



Цитата(ViKo @ Apr 11 2010, 16:59) *
Вопрос принципиальный. Можно конвертировать из *.tdf в *.v


Сранивать с tdf некорректно. Это описание по сути - графическое представление lpm функций в текстовом виде (нет понятия в этом языке фронта клока)
При переходе на поведенческое описание - меняется даже стиль описания.
используйте lpm в крайних случаях. Например когда по ресурсам не проходите.
В чем принцип, да еще на ацексе. (5 лет назад рисовал его в максе, если надо в нем и дорисую)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 11 2010, 16:03
Сообщение #66


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Я его сделал (Quartus, Coutner, Carry)! smile.gif
Код
module  CountCarry
#(parameter    WIDTH = 24)
  (
  input        rst,
  input        clk,
  input        clk_en,
  input        cnt_en,
  input        load,
  input        [WIDTH-1:0] data,
  output    [WIDTH-1:0] cnt,
  output    cout, cout2
  );
  
  wire [WIDTH:0] cnt_reg;
  wire [WIDTH:0] cnt_next;
  wire [WIDTH:0] cnt_carry;
  wire [WIDTH:0] cnt_init = {1'b0, data};

  genvar i;
  generate
    for (i=0; i<=WIDTH; i++) begin : dff_gen

      carry  carry
      (
        .in    ((i ? cnt_carry[i-1] : cnt_en) & cnt_reg[i]),
        .out    (cnt_carry[i])
      );

      dffeas  dffeas
      (
        .clk    (clk),
        .d    ((i ? cnt_carry[i-1] : cnt_en) ^ cnt_reg[i]),
        .ena    (clk_en),
        .asdata    (cnt_init[i]),
        .clrn    (rst),
        .sload    (load),
        .q    (cnt_reg[i])
      );
    end
  endgenerate

  assign cnt = cnt_reg[WIDTH-1:0];
  assign cout = cnt_reg[WIDTH];
  assign cout2 = cnt_next[WIDTH];

endmodule

28 ЛЭ для ACEX, один из которых - чисто инвертор для load.
Не зря в хэлпе говорится, что CARRY оставлен для совместимости с проектами на MAXPlus.
Благодарю "коллективный разум" форума, и des00 персонально! cheers.gif
Go to the top of the page
 
+Quote Post
des00
сообщение Apr 11 2010, 16:26
Сообщение #67


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

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



Цитата(ViKo @ Apr 11 2010, 10:18) *
Я его сделал (Quartus, Coutner, Carry)! smile.gif

хмм, странно в процессе ковыряния я делал что то подобное, давало 50 плиток. Сейчас еще раз проверил дало 28 плиток biggrin.gif


--------------------
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 12 2010, 21:20
Сообщение #68


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Выход переполнения счетчика (который выдается наружу) нужно брать не с выхода суммы последнего сумматора, а с выхода переноса.
Вот - "правильный" счетчик, со всеми достоинствами - регулярной структурой, предсказуемым быстродействием, и компакный. Только выбирайте синхронный выход переполнения (там их два).
Код
module  CountPrim
#(
  parameter    WIDTH = 8,        // number of bits
  parameter    DIRECT = "UP"        // count direction: "UP" or "DOWN"
  )
  (
  input        rst_n,        // async reset
  input        clk_en,        // clock enable all flip-flops
  input        clk,
  input        cnt_en,        // count enable
  input        load,        // hi-level sync load
  input        [WIDTH-1:0] data,    // data for sync load
  output bit    [WIDTH-1:0] cnt,    // bits of counter
  output bit    rcry,            // ripple carry
  output bit    tcry            // triggered (sync) carry
  );
  
  wire [WIDTH:-1] cnt_cry;

  carry  cryin (
    .in        (cnt_en),
    .out    (cnt_cry[-1]) );

  genvar i;
  generate
    for (i=0; i<WIDTH; i++) begin : bitgen
      if (DIRECT == "DOWN")
        carry  crycnt (
          .in    (cnt_cry[i-1] & !cnt[i]),
          .out    (cnt_cry[i]) );
      else                // "UP"
        carry  crycnt (
          .in    (cnt_cry[i-1] & cnt[i]),
          .out    (cnt_cry[i]) );
      
      dffeas  dffcnt (
        .clk    (clk),
        .d    (cnt_cry[i-1] ^ cnt[i]),
        .ena    (clk_en),
        .asdata    (data[i]),
        .clrn    (rst_n),
        .sload    (load),
        .q    (cnt[i]) );
    end
  endgenerate

  assign rcry = cnt_cry[WIDTH-1];
  dffeas  dffcry (
    .clk    (clk),
    .d    (rcry),
    .ena    (clk_en),
    .clrn    (rst_n),
    .q    (tcry) );
endmodule
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 29th July 2025 - 02:18
Рейтинг@Mail.ru


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