Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как уменьшить объем проекта?
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
Docent86
Создаю проект и столкнулся с такой проблемой - логических ячеек категорически нехватает, установил оптимизацию по площади - всего 1% выиграл. Есть ограничение по используемой ПЛИС - максимум cycloneIII EP3c10... Пока не повесил пины - проект занимал копейки (270), после вывода на пины объем увеличился в сотни раз (57,162). Разделение на несколько ПЛИС помогает, но тогда устройство не выгодно по себестоимости. Подскажите новичку как можно оптимизировать?
на входе в схему 72 разряда, затем разные преобразования для каждых 12 разрядов и 2 пина на выходе - последовательный код + сигнал управления.
P.S. Возможно ли это из-за использования длинных шаблонов в преобразовании и/или больших функций case
Kuzmi4
2 Docent86
Цитата
Пока не повесил пины - проект занимал копейки (270), после вывода на пины объем увеличился в сотни раз (57,162)

пока нет физических выводов на пины квартус соптимизирует всё что вы там написали, как только появляются физические выводы "в мир" - квартус вам и выдаёт всю вашу кухню.

Цитата
Подскажите новичку как можно оптимизировать?

Общие приёмы можно в инете найти да и тут на форуме квинтессенцию их выкладывали (встречал где то недели 2-3 назад в " Программируемая логика (ПЛИС) - Programmable Logic (FPGA,CPLD, PLD)"), а так без кода сказать трудно что там не так.
agate
QUOTE (Docent86 @ Jul 29 2010, 00:22) *
Создаю проект и столкнулся с такой проблемой - логических ячеек категорически нехватает, установил оптимизацию по площади - всего 1% выиграл. Есть ограничение по используемой ПЛИС - максимум cycloneIII EP3c10... Пока не повесил пины - проект занимал копейки (270), после вывода на пины объем увеличился в сотни раз (57,162). Разделение на несколько ПЛИС помогает, но тогда устройство не выгодно по себестоимости. Подскажите новичку как можно оптимизировать?
на входе в схему 72 разряда, затем разные преобразования для каждых 12 разрядов и 2 пина на выходе - последовательный код + сигнал управления.
P.S. Возможно ли это из-за использования длинных шаблонов в преобразовании и/или больших функций case

Ваша ФПГА 10К ( ЛУТ4 + ФФ)
1. определите сколько Логики и сколько ФФ потребляет проект. Логику иногда можно оптимизировать.
2. читайте Доклад -если критическая цепь очень длинная то наверняка она сьедает много ЛУТ - неоптимальный алгоритм?
3. Synplify иногда может улучшить area на 50%
4. Используйте RAM где можно вместо регистров
des00
Цитата(Docent86 @ Jul 28 2010, 15:22) *
Пока не повесил пины - проект занимал копейки (270), после вывода на пины объем увеличился в сотни раз (57,162).

Что то вы темните, даже если вы не назначили пины в Pin Planner, ква автоматически раскидывает пины как ему заблагорассудится. Не мог так увеличится размер. Либо под словами "Пока не повесил пины" вы понимаете назначение пинов на топлевеле через assign например (Verilog) тогда вы сами себе злобный буратина. Раньше думать надо было %)
А общий совет такой: в одну руку Report -> Analysis & Synthesis -> Resourse Utilization by Entity и в путь, смотреть сколько и что у вас весит, во вторую руку сорец + тетрадь с карандашом и считать сколько должен приблизительно весить, исходя из 4-х входового люта. Вот и проверите правильно понял вас квартус или нет %)

Цитата(agate @ Jul 28 2010, 16:49) *
2. читайте Доклад -если критическая цепь очень длинная то наверняка она сьедает много ЛУТ - неоптимальный алгоритм?

В контексте темы это явно лишнее, у автора пока проблема с ресурсом, а не времянкой.
Цитата
3. Synplify иногда может улучшить area на 50%

Только в случае сильно не оптимального кода, уже обсуждалось %)
Gothard
Не знаю, как у Альтеры, но у Xilinx есть инструмент FloorPlaner - после этапа Translate можно очень наглядно посмотреть какие блоки, сколько ресурсов занимают на кристалле. К каждому блоку иерархии приводится, сколько триггеров, лутов и прочего в него входит. А если и Map был произведен, то можно визуально посмотреть где эти ресурсы на кристалле и сколько площади занимают.

