Проектирование учебного процессора для реализации в базисе ПЛИС Altera с использованием системы MATLAB/Simulink
При количестве логических вентилей в проекте свыше 5000 визуализировать выполняемые функции устройства крайне сложно. Гарантировать, что весь проект можно осознать, только взглянув на его схему, практически невозможно.
Разработчики, использующие в своих проектах методологию системного уровня проектирования (Electronic System Level (ESL) Design — проектирование на системном уровне или проектирование «сверху вниз»), получат очевидные преимущества. Во-первых, любой отдельно взятый разработчик может обеспечить решение задачи повышенной (и постоянно увеличивающейся) сложности, обращаясь к более высоким уровням абстракции и реализуя мелкие детали проекта в условиях автоматизированного процесса. Проще и быстрее разрабатывать модели сложнофункциональных устройств на более высоких уровнях абстракции, чем с использованием уровня регистровых передач (RTL-уровень, register transfer level). Самый простой способ понять концепцию RTL-описания — представить сложнофункциональное устройство в виде совокупности регистров, связанных между собой элементами комбинационной логики и управляемых с помощью общего синхросигнала. Симуляция в этом случае выполняется на несколько порядков быстрее, поскольку не симулируются несущественные для данного уровня абстракции детали.
Во-вторых, разработчики могут значительно сократить цикл производства и улучшить качество изделий, благодаря проверке функциональных возможностей, еще на этапе проектирования, когда внести изменения в системы легко и относительно дешево.
Первым этапом в потоке ESL-проектирования является определение требований к проекту. Требования устанавливаются конкретным заказчиком или определяются в результате соответствующих маркетинговых исследований.
Далее проводится системное проектирование и верификация алгоритмов, как правило, с помощью языка программирования С/С++/SystemC или с помощью специальных средств визуально-имитационного моделирования типа MATLAB/Simulink компании The MathWorks или SPW2000 (signal processing worksystem — рабочая среда обработки сигналов) компании Cadence. На этом этапе могут быть использованы и ESL-продукты компании Summit Design, такие как Visual Elite, FastC, System Architect и Virtual CPU. С помощью текстовых или графических средств создаются исполняемые функциональные спецификации, которые описывают поведение проекта в рамках заданных ограничений. Функциональная верификация технологически независима. Такое описание лишено деталей реализации.
Simulink— графическая среда визуальноимитационного моделирования аналоговых и дискретных систем; предоставляет пользователю графический интерфейс для конструирования моделей из стандартных функциональных блоков. Simulink работает с линейными, нелинейными, непрерывными, дискретными и многомерными системами. Система MATLAB/Simulink содержит встроенный генератор кода языка описания аппаратных средств HDL (Simulink HDL Coder) и ориентирована на поддержку симулятора VHDL ModelSim. Simulink HDL Coder — программный продукт для генерации VHDL-кода без привязки к конкретной архитектуре ПЛИС и платформе по Simulink-моделям. Справедливости ради следует заметить, что стиль кодирования может повлиять на производительность проектируемого устройства, особенно на ПЛИС. Логически эквивалентные, но разные RTL-операторы могут выдавать различные результаты.
Покажем возможности системы MATLAB/ Simulink на этапе ESL-проектирования по созданию микропроцессорных ядер. Воспользуемся системой команд синхронного процессора, реализованного с помощью управляющего автомата, с циклом работы в два такта [1, 2]. В работе [3] по коду языка VHDL синхронного процессора с управляющим автоматом, представленного в работе [2], с использованием САПР ПЛИС Quartus II была описана разработка проекта с применением мегафункции асинхронного ПЗУ и проекта без использования управляющего автомата с применением мегафункции асинхронного ОЗУ.
Для учебных целей разработаем два проекта с использованием асинхронного и синхронного ПЗУ на языке VHDL, с системой команд из работы [2]. Для ускорения процесса проектирования предлагается использовать возможности Simulink HDL Coder.
Запуск процессора в Simulink следует производить с помощью отладчика (Simulink Debugger). Перед отладкой необходимо зайти в меню Simulation/Configuration Parameters и выбрать диалог Solver («решатели», методы численного решения дифференциальных и дифференциально-алгебраических уравнений). В Solver options выбрать Type: Fixedstep; Solver: discrete (no continuous state); Fixed step size (fundamental sample time) — 1.0.
На . 1 показана отладка процессора. Процессор состоит из следующих блоков: ROM — ПЗУ процессора; COP— блок выделения полей команды; ALU — АЛУ процессора; RON — регистры общего назначения, регистры А и B; RSN— регистры специального назначения, регистр R для обеспечения команд обращения к подпрограммам (CALL) и возврата (RET) и регистр-счетчик Ip. На рис. 2 показан файл прошивки ПЗУ. Для построе- ния ПЗУ используется функциональный блок Lookup Table, формирующий таблицу, в строках которой находятся порядковые номера (адреса) команд. Например, строке 1 соответствует команда 1036D (мнемонический код MOV A,12). Адреса команд (входной порт addr), вещественные числа (Real World Values) 0, 1, 2 … 23, представляются в формате uint8 (Unsigned integer fixed-point data type, целые числа без знака в формате с фиксированной запятой, с 8-битной точностью), а команды (выходной порт) представляются в формате uint16, c 16-битной точностью. Все сигналы в процессоре представлены в формате uint8, кроме сигналов cmd и cmdData, они представлены в формате uint16.
В формате с фиксированной запятой без знака вещественное число V можно считать обозначением полинома [4]:
где bi — двоичное число, bi = 1,0; ws — размер слова, ответственного за точность представления десятичных чисел с запятой, максимально 128 бит; S — масштаб, S = 2E, E — число битов левее младшего значащего бита (LSB) в слове, обозначающих месторасположение позиционной точки (разделительной точки или разделительной запятой). Для целых чисел S = 1. Например, число 0011.0101 при длине слова ws = 8:
Выделение полей команды осуществляется в блоке COP (рис. 3). Сигнал OutCmd (uint8)— 8 старших битов 16-разрядной команды CmdData (uint16), извлекаемой из ПЗУ. Сигнал OutData (uint8) — 8 младших бит, содержащих данные. Функциональные блоки Shift Arithmetic (арифметический сдвиг) и Data Type Conversion (преобразование типа данных) используются для формирования сигнала OutCmd. Они осуществляют логический сдвиг вправо сигнала CmdData, младшими битами вперед. Для формирования сигнала OutData осуществляется логический сдвиг влево сигнала CmdData, старшими битами вперед, а затем сдвиг вправо, на 8 бит вперед.
В блоках Display (command, Cmd, Data, RegA, RegB, RegR, counter IP) отображается содержимое внутренних узлов процессора. Например, по команде MOV A,12 в регистр А загружается число 12, по команде MOV B,23 в регистр B загружается число 23. А по команде 1540 должно произойти сложение содержимого регистров с сохранением результата в регистре А.
На рис. 4 показан блок АЛУ. Приведем пример M-файла функции АЛУ в системе MATLAB/Simulink:
function [outA, outB, outR, outIp] = alu(inCmd,inData,inA,inB,inIp,inR) outA = inA; outB = inB; outR = inR; outIp = inIp+1; switch inCmd |
||||
case 0 %NOP case 1 %JMP |
||||
outIp = inData; | ||||
case 2 %JMPZ | ||||
if inA == 0 | ||||
outIp = inData; | ||||
end | ||||
case 3 % CALL | ||||
outR = inIp+1; outIp = inData; |
||||
case 4 %MOV A,xx | ||||
outA = inData; | ||||
case 5 %MOV B,xx | ||||
outB = inData; | ||||
case 6 | ||||
switch inData | ||||
case 0 %RET | ||||
outIp = inR; | ||||
case 1 %MOV A,B | ||||
outA = inB; | ||||
case 2 %MOV B,A | ||||
outB = inA; | ||||
case 3 %XCHG A,B | ||||
X = inB; outB = inA; outA = X; |
||||
case 4 %ADD A,B | ||||
outA = inA+inB; | ||||
case 5 %SUB A,B | ||||
outA = inA-inB; | ||||
case 6 %AND A,B | ||||
outA = bitand(inA,inB); | ||||
case 7 %OR A,B | ||||
outA = bitor(inA,inB); | ||||
case 8 %XOR A,B | ||||
outA = bitxor(inA,inB); | ||||
case 9 %DEC A | ||||
outA = inA-1; | ||||
end | ||||
end |
Текст функции начинается с заголовка function, имеющего следующий вид:
function [y1, y2, …]=fname(x1,x2, …), |
где fname — имя фунции; x1, x2 и т. д. — входные параметры; y1, y2 и т. д. — выходные параметры. В условном операторе switch выбирается одна из возможных альтернатив. Запись оператора выбора производится с помощью ключевых слов switch, case, otherwise. При выполнении оператора switch значение inCmd поочередно сравнивается с 1, 2, 3, … При обнаружении первого совпадения выполняются операторы соответствующей ветви, после чего производится выход из оператора выбора.
На рис. 5 показано построение регистров общего назначения с использованием функциональных блоков Memory. Аналогично формируются и блоки регистров специального назначения.
Далее с помощью Simulink HDL Coder сгенерируем код языка VHDL функциональных блоков проектируемого процессора. При этом необходимо помнить, что САПР ПЛИС Quartus II относится к компиляторамсинтезаторам и имеет привязку к конкретной архитектуре, а сгенерированный код языка VHDL с помощью Simulink HDL Coder в первую очередь предназначен для ModelSim SE (Mentor Graphics HDL simulator). Последняя версия САПР ПЛИС Quartus II (версия 8.1) cодержит адаптированный симулятор ModelSim-Altera.
Пример сгенерированного описания прошивки асинхронного ПЗУ на языке VHDL:
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.numeric_std.ALL; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; ENTITY ROM IS PORT( |
|
addr: IN std_logic_vector(7 DOWNTO 0); cmd: OUT std_logic_vector(15 DOWNTO 0)); |
|
END ROM; ARCHITECTURE rtl OF ROM IS SIGNAL Lookup_Table_out1: std_logic_vector(15 DOWNTO 0); BEGIN PROCESS(addr) BEGIN CASE addr IS |
|
WHEN «00000000» => Lookup_Table_out1 <= «0000010000001100»; WHEN «00000001» => Lookup_Table_out1 <= «0000010100010111»; WHEN «00000010» => Lookup_Table_out1 <= «0000011000000100»; WHEN «00000011» => Lookup_Table_out1 <= «0000011000001001»; WHEN «00000100» => Lookup_Table_out1 <= «0000010101001110»; WHEN «00000101» => Lookup_Table_out1 <= «0000011000000011»; WHEN «00000110» => Lookup_Table_out1 <= «0000011000000101»; WHEN «00000111» => Lookup_Table_out1 <= «0000011000001001»; WHEN «00001000» => Lookup_Table_out1 <= «0000011000000110»; WHEN «00001001» => Lookup_Table_out1 <= «0000001000001011»; WHEN «00001010» => Lookup_Table_out1 <= «0000000100000111»; WHEN «00001011» => Lookup_Table_out1 <= «0000010000001101»; WHEN «00001100» => Lookup_Table_out1 <= «0000010101110101»; WHEN «00001101» => Lookup_Table_out1 <= «0000011000000111»; WHEN «00001110» => Lookup_Table_out1 <= «0000011000000011»; WHEN «00001111» => Lookup_Table_out1 <= «0000011000001000»; WHEN «00010000» => Lookup_Table_out1 <= «0000000100010101»; WHEN «00010001» => Lookup_Table_out1 <= «0000010001101111»; WHEN «00010010» => Lookup_Table_out1 <= «0000010111001000»; WHEN «00010011» => Lookup_Table_out1 <= «0000011000000110»; WHEN «00010100» => Lookup_Table_out1 <= «0000011000000000»; WHEN «00010101» => Lookup_Table_out1 <= «0000001100010001»; WHEN «00010110» => Lookup_Table_out1 <= «0000000000000000»; WHEN OTHERS => Lookup_Table_out1 <= «0000000000000000»; |
|
END CASE; END PROCESS; cmd <=Lookup_Table_out1; END rtl; |
Выделение полей команды на языке VHDL будет выглядеть следующим образом:
library ieee; USE IEEE.std_logic_1164.ALL; USE IEEE.numeric_std.ALL; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; ENTITY COP IS PORT( cmdData : IN std_logic_vector(15 DOWNTO 0); OutData : OUT std_logic_vector(7 DOWNTO 0); OutCmd : OUT std_logic_vector(7 DOWNTO 0)); END COP; ARCHITECTURE rtl OF COP IS BEGIN OutCmd<=cmdData(15 downto 8); OutData<=cmdData(7 downto 0); END rtl; |
Пример описания асинхронного АЛУ на языке VHDL:
LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; ENTITY ALU_entity IS PORT ( |
||||||
inCmd : IN std_logic_vector(7 DOWNTO 0); inData : IN std_logic_vector(7 DOWNTO 0); inA : IN std_logic_vector(7 DOWNTO 0); inB : IN std_logic_vector(7 DOWNTO 0); inIp : IN std_logic_vector(7 DOWNTO 0); inR : IN std_logic_vector(7 DOWNTO 0); outA : OUT std_logic_vector(7 DOWNTO 0); outB : OUT std_logic_vector(7 DOWNTO 0); outR : OUT std_logic_vector(7 DOWNTO 0); outIp : OUT std_logic_vector(7 DOWNTO 0)); |
||||||
END ALU_entity; ARCHITECTURE fsm_SFHDL OF ALU_entity IS BEGIN PROCESS (inCmd, inData, inA, inB, inIp, inR) |
||||||
BEGIN | ||||||
outA <= inA; outB <= inB; outR <= inR; outIp <= inIp+1; CASE inCmd IS |
||||||
WHEN «00000000» => | ||||||
—NOP NULL; |
||||||
WHEN «00000001» => | ||||||
—JMP outIp <= inData; |
||||||
WHEN «00000010» => | ||||||
IF inA = 0 THEN | ||||||
—JMPZ outIp <= inData; |
||||||
END IF; | ||||||
WHEN «00000011» => | ||||||
— CALL outR <= inIp+1; |
||||||
outIp <= inData; | ||||||
WHEN «00000100» => | ||||||
—MOV A,xx outA <= inData; |
||||||
WHEN «00000101» => | ||||||
—MOV B,xx outB <= inData; |
||||||
WHEN «00000110» => | ||||||
CASE inData IS | ||||||
WHEN «00000000» => | ||||||
—RET outIp <= inR; |
||||||
WHEN «00000001» => | ||||||
—MOV A,B outA <= inB; |
||||||
WHEN «00000010» => | ||||||
—MOV B,A outB <= inA; |
||||||
WHEN «00000011» => | ||||||
—XCHG A,B outB <= inA; outA <= inB; |
||||||
WHEN «00000100» => | ||||||
—ADD A,B outA <= inA + inB; |
||||||
WHEN «00000101» => | ||||||
—SUB A,B outA <= inA— inB; |
||||||
WHEN «00000110» => | ||||||
—AND A,B outA <= inA AND inB; |
||||||
WHEN «00000111» => | ||||||
—OR A,B outA <= inA OR inB; |
||||||
WHEN «00001000» => | ||||||
—XOR A,B outA <= inA XOR inB; |
||||||
WHEN «00001001» => | ||||||
—DEC A outA <= inA— 1; |
||||||
WHEN OTHERS => | ||||||
NULL; | ||||||
END CASE; | ||||||
WHEN OTHERS => | ||||||
NULL; | ||||||
END CASE; | ||||||
END PROCESS; | ||||||
END fsm_SFHDL; |
Регистры общего назначения (РОН):
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.numeric_std.ALL; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; ENTITY RON IS |
||||
PORT | ( clk : reset : enb : inA : inB : outA : outB : |
IN IN IN IN IN OUT OUT |
std_logic; std_logic; std_logic; std_logic_vector(7 DOWNTO 0); std_logic_vector(7 DOWNTO 0); std_logic_vector(7 DOWNTO 0); std_logic_vector(7 DOWNTO 0)); |
|
END RON; ARCHITECTURE rtl OF RON IS BEGIN |
||||
PROCESS (clk, reset) BEGIN |
||||
IF reset = ‘1’ THEN | ||||
outA <= (OTHERS => ‘0’); | ||||
ELSIF clk’event AND clk = ‘1’ THEN | ||||
IF enb = ‘1’ THEN | ||||
outA <= inA; | ||||
END IF; | ||||
END IF; | ||||
END PROCESS; PROCESS (clk, reset) BEGIN |
||||
IF reset = ‘1’ THEN | ||||
outB <= (OTHERS => ‘0’); | ||||
ELSIF clk’event AND clk = ‘1’ THEN | ||||
IF enb = ‘1’ THEN | ||||
outB <= inB; | ||||
END IF; | ||||
END IF; | ||||
END PROCESS; | ||||
END rtl; |
С целью сокращения избыточности кода все блоки процессора подверглись ручному редактированию. При генерации кода языка VHDL функциональных блоков процессора Simulink HDL Coder использует только два пакета— std_logic_1164 и numeric_std, так как заранее предполагается, что процессор работает только с целыми положительными двоичными числами (тип unsigned). Добавим в каждый блок следующие пакеты: std_logic_arith и std_logic_unsigned (обязательны в блоке АЛУ). Компилятор-синтезатор наиболее эффективно отображает в ресурсы ПЛИС функции (например, арифметические), которые используются из пакетов std_logic_1164, numeric_ std, std_logic_arith и std_logic_unsigned.
На рис. 6, 7 показана тестовая схема процессора в графическом редакторе САПР ПЛИС Quartus II и временная диаграмма работы. Анализируя полученные результаты, приходим к выводу, что ПЗУ и АЛУ являются асинхронными блоками. Регистры общего и специального назначения представляют собой 8-разрядные регистры, тактируемые фронтом синхросигнала, с асинхронным сбросом reset и синхронным сигналом ena. Недостатком сгенерированного кода языка VHDL являются нетактируемое АЛУ и ПЗУ.
Сгенерируем файл прошивки ПЗУ, используя M-файл и fi-объекты системы MATLAB. Fi-объекты позволяют представлять числа в формате с фиксированной запятой. Например, по команде а = fi(1536) целое положительное десятичное число 1536 будет представлено в формате M.N, где M — общее число двоичных разрядов, N— число разрядов дробной части. Наиболее распространенный формат—16.15. Пятнадцать разрядов после запятой обеспечивают дискретность представления, равную 2–15≈3×10–5. В нашем случае используем следующий формат: a = fi(v, s, w, f), где v — объект со значением, s — знак (0 (false) — для чисел без знака и 1 (true) — для чисел со знаком), w— размер слова в битах (целая часть числа), f— дробная часть числа в битах. Например, по команде а = fi(1536, 0, 16, 0) целое положительное десятичное число 1536 будет представлено в формате 16.0. По команде disp(bin(a)) можно посмотреть десятичное число в двоичной форме: 0000011000000000. Пример M-файл прошивки ПЗУ в системе MATLAB/Simulink:
function rom_out = Memory(addr) persistent data; data = fi(zeros(1, 256), 0, 16, 0); data(1) = fi(1036, 0, 16, 0); data(2) = fi(1303, 0, 16, 0); data(3) = fi(1540, 0, 16, 0); data(4) = fi(1545, 0, 16, 0); data(5) = fi(1358, 0, 16, 0); data(6) = fi(1539, 0, 16, 0); data(7) = fi(1541, 0, 16, 0); data(8) = fi(1545, 0, 16, 0); data(9) = fi(1542, 0, 16, 0); data(10) = fi(523, 0, 16, 0); data(11) = fi(263, 0, 16, 0); data(12) = fi(1037, 0, 16, 0); data(13) = fi(1397, 0, 16, 0); data(14) = fi(1543, 0, 16, 0); data(15) = fi(1539, 0, 16, 0); data(16) = fi(1544, 0, 16, 0); data(17) = fi(277, 0, 16, 0); data(18) = fi(1135, 0, 16, 0); data(19) = fi(1480, 0, 16, 0); data(20) = fi(1542, 0, 16, 0); data(21) = fi(1536, 0, 16, 0); data(22) = fi(785, 0, 16, 0); data(23) = fi(0, 0, 16, 0); rom_out = data(addr+1); |
Отредактированный вариант сгенерированного файла программой Simulink HDL Coder в САПР Quartus II будет выглядеть так:
LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; ENTITY rom_syn IS |
|||||
PORT ( | |||||
clk : IN std_logic; clk_enable : IN std_logic; reset : IN std_logic; addr : IN std_logic_vector(7 DOWNTO 0); rom_out : OUT std_logic_vector(15 DOWNTO 0)); |
|||||
END rom_syn; ARCHITECTURE a OF rom_syn IS |
|||||
TYPE T_UFIX_16_256 IS ARRAY (255 DOWNTO 0) of unsigned (15 DOWNTO 0); SIGNAL data : T_UFIX_16_256; SIGNAL data_next : T_UFIX_16_256; |
|||||
BEGIN | |||||
PROCESS (reset, clk) | |||||
— local variables VARIABLE b : INTEGER; |
|||||
BEGIN | |||||
IF reset = ‘1’ THEN | |||||
NULL; | |||||
ELSIF clk’EVENT AND clk= ‘1’ THEN | |||||
IF clk_enable= ‘1’ THEN |
|||||
FOR b IN 0 TO 255 LOOP | |||||
data(b) <= data_next(b); | |||||
END LOOP; | |||||
END IF; | |||||
END IF; | |||||
END PROCESS; PROCESS (addr) |
|||||
— local variables VARIABLE data_temp : T_UFIX_16_256; |
|||||
BEGIN | |||||
FOR b IN 0 TO 255 LOOP | |||||
data_temp(b) := to_unsigned(0, 16); | |||||
END LOOP; data_temp(0) := to_unsigned(1036, 16); data_temp(1) := to_unsigned(1303, 16); data_temp(2) := to_unsigned(1540, 16); data_temp(3) := to_unsigned(1545, 16); data_temp(4) := to_unsigned(1358, 16); data_temp(5) := to_unsigned(1539, 16); data_temp(6) := to_unsigned(1541, 16); data_temp(7) := to_unsigned(1545, 16); data_temp(8) := to_unsigned(1542, 16); data_temp(9) := to_unsigned(523, 16); data_temp(10) := to_unsigned(263, 16); data_temp(11) := to_unsigned(1037, 16); data_temp(12) := to_unsigned(1397, 16); data_temp(13) := to_unsigned(1543, 16); data_temp(14) := to_unsigned(1539, 16); data_temp(15) := to_unsigned(1544, 16); data_temp(16) := to_unsigned(277, 16); data_temp(17) := to_unsigned(1135, 16); data_temp(18) := to_unsigned(1480, 16); data_temp(19) := to_unsigned(1542, 16); data_temp(20) := to_unsigned(1536, 16); data_temp(21) := to_unsigned(785, 16); data_temp(22) := to_unsigned(0, 16); |
|||||
rom_out <= std_logic_vector(data_temp(to_integer(unsigned(addr)))); END PROCESS; |
|||||
END a; |
Анализируя этот код, можно сделать вывод, что сгенерировано синхронное ПЗУ с асинхронным сбросом, синхронным сигналом разрешения тактирования clk_enable. Для организации массива памяти используется последовательный оператор for … loop, выполняющий повторяющиеся операторы.
Оператор for … loop имеет целую схему итерации, при которой количество повторов определяется целым диапазоном. Цикл повторяется один раз для каждого значения диапазона. После того как будет достигнуто последнее значение диапазона итерации, цикл пропускается, и выполнение программы продолжается, начиная с оператора, стоящего вслед за циклом.
Следует упомянуть про функции преобразования типов to_integer и to_unsigned из пакета Numeric_std, которые используются при проектировании синхронного ПЗУ. Функция to_integer преобразует тип unsigned в подтип natural (встроенный подтип natural используют для объектов, которые не должны принимать отрицательные значения), а функция to_unsigned преобразует подтип natural в тип unsigned, при этом необходимо указывать размер желаемого слова.
На рис. 8 показаны изменения, которые необходимо внести в проект для ПЗУ с использованием М-функции в системе MATLAB/Simulink (рис. 8а) и для синхронного ПЗУ в САПР ПЛИС Quartus II (рис. 8б). На рис. 9 представлена временная диаграмма работы процессора с синхронным ПЗУ.
Проект микропроцессора с синхронным ПЗУ, код языка VHDL которого был получен с использованием Simulink HDL Coder, продемонстрировал работоспособность как на старых, так и на новых сериях ПЛИС фирмы Altera, что не удавалось осуществить с использованием встроенных мегафункций ОЗУ и ПЗУ [3]. На рис. 10 показана тестовая схема процессора в графическом редакторе САПР ПЛИС Quartus II (версия 8) с циклом работы в два такта с синхронным ПЗУ. В работе [2] приведен код языка VHDL процессора с циклом работы в два такта. Сравнивая рис. 9 и рис. 11 видим, что два процессора логически работают одинаково. Однако на временной диаграмме (рис. 9) имеется большое количество гличей. Это объясняется разными архитектурными решениями при реализации процессоров.
Система MATLAB/Simulink c Simulink HDL Coder может быть эффективно использована для ускорения процесса разработки моделей микропроцессорных ядер. Проект микропроцессора с асинхронным ПЗУ на языке VHDL может быть успешно размещен в ПЛИС APEX20KE EP20K30ETC144-1, при этом общее число задействованных ресурсов составляет 22%, с рабочей частотой до 60 МГц.
Недостатком процессора, реализованного в системе MATLAB/Simulink и адаптированного в САПР Quartus II, является отсутствие управляющего автомата.
- Тарасов И. Проектирование конфигурируемых процессоров на базе ПЛИС. Часть I // Компоненты и технологии. 2006. № 2.
- Тарасов И. Проектирование конфигурируемых процессоров на базе ПЛИС. Часть II // Компоненты и технологии. 2006. № 3.
- Строгонов А. Проектирование учебного процессора для реализации в базисе ПЛИС // Компоненты и технологии. 2009. № 3.
- www.mathworks.com. Simulink fixed point for use with Simulink. User Guide. Version 5.