close

Вход

Забыли?

вход по аккаунту

?

Записка-мой финал

код для вставкиСкачать
 ВВЕДЕНИЕ
В ходе выполнения курсового проекта требуется реализовать микроЭВМ с условиями, приведенными в задании к курсовому проекту.
Тип архитектуры, используемой при реализации - гарвардская.
Гарвардская архитектура - архитектура ЭВМ, отличительным признаком которой является раздельное хранение и обработка команд и данных. Архитектура была разработана Говардом Эйкеном в конце 1930-х годов в Гарвардском университете.
В Гарвардской архитектуре принципиально невозможно осуществить операцию записи в память программ, что исключает возможность случайного разрушения управляющей программы в случае ошибки программы при работе с данными или атаки третьих лиц. Кроме того, для работы с памятью программ и с памятью данных организуются отдельные шины обмена данными (системные шины),
В такой архитектуре невозможны многие методы программирования (например, программа не может во время выполнения менять свой код; невозможно динамически перераспределять память между программным кодом и данными), зато гарвардская архитектура позволяет более эффективно выполнять работу в случае ограниченных ресурсов, поэтому она часто применяется во встраиваемых системах.
На рисунке 1 приведена схема гарвардской архитектуры.
Рисунок 1 - Схема гарвардской архитектуры
Гарвардской архитектуре используется два вида памяти микропроцессора:
* Память программ (для хранения инструкций микропроцессора)
* Память данных (для временного хранения и обработки переменных)
В гарвардской архитектуре принципиально невозможно осуществить операцию записи в память программ, что исключает возможность случайного разрушения управляющей программы в случае ошибки программы при работе с данными или атаки третьих лиц. Кроме того, для работы с памятью программ и с памятью данных организуются отдельные шины обмена данными (системные шины).
Гарвардская архитектура применяется в микроконтроллерах и в сигнальных процессорах, где требуется обеспечить высокую надёжность работы аппаратуры. В сигнальных процессорах Гарвардская архитектура дополняется применением трехшинного операционного блока микропроцессора. Трехшинная архитектура операционного блока позволяет совместить операции считывания двух операндов с записью результата выполнения команды в оперативную память микропроцессора. Это значительно увеличивает производительность сигнального микропроцессора без увеличения его тактовой частоты.
Применение двух системных шин для обращения к памяти программ и памяти данных в гарвардской архитектуре имеет два недостатка - высокую стоимость и большое количество внешних выводов микропроцессора. При использовании двух шин для передачи команд и данных, микропроцессор должен иметь почти вдвое больше выводов, так как шина адреса и шина данных составляют основную часть выводов микропроцессора. Для уменьшения количества выводов кристалла микропроцессора фирмы-производители микросхем объединили шины данных и шины адреса для внешней памяти данных и программ, оставив только различные сигналы управления (WR, RD, IRQ) а внутри микропроцессора сохранили классическую гарвардскую архитектуру. Такое решение получило название модифицированная гарвардская архитектура.
Модифицированная гарвардская структура применяется в современных микросхемах сигнальных процессоров. Ещё дальше по пути уменьшения стоимости кристалла за счет уменьшения площади, занимаемой системными шинами пошли производители однокристалльных ЭВМ - микроконтроллеров. В этих микросхемах применяется одна системная шина для передачи команд и данных (модифицированная гарвардская архитектура) и внутри кристалла.
При разработке микроЭВМ мы будем использовать программу Altera Quartus II 9.1.
Отличительные особенности программного комплекса Altera Quartus II 9.1:
• Поддержка семейств FPGA
• Опция интерфейса пользователя MAX+
• Файл однократных присваиваний (.qsf)
• Средство просмотра RTL
• Поддержка изменений компиляции
• Формирование последовательности тактирования встроенной памяти
• Новая опция методики "сбалансированной" оптимизации
• Функция улучшенной синхронизации SignalTap(r) II
Программный интерфейс: Позволяет пользователям MAX+ использовать предоставляемые Quartus II возможности, не затрудняя себя изучением нового интерфейса. Будет ли Quartus II установлен первым или будет установлен впоследствии, пользователь увидит окно диалога, позволяющее "увидеть-и-ощутить ( look-and-feel )" выбор: Quartus II или MAX+. Однако, пользователь может в любое время изменить этот выбор. Средство просмотра: Новое средства просмотра RTL файлов программы Quartus II обеспечивает возможность схематического представления VHDL и Verilog RTL файлов, что может быть использовано для анализа структуры проекта до проведения этапов поведенческого моделирования, синтеза, размещения и маршрутизации. Средство просмотра RTL позволяет разработчику управлять иерархией проекта и размещать отдельные элементы, представляющие интерес, для упрощения отладки и оптимизации. Выбранные в средстве просмотра RTL элементы могут быть напрямую трассированы в исходный файл проекта.
Изменения компиляции: Позволяют разработчикам экспериментировать с различными установками компиляции и присвоениями проекта. Группа установок, присвоений и результатов компиляции может быть сохранена и обработана отдельно как версия проекта.
Формирование последовательности тактирования встроенной памяти: Функция компилятора памяти программы Quartus II может быть задействована для упрощения использования встроенной в FPGA памяти, за счет способности динамически генерировать последовательности импульсов, необходимые для операций чтения/записи RAM и FIFO, на основе выбранных конфигураций. Такая возможность обеспечивается MegaWizard (r) Plug - In Manager.
1 РАЗРАБОТКА ОБЩЕЙ СТРУКТУРЫ МИКРОЭВМ
1.1 Функциональный состав
Согласно заданию, шина данных ограничена 8 битами, а шина адреса ограничена 10 битами. Тип адресации памяти - регистрово-косвенная. При косвенно-регистровой адресации искомый операнд берется из памяти или отправляется в память, но адрес не фиксируется жестко в команде, как при прямой адресации, а находится в регистре. Если адрес используется таким образом, он называется указателем. Преимущество косвенной адресации состоит в том, что можно обращаться к памяти, не имея в команде полного адреса.
В ходе разработки микроЭВМ была составлена функциональная схема, представленная на рисунке 1.1. Исходя из полученной схемы, рассмотрим более подробно компоненты, которые формируют данное устройство.
Рисунок 1.1 - Функциональная схема разрабатываемой микроЭВМ.
Функциональными блоками микроЭВМ являются: синхронные ПЗУ данных и команд, синхронные ОЗУ, регистры общего назначения, АЛУ, устройство управления, контроллер прямого доступа к памяти, контроллер прерываний.
ПЗУ (постоянное запоминающее устройство) - энергонезависимый тип памяти, позволяющий постоянно хранить данные, внесенные на этапе прошивки. Данный тип памяти - только для чтения. В ПЗУ - основная программа микроЭВМ. Считывание происходит асинхронно по изменению состояния адресных входов.
ОЗУ (оперативное запоминающее устройство) - энергозависимый тип памяти, в данной микроЭВМ - синхронное. Необходимость данного типа памяти обосновано тем, что ее содержимое может быть легко модифицировано, что важно для функционирования ЭВМ как вычислительной системы. АЛУ должно реализовывать операции сравнения (CMP) и побитового сложения "И" (AND). Контроллер прерываний предназначен для обслуживания запросов на прерываний, которые поступили от внешних устройств. При поступлении запроса на прерывание основной командный цикл прерывается и выполняется микрокоманда соответствующего прерывания.
Контроллер прямого доступа к памяти предназначен для обмена данными между внешними устройствами и ОЗУ без участия центрального процессора. Начальный адрес контроллера прямого доступа к памяти - 10. Объем при передачи данных в режиме прямого доступа к памяти - 8.
В своем составе микроЭВМ также должно содержать регистры общего назначения (РОНы). Должно быть реализовано 12 регистров общего назначения. Устройство управления служит для выдачи всех управляющих сигналов (такие как чтение/запись в память, синхросигналы для работы устройств, асинхронные сигналы-события.
1.2 Описание взаимодействия всех блоков микроЭВМ
МикроЭВМ будет содержать 4 общие шины, через которые будет осуществляться обмен между отдельными устройствами: шина управления (ШУ), шина данных (ШД), шина адреса (ША), шина команд (ШК).
Шина управления включает в себя все управляющие и синхросигналы устройств.
Шина данных используется для передачи непосредственно данных (значений операндов). По заданию курсового проекта шина данных должна быть 8-разрядной. Таким образом, размер одного машинного слова для данной ЭВМ - 8 бит. Шина адреса необходима для адресации памяти. По условию она должна быть 10-разрядной. Следовательно, ПЗУ и ОЗУ должны адресоваться 10 битами. Исходя из разрядности шины адреса, максимально адресуемый размер памяти равен 1024 словам. Шина команд используется для передачи данных машинных инструкций. Разрядность шины принята равной разрядности ШД.
В общем случае выполнение команды в ЭВМ будет выполняться в несколько этапов:
* чтение команды из ОЗУ команд;
* анализ кода операции;
* чтение данных для выполнения команды из ОЗУ данных;
* выполнение команды;
* запись результатов.
Назначение используемых сигналов приведено в таблицах 1.1 - 1.5.
Таблица 1.1 - Назначение сигналов постоянного запоминающего устройства
НазваниеТипНазначение123clockВходнойСигнал тактирования микросхемыadress[9..0]ВходнойАдрес ячейки памятиout_data[7..0]ВыходнойВыходные данные Таблица 1.2 - Назначение сигналов оперативного запоминающего устройства
НазваниеТипНазначение123in_data[7..0]ВходнойВходные данныеadress[9..0]ВходнойАдрес ячейки памятиClockВходнойСигнал тактирования микросхемыout_data[7..0]ВыходнойВыходные данныеWeВходнойСигнал записи\чтения Таблица 1.3 - Назначение входов и выходов АЛУ
НазваниеТипНазначение123A[7..0]ВходнойПервый операнд операцииB[7..0]ВходнойВторой операнд операции
CMP_SELВходнойВыбор режима сравнениеAND_SELВходнойВыбор режима логического ИCSВходнойРазрешение работы устройстваCLKВходнойТактовый синхросигналRESULT[7..0]ВыходнойРезультат операции ANDbiggerВыходнойА>B (операция CMP)smallerВыходнойA<B (операция CMP)equalВыходнойA=B (операция CMP) Таблица 1.4 - Назначение входов и выходов КПДП
Название Тип Назначение123DMA_ACK_WRВходнойЗапрос на запись в памятьDMA_ACK_RDВходнойЗапрос на чтение из памятиCPU_READYВходнойСигнал об освобождении шин устройством управленияCLKВходнойСинхросигналDATAВыходнойИнформационные двунаправленные входы внешнего устройстваBUS_ADDRВыходнойАдрес, выставляемый на шину адресаBUS_DATAВыходнойИнформационные двунаправленные входы шины данныхRAM_CSВыходнойСигнал разрешения работы ОЗУRAM_WEВыходнойСигнал разрешения записи в ОЗУRAM_OEВыходнойСигнал разрешения чтения из ОЗУCPU_DMA_ACKВыходнойСигнал о запросе на ПДП для устройства управленияEND_OF_CYCLEВыходнойСигнал о конце цикла обмена данными с памятью Таблица 1.5 - Назначение входов и выходов контроллера прерываний
Название Тип Назначение123IRQ_INВходнойЛинии прерыванийCLIВходнойСигнал запрета прерыванияSTIВходнойСигнал разрешения прерыванияNUMВходнойНомер запрещаемого/разрешаемого прерыванияCLKВходнойСинхросигналADDRВыходнойАдрес обработчика прерыванияIRQ_OUTВыходнойВыход сигнала возникновения прерыванияMASK[4..0]ВыходнойМаска прерываний Таблица 1.6 - Назначение входов и выходов УУ
СигналТипНазначение12RESETВходнойСигнал сброса микро-ЭВМCLKВходнойСинхросигналIRQ_INВходнойВход, информирующий о возникновении прерыванияIRQ_ADDR[9..0]ВходнойАдрес обработчика прерыванияDMA_ACKВходнойВход, информирующий о требовании передать управление КПДПDMA_END_OF_CYCLEВходнойВход, информирующий о завершении цикла КПДПADDR[9..0]ВходнойАдресные выходыCMD_DATA[7..0]ВходнойВходы шины командDATA[7..0]ВходнойВходы шины данныхROM_OEВходнойСигнал о разрешении чтения из ПЗУCMD_RAM_CSВходнойСигнал о разрешении работы ОЗУ командCMD_RAM _WEВходнойСигнал о разрешении записи в ОЗУ командCMD_RAM _OEВходнойСигнал о разрешении чтения из ОЗУ командDATA_RAM_CSВходнойСигнал о разрешении работы ОЗУ данныхDATA _RAM _WEВходнойСигнал о разрешении записи в ОЗУ данныхDATA _RAM _OEВходнойСигнал о разрешении чтения из ОЗУ данныхREGS_CSВходнойСигнал о разрешении работы блока регистров
Продолжение таблицы 1.6.
123REGS _WEВходнойСигнал о разрешении записи в регистрыREGS _OEВходнойСигнал о разрешении чтения из регистровREGS _ADDR[9..0]ВходнойАдрес данных регистраALD_CSВходнойСигнал о разрешении работы блока АЛУALD_CMPВходнойСигнал выбора операции сравнения блока АЛУALD_ANDВходнойСигнал выбора операции И блока АЛУALD_A[9..0]ВходнойПервый операнд для АЛУALD_B[9..0]ВходнойВторой операнд для АЛУIRQ_CLIВходнойСигнал о запрете прерыванийIRQ_STIВходнойСигнал о разрешении прерыванийIRQ_NUM[4..0]ВходнойНомер разрешаемого/запрещаемого прерыванияDMA_READYВходнойОсвобождение шин устройством управления 2 РАЗРАБОТКА ОСНОВНЫХ УСТРОЙСТ МИКРОЭВМ
2.1 Функциональный состав и работы ПЗУ
В курсовом проекте должны быть реализованы запоминающие устройства двух типов:
1. постоянное запоминающее устройства, где храниться программа.
2. оперативное запоминающее устройство.
Рассмотрим работу ПЗУ и временные диаграммы его работы. Условно-графическое изображение ПЗУ приведено на рисунке 2.1.
Рисунок 2.1 - Условно-графическое изображение ПЗУ.
По условию задания, ПЗУ в проекте работает в асинхронном режиме. Временная диаграмма устройства может быть представлена только циклом чтения, так как этот тип памяти является энергонезависимым и служит для постоянного хранения программы (команд и микроопераций), поэтому данные в ПЗУ записываются обычно один раз.
Рисунок 2.2 - Временная диаграмма работы ПЗУ.
ПЗУ память проверена путём чтения данных из MIF-файла по соответствующим адресам.
Листинг 2.1 реализация MIF-файла.
WIDTH=8;
DEPTH=1024;
ADDRESS_RADIX=UNS;
DATA_RADIX=UNS;
CONTENT BEGIN
0 : 1;
1 : 3;
2 : 5;
3 : 7;
4 : 9;
5 : 7;
6 : 5;
7 : 3;
[8..1023] : 0;
END;
2.1.2 Функциональный состав и временные диаграммы работы ОЗУ
По условию задания необходимо реализовать оперативное запоминающее устройство, работающее в синхронном режиме. Данное устройство будет реализовано в виде отдельного блока, согласно данной по условию архитектуре системы. Рассмотрим работу ОЗУ и временные диаграммы его работы. Условно-графическое изображение ОЗУ приведено на рисунке 2.3, а временная диаграмма работы - на рисунке 2.4.
Рисунок 2.3 - Условно-графическое изображение ОЗУ.
Рисунок 2.4 - Временная диаграмма работы ОЗУ.
Для проверки были поданы из порта DAT произвольные данные и записаны в ОЗУ, а после считаны.
Листинг 2.2 реализация VHDL-кода ОЗУ.
USE ieee.std_logic_1164.all;
LIBRARY altera_mf;
USE altera_mf.all;
ENTITY lpm_rom0 IS
PORT
(
address: IN STD_LOGIC_VECTOR (9 DOWNTO 0);
clock: IN STD_LOGIC := '1';
q: OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END lpm_rom0;
ARCHITECTURE SYN OF lpm_rom0 IS
SIGNAL sub_wire0: STD_LOGIC_VECTOR (7 DOWNTO 0);
COMPONENT altsyncram
GENERIC (
clock_enable_input_a: STRING;
clock_enable_output_a: STRING;
init_file: STRING;
intended_device_family: STRING;
lpm_hint: STRING;
lpm_type: STRING;
numwords_a: NATURAL;
operation_mode: STRING;
outdata_aclr_a: STRING;
outdata_reg_a: STRING;
widthad_a: NATURAL;
width_a: NATURAL;
width_byteena_a: NATURAL
);
PORT (
clock0: IN STD_LOGIC ;
address_a: IN STD_LOGIC_VECTOR (9 DOWNTO 0);
q_a: OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END COMPONENT;
BEGIN
q <= sub_wire0(7 DOWNTO 0);
altsyncram_component : altsyncram
GENERIC MAP (
clock_enable_input_a => "BYPASS",
clock_enable_output_a => "BYPASS",
init_file => "rom.mif",
intended_device_family => "Stratix II",
lpm_hint => "ENABLE_RUNTIME_MOD=NO",
lpm_type => "altsyncram",
numwords_a => 1024,
operation_mode => "ROM",
outdata_aclr_a => "NONE",
outdata_reg_a => "CLOCK0",
widthad_a => 10,
width_a => 8,
width_byteena_a => 1
)
PORT MAP (
clock0 => clock,
address_a => address,
q_a => sub_wire0
);
END SYN;
2.1.3 Совмещенная схема работы ОЗУ и ПЗУ. Рисунок 2.5 - Совмещенная схема ОЗУ и ПЗУ.
Рисунок 2.6 - Временная диаграмма работы ОЗУ
Для проверки совмещённой памяти ОЗУ записала данные из ПЗУ памяти и затем считаны из неё, по тем же адресам.
Рисунок 2.7 - УГО блока памяти.
2.2 Разработка устройства управления. Функциональный состав и временные диаграммы
Данное устройство представляет собой автомат с конечным числом состояний, меняющий значение на выходах в зависимости от состояния в котором он находится. Выходы устройства управления подключаются к входам всех остальных устройств микроЭВМ посредством шины управления.
УУ является центральны блоком во всей системе микроЭВМ, на нем сходятся все логические связи. Именно блок устройства управления осуществляет управление всеми составляющими микроЭВМ. Правильная работа устройства управления определяет, насколько правильно будет работать вся схема в целом.
Устройства управления делятся на:
- УУ с жесткой, или схемной логикой; - УУ с программируемой логикой (микропрограммные УУ).
В устройствах управления первого типа для каждой команды, задаваемой кодом операции, строится набор комбинационных схем, которые в нужных тактах вырабатывают необходимые управляющие сигналы.
В микропрограммном УУ каждой команде ставится в соответствие совокупность хранимых в специальной памяти слов - микрокоманд. Каждая из микрокоманд содержит информацию о микрооперациях, подлежащих выполнению в данном такте, и указание, какое слово должно быть выбрано из памяти в следующем такте. Функциональная схема устройства управления приведена на рисунке 2.8. Рисунок 2.8 - Функциональная схема устройства управления.
.
2.3 Разработка АЛУ. Функциональный состав и временные диаграммы
АЛУ - блок микроЭВМ, предназначенный для выполнения арифметических и логических операций. Условное графическое обозначение АЛУ представлено на рисунке 2.3.1.
Блок АЛУ функционально состоит из двух частей: компаратора и блока побитовое реализующего логическое умножение. АЛУ реализовано на языке VHDL и представлено в листинге 2.9.
Рисунок 2.9 - Условно-графическое обозначение АЛУ.
На рисунке 2.10 изображены временные диаграммы работы АЛУ.
Рисунок 2.10 - Временная диаграмма работы АЛУ.
Значения операндов необходимых для обработки подаются на входы А и В. При высоком уровне сигнала CS в зависимости от выбора операции сравнения или логического умножения, входы AND_SEL и CMP_SEL соответственно, выполняется операция. В случае операции сравнения высокий уровень сигал возвращается на выход EQUAL - в случае равенства операндов, SMALLER - в случае если первый операнд меньше второго, BIGGER - в случае если первый операнд больше второго. В случае операции побитого умножения результат возвращается на выход RESULT.
Листинг 2.3 Реализации АЛУ:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity ald is
GENERIC
(
DATA_WIDTH : integer :=10
);
port
(
A, B : in std_logic_vector(9 downto 0);
CMP_SEL, AND_SEL: in std_logic;
CS : in std_logic;
CLK : in std_logic;
RESULT : out std_logic_vector(9 downto 0) := (others => 'Z');
BIGGER, SMALLER, EQUAL: out std_logic
);
end entity ald;
architecture rtl of ald is
shared variable temp: std_logic_vector(9 downto 0); begin
process(clk)
begin
if (rising_edge(clk)) then
if (cs = '1') then
if (cmp_sel='1') then
if (conv_integer(A) > conv_integer(B)) then
BIGGER <= '1';
SMALLER <= '0';
EQUAL <= '0';
temp := (others => 'Z');
elsif (conv_integer(A) < conv_integer(B)) then
BIGGER <= '0';
SMALLER <= '1';
EQUAL <= '0';
temp := (others => 'Z');
else BIGGER <= '0';
SMALLER <= '0';
EQUAL <= '1';
temp := (others => 'Z');
end if;
elsif (and_sel='1') then temp := std_logic_vector(to_unsigned(conv_integer(A and B),temp'length));
else
temp := (others => 'Z');
end if;
result <= temp(9 downto 0);
else
result <= (others => 'Z');
end if;
end if;
end process;
end architecture rtl;
2.3.1 Блок регистров общего назначения (РОН)
Регистры общего назначения используются для временного хранения, как промежуточных данных, так и результата операции. Общее число РОН по условию курсового проекта составляет 12. В данном курсовом проекте необходимо был реализовать РОНы с регистрово-косвенной адресацией. Для этого в блок РОНов был строен дополнительный блок регистров, хранящий непосредственно адреса всех РОНов. Таким образом обращение к РОНам организовывается косвенно, через дополнительный блок регистров.
Условно-графическое обозначение РОН изображено на рисунке 2.11. Рисунок 2.11 - Условно-графическое обозначение РОН.
Реализация данного блока выполнялась программно. Код реализации РОН представлен в листинге 2.12.
Листинг 2.4 Реализация РОНов:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY gpr IS
PORT
(
clk : IN std_logic;
we : IN std_logic;
re : IN std_logic;
adr: IN std_logic_vector (3 DOWNTO 0);
in_data : IN std_logic_vector (9 DOWNTO 0);
out_data : OUT std_logic_vector (9 DOWNTO 0);
interrupt : OUT std_logic
);
END gpr;
ARCHITECTURE Level1 OF gpr IS
shared variable flag: integer:=0;
shared variable quit: integer:=1;
BEGIN
PROCESS(clk)
variable zero: std_logic :='0';
type registr1 is array(0 to 11) of std_logic_vector(3 downto 0);
type registr2 is array(0 to 11) of std_logic_vector(9 downto 0);
variable reg1 : registr1;
variable reg2 : registr2;
BEGIN
reg1(0) := "0000";
reg1(1) := "0001";
reg1(2) := "0010";
reg1(3) := "0011";
reg1(4) := "0100";
reg1(5) := "0101";
reg1(6) := "0110";
reg1(7) := "0111";
reg1(8) := "1000";
reg1(9) := "1001";
reg1(10) := "1010";
reg1(11) := "1011"; quit:=1; IF (clk'event AND clk = '1' ) THEN if(we = '1' AND flag=0 AND quit=1) then
case adr(3 downto 0) is
when "0000"=> case reg1(0)(3 downto 0) is when "0000"=> reg2(0) := in_data;
when "0001"=> reg2(1) := in_data;
when "0010"=> reg2(2) := in_data;
when "0011"=> reg2(3) := in_data;
when "0100"=> reg2(4) := in_data;
when "0101"=> reg2(5) := in_data;
when "0110"=> reg2(6) := in_data;
when "0111"=> reg2(7) := in_data;
when "1000"=> reg2(8) := in_data;
when "1001"=> reg2(9):= in_data;
when "1010"=> reg2(10) := in_data;
when "1011"=> reg2(11) := in_data;
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "0001"=> case reg1(1)(3 downto 0) is when "0000"=> reg2(0) := in_data;
when "0001"=> reg2(1) := in_data;
when "0010"=> reg2(2) := in_data;
when "0011"=> reg2(3) := in_data;
when "0100"=> reg2(4) := in_data;
when "0101"=> reg2(5) := in_data;
when "0110"=> reg2(6) := in_data;
when "0111"=> reg2(7) := in_data;
when "1000"=> reg2(8) := in_data;
when "1001"=> reg2(9):= in_data;
when "1010"=> reg2(10) := in_data;
when "1011"=> reg2(11) := in_data;
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "0010"=> case reg1(2)(3 downto 0) is when "0000"=> reg2(0) := in_data;
when "0001"=> reg2(1) := in_data;
when "0010"=> reg2(2) := in_data;
when "0011"=> reg2(3) := in_data;
when "0100"=> reg2(4) := in_data;
when "0101"=> reg2(5) := in_data;
when "0110"=> reg2(6) := in_data;
when "0111"=> reg2(7) := in_data;
when "1000"=> reg2(8) := in_data;
when "1001"=> reg2(9):= in_data;
when "1010"=> reg2(10) := in_data;
when "1011"=> reg2(11) := in_data;
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "0011"=> case reg1(3)(3 downto 0) is when "0000"=> reg2(0) := in_data;
when "0001"=> reg2(1) := in_data;
when "0010"=> reg2(2) := in_data;
when "0011"=> reg2(3) := in_data;
when "0100"=> reg2(4) := in_data;
when "0101"=> reg2(5) := in_data;
when "0110"=> reg2(6) := in_data;
when "0111"=> reg2(7) := in_data;
when "1000"=> reg2(8) := in_data;
when "1001"=> reg2(9):= in_data;
when "1010"=> reg2(10) := in_data;
when "1011"=> reg2(11) := in_data;
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "0100"=> case reg1(4)(3 downto 0) is when "0000"=> reg2(0) := in_data;
when "0001"=> reg2(1) := in_data;
when "0010"=> reg2(2) := in_data;
when "0011"=> reg2(3) := in_data;
when "0100"=> reg2(4) := in_data;
when "0101"=> reg2(5) := in_data;
when "0110"=> reg2(6) := in_data;
when "0111"=> reg2(7) := in_data;
when "1000"=> reg2(8) := in_data;
when "1001"=> reg2(9):= in_data;
when "1010"=> reg2(10) := in_data;
when "1011"=> reg2(11) := in_data;
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "0101"=> case reg1(5)(3 downto 0) is when "0000"=> reg2(0) := in_data;
when "0001"=> reg2(1) := in_data;
when "0010"=> reg2(2) := in_data;
when "0011"=> reg2(3) := in_data;
when "0100"=> reg2(4) := in_data;
when "0101"=> reg2(5) := in_data;
when "0110"=> reg2(6) := in_data;
when "0111"=> reg2(7) := in_data;
when "1000"=> reg2(8) := in_data;
when "1001"=> reg2(9):= in_data;
when "1010"=> reg2(10) := in_data;
when "1011"=> reg2(11) := in_data;
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "0110"=> case reg1(6)(3 downto 0) is when "0000"=> reg2(0) := in_data;
when "0001"=> reg2(1) := in_data;
when "0010"=> reg2(2) := in_data;
when "0011"=> reg2(3) := in_data;
when "0100"=> reg2(4) := in_data;
when "0101"=> reg2(5) := in_data;
when "0110"=> reg2(6) := in_data;
when "0111"=> reg2(7) := in_data;
when "1000"=> reg2(8) := in_data;
when "1001"=> reg2(9) := in_data;
when "1010"=> reg2(10) := in_data;
when "1011"=> reg2(11) := in_data;
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "0111"=> case reg1(7)(3 downto 0) is when "0000"=> reg2(0) := in_data;
when "0001"=> reg2(1) := in_data;
when "0010"=> reg2(2) := in_data;
when "0011"=> reg2(3) := in_data;
when "0100"=> reg2(4) := in_data;
when "0101"=> reg2(5) := in_data;
when "0110"=> reg2(6) := in_data;
when "0111"=> reg2(7) := in_data;
when "1000"=> reg2(8) := in_data;
when "1001"=> reg2(9):= in_data;
when "1010"=> reg2(10) := in_data;
when "1011"=> reg2(11) := in_data;
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "1001"=> case reg1(8)(3 downto 0) is when "0000"=> reg2(0) := in_data;
when "0001"=> reg2(1) := in_data;
when "0010"=> reg2(2) := in_data;
when "0011"=> reg2(3) := in_data;
when "0100"=> reg2(4) := in_data;
when "0101"=> reg2(5) := in_data;
when "0110"=> reg2(6) := in_data;
when "0111"=> reg2(7) := in_data;
when "1000"=> reg2(8) := in_data;
when "1001"=> reg2(9):= in_data;
when "1010"=> reg2(10) := in_data;
when "1011"=> reg2(11) := in_data;
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "1010"=> case reg1(9)(3 downto 0) is when "0000"=> reg2(0) := in_data;
when "0001"=> reg2(1) := in_data;
when "0010"=> reg2(2) := in_data;
when "0011"=> reg2(3) := in_data;
when "0100"=> reg2(4) := in_data;
when "0101"=> reg2(5) := in_data;
when "0110"=> reg2(6) := in_data;
when "0111"=> reg2(7) := in_data;
when "1000"=> reg2(8) := in_data;
when "1001"=> reg2(9):= in_data;
when "1010"=> reg2(10) := in_data;
when "1011"=> reg2(11) := in_data;
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "1011"=> case reg1(10)(3 downto 0) is when "0000"=> reg2(0) := in_data;
when "0001"=> reg2(1) := in_data;
when "0010"=> reg2(2) := in_data;
when "0011"=> reg2(3) := in_data;
when "0100"=> reg2(4) := in_data;
when "0101"=> reg2(5) := in_data;
when "0110"=> reg2(6) := in_data;
when "0111"=> reg2(7) := in_data;
when "1000"=> reg2(8) := in_data;
when "1001"=> reg2(9):= in_data;
when "1010"=> reg2(10) := in_data;
when "1011"=> reg2(11) := in_data;
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "1100"=> case reg1(11)(3 downto 0) is when "0000"=> reg2(0) := in_data;
when "0001"=> reg2(1) := in_data;
when "0010"=> reg2(2) := in_data;
when "0011"=> reg2(3) := in_data;
when "0100"=> reg2(4) := in_data;
when "0101"=> reg2(5) := in_data;
when "0110"=> reg2(6) := in_data;
when "0111"=> reg2(7) := in_data;
when "1000"=> reg2(8) := in_data;
when "1001"=> reg2(9):= in_data;
when "1010"=> reg2(10) := in_data;
when "1011"=> reg2(11) := in_data;
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case; when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
quit := 0; case adr(3 downto 0) is
when "0000"=> case reg1(0)(3 downto 0) is when "0000"=> out_data <= reg2(0);
when "0001"=> out_data <= reg2(1);
when "0010"=> out_data <= reg2(2);
when "0011"=> out_data <= reg2(3);
when "0100"=> out_data <= reg2(4);
when "0101"=> out_data <= reg2(5);
when "0110"=> out_data <= reg2(6);
when "0111"=> out_data <= reg2(7);
when "1000"=> out_data <= reg2(8);
when "1001"=> out_data <= reg2(9);
when "1010"=> out_data <= reg2(10);
when "1011"=> out_data <= reg2(11);
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "0001"=> case reg1(1)(3 downto 0) is when "0000"=> out_data <= reg2(0);
when "0001"=> out_data <= reg2(1);
when "0010"=> out_data <= reg2(2);
when "0011"=> out_data <= reg2(3);
when "0100"=> out_data <= reg2(4);
when "0101"=> out_data <= reg2(5);
when "0110"=> out_data <= reg2(6);
when "0111"=> out_data <= reg2(7);
when "1000"=> out_data <= reg2(8);
when "1001"=> out_data <= reg2(9);
when "1010"=> out_data <= reg2(10);
when "1011"=> out_data <= reg2(11);
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "0010"=> case reg1(2)(3 downto 0) is when "0000"=> out_data <= reg2(0);
when "0001"=> out_data <= reg2(1);
when "0010"=> out_data <= reg2(2);
when "0011"=> out_data <= reg2(3);
when "0100"=> out_data <= reg2(4);
when "0101"=> out_data <= reg2(5);
when "0110"=> out_data <= reg2(6);
when "0111"=> out_data <= reg2(7);
when "1000"=> out_data <= reg2(8);
when "1001"=> out_data <= reg2(9);
when "1010"=> out_data <= reg2(10);
when "1011"=> out_data <= reg2(11);
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "0011"=> case reg1(3)(3 downto 0) is when "0000"=> out_data <= reg2(0);
when "0001"=> out_data <= reg2(1);
when "0010"=> out_data <= reg2(2);
when "0011"=> out_data <= reg2(3);
when "0100"=> out_data <= reg2(4);
when "0101"=> out_data <= reg2(5);
when "0110"=> out_data <= reg2(6);
when "0111"=> out_data <= reg2(7);
when "1000"=> out_data <= reg2(8);
when "1001"=> out_data <= reg2(9);
when "1010"=> out_data <= reg2(10);
when "1011"=> out_data <= reg2(11);
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "0100"=> case reg1(4)(3 downto 0) is when "0000"=> out_data <= reg2(0);
when "0001"=> out_data <= reg2(1);
when "0010"=> out_data <= reg2(2);
when "0011"=> out_data <= reg2(3);
when "0100"=> out_data <= reg2(4);
when "0101"=> out_data <= reg2(5);
when "0110"=> out_data <= reg2(6);
when "0111"=> out_data <= reg2(7);
when "1000"=> out_data <= reg2(8);
when "1001"=> out_data <= reg2(9);
when "1010"=> out_data <= reg2(10);
when "1011"=> out_data <= reg2(11);
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "0101"=> case reg1(5)(3 downto 0) is when "0000"=> out_data <= reg2(0);
when "0001"=> out_data <= reg2(1);
when "0010"=> out_data <= reg2(2);
when "0011"=> out_data <= reg2(3);
when "0100"=> out_data <= reg2(4);
when "0101"=> out_data <= reg2(5);
when "0110"=> out_data <= reg2(6);
when "0111"=> out_data <= reg2(7);
when "1000"=> out_data <= reg2(8);
when "1001"=> out_data <= reg2(9);
when "1010"=> out_data <= reg2(10);
when "1011"=> out_data <= reg2(11);
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "0110"=> case reg1(6)(3 downto 0) is when "0000"=> out_data <= reg2(0);
when "0001"=> out_data <= reg2(1);
when "0010"=> out_data <= reg2(2);
when "0011"=> out_data <= reg2(3);
when "0100"=> out_data <= reg2(4);
when "0101"=> out_data <= reg2(5);
when "0110"=> out_data <= reg2(6);
when "0111"=> out_data <= reg2(7);
when "1000"=> out_data <= reg2(8);
when "1001"=> out_data <= reg2(9);
when "1010"=> out_data <= reg2(10);
when "1011"=> out_data <= reg2(11);
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "0111"=> case reg1(7)(3 downto 0) is when "0000"=> out_data <= reg2(0);
when "0001"=> out_data <= reg2(1);
when "0010"=> out_data <= reg2(2);
when "0011"=> out_data <= reg2(3);
when "0100"=> out_data <= reg2(4);
when "0101"=> out_data <= reg2(5);
when "0110"=> out_data <= reg2(6);
when "0111"=> out_data <= reg2(7);
when "1000"=> out_data <= reg2(8);
when "1001"=> out_data <= reg2(9);
when "1010"=> out_data <= reg2(10);
when "1011"=> out_data <= reg2(11);
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "1000"=> case reg1(8)(3 downto 0) is when "0000"=> out_data <= reg2(0);
when "0001"=> out_data <= reg2(1);
when "0010"=> out_data <= reg2(2);
when "0011"=> out_data <= reg2(3);
when "0100"=> out_data <= reg2(4);
when "0101"=> out_data <= reg2(5);
when "0110"=> out_data <= reg2(6);
when "0111"=> out_data <= reg2(7);
when "1000"=> out_data <= reg2(8);
when "1001"=> out_data <= reg2(9);
when "1010"=> out_data <= reg2(10);
when "1011"=> out_data <= reg2(11);
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "1001"=> case reg1(9)(3 downto 0) is when "0000"=> out_data <= reg2(0);
when "0001"=> out_data <= reg2(1);
when "0010"=> out_data <= reg2(2);
when "0011"=> out_data <= reg2(3);
when "0100"=> out_data <= reg2(4);
when "0101"=> out_data <= reg2(5);
when "0110"=> out_data <= reg2(6);
when "0111"=> out_data <= reg2(7);
when "1000"=> out_data <= reg2(8);
when "1001"=> out_data <= reg2(9);
when "1010"=> out_data <= reg2(10);
when "1011"=> out_data <= reg2(11);
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "1010"=> case reg1(10)(3 downto 0) is when "0000"=> out_data <= reg2(0);
when "0001"=> out_data <= reg2(1);
when "0010"=> out_data <= reg2(2);
when "0011"=> out_data <= reg2(3);
when "0100"=> out_data <= reg2(4);
when "0101"=> out_data <= reg2(5);
when "0110"=> out_data <= reg2(6);
when "0111"=> out_data <= reg2(7);
when "1000"=> out_data <= reg2(8);
when "1001"=> out_data <= reg2(9);
when "1010"=> out_data <= reg2(10);
when "1011"=> out_data <= reg2(11);
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when "1011"=> case reg1(11)(3 downto 0) is when "0000"=> out_data <= reg2(0);
when "0001"=> out_data <= reg2(1);
when "0010"=> out_data <= reg2(2);
when "0011"=> out_data <= reg2(3);
when "0100"=> out_data <= reg2(4);
when "0101"=> out_data <= reg2(5);
when "0110"=> out_data <= reg2(6);
when "0111"=> out_data <= reg2(7);
when "1000"=> out_data <= reg2(8);
when "1001"=> out_data <= reg2(9);
when "1010"=> out_data <= reg2(10);
when "1011"=> out_data <= reg2(11);
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
when others => zero:=NOT zero; interrupt<=zero; zero:=NOT zero; flag:=1;quit:=0;
end case;
quit := 0;
end if;
if(flag=1 AND quit=1) then quit:=0;
flag:=0;
zero:=NOT zero;
zero:=NOT zero;
interrupt<=zero;
end if;
end if; END PROCESS;
END Level1;
Работа устройства осуществляется следующим образом: при наличии высокого уровня входного сигналов CLK и WE производится запись информации, поступившей на вход IN_DATA устройства, по адресу на входе ADR. Чтение данных из РОН осуществляется при подаче на вход адресов требуемого регистра, а также высоко уровня сигналов CLK и RE. При адресация в устройстве осуществляется с помощью дополнительного блока регистров, хранящего адреса необходимых регистров с дынными.
2.4 Разработка КПДП. Функциональный состав и временные диаграммы
КПДП организует прямой доступ к памяти внешним устройствам. Для подсчета текущего адреса и количества переданных слов данное устройство содержит в себе собственный счетчик адреса. В начале цикла КПДП счетчик адреса устанавливается в начальный адрес (по условию 8), и начинает отсчет 8 циклов передачи слова. Условно-графическое изображение КПДП изображено на рисунке 2.13.
Рисунок 2.12 - Условно-графическое обозначение КПДП.
Временная диаграмма работы КПДП изображена на рисунке 2.4.2.
Рисунок 2.13 - Временная диаграмма работы КПДП.
Возникает запрос на чтение данных из памяти ЭВМ. Запрос сразу же передается устройству управления, после чего оно, освободив шины адреса и данных, передает сигнал на вход DMA_CPU_READY. Получив этот сигнал, КПДП начинает работу с памятью, выставив сигналы разрешения работы и чтения ОЗУ, а также начальный адрес. В результате данные с шины данных ЭВМ (BUS_DATA) транслируются на шину данных внешнего устройства (DATA). После записи 8 байт информации КПДП выставляет сигнал DMA_CYCLE_END, сигнализирующий о завершении цикла обмена с памятью. Функциональная схема контроллера прямого доступа к памяти изображена на рисунке 2.14.
Программный код реализации КПДП на языке VHDL представлен в листинге 2.5. Листинг 2.5 Реализации КПДП:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.ALL;
use ieee.std_logic_arith.all;
entity dma is
generic (
ADDR_WIDTH :integer := 10;
DATA_WIDTH :integer := 8;
START_ADDR :integer := 4;
BYTE_CNT :integer := 6
);
port (
DMA_ACK_WR :in std_logic;
DMA_ACK_RD :in std_logic;
DATA :inout std_logic_vector (data_width-1 downto 0) := (others => 'Z');
CPU_READY:in std_logic;
CLK :in std_logic;
BUS_ADDR :out std_logic_vector (addr_width-1 downto 0) := (others => 'Z');
BUS_DATA :inout std_logic_vector (data_width-1 downto 0) := (others => 'Z');
RAM_CS :out std_logic := 'Z';
RAM_WE :out std_logic := 'Z';
RAM_OE :out std_logic := 'Z';
CPU_DMA_ACK:out std_logic := '0';
END_OF_CYCLE:out std_logic := '0'
);
end entity;
architecture rtl of dma is
procedure SetRam(r_cs :in std_logic;
r_we :in std_logic;
r_oe :in std_logic;
r_addr : in std_logic_vector (addr_width-1 downto 0) := (others => 'Z');
r_data : std_logic_vector (data_width-1 downto 0) := (others => 'Z')) is
begin
ram_cs <= r_cs;
ram_we <= r_we;
ram_oe <= r_oe;
bus_addr <= r_addr;
bus_data <= r_data;
end procedure;
-- Overloaded subprogram to set memory control signals --
procedure SetRam(r_cs :in std_logic;
r_we :in std_logic;
r_oe :in std_logic;
r_addr : in integer;
r_data : std_logic_vector (data_width-1 downto 0) := (others => 'Z')) is
begin
SetRam(r_cs, r_we, r_oe, std_logic_vector(to_unsigned(r_addr, ADDR_WIDTH)), r_data);
end procedure;
shared variable addrcnt :integer:=start_addr;
shared variable wordcnt :integer:=byte_cnt;
shared variable wr :boolean;
shared variable cycle :boolean:=false;
begin
process(clk)
begin
if ( rising_edge(clk)) then
if (dma_ack_wr = '1' or dma_ack_rd = '1') then cpu_dma_ack <= '1';
if (dma_ack_wr = '1') then
wr := true;
elsif (dma_ack_rd = '1') then
wr := false;
end if;
else
cpu_dma_ack <= '0';
end if;
if (cpu_ready = '1') then
cycle := true;
addrcnt := start_addr;
wordcnt := byte_cnt;
end if;
if (cycle) then
if (wordcnt>0) then
if (wr) then
SetRam('1', '1', '0', addrcnt, data);
else
if (wordcnt/=byte_cnt) then
data <= bus_data;
end if;
SetRam('1', '0', '1', addrcnt);
end if;
addrcnt := addrcnt + 1;
wordcnt := wordcnt - 1;
else
if (not wr) then
data <= bus_data;
end if;
SetRam('0', '0', '0');
end_of_cycle <= '1';
cycle := false;
end if;
else
data <= (others => 'Z');
SetRam('Z', 'Z', 'Z');
end_of_cycle <= '0';
end if;
end if;
end process;
end rtl;
2.5 Разработка системы прерываний. Функциональный состав и временные диаграммы
Устройство должно постоянно хранить в себе маску прерываний. Маска прерываний представляет собой 5-разрядное число, каждый разряд которого хранит информацию о текущем состоянии соответствующей линии прерывания. Если в разряде хранится логическая единица, то это означает, что данная линия прерывания работает. Также контроллер прерываний хранит в себе все начальные адреса обработчиков для каждой из линий. Эти адреса в случае возникновения прерывания передаются устройству управления.
Условное обозначение данного устройства изображено на рисунке 2.14.
Рисунок 2.14 - Условное графическое изображение контроллера прерываний.
Временная диаграмма работы устройства изображена на рисунке 2.15.
Рисунок 2.15 - Временная диаграмма работы контроллера прерываний.
При выставленном сигнале STI разрешаются все прерывания, и маска устанавливается в единицы, поступающие прерывания обрабатываются. При сигнале CLI все прерывания запрещаются маска устанавливается в ноль и прерывания не обрабатываются.
Листинг 2.6. Реализации контроллера прерываний:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity irkq is
generic (
IRQ_CNT:integer := 5;
ADDR_WIDTH :integer := 10
);
port (
IRQ_IN : in std_logic_vector (irq_cnt-1 downto 0);
CLI : in std_logic;
STI : in std_logic;
NUM: in integer range 0 to 4;
CLK : in std_logic;
ADDR : out std_logic_vector (addr_width-1 downto 0);
IRQ_OUT: out std_logic;
MASK : out std_logic_vector (irq_cnt-1 downto 0)
);
end irkq;
architecture rtl of irkq is
shared variable int_mask : std_logic_vector (irq_cnt-1 downto 0) := (others => '1');
begin
process (clk)
variable buf : unsigned (irq_cnt-1 downto 0):= (0=>'1',others=>'0');
begin
if (rising_edge(clk)) then
if (cli = '1') then
if (num < 4) then int_mask := int_mask and not std_logic_vector(shift_left(buf,num));
else
int_mask := (others=>'0');
end if;
end if;
if (sti = '1') then
if (num < 4) then int_mask := int_mask or std_logic_vector(shift_left(buf,num));
else
int_mask := (others=>'1');
end if;
end if;
if (irq_in(0) = '1' and int_mask(0) = '1') then addr <= std_logic_vector(to_unsigned(32,addr'length)); irq_out <= '1';
elsif (irq_in(1) = '1' and int_mask(1) = '1') then addr <= std_logic_vector(to_unsigned(34,addr'length)); irq_out <= '1'; elsif (irq_in(2) = '1' and int_mask(2) = '1') then addr <= std_logic_vector(to_unsigned(36,addr'length)); irq_out <= '1'; elsif (irq_in(3) = '1' and int_mask(3) = '1') then addr <= std_logic_vector(to_unsigned(38,addr'length)); irq_out <= '1'; elsif (irq_in(4) = '1' and int_mask(4) = '1') then addr <= std_logic_vector(to_unsigned(42,addr'length)); irq_out <= '1'; else addr <= (others => 'Z'); irq_out <= '0'; end if;
mask <= int_mask;
end if;
end process;
end rtl;
3РАЗРАБОТКА ПРИНЦИПИАЛЬНОЙ СХЕМЫ УСТРОЙСТВА
3.1. Описание работы устройства на вентельно-регистровом уровне Устройство управления - узел микропроцессора, выполняющий управление прочими компонентами. В задачи устройства управления входит выборка и декодирование потока инструкций, выдача кодов функций в исполнительные устройства, принятие решений по признакам результатов вычислений, синхронизация узлов микропроцессора. В состав устройства управления входят следующие блоки: * Блок генерации адресов инструкций. Он содержит в себе регистр программного счётчика (program counter или instruction pointer), хранящий адрес считываемой из памяти инструкции, и модифицирующийся после выборки каждой инструкции. * Блок выборки инструкции, обеспечивающий считывание программ из памяти через устройство ввода-вывода. Он получает на вход адрес с блока генерации адреса инструкции, передаёт его на УВВ, получает с него данные по переданному адресу, и выдаёт на блок декодирования интсрукций. * Блок декодирования инструкций, производящий преобразование кодов инструкций в последовательность кодов функций, передаваемые на исполнительные устройства. * Блок переходов. Получает функциональные коды переходов и ветвлений, признаки результатов операций с функциональных устройств, проверяет истинность условия перехода, и передаёт сигнал на изменение программного счётчика. На рисунке 3. 1 приедено условно-графическое изображение блока генерации адресов инструкций.
Рисунок 3.1 - УГО блока генерациии адресов инструкций
При поступление каждого пятого такта, на блоке генерации формируется следующей команды, значение на три отличное от предыдущего, при этом при условии безусловного перехода значение адреса инструкций может задаваться принудительно при помощи входа input[9..0]. Рисунок 3.2 - УГО блока выборки инструкций
После формирования каждой из инструкция блок выборки инструкций обращается к памяти комманд и извлекает из нею текущую комману, при этом сразу после извлечения формирует специальный сигнал got_comand, который сообщает о том что текущая команда получена, что бы сохранить актуальность сигнала, сигнал автоматически сбрасывается каждые три такта.
Блок лекодирования инструкций представляет собой обынчный трехвходовы дешефратор. Так как при заданном условии курсового проекта все команды, необходимын для реализации в у стройсве управления, могут быть представлены в виде трех битов информации. Рисунок 3.3. - УГО блока декодирвани инструкий
Принципиальная схема блока декодирования инструкий представлена ниже, на рисунке 3. 4.
Рисунок 3.4. - Принципиальная схема блока декодирования команд
В связи с отсутсвием как таковом, влияния результатов работы функциональных устройств на текущие команды или команды необходимы исполнять далее в ходе работы микроЭВМ, в блокепереходво как таковм необхлдимость отчутсвует.
3.2Описание времнной диаграмы устройства
Услвоно-графическое изображение устройства управления приведено на рисунку 3.5.
Рисунок 3.5. - УГО устройства управления
Векторная диаграмма устройства управления описана в приложении. В зависимости от поступления тактового сигнала CLK, происходит изменение значения сигнала ADR[9..0], формирующего адрес выполняемой команды, затем в соответствии от результатов извлечения данной команды, запрашиваются адреса операндов и значения операндов формируются на соответствующих выходах. В случае высоко уровня сигнала на входе IRQ_IN работа устройства приостанавливается и выполняется команда лежащую по адресу, заданному на вхоже устройства IRQ_ADR[9..0]. В случае высокого уровня сигнала DMA_ACK работа устройства также приостанавливается, а на выходах устройства формируются сигналы DMA_READY, сигнализирующий о том, что память свободна и КПДП может работать и сигнал DMA_CONTROL служащий сигналом запуска КПДП. При поступлении сигнала RESET счетчик формирования адреса команды сбрасывается.
4 ОПТИМИЗАЦИЯ МИКРОЭВМ
Оптимизация микроЭВМ как правило подразумевает под собой повышение его производительности. Относительно данного курсового проекта, его производительность может быть улучшена следующими способами.
1) Повышением частоты работы основного тактового генератора
Для оптимизации работы устройства в схеме ищется цепочка, вносящая наибольшую задержку при прохождении сигнала. Частоту тактового генератора можно выбрать немного больше, чем задержка самой медленной цепочки.
2) Сокращением длительности выполнения фаз отдельных команд
Сокращение длительности выполнения отдельных фаз команд можно достичь путем увеличения частоты тактового генератора, что приведет к увеличению количества выполняемых команд в единицу времени.
3) Реализацией одновременного выполнения некоторых фаз отдельных команд
Для поддержания максимальной загрузки УУ должен использоваться параллелизм уровня команд, основанный на выявлении последовательностей несвязанных команд, которые могут выполняться в конвейере с совмещением. Чтобы избежать приостановки конвейера зависимая команда должна быть отделена от исходной команды на расстояние в тактах, равное задержке конвейера для этой исходной команды.
4) Реализацией конвейерного выполнения фаз последовательностей команд
Конвейеризация (или конвейерная обработка) в общем случае основана на разделении подлежащей исполнению функции на более мелкие части, называемые ступенями, и выделении для каждой из них отдельного блока аппаратуры. Так обработку любой машинной команды можно разделить на несколько этапов (несколько ступеней), организовав передачу данных от одного этапа к следующему. При этом конвейерную обработку можно использовать для совмещения этапов выполнения разных команд. Производительность при этом возрастает благодаря тому, что одновременно на различных ступенях конвейера выполняются несколько команд. Конвейерная обработка такого рода широко применяется во всех современных быстродействующих процессорах.
Выполнение типичной команды можно разделить на следующие этапы: - выборка команды (по адресу, заданному счетчиком команд, из памяти извлекается команда); - декодирование команды / выборка операндов из регистров; - выполнение операции / вычисление эффективного адреса памяти;
- обращение к памяти; - запоминание результата.
Конвейеризация увеличивает пропускную способность процессора (количество команд, завершающихся в единицу времени), но она не сокращает время выполнения отдельной команды. В действительности, она даже несколько увеличивает время выполнения каждой команды из-за накладных расходов, связанных с управлением регистровыми станциями. Однако увеличение пропускной способности означает, что программа будет выполняться быстрее по сравнению с простой неконвейерной схемой.
ЗАКЛЮЧЕНИЕ
В соответствии с заданием на курсовое проектирование была реализована Гарвардская архитектура. Основное её преимущество заключается в разделении памяти команд и данных, что позволяет значительно повысить производительность системы, так как появляется возможность работ и с командами, и с данными. Благодаря этому можно рационально использовать и перераспределять ресурсы системы. Для систем с Гарвардской архитектурой легче разрабатывать программы, также устройства, построенные на данной архитектуре имеют повышенную отказоустойчивость. Несмотря на ряд ключевых преимуществ Гарвардская система, в связи со своей дороговизной, не получила широкого распространения. Однако она часто используется в системах требовательных к повышенной отказоустойчивости и производительности.
В данном курсовом микроЭВМ была реализована в среде Quartus II. МикроЭВМ устроена по принципу Гарвардской архитектуры. Шина адреса имеет разрядность 10 бит, шина данных 8 бит. Блок РОНов содержит 12 регистров. Разработанное устройство управление выполняет следующие команды: MOV, JUMP, CMP, AND, HLT, CLI. STI. Также был разработан КПДП для прямого доступа к памяти с начальным адресом 8 бит и количеством байт для передачи 4 и система прерываний с 5 линиями прерывания.
Было разработано АЛУ, реализующее следующие операции: операцию CMP - операция сравнения двух целых положительных чисел, и операцию AND - операция логического умножения.
При проведении оптимизации микроЭВМ были рассмотрены следующие возможные варианты:
Повышение частоты работы основного тактового генератора;
Сокращение длительности выполнения фаз отдельных команд;
Реализацией одновременного выполнения некоторых фаз отдельных команд Конвейерное выполнение фаз последовательностей команд.
В ходе выполнения курсового проекта мною были приобретены навыки построения микроЭВМ, изучены особенности Гарвардской архитектуры и языка VHDL, приобретены навыки работы в Quartus II и изучены принципы построения отдельных блоков в нём. СПИСОК ИСПОЛЬЗОВАННОЙ ЛИТЕРАТУРЫ
1. Калинцев С.В. Структурная и функциональная организация ЭВМ. Учебно-методический комплекс. -Новополоцк.:ПГУ, 2008-284c.
2. Угрюмов Е.П. Цифровая схемотехника. - М.: С-Петербург, 2001 - 518с.
3. Угрюмов Е.П. Проектирование элементов и узлов ЭВМ. - М.: Высшая школа, 1987 - 318с.
ЭЛЕКТРОННЫЕ ИСТОЧНИКИ
Э1 http://www.altera.com - Альтера. Режим доступа: 18.09.2013, 23-59
Э2 http://www.gaw.ru/html.cgi/txt/doc/micros/arm/arh_sam7s/24.htm -Рынок микроэлектроники. Режим доступа: 11.12.2013, 14-15
ПРИЛОЖЕНИЕ А
(обязательное)
ОБЩАЯ СХЕМА МИКРО-ЭВМ
ПРИЛОЖЕНИЕ Б
(обязательное)
ПРИНЦИПИАЛЬНАЯ СХЕМА УПРАВЛЯЮЩЕГО УСТРОЙСТВА
ПРИЛОЖЕНИЕ В
(обязательное)
ВРЕМЕННАЯ ДИАГРАММА РАБОТЫ УПРАВЛЯЮЩЕГО УСТРОЙСТВА
Документ
Категория
Рефераты
Просмотров
78
Размер файла
2 118 Кб
Теги
записка, финал, мой
1/--страниц
Пожаловаться на содержимое документа