Наверняка у Альтеры есть что-то подобное. Посмотрите сколько ресурсов занимают ваши блоки, оцените - адекватное ли это число и смотрите как можно оптимизировать самые "толстые".

P.S.: для того, чтобы была видна иерархия блоков в FloorPlaner, при синтезе (опять же XST) необходимо было устанавливать опцию "Keep Hierarhy"
iosifk
Цитата(Docent86 @ Jul 29 2010, 01:22) *
Создаю проект и столкнулся с такой проблемой - логических ячеек категорически нехватает,
Подскажите новичку как можно оптимизировать?

Начните с самого начала. Посмотрите, может быть Вы что-то делаете "В лоб". Замените параллельную обработку на последовательную. Попробуйте сделать не много одинаковых узлов, а один, и им последовательно обрабатывать данные. Вместо регистров - память. И так далее.
Если входные данные идут медленнее, чем максимально-допустимая тактовая в ПЛИС, то это значит, что можно применить последовательную обработку. А текущий проект - выкинуть.

До тех пор, пока Вы не будете спрашивать более конкретно, и не получите конкретных ответов...

PS У меня на сайте найдите "О гайке М3"... Вроде это даже на этом форуме в статьях есть... Еще у меня есть цикл статей "Микропроцессор своими руками". Читайте о начале проектирования и о многопоточности...
Удачи!
rv3dll(lex)
ну последовательная обработка это конечно хорошо, но тогда вместо триггеров расходуются мультиплексоры. правильно говорят - очень сложно ответить на вопрос, который таким образом задан. Текущий проект выкидывать пока не надо(
iosifk
Цитата(rv3dll(lex) @ Jul 29 2010, 10:15) *
ну последовательная обработка это конечно хорошо, но тогда вместо триггеров расходуются мультиплексоры. п

Да нет, нет мультиплексоров.
Пишем во входную память или в ФИФО, потом одним узлом обрабатываем, результат пишем в другую память... Где тут мультиплексоры?
rv3dll(lex)
Цитата(iosifk @ Jul 29 2010, 11:10) *
Да нет, нет мультиплексоров.
Пишем во входную память или в ФИФО, потом одним узлом обрабатываем, результат пишем в другую память... Где тут мультиплексоры?


это если данные по одному каналу приходят, а если, как у меня например, несколько входных каналов по 16 бит и один dsp фильтр, то прежде чем на него подавать надо несколько каналов по очереди подавать на один, а потом после фильтра развести обратно на несколько. вот тут и мультиплексоры появляются и регистры на выходах. Для DSP фильтра это приемлемо, так как слайсов дспишных мало, а для других целей не факт.
agate
QUOTE (des00 @ Jul 29 2010, 05:12) *
Что то вы темните, даже если вы не назначили пины в Pin Planner, ква автоматически раскидывает пины как ему заблагорассудится. Не мог так увеличится размер. Либо под словами "Пока не повесил пины" вы понимаете назначение пинов на топлевеле через assign например (Verilog) тогда вы сами себе злобный буратина. Раньше думать надо было %)
А общий совет такой: в одну руку Report -> Analysis & Synthesis -> Resourse Utilization by Entity и в путь, смотреть сколько и что у вас весит, во вторую руку сорец + тетрадь с карандашом и считать сколько должен приблизительно весить, исходя из 4-х входового люта. Вот и проверите правильно понял вас квартус или нет %)


В контексте темы это явно лишнее, у автора пока проблема с ресурсом, а не времянкой.

Только в случае сильно не оптимального кода, уже обсуждалось %)

Смотри в контекст глубже и шире:
Имеется ввиду critical путь - ето не только тайминг но и глубина логики - они шагают по жизни вместе. Т.е. если покажет logic depth > 30+ и таких много, то явно какaя-нибудь FOR лооп в коде не продумана.
des00
Цитата(agate @ Jul 29 2010, 05:24) *
Имеется ввиду critical путь - ето не только тайминг но и глубина логики - они шагают по жизни вместе. Т.е. если покажет logic depth > 30+ и таких много, то явно какaя-нибудь FOR лооп в коде не продумана.

