Jump to content
    

Реализация конвейера на VHDL

Проц создавался как следующая реализация выше приведенного аналога "однобитового процессора".

Но в процессе создания он превратился в новый вид, можно так сказать. По общей структуре проц такой же как и предыдущие, это связка DP и CU.

Но сами DP и CU из за конвейера серьезно отличаются от предыдущих. Описание и картинки внутренней структуры выложу через пару дней сюда. Скажу сразу, без реализации write back конструкцию можно считать ущербной. Требуется доработка.

Share this post


Link to post
Share on other sites

У меня была вторая мечта, расколоть "Однобитовый микропроцессор" из журнала КиТ 6.2003. .... Обе версии максимально близки по структуре и системе команд к оригиналу описанному в статье КиТ 6.2003

....

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

 

Спасибо за то, что читаете мои статьи. Про конвейер я конечно мог бы и подробнее написать. И предсказание ветвлений объяснить, но это тогда не "ложилось" в ПЛИС, т.к. объем памяти у них был мал. И тогда никто об этом для ПЛИС не задумывался. Для сравнения можно посмотреть то, сколько места занимает обычный НИОС и ускоренный...

А более подробно об этом можно прочитать у Танненбаума в книге "Архитектура компьютера"... см. сайт - http://www.natahaus.ru/

 

Share this post


Link to post
Share on other sites

а почему к этим ветвлениям прицыпились? ничем от остального не отличаются

 

1) поставьте дилей слоты (delay slot) - то есть пока инструкция дойдет до экзекушина или врайтбека - пусть выбирает инструкции (фетч), как ни в чем не бывало

потом можно эти места ноп-ами забить - и вот вам конвеер неостанавливаемый

а уж если хотите быстро считать и побить по производительности всех - то в эти дилей слоты можно и дельных инструкций насовать

 

из канонических процессоров с дилей слотами - посмотрите SPARC (sparcv8.pdf)

из модных TMS C6000 - там с этими дилей слотами че тока не вытворяют :)

 

2) предсказание - в здравых архитектурах компилер в команду условного перехода добавляет битик - вероятность перехода/вероятность не перехода, так как изменение PC происходит на ранних ступеньках конвеера - это просто и эффективно

 

ну то есть если jump if non zero (jnz) стоит в конце цикла, то компилятор ставит битик - переход, и выборка идет с нового адреса, если цикл закончился и переход нужно проскочить (что будет известно позже) - ну чтож штраф за неверное предсказание, но это редко

 

если же в архитектуре (ISA) нет таких битиков, то изголяются, у того же АРМа - переход назад считается более вероятным (видел вроде бы модель ARM11 в симуляторе)

 

 

 

Share this post


Link to post
Share on other sites

Почитал Танненбаума, ветвление с предсказаниями не так то просто реализовать, потому что в случае ошибки придется делать откат уже исполненных команд.

Share this post


Link to post
Share on other sites

Почитал Танненбаума, ветвление с предсказаниями не так то просто реализовать, потому что в случае ошибки придется делать откат уже исполненных команд.

Интересно как это реализовывается, например в Pentium4 ?

 

upd

 

литература

Все равно однозначного ответа не нашел.

Share this post


Link to post
Share on other sites

Интересно как это реализовывается, например в Pentium4 ?

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

Но описано так, чтобы по трезвой не понять было...

 

Share this post


Link to post
Share on other sites

Интересно как это реализовывается, например в Pentium4 ?
В P4 не скажу, а в современных OOO довольно просто. У них есть стадия retire'минга комманд (это когда результаты выполнения комманды заносятся в память). При этом физически выполняется запись в память (для команд записи), или отправляется информация о номере регистра в блок register renaming (для регистровых операций). Соотвественно все комманды, ожидающие retire складываются в спец. буффер. При branch missprediction буффер очищается

 

Share this post


Link to post
Share on other sites

В прикрепленных файлах два варианта процессоров с конвейером и встроенным механизмом write back.

Последовательный процессор, длина исполнения команды в два операнда равна два такта, в один операнд один такт.

Параллельный процессор, выборка и исполнение одно и двух операндных команд производится в один такт.

Оба процессора проверены на разных последовательностях команд, работают нормально, потерь данных не происходит при последовательном изменении одного и того же регистра или ячейки памяти. Моделирование в P&R на одной и той же программе, которая пишет, читает, изменяет, регистры, память и делает переходы, выдало такие результаты:

Последовательный Tmin 9.2ns общее время исполнения отрезка программы 3800ns

Параллельный Tmin 9.2ns общее время исполнения отрезка программы 2800ns

 

Конвейер, как и ранее полностью очищается при выполнении перехода, механизм write back в обоих процессорах сделан так, запоминается записанное значение и подставляется вместо регистра или ячейки памяти, если те не успевают выдать корректные данные. В последовательном процессоре writeback встроен только для регистров. В параллельном два механизма, для регистров и для памяти.

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

 

Share this post


Link to post
Share on other sites

Продолжаю делать велосипед :) Стал задумываться о синтезе, т.к. зачем же нужен конвейер если не для эффективной реализации.

Скажите пожалуйста, насколько эффективно синтезатор может обработать код подобного вида?

 

            
      alu_data0 <= x"00000000";
      alu_data1 <= x"00000000";
      alu_operation <= NOP;
      mem_operation <= NOP;
      mem_address <= 0;
      mem_operand <= x"00000000";      

      case cmd(0).class is
        
        when INSTR_ALU_INT =>

          alu_data0 <= data0;
          alu_data1 <= data1;
          alu_operation <= cmd(0).op_code;        
          instr_pointer <= instr_pointer+1;
        
        when INSTR_MEMORY => 
        
          mem_operand <= data0;
          mem_address <= addr;
          mem_operation <= cmd(0).op_code;
          instr_pointer <= instr_pointer+1;
          
        when INSTR_CONTROL =>
        
          case cmd(0).op_code is
            when HLT =>   instr_pointer <= instr_pointer;
            when JMP =>   instr_pointer <= addr;
            when JNZ =>   
              if flags.Zero then
                instr_pointer <= addr;
              else
                instr_pointer <= instr_pointer+1;
              end if;
            when JG =>
              if flags.GT then
                instr_pointer <= addr;
              else
                instr_pointer <= instr_pointer+1;
              end if;
            when JL =>
              if flags.LT then
                instr_pointer <= addr;
              else
                instr_pointer <= instr_pointer+1;
              end if;
            when JGE =>
              if flags.GE then
                instr_pointer <= addr;
              else
                instr_pointer <= instr_pointer+1;
              end if;
            when JLE =>
              if flags.LE then
                instr_pointer <= addr;
              else
                instr_pointer <= instr_pointer+1;
              end if;
            when others => instr_pointer <= instr_pointer; report "Error, this command should not pass in to control unit";
          end case;
          
        when others => report "Error, unknown command type";
      end case;
        
      cmd(1) <= cmd(0); 
     
    end if;
  end process;

 

 

Интересуют 4 вещи:

1) Вложенный case. Насколько это хорошо/плохо. М.б. имеет смысл разбить на 2 стадии? То есть внутренний case перенести на следующую стадию конвейера. Или даже на 3 стадии - чтобы if внутри убрать.

2) Нужно ли стараться задать значения всем сигналам во всех вариантах выполнения процесса? У Сергиренко в книжке я прочитал что если не все значения сигнала перебрали в case, то создается защелка, что менее эффективно. Но у меня так постоянно получается. В некоторых случаях нужно сигнал изменить, а в других оставить, какой был. А в некоторых случаях не важно - можно записать нулями например. Если я правильно понимаю, то когда мне нужно сохранить предыдущее значение сигнала, защелка все-равно создается. Например здесь, в случае NOP мне обязательно надо сохранить предыдущее значение сигнала 'С'.

case cmd is
        when NOP     =>   null;
        when MOVE    =>   C <= B;
        when ADD_INT =>   C <= to_std_lv(iA + iB);
        when SUB_INT =>   C <= to_std_lv(iA - iB);
        when MUL_INT =>   C <= to_std_lv(iA * iB);
        ...
        when others => report "Error, this command should not pass in to ALU";
end case;

3) Наверняка симулятор и/или синтезатор могут мне сказать, какой минимальной задержкой обладает схема и где конкретно проблема в коде.

Не подскажите, как/где посмотреть? :) Использую Quartus 10.0 sp1 и ModelSim 6.5e (оба бесплатные).

 

4) М.б. есть хорошая книжка или ссылка где можно почитать, во что отображается тот или иной код и как работают синтезаторы? Можно на английском.

То есть понятно конечно что я могу посмотреть в квартусе то, что синтезатор выплюнет, но я к сожалению не очень понимаю эти схемы и мне бы хотелось иметь набор простых примеров - вот это хорошо а это плохо потому что ...

Edited by FROL_256

Share this post


Link to post
Share on other sites

1. Вложенный case преобразуется либо в мультиплексор, либо в ROM

оптимально сначала самому нарисовать на бумажке что именно хочется получить, в результате синтеза,

а затем добиться от синтезатора этой схемы.

Если просто описать математические операции и отдать синтезатору, он из case сделает монстроподобную схему.

Поэтому лучше либо не делать вложенные case, либо сделать внутренние case в виде блоков, которые подключаются

к основному. При этом нужно добиться чтобы остальные варианты case имели такой же интерфейс, это если

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

Но это исключительно мой взгляд, на истину не претендую

2. Чтобы не было защелок выход простой, допустим всего 16 выборов, задействовано только 5, тогда четыре как обычно,

а пятый заменить на others, тогда никаких защелок не будет, и будут задействованы все 16 выборов, 4 как 4, а 5й остальные 11.

3. Это у гуру спрашивайте, я смотрю в Timing отчете P&R

4. Вот пост, в нем документ Learning_VHDL.pdf, там текст на VHDL и картинка во что текст синтезирует XST от Xilinx, с вероятностью 98% остальные синтезаторы выдадут тоже самое http://electronix.ru/forum/index.php?showt...st&p=825138

Share this post


Link to post
Share on other sites

Почитал Танненбаума, ветвление с предсказаниями не так то просто реализовать, потому что в случае ошибки придется делать откат уже исполненных команд.

 

 

стоит еще упомянуть:

Computer Architecture: A Quantitative Approach,

John L. Hennessy (Author)

David A. Patterson (Author)

 

Share this post


Link to post
Share on other sites

tAmega

Большое спасибо. Буду смотреть конспект лекций.

 

>2. Чтобы не было защелок выход простой, допустим всего 16 выборов, задействовано только 5, тогда четыре как обычно,

 

Извините я не понял) И проблему плохо описал. У меня есть 2 выходных сигнала - 'С' и flags

'C' записывают все команды. flags записывает только одна команда - CPM.

 

Я переформулирую вопрос - для того чтобы не было защелок достаточно указать others в конструкции case?

Или обязательно записать все выходные сигналы в каждом варианте case?

Вот например в этом случае будет защелка?

signal A,B : out integer;
...
case cmd is 
  when "00" => A <= 0;
  when "01" => A <= 1;
  when "10" => B <= 1;
  when others => A<=2;
end case;

Edited by FROL_256

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...