Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Вс май 27, 2018 21:25

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
 Заголовок сообщения: Конвейерный многоядерный процессор.
СообщениеДобавлено: Пн мар 12, 2012 19:34 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
При разработке процессоров на ПЛИС фирмы ALTERA возникает ряд сложностей, связанный с особенностями встроенной блоковой памяти. Память может работать на высокой частоте, но время выборки составляет несколько тактов, в результате чего при последовательной выборке команд и данных возникают лишние задержки.

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

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

Запишем работу блочной памяти ПЛИС (здесь и далее речь и блочной памяти ПЛИС ф. ALTERA) в виде следующих действий:

1. фиксация адреса.
2. Выборка данных из массива и фиксация их в выходном регистре.

Фактически, это те два такта, требуемые для выборки данных из блочной памяти ПЛИС.
Реально, для увеличения скорости работы памяти, приходится добавлять на выход еще один регистр, и тогда добавляется этап:

3. Фиксация выходных данных в дополнительном регистре.

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

1. Фиксация команды в регистре команд
2. Дешифрация и исполнение команды - модификация "всех" регистров процессора.

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

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

Объединяя обе схемы получаем следующую последовательность действий, которую должна выполнять система процессор-память:

1. фиксация адреса.
2. Выборка данных из массива и фиксация их в выходном регистре.
3. Фиксация выходных данных в дополнительном регистре.
4. Фиксация команды в регистре команд
5. Дешифрация и исполнение команды - модификация "всех" регистров процессора.
6. Дополнительный период для исполнения команды

Эта последовательность в простейшем случае должна исполняться по кругу.
При этом на исполнения одной команды процессора тратится шесть тактов.

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

Идея в следующем.
Состояние процессора определяется содержимым его регистров, и может быть помещено в некий регистр конечной длины.
Возьмем 6 таких регистров, поместим в них начальные данные для шести процессоров и зациклим регистры в кольцо так, что бы каждый такт содержимое регистров сдвигалось по кругу.
Закрепим за каждой позицией в круге одно из действий описанных выше, и получим в результате кольцевой шестипозиционный конвейер, который при исполнении будет за шесть тактов выполнять шесть потоков команд для шести процессоров.

Общая скорость исполнения для такой системы соответствует тактовой частоте. И на каждый процесс отводится ровно 1/6 общего времени без потерь на переключение процессов.

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

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Конвеерный многоядерный процессор.
СообщениеДобавлено: Вт мар 13, 2012 18:30 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
Сегодня высказанная выше идея прошла практическую проверку.

За основу взял свой четырехбитный EQUINOX, раскидал его логику на конвейер, подключил тестовую память и прогнал маленькую тестовую программку с симуляторе, запуская одно из шести ядер.

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

Результаты для 6Е16 получились такие:

Объем шестиядерного процессора - ~3000LCELLs
Частота на циклоне-3 с максимальным спидгрейдом - 250MHz.
на циклоне-3 со спидгрейдом 8 частота - 200-210 MHz.
на циклоне-2 со спидгрейдом 7 частота - 200MHz.

Для интереса посмотрел, что получается на 3-м стратиксе... :shock: - более 500MHz...

Все варианты с включенным в систему команд умножением 16x16.

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Конвейерный многоядерный процессор.
СообщениеДобавлено: Вт мар 13, 2012 21:38 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 6314
Благодарил (а): 14 раз.
Поблагодарили: 99 раз.
Так оно в один logic level уложилось? А сколько команд в АЛУ?


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Конвейерный многоядерный процессор.
СообщениеДобавлено: Вт мар 13, 2012 22:16 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
Хищник писал(а):
Так оно в один logic level уложилось? А сколько команд в АЛУ?


в один не уложилось.. в АЛУ три ступени выполнения. А операций почти два десятка.

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Конвейерный многоядерный процессор.
СообщениеДобавлено: Вт мар 13, 2012 23:06 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 6314
Благодарил (а): 14 раз.
Поблагодарили: 99 раз.
WingLion писал(а):
в один не уложилось.. в АЛУ три ступени выполнения. А операций почти два десятка.

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


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Конвейерный многоядерный процессор.
СообщениеДобавлено: Ср мар 14, 2012 04:30 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
Хищник писал(а):
Но если такие частоты, то между триггерами явно должно быть минимум логики. Или сами операции конвейеризованы, и три отсюда ступени?


конвейер в АЛУ возникает фактически из-за необходимости мультиплексирования результатов. А сами операции выполняются за один такт на отдельных схемах.

фактически отдельно есть умножитель, сумматор-вычитатель, логик (and/or/xor/nand), инкрементер/декрементер/инвертор, вычислитель флага нуля и pc+1 в доп регистре вычисляется. Сейчас вспомнил, что надо еще чистый сдвигатель в процессор добавить, а то умножением его делать, как планировал, не кузяво.

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

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Конвейерный многоядерный процессор.
СообщениеДобавлено: Ср мар 14, 2012 19:13 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
Для ясности, о чем тут идет речь и чтобы собрать мысли в кучу (короче, чтобы навести тень на плетень), привожу здесь части кода процессора.

