Проектирование учебного процессора для реализации в базисе ПЛИС

№ 3’2009
Микропроцессорные ядра представляют важный класс вычислительных заготовок, так как главным образом от их качеств зависят основные технические и потребительские свойства систем на кристалле. Эти заготовки разделяются по степени гибкости настройки под условия потребителя на программные («мягкие», описанные на языке HDL), жесткие (логическая схема) и аппаратные («твердые» маски под определенную технологию).

Программные заготовки можно легко подстраивать к условиям нового проекта, они обладают высоким быстродействием и независимы от технологии. Их реализация в ПЛИС (например, 8-разрядное микропроцессорное ядро PicoBlaze для реализации в базисе ПЛИС семейств Spartan и Virtex [2]) позволяет ускорить процесс разработки микропроцессорных систем. Наиболее важными потребительскими свойствами вычислительных заготовок процессоров являются повторяемость, быстрoдействие, аппаратурные затраты.

Путем несложной перенастройки «мягкой» заготовки можно получить ряд модификаций микроконтроллера с различным сочетанием объема памяти, периферийных устройств, источников прерывания и т. п. Такой процессор можно реализовать в ПЛИС различных фирм. Описание процессора на языке VHDL позволяет не только сделать ее перенастраиваемой и независимой от технологии, но и выполнять ее моделирование и синтез на симуляторах и средствах синтеза различных фирм.

В работах [3–6] рассматривается проектирование процессоров для реализации в базе ПЛИС с использованием языков аппаратурных средств VHDL [3, 4] и AHDL [6]. Интересный вариант построения RISC-процессора на языке VHDL описан в работе [1]. Проект процессора ориентирован на реализацию в ПЛИС Virtex-E фирмы Xilinx. Процессор имеет структуру с распределенным управлением, развитую систему команд и может быть использован в качестве основы ультрабыстрого процессора 80С51.

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

Таблица 1. Система команд процессора с синхронной архитектурой [3]
Код операции Мнемоника Описание
0 NOP Нет операции
01xxH JMP Безусловный переход по адресу, заданному младшим байтом команды
02xxH JMPZ Переход по адресу, заданному младшим байтом команды, если содержимое регистра A равно нулю
03xxH CALL Вызов подпрограммы по адресу, заданному младшим байтом команды
04xxH MOV A,xx Непосредственная загрузка в регистр A значения, заданного младшим байтом команды
05xxH MOV B,xx Непосредственная загрузка в регистр B значения, заданного младшим байтом команды
0600H Возврат из подпрограммы
0601H MOV A,B Загрузка в регистр A значения, содержащегося в регистре B
0602H MOV B,A Загрузка в регистр B значения, содержащегося в регистре A
0603H XCHG A,B Обмен местами значений в регистрах A и B
0604H ADD A,B Сложение значений в регистрах A и B, результат помещается в A
0605H SUB A,B Вычитание значений в регистрах A и B, результат помещается в A
0606H AND A,B Побитное логическое И значений в регистрах A и B, результат помещается в A
0607H OR A,B Побитное логическое ИЛИ значений в регистрах A и B, результат помещается в A
0608H XOR A,B Побитное логическое ИСКЛЮЧАЮЩЕЕ ИЛИ значений в регистрах A и B, результат помещается в A
0609H DEC A Декремент регистра А (вычитание 1)

Предлагаемый в работе [3] процессор способен работать с синхронным ОЗУ. Это обеспечивается употреблением оператора case, который используется в ветви оператора if при детектировании атрибута переднего фронта синхроимпульса clk и позволяет организовать цикл работы в два такта.

В качестве примера воспользуемся процессором, представленным в работе [3], и реализуем его в ПЛИС фирмы Altera APEX20KE с асинхронным ПЗУ. Реализация синхронного процессора с циклом работы в два такта возможна при использовании более современных семейств ПЛИС фирмы Altera — Stratix и Сyclone.

Рис. 1. Тестовая схема процессора в графическом редакторе САПР ПЛИС Quartus II  с использованием управляющего автомата и асинхронного ПЗУ
Рис. 1. Тестовая схема процессора в графическом редакторе САПР ПЛИС Quartus II
с использованием управляющего автомата и асинхронного ПЗУ

На рис. 1 показана тестовая схема управляющего автомата процессора в графическом редакторе САПР ПЛИС Quartus II, а на рис. 2 — содержимое конфигурационного файла ПЗУ. В описание процессора на языке VHDL добавлен асинхронный сброс регистров А, В и счетчика команд на регистре ip. Как и в работе [3], декодирование переменной-селектора cmd осуществляется с помощью оператора case.

Рис. 2. Файл конфигурации ПЗУ  для тестирования команды обращения к подпрограммам CALL и возврата RET
Рис. 2. Файл конфигурации ПЗУ
для тестирования команды обращения
к подпрограммам CALL и возврата RET

Оператор case, подобно оператору if, задает ветвление алгоритма. В этом операторе вычисляется заданное выражение expression, по его значению выбирается одна из альтернатив choices (constant_value) и исполняются соответствующие последовательные операторы statement. В каждом из наборов альтернатив constant_value можно записать один или большее число последовательных операторов.

Значения в списках разделяются символом «|». Когда значение выражения встречается в одном из списков значений, выполняется соответствующая последовательность операторов. Если значение выражения не присутствует ни в одном из списков, то выполняется список операторов, соответствующий ветви when others.

Синтаксис оператора case :

CASE __expression IS
WHEN __constant_value =>
__statement;
__statement;
WHEN __constant_value =>
__statement;
__statement;
WHEN OTHERS =>
__statement;
__statement;
END CASE;

Функция conv_integer(cmd) переводит вектор в десятичное число отдельных кодов. При каждом допустимом значении кода команды происходят различные действия, которые состоят в присвоении регистрам новых значений в соответствии с описанием команд. Счетчик команд (регистр) не обновляется автоматически, поэтому в каждом варианте кода команды присваивание счетчику нового значения указывается явно [3]. Процессор ограничивается двумя регистрами общего назначения (A и В), а также имеет указатель инструкций ip и регистр r для хранения адреса, с которого происходит вызов подпрограммы, поддерживает минимальный набор команд: команда пересылки «регистр – регистр»; команды непосредственной загрузки; команда безусловного перехода к новому адресу; команды перехода по условию; набор арифметико-логических операций [3]. Приведем пример реализации на языке VHDL управляющего автомата:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity proc is
port (ip: inout std_logic_vector(7 downto 0);
cmd: inout std_logic_vector(15 downto 0);
clk,res: in std_logic;
a: inout std_logic_vector(7 downto 0);
b,r: inout std_logic_vector(7 downto 0));
end proc;
architecture a of proc is
signal stage: std_logic;
begin
process(clk)
begin
if (res = '1') then 
a <=«00000000»;
b <=«00000000»;
ip <=«00000000»;
elsif clk'event and clk='1' then
case stage is
when '0'=> stage<='1';
when others=> stage<='0';
case conv_integer(cmd) is
when 0=> ip <= ip+1;
when 256 to 511 =>ip<=cmd(7 downto 0);
when 512 to 767 =>if conv_integer(a)=0
then ip<=cmd(7 downto 0);
else ip<=ip+1;
end if;
when 768 to 1023 =>r<=ip; ip<=cmd(7 downto 0);
when 1024 to 1279 => a<=cmd(7 downto 0); ip<=ip+1;
when 1280 to 1535 => b<=cmd(7 downto 0); ip<=ip+1;
when 1536 =>ip<=r+1;
when 1537=>a<=b; ip<=ip+1;
when 1538=>b<=a; ip<=ip+1;
when 1539=>a<=b;b<=a; ip<=ip+1;
when 1540=>a<=a+b; ip<=ip+1;
when 1541=>a<=a-b; ip<=ip+1;
when 1542=>a<=a and b; ip<=ip+1;
when 1543=>a<=a or b; ip<=ip+1;
when 1544=>a<=a xor b; ip<=ip+1;
when 1545=>a<=a-1; ip<=ip+1;
when others=>ip<=ip+1;
end case;
end case;
end if;
end process;
end a;

Наиболее сложными являются команды передачи управления JMP и JMPZ, а также команда обращения к подпрограммам CALL и команда возврата из подпрограмм RET. Временные диаграммы на рис. 3 демонстрируют принцип работы управляющего автомата с асинхронным ПЗУ при отработке команд CALL (0305H) и RET (0600H). При нормальной последовательности работы процессора отрабатываются регистровые команды. Последовательно загружаются регистры А и В. В регистр А загружается число 1D (1H), а в регистр В — число 17D (11H). По команде 0305H происходит запись содержимого счетчика команд ip в регистр r (2D) и загрузка в счетчик команд числа 5D. Таким образом, процессор начнет выполнять подпрограмму, хранящуюся в ПЗУ, с адреса 5H. По указанному адресу извлекается регистровая команда 0403H. Происходит загрузка в регистр A числа 3H, командой 0404H — загрузка числа 4H. Посредством следующей команды с кодом 0604Н произойдет сложение содержимых регистров с сохранением результата в регистре А (число 21D). Далее будут отработаны команды 0406Н и 0407Н. По команде возврата из подпрограммы 600Н произойдет изменение содержимого счетчика с 10D на 2D+1D, то есть на 3D.

Рис. 3. Временная диаграмма работы процессора с использованием управляющего автомата и асинхронного ПЗУ (отрабатываются регистровые команды и команда вызова подпрограммы с кодом 0305H (CALL)  и команда возврата из подпрограммы 0600H (RET))
Рис. 3. Временная диаграмма работы процессора с использованием управляющего автомата и асинхронного ПЗУ
(отрабатываются регистровые команды и команда вызова подпрограммы с кодом 0305H (CALL)
и команда возврата из подпрограммы 0600H (RET))

Для использования устаревших серий ПЛИС в учебных проектах предлагается отказаться от цикла работы в два такта. С этой целью регистровые команды 04xxH, 05xxH, 0601H–0609H предлагается реализовать на тактируемом дешифраторе, выполняющем функцию арифметически-логического устройства (АЛУ):

LIBRARY ieee;
use ieee.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
ENTITY alu IS
PORT
(cmd : IN STD_LOGIC_VECTOR (10 DOWNTO 0);
clk,res : IN STD_LOGIC;
a,b : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END alu;
ARCHITECTURE a OF alu IS
signal regA,regB: std_logic_vector(7 downto 0);
BEGIN
PROCESS (clk,res)
BEGIN
if (RES = '1') then 
egA <=«00000000»;
regB <=«00000000»;
elsif (clk'event and clk='1') then
case conv_integer(cmd) is
when 1024 to 1279 => regA<=cmd(7 downto 0); 
when 1280 to 1535 => regB<=cmd(7 downto 0);
when 1537=>regA<=regB; 
when 1538=>regB<=regA; 
when 1539=>regA<=regB; regB<=regA; 
when 1540=>regA<=regA+regB; 
when 1541=>regA<=regA-regB;
when 1542=>regA<=regA and regB; 
when 1543=>regA<=regA or regB; 
when 1544=>regA<=regA xor regB; 
when 1545=>regA<=regA-1; 
when others=> a<=regA; b<=regB;
end case;
end if;
a<=regA;
b<=regB;
END PROCESS;
END a;
Рис. 4. Тестовая схема процессора без использования управляющего автомата с асинхронным ПЗУ  в
Рис. 4. Тестовая схема процессора без использования управляющего автомата с асинхронным ПЗУ
в

А команды передачи управления JMP, JMPZ и обращения к подпрограммам с кодами 01xxH-03xxH, 0600H на 8-разрядном суммирующем счетчике адресов памяти команд, тактируемом фронтом синхросигнала (рис. 4), выглядят так:

LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
ENTITY counter IS
PORT(
	Clk : IN STD_LOGIC;
	reset : IN STD_LOGIC;
	cmd : IN STD_LOGIC_VECTOR(10 downto 0);
	a : INOUT STD_LOGIC_VECTOR(7 downto 0);
	r : INOUT STD_LOGIC_VECTOR(7 downto 0);
	Qa,Qb : OUT STD_LOGIC_VECTOR(7 downto 0));
END counter;
ARCHITECTURE a OF counter IS
SIGNAL pci,data,regA: STD_LOGIC_VECTOR(7 downto 0);
SIGNAL cop: STD_LOGIC_VECTOR(2 downto 0);
BEGIN
regA<=a;
cop<=cmd(10 downto 8);
data<=cmd(7 downto 0);
-- cmd 11 bit wide
-- 11 bit encoding
-- JMP: 001 <data>
-- JMPZ: 010 <data>
-- CALL: 011 <data>
-- RET: 110 00000000
process(clk,reset)
begin
	if (reset = '1') then 
	pci <=(others=>'0'); 
	r <=(others=>'0');
	elsif (clk'event and clk='1') then 
	if
	cop=«001» then pci<=data;
	elsif (cop=«010» and conv_integer(regA)=0) then pci<=data;
	elsif cop=«011» then r<=pci; pci<=data;
	elsif cmd=«11000000000» then pci<=r+1;
	else pci<=pci+1;
	end if; 
	end if; 
end process;
Qa <= pci;
Qb <=data;
a<=regA;
END a;

Счетчик содержит асинхронный сброс Reset. Активным является сигнал высокого уровня. Во вложенных ветвях оператора if происходит проверка условий и синхронная загрузка счетчика команд.

Оператор if используется для ветвления алгоритма по различным условиям. Наиболее простой синтаксис имеет вид:

IF __expression THEN __statement;
END IF;

Вначале проверяется булево выражение boolean-expression, и если оно имеет значение true, то исполняется последовательный оператор sequential-statement. Возможно использовать предложение else c другим последовательным оператором sequential-statement, который исполняется, если булево выражение имеет значение false. В САПР Quartus II рекомендуется использовать следующий синтаксис оператора if (шаблон):

IF __expression THEN 
__statement;
__statement;
ELSIF __expression THEN
__statement;
__statement;
ELSE
__statement;
__statement;
END IF;

Счетчик команд ip и регистр r при инициализации системы по сигналу Reset устанавливаются в состояние 0, после чего производится счет адресов памяти программ, хранимых в ПЗУ. Регистр r выполняет функцию стека, в который заносится прежнее состояние счетчика команд. Из шины cmd[10..0] для счетчика команд выделяется поле cop[10..8] и поле data[7..0]. Поле cop означает код операции, который используется для идентификации команд JMP, JMPZ и CALL. Для команды RET поле cop не формируется, а задается полный адрес на шине cmd «11000000000», это связано с тем, что 8 младших бит для команд JMP, JMPZ и CALL могут принимать любые значения, а для команды RET — только указанное. Поле data содержит 8-разрядный операнд, который загружается в регистр команд.

Рис. 5. Временные диаграммы работы процессора без использования управляющего автомата с асинхронным ПЗУ
Рис. 5. Временные диаграммы работы процессора без использования управляющего автомата с асинхронным ПЗУ

ПЗУ реализовано с использованием мегафункции LPM_ROM. В таблице 2 представлены сведения по общему числу задействованных ресурсов ПЛИС. В обоих случаях проект отображается в ПЛИС APEX20KE. На рис. 5 показано тестирование процессора.

Таблица 2. Общие сведения по числу задействованных ресурсов ПЛИС APEX20KE
Номер проекта ПЛИС Общее число
логических элементов
Общее число
используемых ESB-бит
D-триггеров
С использованием управляющего автомата EP20K30ETC144-1 198/1200 (16%) 2816/24576 (11%) 32
Вариант с асинхронным ПЗУ EP20K30ETC144-1 164/1200 (13%) 2816/24576 (11%) 32

Рассмотрим вариант реализации проектируемого процессора с использованием асинхронного ОЗУ (рис. 6). Для этого воспользуемся мегафункцией LPM_RAM_IO. Для того чтобы ОЗУ выполняло функцию ПЗУ, необходимо сигнал разрешения записи we «посадить» на «землю», так как активным является сигнал высокого уровня, а сигнал разрешения вывода outenab подключить к питанию. На рис. 7 показан файл конфигурации ОЗУ для тестирования команды JMPZ c кодом 0205H. По команде 0205H осуществляется переход по адресу, заданному младшим байтом команды (на адрес в ОЗУ под номером 5, где хранится команда 0403H), если содержимое регистра A равно нулю. Чтобы содержимое регистра А оказалось равным нулю, необходимо воспользоваться регистровыми командами 0405H и 0505H для загрузки в регистры А и В числа 5, а затем с помощью команды 0605H (SUB A,B) осуществить операцию A–B (рис. 8).

Рис. 6. Тестовая схема процессора без использования управляющего автомата с асинхронным ОЗУ  в графическом редакторе САПР ПЛИС Quartus II
Рис. 6. Тестовая схема процессора без использования управляющего автомата с асинхронным ОЗУ
в графическом редакторе САПР ПЛИС Quartus II
Рис. 7. Файл конфигурации ОЗУ для тестирования команды JMPZ
Рис. 7. Файл конфигурации ОЗУ для тестирования
команды JMPZ
Рис. 8. Временные диаграммы работы процессора с асинхронным ОЗУ (тестирование команды JMPZ)
Рис. 8. Временные диаграммы работы процессора с асинхронным ОЗУ (тестирование команды JMPZ)

Данный вариант процессора, реализованный в базисе ПЛИС, можно отнести к классу RISC-процессоров, у которых все команды выполняются за один такт синхрочастоты. Процессор может быть модифицирован путем наращивания блока регистров, добавления блока управления прерываний, добавления блока управления ввода/вывода и других функциональных блоков. Вариант с асинхронным ПЗУ, реализованный в ПЛИС APEX20KE EP20K30ETC144-1, занимает всего лишь 13% от общего числа логических элементов и способен работать на частоте 60 МГц. Модифицированный вариант оказался на 3% компактнее по числу задействованных ресурсов ПЛИС и способен работать с морально устаревшими сериями ПЛИС. Однако процессор без использования управляющего автомата может быть пригоден для учебных целей. Недостатком является невозможность поддержки современной концепции синхронного кодирования при разработке микропроцессорных ядер.

Литература

  1. Сергиенко А. М. VHDL для проектирования вычислительных устройств. Киев: ООО «ТИД «ДС»», 2003.
  2. Зотов В. Ю. Проектирование встраиваемых микропроцессорных систем на основе ПЛИС фирмы XILINX. М.: Горячая линия – Телеком, 2006.
  3. Тарасов И. Проектирование конфигурируемых процессоров на базе ПЛИС. Часть I // Компоненты и технологии. 2006. № 2.
  4. Тарасов И. Проектирование конфигурируемых процессоров на базе ПЛИС. Часть II // Компоненты и технологии. 2006. № 3.
  5. Каршенбойм И. Микропроцессор своими руками // Компоненты и технологии. 2002. № 6–7.
  6. Каршенбойм И. Микропроцессор своими руками-2. Битовый процессор // Компоненты и технологии. 2003. № 7–8.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *