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

 
 
5 страниц V  < 1 2 3 4 > »   
Reply to this topicStart new topic
> Счетчик на примитивах CARRY_SUM и DFFE
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

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

 


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


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