Ну у меня на математике встречается >30 ти глубина и таких много, и без всяких форов. Глубина критического пути, при выполнении времянок, не говорит вообще ни о чем. И в контексте к вопросу автора вряд ли применима.
agate
QUOTE (des00 @ Jul 29 2010, 14:51) *
Глубина критического пути, при выполнении времянок, не говорит вообще ни о чем.

No comments.
Docent86
Задержался с просмотром страницы... Сегодня на работе поковырял что к чему - весь ресурс "съела" математика - в частности деления и умножения на числа не кратные 2^х. Пришлось снизить точность вычислений.

Тут тогда навязывается другой вопрос - подскажете экономичный алгоритм перевода из двоичного кода в ДДК. Я делал перевод в integer затем брал остаток от делений на 10 для каждого разряда десятичного числа и каждую из десятичных цифр обратно в двоичное:

aD:= conv_integer (Average(11 downto 0));
aD:= aD/1187; -- деление подобного рода повторяется но с разными коэфициентами

aD0:=aD rem 10; aD:=(aD-aD0)/10; --а такое преобразование можно и в одну функцию записать
aD1:=aD rem 10; aD:=(aD-aD1)/10;
aD2:=aD rem 10; aD:=(aD-aD2)/10;
aD3:=aD rem 10;
...
X(0 to 3) <= conv_std_logic_vector(aD4,4);
X(4 to 7) <= conv_std_logic_vector(aD3,4);
...


C VHDL начал совсем недавно работать, до этого занимался ОПК и в основном только на Си, поэтому понял не целесообразность таких вычислений. Другого пока не придумал, но перевод крайне необходим. Можно было бы как одну функцию записать, но там коэфициенты разные.

Как это было связано с выставлением пинов понятия пока не имею - видимо при компиляции блок без разводки игнорировался

А так в целом проект уместился теперь в 4.000, но математику надо все равно поменять
sazh
Цитата(Docent86 @ Jul 29 2010, 23:06) *
Тут тогда навязывается другой вопрос - подскажете экономичный алгоритм перевода из двоичного кода в ДДК.

Что такое ДДК
Docent86
Цитата(sazh @ Jul 29 2010, 23:17) *
Что такое ДДК



Двоично-Десятичный Код (BCD)
sazh
Цитата(Docent86 @ Jul 29 2010, 23:25) *
Двоично-Десятичный Код (BCD)


Преобразование bin2- bcd, bcd- bin2 неоднократно здесь рассматривалось. Воспользуйтесь поиском.
des00
Цитата(Docent86 @ Jul 29 2010, 14:06) *
aD:= conv_integer (Average(11 downto 0));
aD:= aD/1187; -- деление подобного рода повторяется но с разными коэфициентами

aD0:=aD rem 10; aD:=(aD-aD0)/10; --а такое преобразование можно и в одну функцию записать
aD1:=aD rem 10; aD:=(aD-aD1)/10;
aD2:=aD rem 10; aD:=(aD-aD2)/10;
aD3:=aD rem 10;
...
X(0 to 3) <= conv_std_logic_vector(aD4,4);
X(4 to 7) <= conv_std_logic_vector(aD3,4);
...

о времена о нравы, а гуглем алгоритмы BCD почитать до того как делать в лоб? Весит сие плиток 150-300 чистой логики.
rv3dll(lex)
на входе ДДК а внутри бинарный?
des00
Цитата(rv3dll(lex) @ Jul 29 2010, 23:31) *
на входе ДДК а внутри бинарный?

если делит на 10ть то скорее наоборот %)
rv3dll(lex)
иногда проще домножить и делить потом на 2^n
bogaev_roman
Действительно проще привести коэффициент к требуемой точности, умножить, а потом просто сдвинуть результат вправо.
Docent86
На входе бинарные 12 разрядные коды, на выходе дв.дес.числа.
Нашел другой способ перевода - через счетчики по модулю 10 с переносом - уложился в 1500 ячеек (весь проект) при этом вернул точность обратно.
des00
Цитата(Docent86 @ Jul 30 2010, 00:42) *
На входе бинарные 12 разрядные коды, на выходе дв.дес.числа.
Нашел другой способ перевода - через счетчики по модулю 10 с переносом - уложился в 1500 ячеек (весь проект) при этом вернул точность обратно.

