Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Оптимальная реализация мультиплексора
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
DeadMoroz
Ситуация такая - в проекте имеется большой мультиплексор к которому подключена куча регистров. 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).
Принимаются любые соображения.
dxp
Цитата(DeadMoroz @ Jan 15 2008, 19:25) *
Как можно соптимизировать этого монстра - разбить на кучу маленьких и запайплайнить? Или как?

Самым кардинальным способом является тот, который вы упомянули - слепить конвейер. Остальное - ловля блох, имхо.
Victor®
Цитата(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).
Принимаются любые соображения.


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

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


При любом описании (if-else, tri-state, case) и т.д. реализация получится прблизительно одинаковой.
Однако могу вам предложить несколько другой подход.
Если в вашем проекте последовательность формирования сигналов селекции, а следовательно и последовательность выдачи данных одна и таже, можно все данные вначале выгружать в буферный конвейерный регистр, а затем выдавать их на внешнюю шину. Конечно такая реализация "съест" много рессурсов, но производительность получится максимальной. Кроме того в этом случае вы получите информацию о статусе системы в момент переноса данных в буферный регистр, т.е. не совсем реальное время. Насколько это подойдет определяется конечно же конкретными требованиями системы.
DeadMoroz
Victor - не пойму, почему форма сигнала может измениться? ведь конвеер только добавит задержку на n тактов?

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

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

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

Поясню.

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

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

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

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

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

Удачи.
Postoroniy_V
Цитата(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
EvgenyNik
DeadMoroz, фактически у Вас 8-битные регистры, но 16-разрядная шина.
Предлагаю во-первых, объединить регистры по два и разбирать их уже внутри CPU. Т.е. младший разряд адреса не выдавать наружу, а использовать внутри программы для выбора октавы слова. Это сэкономит время при последовательном чтении двух регистров и упростить процесс и скорость мультиплексирования.
Во-вторых, возможно, Вам подойдёт вариант (совместно с первым) пакетного чтения всех данных и выбор нужных уже внутри CPU. В этом случае можно применить буферный регистр (о нём, видимо, шла речь выше) с параллельной загрузкой всех данных и последовательной выдачей по 16 бит.
Victor®
Цитата(DeadMoroz @ Jan 16 2008, 03:38) *
Victor - не пойму, почему форма сигнала может измениться? ведь конвеер только добавит задержку на n тактов?

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

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


Привет!
Посмотрите рисунок... сравните D и Q.
Естественно, чем выше частота тактирования относительно D,
тем меньше эффект проявляется
DeadMoroz
des00 - так сразу не скажу где затык - в цепи данных или декодирования, позже посмотрю, но насколько я помню, Static Timing Analyzer показывал 5 слоев логики. Использую я кстати Spartan-3E 500ку + XST, не альтеру.

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

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

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

Это потому, что у вас описан не мультиплексор, а priority encoder. Мультиплексор делается на case и будучи 1:32 получится довольно быстрым (один слой LUT и далее MUXFX) .
DeadMoroz
Как я уже говорил, я пробовал разные варианты. Как не странно, самый быстрый был на тристейтах (я не утверждаю, что mux был самый быстрый, просто при такой реализации Fmax проекта была max)
des00
Цитата(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) и получите бинарный адрес на регистре.

Удачи.
yuri_d
Цитата(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. Иными словами адрес представляе собой двоичное число. Иначе всё выродится в схему, предложенную выше (выборка по и, далее объединение по или).
DmitryR
Цитата(DeadMoroz @ Jan 17 2008, 01:44) *
Как я уже говорил, я пробовал разные варианты.

Вы бы положили сюда вариант как вы делаете на case, может все же неправильно? Посмотрите на принципиальную схему после синтеза, что там стоит, мультиплексор или что-то еще.
DeadMoroz
А код с case был такой:
Код
--  -- DATAOUT MX reg -> registers read
--  process(CLK100, sreg_addr, sreg_test, sreg_pfd0, sreg_pfd1)
--  begin
--    if(rising_edge(CLK100)) then  
--        case(sreg_addr) is
--          when SREG_TEST_ADDR => -- read Test reg                  
--            dataout_reg(15 downto 0)<=x"00" & sreg_test(7 downto 0);
--          when SREG_PFD0_ADDR => -- read Pulse Freq Div 0 reg                
--            dataout_reg(15 downto 0)<=x"00" & sreg_pfd0(7 downto 0);
--          when SREG_PFD1_ADDR => -- read Pulse Freq Div 1 reg                
--            dataout_reg(15 downto 0)<=x"00" & sreg_pfd1(7 downto 0);
--          when SREG_PW0_ADDR => -- read Pulse Width 0 reg                
--            dataout_reg(15 downto 0)<=x"00" & sreg_pw0(7 downto 0);
--          when SREG_PW1_ADDR => -- read Pulse Width 1 reg                  
--            dataout_reg(15 downto 0)<=x"00" & sreg_pw1(7 downto 0);
--          when SREG_PCTL_ADDR => -- read Pulse Control reg                  
--            dataout_reg(15 downto 0)<=x"00" & sreg_pctl(7 downto 0);
--          when SREG_NCMD_ADDR => -- read NAND flash command reg                  
--            dataout_reg(15 downto 0)<=x"00" & sreg_ncmd(7 downto 0);
--          when SREG_NSTA_ADDR => -- read NAND flash status reg                  
--            dataout_reg(15 downto 0)<="0000000" & nand_busy & sreg_nsta(7 downto 0);
--          when SREG_NRWC_ADDR => -- read NAND flash read/write counter reg                  
--            dataout_reg(15 downto 0)<=sreg_nrwc(15 downto 0);
--          when SREG_NADR1_ADDR => -- read NAND flash Address 1 reg                  
--            dataout_reg(15 downto 0)<=x"00" & sreg_nadr1(7 downto 0);
--          when SREG_NADR2_ADDR => -- read NAND flash Address 2 reg                  
--            dataout_reg(15 downto 0)<=x"00" & sreg_nadr2(7 downto 0);
--          when SREG_NADR3_ADDR => -- read NAND flash Address 3 reg                  
--            dataout_reg(15 downto 0)<=x"00" & sreg_nadr3(7 downto 0);
--          when SREG_NADR4_ADDR => -- read NAND flash Address 4 reg                  
--            dataout_reg(15 downto 0)<=x"00" & sreg_nadr4(7 downto 0);
--          when SREG_NADR5_ADDR => -- read NAND flash Address 5 reg                  
--            dataout_reg(15 downto 0)<=x"00" & sreg_nadr5(7 downto 0);
--          when SREG_NID1_ADDR => -- read NAND flash ID 1 reg                  
--            dataout_reg(15 downto 0)<=x"00" & sreg_nid1(7 downto 0);
--          when SREG_NID2_ADDR => -- read NAND flash ID 2 reg                  
--            dataout_reg(15 downto 0)<=x"00" & sreg_nid2(7 downto 0);
--          when SREG_NID3_ADDR => -- read NAND flash ID 3 reg                  
--            dataout_reg(15 downto 0)<=x"00" & sreg_nid3(7 downto 0);
--          when SREG_NID4_ADDR => -- read NAND flash ID 4 reg                  
--            dataout_reg(15 downto 0)<=x"00" & sreg_nid4(7 downto 0);
--          when SREG_NID5_ADDR => -- read NAND flash ID 5 reg                  
--            dataout_reg(15 downto 0)<=x"00" & sreg_nid5(7 downto 0);
--                
--          when others =>                  
--            dataout_reg(15 downto 0)<=x"FF" & x"FF";
--        end case;
--    end if;
--  end process;


Блин, может это все из-за CLK который я вставил вначале, я думал, что это все засинтезируется в mux + reg за ним. Завтра проверю.
DmitryR
Надеюсь, значения SREG_XXX идут по порядку? Если нет - мультиплексора не выйдет. Потом, входы мультиплексора должны идти с регистров (sreg_addr в том числе). Кстати, я бы заодно поставил sreg_addr(4 downto 0).
DeadMoroz
не по порядку, через два - регистры же 16битные
constant SREG_TEST_ADDR: std_logic_vector(15 downto 0):=x"0000";
constant SREG_PFD0_ADDR: std_logic_vector(15 downto 0):=x"0002";
constant SREG_PFD1_ADDR: std_logic_vector(15 downto 0):=x"0004";
constant SREG_PW0_ADDR: std_logic_vector(15 downto 0):=x"0006";
constant SREG_PW1_ADDR: std_logic_vector(15 downto 0):=x"0008";
конечно да, можно поменьше разрядов декодировать, разряды 7-1
DmitryR
Цитата(DeadMoroz @ Jan 17 2008, 16:37) *
не по порядку, через два - регистры же 16битные
конечно да, можно поменьше разрядов декодировать, разряды 7-1

6-1 только, мультиплексор 32:1 требует 5 управляющих разрядов. Делайте, расскажите что вышло.
EvgenyNik
Если не жалко ресурсов, но важна скорость, то можно сделать 2 параллельных мультиплексора, управляемых поочерёдно (допустим Т-триггером с тактированием от того же CLK100) и быстрый MUX2(x16)-1(x16) им на выход. Управляющие ENэйблы, конечно, тоже придётся где-то защёлкивать.
Тогда вы будете получать запрошенные данные при запросе следующих и при тех же 100МГц за счёт чередования сможете получать данные почти на 200МГц. Пока вы считываете данные с одного, другой коммутирует на свой выход нужный регистр.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.