Обзор высокоуровневого языка разработки аппаратуры HaSCoL на примере клона процессора Xilinx Microblaze



Скачать 158.79 Kb.
Pdf просмотр
Дата24.11.2016
Размер158.79 Kb.
Просмотров408
Скачиваний0
ТипОбзор

Обзор высокоуровневого языка разработки аппаратуры
HaSCoL на примере клона процессора Xilinx Microblaze
О. Медведев, НИИ ИТ СПбГУ, м.н.с. Oleg.Medvedev@lanit-tercom.com
Введение
Широко известный эмпирический закон Мура гласит, что каждые полтора-два года количество транзисторов, умещающихся на заданной площади интегральной схемы (ИС), удваивается за счет изменений в технологии изготовления. В последние годы это открыло возможность создавать сложные системы на кристалле, содержащие абсолютно разные компоненты, такие как процессоры общего назначения, специальные процессоры (сетевые, цифровой обработки сигналов), полностью аппаратные реализации алгоритмов. Подобные системы позволяют создавать новые поколения электронных устройств. Однако, закон Мура говорит лишь о том, что фабричное изготовление серии ИС с определенным числом транзисторов дешевеет со временем. Стоимость же разработки, наоборот, лишь растёт, вслед за сложностью и разнородностью устройств.
Самым распространённым сегодня способом реализации синхронной цифровой ИС является ее описание на языке уровня RTL («уровень регистровых пересылок», англ.«Register
Transfer Level»), к которым относятся такие языки, как VHDL, Verilog. Широко распространено мнение (например, оно выражено в предисловиях большинства статей из сборника (1)), что такие описания являются слишком низкоуровневыми. Создаётся множество систем, призванных поднять уровень абстракции разработки аппаратуры, несильно проиграв в качестве (и, таким образом, снизив стоимость разработки ИС засчет повышения производительности труда инженеров). Среди них пока нет доминирующей.
В данной работе рассмотрен высокоуровневый язык описания аппаратуры HaSCoL (2),
(3), (5) в контекcте разработки на нем клона процессора Xilinx Microblaze (4). Будет вкратце описана архитектура процессора, а также, на его примере, будут показаны некоторые из тех особенности языка, которые, по моему мнению, облегчают разработку аппаратуры на
HaSCoL по сравнению с VHDL/Verilog.
Краткое описание процессора
Процессор является клоном конфигурируемого RISC процессора Xilinx Microblaze для встроенных систем и реализует наиболее производительную его версию ― с пятистадийным конвеером, MMU (Memory Management Unit), кешем инструкций.
Обязанности между стадиями конвеера распределены примерно следующим образом:

Fetch ― спекулятивная загрузка инструкций через интерфейс MMU, изменение адреса загрузки по команде перехода от Ex1, пропуск загруженных зря инструкций;

Decode ― проверка на исполнение некорректных и запрещенных инструкций; задержка инструкций, которые читают из регистров, значение которых еще неизвестно (то есть, часть механизма обработки конфликтов по данным); загрузка значений операндов;

Ex0 ― исполнение всех необходимых логических и арифметических операций, кроме сдвигов на произвольную длину и умножений; посылка команд в конвеер сдвигов- умножений; вычисление условий переходов; отправка команды на работу с шиной данных в
MMU, команды на переход в Fetcher; пропуск инструкций, идущих после исполнившегося перехода;

Ex1 ― часть конвеера умножений и сдвигов на переменное число битов;

Write-Back ― запись результатов вычислений в регистры общего назначения; возбуждение прерываний, исключений;
Параллельно стадиям Ex0, Ex1, Write-Back, расположен конвеер умножений и сдвигов на произвольное число битов.

Общая идея разработки процессора заключалась в том, что часто случающиеся операции (исполнение обычных инструкций, загрузка из кеша, из ITLB/DTLB
1
) исполняются конвеерно, допуская производительность в одну инструкцию за такт. Более редкие операции
(чтение регистров MMU, поиск в UTLB) могут приостанавливать конвеер. При этом, пока конвеер заблокирован, все недоисполенные инструкции доисполняются насколько это возможно (что обеспечивается семантикой соответствующих конструкций языка).
Краткая информация о языке и реализующих его инструментах
ИС на HaSCoL представляется в виде набора каналов для передачи сообщений и обработчиков, которые могут ожидать сообщения из канала (каналов) и посылать результаты работы в каналы. Время в языке дискретно и измеряется в тактах. Доставка сообщений не занимает времени. Поддержана блокирующая доставка сообщений ― сообщение считается переданным только в том такте, в котором получатель сигнализирует о готовности принять сообщение. До этого момента посылающий обработчик частично блокируется.
Каждый обработчик является конвеером. Причем, если в нем более одной стадии, то данные, после обработки в 1-ой стадии, попадают во 2-ую только на следующем такте. При этом блокировка распространяется автоматически, так что приостановка одной стадии конвеера на ожидание готовности получателя сообщения влечет приостановку предыдущих стадий в случае, когда это необходимо, чтобы избежать потери данных. Также, автоматически генерируются конвеерные регистры для распространения параметров сообщений и локальных переменных. Данная возможность особенно наглядно видна на следующем примере, реализующем трехстадийный конвеер для вычисления квадратного многочлена:
poly(a, b, c, x : integer(32)) { –- конвеер получает данные из канала poly x2 = x * x | bx = b * x; -- символ ';' обозначает конец такта ax2 = a * x2 | bxc = bx + c; -- '|' ― параллельное исполнение операторов send result(ax2 + bxc) –- «send» означает блокирующую посылку сообщения
}
В этом конвеере заводятся локальные переменные x2, bx, ax2, bxc, позволяющие донести результаты промежуточных вычислений до следующих стадий конвеера. Для данного примера автоматически генерируются 6 регистров для передачи параметров и переменных по стадиям. В оптимальном режиме работы обработчик принимает новый многочлен и точку на каждом такте и выдает на каждом такте значение многочлена, принятого два такта назад. Если канал «result» становится неготов принимать сообщения, то в конвеере накапливаются промежуточные результаты для двух послдених точек и канал
«poly» также становится неготов принимать сообщения.
Несколько обработчиков могут слушать один и тот же канал или посылать сообщения в один и тот же канал. Язык поддерживает возможность указания того, как следует разрешать возникающие при этом конфликты.
Также, язык поддерживает возможность декомпозиции устройства не несколько блоков
― аналогично механизму «entity/architecture» в VHDL. Эта же возможность позволяет легко интегрировать существующие блоки, реализованные на VHDL, в устройство на HaSCoL.
Инструментальные средства поддерживают генерацию описания ИС на HaSCoL в
синтезируемый VHDL, совместимый с такими средствами симуляции и синтеза, как
Modelsim, Xilinx XST, Synplify.
Также в процессе разработки находится генерация в SystemC, совместимый с компилятором gcc и открытой реализацией SystemC.
Несмотря на наличие в языке высокоуровневых конструкций (таких, как блокирующая посылка сообщения), их семантика подобрана так, что позволяет точно разобраться, что в каком такте происходит, если это необходимо в целях ручной оптимизации ИС.
1 про архитектурные особенности процессора Microblaze см. (4)

Некоторые конструкции на примере их применения в процессоре
В данном разделе обсуждаются некоторые конструкции языка, оказавшиеся полезными в реализации процессора.
Порты каналов, приоритеты портов
Синтаксически допустимо написать несколько операторов посылки сообщения в один и тот же канал. Для того, чтобы указывать желаемое поведение в случае, когда начинается посылка нескольких сообщений в одном и том же такте в один и тот же канал, можно объявить, что у канала есть несколько «портов». Если в одном такте приходят сообщения на разные порты, то сообщение с самого выскоприоритетного из них канал начинает принимать, а остальные сообщения он принять не готов.
Пример таков: формально, у процессора Microblaze гарвардская архитектура ― есть отдельная шина для чтения инструкций и для работы с данными. В нашей реализации это выражается в наличии двухканального MMU и отдельного кеша инструкций. Однако, внешняя шина одна, и мастер шины тоже один. Таким образом, на каждом такте, мастер может принять не больше одного запроса ― либо по инструкциям, либо по данным.
Синтаксически, описание канала, принимающего очередную команду, которую надо выставить на шину, выглядит как in toBus(isForInstruction : 1, cmd : busCommand)[DataPort, InstructionPort] ...
Имена портов указаны в квадратных скобках в порядке убывания приоритета. Так выглядит посылка в порт канала: «
... send toBus'DataPort(0b0, cmd) ...»
Таким образом, команды чтения-записи данных имеют более высокий приоритет и могут приостанавливать деятельность блока загрузки инструкций.
Синхронизация нескольких каналов в заголовке обработчика
Иногда обработчик ждет появления сообщений из нескольких каналов одновременно. В том такте, в котором в каждом канале есть по сообщению, они начинают обрабатываться и одновременно сохраняются в локальных регистрах на случай, если обработка займет несколько тактов. Дальнейшее изменение содержимого каналов не влияет на обрабатываемые данные (своеобразная атомарность транзакции по обработке сообщения). Если локальные регистры можно убрать, не нарушая семантики, оптимизатор это делает.
Примером подобной синхронизации может послужить стадия Write-Back процессора.
Она получает номер регистра, в который нужно сохранить данные от Ex1, а сами данные для некоторых инструкций приходят с шины с задержкой на несколько тактов. Сообщения с номером регистра и данными синхронизируются и происходит запись данных в регистр.
Синтаксически такая синхронизация выглядит как перечисление нескольких каналов в заголовке обработчика через запятую:
fromMMU(readResult), -- в этот канал приходит ответ шины local WaitMMU(rNum : integer(5)) -- сюда приходит сообщение с номером регистра
{ в теле, если ответ шины – не исключение, происходит запись нового значения регистра }
Поток управления
Язык поддерживает знакомые всем конструкции потока управления --- «if-then-else»,
«while». Например, инструкции в кеш читаются с шины строчками по 8 слов в режиме
«burst». Так выглядит обработчик с циклом, отправляющий запросы на чтение:
readBurst(cacheLineAddr) when toBus'InstructionPort { inBurst := 0b1 | inBurstAddr := 0; -- присвоение в глобальные регистры while inBurstAddr != 8 do -- пока счетчик не 8
-- блокирующая посылка запроса на чтение очередного слова с шины send toBus'B(0b1, 0b0, HSIZE_WORD,
-- адрес чтения состоит из адреса строки кеша, 3 битов счетчика и двух нулей cacheLineAddr || inBurstAddr{0:2} || 0b00,