я думаю, что с вашим изначальным подходом, да пораскинув мозгами уложитесь в ~1000 %) И самого младшего сыклона вам за глаза %)
Docent86
Всё, проблемы решены.
Нашел и протестировал BIN-2-BCD на 16 разрядов Binary. Занимает примерно 300 Logic cells работает просто замечательно, намного удобнее в использовании чем на счетчиках. На весь проект ушло 1200 cells

BIN-2-BCD - AHDL:
*****************************************
SUBDESIGN bin2dec
( DATA[15..0] : INPUT;
DIG5[3..0],DIG4[3..0],DIG3[3..0],DIG2[3..0],DIG1[3..0] : OUTPUT;
)
VARIABLE
DATA_A[15..0],DATA_B[15..0],DATA_C[15..0],DATA_D[15..0] : NODE;
BEGIN
IF DATA[]>=60000 THEN DIG5[]=6; DATA_A[]=DATA[]-60000;
ELSIF DATA[]>=50000 THEN DIG5[]=5; DATA_A[]=DATA[]-50000;
ELSIF DATA[]>=40000 THEN DIG5[]=4; DATA_A[]=DATA[]-40000;
ELSIF DATA[]>=30000 THEN DIG5[]=3; DATA_A[]=DATA[]-30000;
ELSIF DATA[]>=20000 THEN DIG5[]=2; DATA_A[]=DATA[]-20000;
ELSIF DATA[]>=10000 THEN DIG5[]=1; DATA_A[]=DATA[]-10000;
ELSE DIG5[]=0; DATA_A[]=DATA[];
END IF;

IF DATA_A[]>=9000 THEN DIG4[]=9; DATA_B[]=DATA_A[]-9000;
ELSIF DATA_A[]>=8000 THEN DIG4[]=8; DATA_B[]=DATA_A[]-8000;
ELSIF DATA_A[]>=7000 THEN DIG4[]=7; DATA_B[]=DATA_A[]-7000;
ELSIF DATA_A[]>=6000 THEN DIG4[]=6; DATA_B[]=DATA_A[]-6000;
ELSIF DATA_A[]>=5000 THEN DIG4[]=5; DATA_B[]=DATA_A[]-5000;
ELSIF DATA_A[]>=4000 THEN DIG4[]=4; DATA_B[]=DATA_A[]-4000;
ELSIF DATA_A[]>=3000 THEN DIG4[]=3; DATA_B[]=DATA_A[]-3000;
ELSIF DATA_A[]>=2000 THEN DIG4[]=2; DATA_B[]=DATA_A[]-2000;
ELSIF DATA_A[]>=1000 THEN DIG4[]=1; DATA_B[]=DATA_A[]-1000;
ELSE DIG4[]=0; DATA_B[]=DATA_A[];
END IF;

IF DATA_B[]>=900 THEN DIG3[]=9; DATA_C[]=DATA_B[]-900;
ELSIF DATA_B[]>=800 THEN DIG3[]=8; DATA_C[]=DATA_B[]-800;
ELSIF DATA_B[]>=700 THEN DIG3[]=7; DATA_C[]=DATA_B[]-700;
ELSIF DATA_B[]>=600 THEN DIG3[]=6; DATA_C[]=DATA_B[]-600;
ELSIF DATA_B[]>=500 THEN DIG3[]=5; DATA_C[]=DATA_B[]-500;
ELSIF DATA_B[]>=400 THEN DIG3[]=4; DATA_C[]=DATA_B[]-400;
ELSIF DATA_B[]>=300 THEN DIG3[]=3; DATA_C[]=DATA_B[]-300;
ELSIF DATA_B[]>=200 THEN DIG3[]=2; DATA_C[]=DATA_B[]-200;
ELSIF DATA_B[]>=100 THEN DIG3[]=1; DATA_C[]=DATA_B[]-100;
ELSE DIG3[]=0; DATA_C[]=DATA_B[];
END IF;