Первое - это верхний файл процессора EQUINOX:


Код:
--- стандартные библиотеки ---
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_unsigned.all;
--- свои библиотеки ---
USE WORK.Common_lib.all; -- общая для всех
USE WORK.EQUINOX_lib.all; -- библиотека для ядра процессора EQUINOX

-- объявляем одиночный процессор
entity EQUINOX_SINGLE is
Port(
   clk,reset,ena : in node := vcc; -- синхро и управляющие входы
   addr : out word; -- адрес памяти/устройств
   do : out word; -- выход данных, записываемых в память/устройства
   di : in word := zero16; -- вход данных/команд из памяти
   mwr,mrd : out node; -- управление работой памяти
   
   test_top,test_bot,test_pc,test_cmd : out word -- тестовые выходы
);
end EQUINOX_SINGLE;

architecture rtl of EQUINOX_SINGLE is

   signal cpu : cpu_t; -- все регистры процессора
        -- объявлены в одной переменной типа record, определенной в библиотеке

begin

        -- главный процесс
   process (clk) begin
      if reset = gnd then
                        -- по сбросу устанавливаем счетчик команд в ноль
         cpu1.pc <= zero16;
                        -- и регистр команд заполняем командами NOP
         cpu.cmd <= nops;
      elsif clk'event and clk = vcc and ena = vcc then
                        -- по каждому разрешенному такту
                        -- выполняем один шаг работы процессора
         cpu <= equinox_main(cpu,di); -- зависящий от состояния
                        -- процессора и входных данных
                        -- функция определена в библиотеке ядра процессора
      end if;
      -- на этом vhdl-описание процессора закончено!
                -- осталось только подключить выходные сигналы
      addr <= equinox_main(cpu,di).oadr;
      do <= equinox_main(cpu,di).odat;
      mwr <= equinox_main(cpu,di).mwr;
      mrd <= equinox_main(cpu,di).mrd;
      
   end process;
   -- и подключить тестовые сигналы
   test_top   <= cpu1.dst.top;
   test_bot   <= cpu1.dst.bot;
   test_pc      <= cpu1.pc;
   test_cmd    <= cpu1.cmd;
   --- теперь совсем конец
end;


Описанный здесь однотактный процессор нормально работает, если в качестве памяти к нему подключить нечто быстрое, выдающее результат за один такт. Например, ПЗУ на логических ячейках, порты ввода/вывода, доп-регистры на ячейках ПЛИС, и получится простейший работоспособный контроллер. С рабочей частотой 100MHz и выше.

Чтобы этот процессор заработал с внутренней памятью ПЛИС, его придется подтормаживать. Если на clk подать 100MHz, то на ena придется подать 33MHz со скважностью 1:3, и схема будет работать фактически на этих 33MHz...

один такт работает логическое ядро процессора, два других - производится выборка из памяти.

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Конвейерный многоядерный процессор.
СообщениеДобавлено: Ср мар 14, 2012 19:28 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
И поэтому я делаю следующий шаг.

В схему добавляются еще два набора регистров процессора, и все три набора включаются в кольцо:

Опускаю шапку и конец исходника, которые фактически не меняются. Измененная часть:
Код:
architecture rtl of EQUINOX_3E16 is

--   signal cpu : cpu_t;
-- три совершенно одинаковых набора регистров
   signal cpu1,cpu2,cpu3 : cpu_t;

begin
   process (clk) begin
   
      if reset = gnd then
                        -- по сбросу все счетчики команд устанавливаются на разные адреса
         cpu1.pc <= zero16;
         cpu2.pc <= zero16+256;
         cpu3.pc <= zero16+512;
         cpu1.cmd <= zero16; -- первое ядро стартует с NOP-ов
         cpu2.cmd <= stops; -- два других
         cpu3.cmd <= stops; -- остановлены
      elsif clk'event and clk = vcc and ena = vcc then
                        -- кольцо из трех наборов регистров с одним логическим ядром
         cpu1 <= equinox_main(cpu3,di);
         cpu2 <= cpu1;
         cpu3 <= cpu2;
      end if;


На вход ena в такой схеме уже можно смело подавать логическую единицу, и все три ядра заработают на частоте 1/3 от частоты clk...

Собственно, в симуляторе это хорошо видно. Картинки не привожу, потому что кто сам с усам, тот их сам легко получит, а кому все это не интересно, тому и картинки не интересны.

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Конвейерный многоядерный процессор.
СообщениеДобавлено: Ср мар 14, 2012 19:37 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
Следующий шаг - это шестиядерный конвейерный вариант.

Тут, собственно, интересно только это:

Начальная схема, где конвейера еще и нет:

Код:
rchitecture rtl of EQUINOX_6E16 is

--attribute altera_attribute : string;
-- Attribute set on architecture, not entity
--attribute altera_attribute of rtl: architecture is "-name AUTO_SHIFT_REGISTER_RECOGNITION OFF";   

   signal cpu : cpu_t;
   signal cpu1,cpu2,cpu3,cpu4,cpu5,cpu6 : cpu_t;

begin
   process (clk) begin
   
      if reset = gnd then
         cpu1.pc <= zero16;
         cpu2.pc <= zero16+256;
         cpu3.pc <= zero16+512;
         cpu4.pc <= zero16+768;
         cpu5.pc <= zero16+1024;
         cpu6.pc <= zero16+1280;
         
         cpu1.cmd <= zero16;
         cpu2.cmd <= stops;
         cpu3.cmd <= stops;
         cpu4.cmd <= stops;
         cpu5.cmd <= stops;
         cpu6.cmd <= stops;
         
      elsif clk'event and clk = vcc and ena = vcc then
         cpu1 <= equinox_main(cpu8,di);
         cpu2 <= cpu1;
         cpu3 <= cpu2;
         cpu4 <= cpu3;
         cpu5 <= cpu4;
         cpu6 <= cpu5;
      end if;
      
      cpu <= cpu4;

      addr <= cpu.oadr;
      do <= cpu.odat;
      mwr <= cpu.mwr;
      mrd <= cpu.mrd;
      id <= cpu.id;
      
   end process;
   
   test_top   <= cpu.dst.top;
   test_bot   <= cpu.dst.bot;
   test_pc      <= cpu.pc;
   test_cmd    <= cpu.cmd;
   


Здесь важно для понимания, что выходные шины подключены не к первому ядру, как в трехядерном варианте, а к 4му, что обеспечивает появление адреса для памяти за 2 такта до момента, когда будут нужны соответствующие данные.

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

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Конвейерный многоядерный процессор.
СообщениеДобавлено: Ср мар 14, 2012 19:53 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
A следующий вариант - это мультиядерный процессор с параметрически задаваемым количеством ядер:
Код:
-- шапка та же
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_unsigned.all;
USE WORK.Common_lib.all;
USE WORK.EQUINOX_lib.all;

entity EQUINOX_NE16 is
generic(
        -- параметр - количество ядер
   N : integer := 8 -- number of CPU cores
);
Port(
   clk,reset,ena : in node := vcc;
   addr : out word;
   do : out word;
   di : in word;
   mwr,mrd : out node;
   id : out byte; -- выход идентификатора ядра
   
   test_top,test_bot,test_pc,test_cmd : out word
);
end EQUINOX_NE16;

architecture rtl of EQUINOX_NE16 is

   -- создаем новый тип-массив из записей с регистрами процессорных ядер
   type cpus_t is array (1 to N) of cpu_t;
   -- объявляем сам массив
   signal cpus : cpus_t;
   
        -- вспомогательная переменная
   signal cpu : cpu_t; -- в схеме она набор отображающий
        -- состояние одного из ядер процессора, а не регистров


        -- вспомогательные сигналы для запуска
   signal cnt_reset : int8; -- счетчик сброса
   signal rst : node; -- внутренний сброс

begin
   process (clk) begin
   
      if reset = gnd then
                        -- по внешнему сбросу, устанавливаем внутренний
                        -- сброс и счетчик наколичество ядер
         cnt_reset <= N; rst <= gnd;
      elsif clk'event and clk = vcc and ena = vcc then
                        -- по тактам перебираем все ядра от N-го до первого
         if cnt_reset > 0 then
                                -- пока счетчик не обнулился,
            cnt_reset <= cnt_reset - 1;
            rst <= gnd; --держим внутренний сброс
         else
            rst <= vcc;
         end if;

         if rst = gnd then
                                -- по внутреннему сбросу инициируем все ядра
            if cnt_reset /= 1 then
                                        -- все не первые стоят
               cpus(cnt_reset).id <= zero8+cnt_reset;
               cpus(cnt_reset).cmd <= stops;
               cpus(cnt_reset).pc <= zero16 + (cnt_reset - 1)*256;
            else
                                        -- а первое стартует с нулевого адреса
               cpus(cnt_reset).id <= zero8+cnt_reset;
               cpus(cnt_reset).cmd <= nops;
               cpus(cnt_reset).pc <= zero16;
            end if;
         else
                                -- кольцо из ядер
            cpus(2 to N) <= cpus(1 to N-1);
                                -- и логическое ядро
            cpus(1) <= equinox_main(cpus(N),di);
         end if;
      end if;
                -- вспомогательный набор регистров соотвтетствует ядру, которое
                -- через 2 такта будет ожидать свои данные на шине di
      cpu <= cpus(N-2);
                -- для него и выводим наружу адрес, данные,
                -- управляющие шины и идентификатор
      addr <= cpu.oadr;
      do <= cpu.odat;
      mwr <= cpu.mwr;
      mrd <= cpu.mrd;
      id <= cpu.id;
      
   end process;
   -- тестовые шины уже можно и выкинуть
   test_top   <= cpu.dst.top;
   test_bot   <= cpu.dst.bot;
   test_pc      <= cpu.pc;
   test_cmd    <= cpu.cmd;
   
end;


Такая вот, штучка....

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

Без оптимизации начальная частота - 89MHz, a при ее включении, частота подымается до 144MHz еще без ручного раскидывания операций по конвейеру.

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB