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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Оптимальная реализация мультиплексора
DeadMoroz
сообщение Jan 15 2008, 13:25
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 3-02-05
Пользователь №: 2 391



Ситуация такая - в проекте имеется большой мультиплексор к которому подключена куча регистров. Timing Analyzer показывает, что это самое тормознутое место в проекте. Сейчас проект растет, при этом Fmax падает. Т.е. необходимо оптимизировать узкие места. Я пробовал несколько способов описания мультиплексора (с помощью case, if, tri-state), но особого изменения по скорости нет. Сейчас использую такое описание:
Код
  -- DATA output MX
  process(nand_busy, sreg_test_sel, sreg_pfd0_sel, sreg_pfd1_sel, sreg_pw0_sel, sreg_pw1_sel, sreg_pctl_sel,
  sreg_ncmd_sel, sreg_nsta_sel, sreg_nrwc_sel, sreg_nadr1_sel, sreg_nadr2_sel, sreg_nadr3_sel,
  sreg_nadr4_sel, sreg_nadr5_sel, sreg_nid1_sel, sreg_nid2_sel, sreg_nid3_sel, sreg_nid4_sel, sreg_nid5_sel,
  nand_buf_sel,
  nand_dout)
  begin
    if(sreg_test_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_test(7 downto 0);
    elsif(sreg_pfd0_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_pfd0(7 downto 0);
    elsif(sreg_pfd1_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_pfd1(7 downto 0);
    elsif(sreg_pw0_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_pw0(7 downto 0);
    elsif(sreg_pw1_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_pw1(7 downto 0);
    elsif(sreg_pctl_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_pctl(7 downto 0);  
    elsif(sreg_ncmd_sel='1') then                              
      dataout_mx(15 downto 0)<=x"00" & sreg_ncmd(7 downto 0);  
    elsif(sreg_nsta_sel='1') then
      dataout_mx(15 downto 0)<=sreg_ncsta(7 downto 0) & sreg_nsta(7 downto 0);  
    elsif(sreg_nrwc_sel='1') then
      dataout_mx(15 downto 0)<=sreg_nrwc(15 downto 0); -- 16 bits
    elsif(sreg_nadr1_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nadr1(7 downto 0);  
    elsif(sreg_nadr2_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nadr2(7 downto 0);  
    elsif(sreg_nadr3_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nadr3(7 downto 0);  
    elsif(sreg_nadr4_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nadr4(7 downto 0);  
    elsif(sreg_nadr5_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nadr5(7 downto 0);  
    elsif(sreg_nid1_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nid1(7 downto 0);  
    elsif(sreg_nid2_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nid2(7 downto 0);  
    elsif(sreg_nid3_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nid3(7 downto 0);  
    elsif(sreg_nid4_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nid4(7 downto 0);  
    elsif(sreg_nid5_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nid5(7 downto 0);  
    elsif(nand_buf_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & nand_dout(7 downto 0);  
    else                                                      
      dataout_mx(15 downto 0)<=x"FFFF";  
    end if;
  end process;  

  -- DATA output reg
  process(CLK100, dataout_mx)
  begin
    if(rising_edge(CLK100)) then
      dataout_reg(15 downto 0)<=dataout_mx(15 downto 0);
    end if;
  end process;


Как можно соптимизировать этого монстра - разбить на кучу маленьких и запайплайнить? Или как?
Сейчас Fmax=106MHz и очень не хочется делать ее меньше. Кстати, использую Spartan-3E(-4).
Принимаются любые соображения.
Go to the top of the page
 
+Quote Post
dxp
сообщение Jan 15 2008, 14:02
Сообщение #2


Adept
******

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



Цитата(DeadMoroz @ Jan 15 2008, 19:25) *
Как можно соптимизировать этого монстра - разбить на кучу маленьких и запайплайнить? Или как?

Самым кардинальным способом является тот, который вы упомянули - слепить конвейер. Остальное - ловля блох, имхо.


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


Lazy
******

Группа: Свой
Сообщений: 2 070
Регистрация: 21-06-04
Из: Ukraine
Пользователь №: 76



Цитата(DeadMoroz @ Jan 15 2008, 17:25) *
Ситуация такая - в проекте имеется большой мультиплексор к которому подключена куча регистров. Timing Analyzer показывает, что это самое тормознутое место в проекте. Сейчас проект растет, при этом Fmax падает. Т.е. необходимо оптимизировать узкие места. Я пробовал несколько способов описания мультиплексора (с помощью case, if, tri-state), но особого изменения по скорости нет. Сейчас использую такое описание:
Код
  -- DATA output MX
  process(nand_busy, sreg_test_sel, sreg_pfd0_sel, sreg_pfd1_sel, sreg_pw0_sel, sreg_pw1_sel, sreg_pctl_sel,
  sreg_ncmd_sel, sreg_nsta_sel, sreg_nrwc_sel, sreg_nadr1_sel, sreg_nadr2_sel, sreg_nadr3_sel,
  sreg_nadr4_sel, sreg_nadr5_sel, sreg_nid1_sel, sreg_nid2_sel, sreg_nid3_sel, sreg_nid4_sel, sreg_nid5_sel,
  nand_buf_sel,
  nand_dout)
  begin
    if(sreg_test_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_test(7 downto 0);
    elsif(sreg_pfd0_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_pfd0(7 downto 0);
    elsif(sreg_pfd1_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_pfd1(7 downto 0);
    elsif(sreg_pw0_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_pw0(7 downto 0);
    elsif(sreg_pw1_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_pw1(7 downto 0);
    elsif(sreg_pctl_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_pctl(7 downto 0);  
    elsif(sreg_ncmd_sel='1') then                              
      dataout_mx(15 downto 0)<=x"00" & sreg_ncmd(7 downto 0);  
    elsif(sreg_nsta_sel='1') then
      dataout_mx(15 downto 0)<=sreg_ncsta(7 downto 0) & sreg_nsta(7 downto 0);  
    elsif(sreg_nrwc_sel='1') then
      dataout_mx(15 downto 0)<=sreg_nrwc(15 downto 0); -- 16 bits
    elsif(sreg_nadr1_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nadr1(7 downto 0);  
    elsif(sreg_nadr2_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nadr2(7 downto 0);  
    elsif(sreg_nadr3_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nadr3(7 downto 0);  
    elsif(sreg_nadr4_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nadr4(7 downto 0);  
    elsif(sreg_nadr5_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nadr5(7 downto 0);  
    elsif(sreg_nid1_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nid1(7 downto 0);  
    elsif(sreg_nid2_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nid2(7 downto 0);  
    elsif(sreg_nid3_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nid3(7 downto 0);  
    elsif(sreg_nid4_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nid4(7 downto 0);  
    elsif(sreg_nid5_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & sreg_nid5(7 downto 0);  
    elsif(nand_buf_sel='1') then
      dataout_mx(15 downto 0)<=x"00" & nand_dout(7 downto 0);  
    else                                                      
      dataout_mx(15 downto 0)<=x"FFFF";  
    end if;
  end process;  

  -- DATA output reg
  process(CLK100, dataout_mx)
  begin
    if(rising_edge(CLK100)) then
      dataout_reg(15 downto 0)<=dataout_mx(15 downto 0);
    end if;
  end process;


Как можно соптимизировать этого монстра - разбить на кучу маленьких и запайплайнить? Или как?
Сейчас Fmax=106MHz и очень не хочется делать ее меньше. Кстати, использую Spartan-3E(-4).
Принимаются любые соображения.


Кстати, осторожно, конвейер может Вам форму сигнала изменить...
Точнее, д-триггеры, из которых он состоит. Если конечно, данные не синхронны
с частотой конвейера....


--------------------
"Everything should be made as simple as possible, but not simpler." - Albert Einstein
Go to the top of the page
 
+Quote Post
sazh
сообщение Jan 15 2008, 15:33
Сообщение #4


Гуру
******

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



Т.е. необходимо оптимизировать узкие места. Я пробовал несколько способов описания мультиплексора (с помощью case, if, tri-state), но особого изменения по скорости нет
/////////////////////////////////////////////////////////////
приоритетное мультиплексирование и мультиплексирование должны давать разные результаты.
Как по времени так и посхемной реализации.
Наверно можно сгруппировать мультиплексирование по разрядности шин.
Go to the top of the page
 
+Quote Post
alex5991
сообщение Jan 15 2008, 15:52
Сообщение #5


Участник
*

Группа: Новичок
Сообщений: 20
Регистрация: 13-10-06
Пользователь №: 21 281



Цитата(DeadMoroz @ Jan 15 2008, 17:25) *
Ситуация такая - в проекте имеется большой мультиплексор к которому подключена куча регистров. Timing Analyzer показывает, что это самое тормознутое место в проекте. Сейчас проект растет, при этом Fmax падает. Т.е. необходимо оптимизировать узкие места. Я пробовал несколько способов описания мультиплексора (с помощью case, if, tri-state), но особого изменения по скорости нет. Сейчас использую такое описание:

Как можно соптимизировать этого монстра - разбить на кучу маленьких и запайплайнить? Или как?
Сейчас Fmax=106MHz и очень не хочется делать ее меньше. Кстати, использую Spartan-3E(-4).
Принимаются любые соображения.


При любом описании (if-else, tri-state, case) и т.д. реализация получится прблизительно одинаковой.
Однако могу вам предложить несколько другой подход.
Если в вашем проекте последовательность формирования сигналов селекции, а следовательно и последовательность выдачи данных одна и таже, можно все данные вначале выгружать в буферный конвейерный регистр, а затем выдавать их на внешнюю шину. Конечно такая реализация "съест" много рессурсов, но производительность получится максимальной. Кроме того в этом случае вы получите информацию о статусе системы в момент переноса данных в буферный регистр, т.е. не совсем реальное время. Насколько это подойдет определяется конечно же конкретными требованиями системы.
Go to the top of the page
 
+Quote Post
DeadMoroz
сообщение Jan 15 2008, 23:38
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 3-02-05
Пользователь №: 2 391



Victor - не пойму, почему форма сигнала может измениться? ведь конвеер только добавит задержку на n тактов?

sazh - Вы имеете ввиду сделать отдельные mx для каждого разряда?

alex5991- такой подход неприменим, т.к. внешний CPU может обращаться к регистрам FPGA в произвольном порядке.
Go to the top of the page
 
+Quote Post
des00
сообщение Jan 16 2008, 03:32
Сообщение #7


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

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



2 DeadMoroz.

А не могли бы вы конкретизировать критические пути ? Это именно пути данных или пути управления ?

Поясню.

Похоже что вы пользуете альтеру, на альтере мультиплексор 4в1 формируется на 2 лютах = 2 слоя логики. остальное каскадируется из него. Итого муксер 16в1 даст 4 слоя логики, муксер 32в1 5 слоев. Если у вас на входе выходе муксера стоят регистры то проблему с такой тактовой мона решить ручным размещением муксера (хотя тут надо смотреть на вашу фпга может там триггерная частота 150МГц ).

Но бОльшая проблема это декодирование onehot сигналов мультиплексирования ! Т.к. в вашем случае вам нужен декодер из 20 ти сигналов в вектор шириной 5 бит, используемый для мультиплексирования. Тут кол-во слоев логики от onehot сигналов до выходного бита данных будет гораздо больше чем в путе по данным.

В этом случае нужно либо конвееризировать этот декодер или выдержать эти сигналы 2 такта и обозвать их мультицикловыми. Или отказаться от onehot кодирования этих сигналов. сделать обычное бинарное кодирование.

Т.е. определите какой именно путь тормозит.

ЗЫ. У хилых там все намного проще, муксер 32в1 использует аппаратный муксер в пределах CLB и путь по данным там намного короче. За счет более коротких трасс данных.

Удачи.


--------------------
Go to the top of the page
 
+Quote Post
Postoroniy_V
сообщение Jan 16 2008, 04:47
Сообщение #8


МедвеД Инженер I
****

Группа: Свой
Сообщений: 816
Регистрация: 21-10-04
Пользователь №: 951



Цитата(DeadMoroz @ Jan 15 2008, 22:25) *
Ситуация такая - в проекте имеется большой мультиплексор к которому подключена куча регистров. Timing Analyzer показывает, что это самое тормознутое место в проекте. Сейчас проект растет, при этом Fmax падает. Т.е. необходимо оптимизировать узкие места. Я пробовал несколько способов описания мультиплексора (с помощью case, if, tri-state), но особого изменения по скорости нет. Сейчас использую такое описание:
................
Как можно соптимизировать этого монстра - разбить на кучу маленьких и запайплайнить? Или как?
Сейчас Fmax=106MHz и очень не хочется делать ее меньше. Кстати, использую Spartan-3E(-4).
Принимаются любые соображения.

У меня "дурацкое" предложение, а что если регистры запихать в память(2-х портоувую)? cranky.gif
предполагаю Ваш ответ, памяти мало и её жалко laughing.gif
Если так, то вариантов не так уж и много, их уже все перечислили smile.gif


--------------------
Cogito ergo sum
Go to the top of the page
 
+Quote Post
EvgenyNik
сообщение Jan 16 2008, 06:17
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 597
Регистрация: 24-05-06
Из: г. Чебоксары
Пользователь №: 17 402



DeadMoroz, фактически у Вас 8-битные регистры, но 16-разрядная шина.
Предлагаю во-первых, объединить регистры по два и разбирать их уже внутри CPU. Т.е. младший разряд адреса не выдавать наружу, а использовать внутри программы для выбора октавы слова. Это сэкономит время при последовательном чтении двух регистров и упростить процесс и скорость мультиплексирования.
Во-вторых, возможно, Вам подойдёт вариант (совместно с первым) пакетного чтения всех данных и выбор нужных уже внутри CPU. В этом случае можно применить буферный регистр (о нём, видимо, шла речь выше) с параллельной загрузкой всех данных и последовательной выдачей по 16 бит.


--------------------
Почему разработчики систем повышенной надёжности плохо справляются с простыми проектами? :)
Go to the top of the page
 
+Quote Post
Victor®
сообщение Jan 16 2008, 07:50
Сообщение #10


Lazy
******

Группа: Свой
Сообщений: 2 070
Регистрация: 21-06-04
Из: Ukraine
Пользователь №: 76



Цитата(DeadMoroz @ Jan 16 2008, 03:38) *
Victor - не пойму, почему форма сигнала может измениться? ведь конвеер только добавит задержку на n тактов?

sazh - Вы имеете ввиду сделать отдельные mx для каждого разряда?

alex5991- такой подход неприменим, т.к. внешний CPU может обращаться к регистрам FPGA в произвольном порядке.


Привет!
Посмотрите рисунок... сравните D и Q.
Естественно, чем выше частота тактирования относительно D,
тем меньше эффект проявляется
Эскизы прикрепленных изображений
Прикрепленное изображение
 


--------------------
"Everything should be made as simple as possible, but not simpler." - Albert Einstein
Go to the top of the page
 
+Quote Post
DeadMoroz
сообщение Jan 16 2008, 14:11
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 3-02-05
Пользователь №: 2 391



des00 - так сразу не скажу где затык - в цепи данных или декодирования, позже посмотрю, но насколько я помню, Static Timing Analyzer показывал 5 слоев логики. Использую я кстати Spartan-3E 500ку + XST, не альтеру.

Postoroniy_V - да я думал насчет такого варианта, и память еще есть и ее даже не жалко, но не получится же получить побитовый доступ к этой двухпортовке. А чтобы получить - придецца забабахать какую нибудь FSM которая будет гонять данные между памятью и регистрами, я так понимаю.

Евгений Николаев - да, конечно, 8ми битные регистры можно объединить, только это временное улучшение, т.к. мне надо будет добавить еще кучу новых.

Victor® - ага, я понял, но вроде мне это не грозит - все внутренние данные синхронны, домен один.
Go to the top of the page
 
+Quote Post
DmitryR
сообщение Jan 16 2008, 15:07
Сообщение #12


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

Группа: Свой
Сообщений: 1 535
Регистрация: 20-02-05
Из: Siegen
Пользователь №: 2 770



Цитата(DeadMoroz @ Jan 16 2008, 17:11) *
des00 - так сразу не скажу где затык - в цепи данных или декодирования, позже посмотрю, но насколько я помню, Static Timing Analyzer показывал 5 слоев логики.

Это потому, что у вас описан не мультиплексор, а priority encoder. Мультиплексор делается на case и будучи 1:32 получится довольно быстрым (один слой LUT и далее MUXFX) .
Go to the top of the page
 
+Quote Post
DeadMoroz
сообщение Jan 16 2008, 22:44
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 3-02-05
Пользователь №: 2 391



Как я уже говорил, я пробовал разные варианты. Как не странно, самый быстрый был на тристейтах (я не утверждаю, что mux был самый быстрый, просто при такой реализации Fmax проекта была max)
Go to the top of the page
 
+Quote Post
des00
сообщение Jan 17 2008, 03:57
Сообщение #14


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

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



Цитата(DeadMoroz @ Jan 16 2008, 09:11) *
des00 - так сразу не скажу где затык - в цепи данных или декодирования, позже посмотрю, но насколько я помню, Static Timing Analyzer показывал 5 слоев логики. Использую я кстати Spartan-3E 500ку + XST, не альтеру.


если платформа от хилых, тогда 32 в 1 должен ложится в LUT-> MUXF4->MUXF5->MUXF6->MUXF7
см refer to the “Using Dedicated Multiplexers” chapter in UG331.
при этом задержки разводки должны отсутствовать, т.к. все идет в пределах CLB.

Все сильно похоже на задержку по цепи управления, определяется это легко. В логах на тайминги указываются начальные и конечные точки измерения задержки.

описывайте мультиплексор через case. если можно играть с адресами, то можно попробывать разбить регистры на группы, что бы выиграть немного в ресурсе.

И ИМХО если есть возможность откажитесь от ohehot кодирования сигналов адреса мультиплексора в пользу бинарных. либо держите их 2 такта ( + multicycle constrain 2) и получите бинарный адрес на регистре.

Удачи.


--------------------
Go to the top of the page
 
+Quote Post
yuri_d
сообщение Jan 17 2008, 08:39
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 292
Регистрация: 28-01-05
Из: МО, Мытищи
Пользователь №: 2 274



Цитата(DeadMoroz @ Jan 15 2008, 16:25) *
Как можно соптимизировать этого монстра - разбить на кучу маленьких и запайплайнить? Или как?
Сейчас Fmax=106MHz и очень не хочется делать ее меньше. Кстати, использую Spartan-3E(-4).

Проблема может быть и в длинне трасс от регистров до регистра после мультиплексора. Так на кристалле XC3S400-4 оринтировочный порог 10 нс. На большем кристалле (Вы не указали размер) будет хуже.

Если не жалко задержать выдачу на 1 такт, то можно предложить такую схему (Dn - данные в регистрах, Sn - выборка региста по методу one-hot):
1) объединяем данные от группы регистров, расположенных недалеко друг от друга и защелкиваем в промежуточный регистр.
Q <= D0 & S0 | D1 & S1 (это ложится в один LUT4+D)
Q <= D0 & S0 | D1 & S1 | D2 & S2 | D3 & S3 (один slice)
2) объединяем выходы промежуточных регистров по "или" и защелкиваем в выходной регистр.
QQ <= Q0 | Q1 | ... Qn

Правда при такой схеме по умолчанию на выходе будет 0 (мы именно такой метод применяем, так как 0 более безопасное значение в случае ошибок программистов). Если принципиально нужно все 1 (FFFF). То используем чуть другую функцию и объединение по "и":
Q <= (D0 | ~S0) & (D1 | ~S1)
QQ <= Q0 & Q1 & ... Qn

Пример логических выражений на языке Verilog. Думаю это не составит проблему.

Использовать мультиплексор (предложения в постах выше) получится только если все регистры идут последовательно в адресном пространстве и выровнены на границу 2 в N. Иными словами адрес представляе собой двоичное число. Иначе всё выродится в схему, предложенную выше (выборка по и, далее объединение по или).
Go to the top of the page
 
+Quote Post

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

 


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


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