IF DATA_C[]>90 THEN DIG2[]=9; DATA_D[]=DATA_C[]-90;
ELSIF DATA_C[]>80 THEN DIG2[]=8; DATA_D[]=DATA_C[]-80;
ELSIF DATA_C[]>70 THEN DIG2[]=7; DATA_D[]=DATA_C[]-70;
ELSIF DATA_C[]>60 THEN DIG2[]=6; DATA_D[]=DATA_C[]-60;
ELSIF DATA_C[]>50 THEN DIG2[]=5; DATA_D[]=DATA_C[]-50;
ELSIF DATA_C[]>40 THEN DIG2[]=4; DATA_D[]=DATA_C[]-40;
ELSIF DATA_C[]>30 THEN DIG2[]=3; DATA_D[]=DATA_C[]-30;
ELSIF DATA_C[]>20 THEN DIG2[]=2; DATA_D[]=DATA_C[]-20;
ELSIF DATA_C[]>10 THEN DIG2[]=1; DATA_D[]=DATA_C[]-10;
ELSE DIG2[]=0; DATA_D[]=DATA_C[];
END IF;
DIG1[]=DATA_D[3..0];
END;
***************************************
Docent86
Еще нашел HEX-BIN

signal hidigit:std_logic_vector(3 downto 0);
signal lowdigit:std_logic_vector(3 downto 0);
signal result:std_logic_vector(7 downto 0);

result<=hidigit*conv_std_logic_vector(10,4)+("0000" & lowdigit);
Maverick
Цитата(Docent86 @ Jul 29 2010, 23:06) *


Цитата
aD0:=aD rem 10; aD:=(aD-aD0)/10; --а такое преобразование можно и в одну функцию записать

Деление на 10 не будет реализовано. Также желательно дополнительно ввести переменную, которая запоминала разность, а потом уже производить деление.
Вы проект делаете для синтеза или только для моделирования?

PS Mой совет почитайте мат. часть
sazh
Цитата(Docent86 @ Jul 30 2010, 09:42) *
На входе бинарные 12 разрядные коды, на выходе дв.дес.числа.
Нашел другой способ перевода - через счетчики по модулю 10 с переносом - уложился в 1500 ячеек (весь проект) при этом вернул точность обратно.


Vhdl не знаю. Но сама идея - преобразование за 13 тактов
Код
library ieee;     -- U.Tietze - Ch.Schenk  page 321
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity bin_bcd is port
(
clk              : in std_logic;
bin              : in std_logic_vector(11 downto 0);
bcd              : out std_logic_vector(15 downto 0);
enable_rd_bcd : out std_logic
);
end bin_bcd;

architecture bin2bcd of bin_bcd is

signal ct_bit_bin : std_logic_vector(3 downto 0);
signal     bin_rg : std_logic_vector(11 downto 0);
signal     bcd_rg : std_logic_vector(15 downto 0);
signal         sum: std_logic_vector(15 downto 0);

begin

sum(3 downto 0) <= bcd_rg(3 downto 0) + 3 when bcd_rg(3 downto 0) > 4 else bcd_rg(3 downto 0);
sum(7 downto 4) <= bcd_rg(7 downto 4) + 3 when bcd_rg(7 downto 4) > 4 else bcd_rg(7 downto 4);
sum(11 downto 8) <= bcd_rg(11 downto 8) + 3 when bcd_rg(11 downto 8) > 4 else bcd_rg(11 downto 8);
sum(15 downto 12) <= bcd_rg(15 downto 12) + 3 when bcd_rg(15 downto 12) > 4 else bcd_rg(15 downto 12);

process (clk)
begin
if (clk'event and clk = '1') then
    if ct_bit_bin = 0 then
        enable_rd_bcd <= '1';
        bcd <= bcd_rg;
        bcd_rg <= X"0000";
        bin_rg <= bin;
        ct_bit_bin <= "1100";
    else
        enable_rd_bcd <= '0';
        bcd_rg <= sum(14 downto 0) & bin_rg(11);
        bin_rg <= bin_rg(10 downto 0) & '0';
        ct_bit_bin <= ct_bit_bin - 1;
    end if;
end if;
end process;

end bin2bcd;

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.