0x00000000)
| inBurstAddr := inBurstAddr + 1 done
}
Сам цикл не является конвеером, поэтому следующее пришедшее в канал readBurst сообщение ждет, пока предыдущее выйдет из цикла.
В отличие от «while», «if-then-else» является полностью конвеерным оператором.
Параллельное исполнение операторов посылки
Предположим, что мы хотим послать сообщения в каналы a и b параллельно. Это можно сделать двумя способами ― «энергичным» и «ленивым».
В первом случае, если канал a готов принимать сообщение, посылка в него произойдет даже если b не готов. Оператор запомнит, что в a сообщение уже послано и будет ждать готовности b. Пример, когда такой вариант желателен ― обработка инструкции «branch-and- link» в модуле Ex0. Данная инструкция переходит по заданному адресу, сохраняя собственный адрес в регистр (чтобы потом можно было вернуться ― фактически, это вызов функции). Если перед ней шла инструкция работы с шиной данных, то стадия Write-Back может оказаться занята этой инструкцией на много тактов (пока шина не ответит). Значит, и канал, идущий в Write-Back, будет занят. Однако, это не мешает послать команду перехода в
Fetcher, который начнет загружать инструкции с нового адреса и проталкивать их в конвеер.
Таким образом, часть времени ожидания шины данных может быть не потеряна зря.
Синтаксически, это выглядит как параллельная композиция («|») операторов посылки.
«Ленивый» способ посылает сообщения одновременно, когда оба получателя готовы.
Заключение
Описанная в работе реализация архитектуры Microblaze была отсинтезирована и разведена (при помощи Xilinx ISE 12.2) для FPGA xc5vlx50t и протестирована на отладочной плате ML505 в окружении GRLIB от Gaisler. Тестирование заключалось в запуске ОС Linux
Snapgear с ядром 2.6, исполнении нагрузочного тестового скрипта, а также интерактивной работе в редакторе joe через терминал (UART).
Также, по результатам разводки, было произведено сравнение нашего клона с оригиналом от Xilinx. Наша реализация занимает примерно на 30% больше ресурсов (LUT,
FF), чем оригинал, и работает на такой же частоте. Однако, исходники процессора на HaSCoL занимают 2920 строк. К примеру, реализация арифметико-логического устройства (Integer
Unit) в Sparc-совместимом процессоре Leon3 от Gaisler занимает больше (на VHDL).
Исходя из этого, можно заметить, что HaSCoL предоставляет возможность реализации цифровых синхронных ИС на более высоком уровне абстракции по сравнению с RTL описаниями (например, VHDL). Описания получаются в разы более компактными, что упрощает их создание, отладку и сопровождение. При этом VHDL, сгенерированный из
HaSCoL, может, по качеству результатов синтеза, конкурировать с написанным вручную.
Литература:
(1)
Coussy P., Morawiec A. High-Level Synthesis: from Algorithm to Digital Circuit. 1st edition. Springer Publishing Company, Incorporated, 2008.
(2)
Boulytchev D., Medvedev O. Hardware Description Language Based on Message Passing and Implicit Pipelining // East-West Design and Test (EWDTS), 2009. Pp. 279-282.
(3)
Medvedev O., Posov I. Using hardware-software codesign language to implement
CANSCID // Formal Methods and Models for Codesign (MEMOCODE), 2010. Pp. 85-88.
(4)
MicroBlaze Processor Reference Guide // http://www.xilinx.com/support/documentation/sw_manuals/mb_ref_guide.pdf
(5)
http://oops.math.spbu.ru/projects/coolkit

Document Outline

  • Обзор высокоуровневого языка разработки аппаратуры HaSCoL на примере клона процессора Xilinx Microblaze
    • Введение
    • Краткое описание процессора
    • Краткая информация о языке и реализующих его инструментах
    • Некоторые конструкции на примере их применения в процессоре
    • Заключение
    • Литература:


Поделитесь с Вашими друзьями:


База данных защищена авторским правом ©nethash.ru 2019
обратиться к администрации

войти | регистрация
    Главная страница


загрузить материал