diff --git a/.pic/Labs/lab_04_cybercobra/ppd_0.drawio.svg b/.pic/Labs/lab_04_cybercobra/ppd_0.drawio.svg new file mode 100644 index 0000000..e64d27e --- /dev/null +++ b/.pic/Labs/lab_04_cybercobra/ppd_0.drawio.svg @@ -0,0 +1,4 @@ + + + +
Register
File
RD1
RD2
WE
clk_i
RA1
RA2
WA
WD
32'd4
ALU
Instruction memory
32
32
32
32
5
5
5
32
32
32
5
read_data_o
addr_i
clk_i
rst_i
,
— входы модуля
+
1'b1
PC
clk_i
rst_i
\ No newline at end of file diff --git a/.pic/Labs/lab_04_cybercobra/ppd_1.drawio.png b/.pic/Labs/lab_04_cybercobra/ppd_1.drawio.png deleted file mode 100644 index 8c8a4b8..0000000 Binary files a/.pic/Labs/lab_04_cybercobra/ppd_1.drawio.png and /dev/null differ diff --git a/.pic/Labs/lab_04_cybercobra/ppd_1.drawio.svg b/.pic/Labs/lab_04_cybercobra/ppd_1.drawio.svg new file mode 100644 index 0000000..e3f001f --- /dev/null +++ b/.pic/Labs/lab_04_cybercobra/ppd_1.drawio.svg @@ -0,0 +1,4 @@ + + + +
Register
File
RD1
RD2
WE
clk_i
RA1
RA2
WA
WD
32'd4
ALU
32
32
32
5
5
5
32
32
32
5
[22:18]
[17:13]
[4:0]
[27:23]
clk_i
rst_i
,
— входы модуля
+
1'b1
Instruction memory
32
read_data_o
addr_i
PC
clk_i
rst_i
\ No newline at end of file diff --git a/.pic/Labs/lab_04_cybercobra/ppd_2.drawio.png b/.pic/Labs/lab_04_cybercobra/ppd_2.drawio.png deleted file mode 100644 index fe60bbd..0000000 Binary files a/.pic/Labs/lab_04_cybercobra/ppd_2.drawio.png and /dev/null differ diff --git a/.pic/Labs/lab_04_cybercobra/ppd_2.drawio.svg b/.pic/Labs/lab_04_cybercobra/ppd_2.drawio.svg new file mode 100644 index 0000000..73e9b13 --- /dev/null +++ b/.pic/Labs/lab_04_cybercobra/ppd_2.drawio.svg @@ -0,0 +1,4 @@ + + + +
Register
File
RD1
RD2
WE
clk_i
RA1
RA2
WA
WD
32'd4
ALU
32
32
32
5
5
5
32
32
32
5
[22:18]
[17:13]
[4:0]
[27:23]
1
[27:5]
23
32
[28]
0
SE
clk_i
rst_i
,
— входы модуля
SE
— знаковое расширение
+
1'b1
Instruction memory
32
read_data_o
addr_i
PC
clk_i
rst_i
\ No newline at end of file diff --git a/.pic/Labs/lab_04_cybercobra/ppd_3.drawio.png b/.pic/Labs/lab_04_cybercobra/ppd_3.drawio.png deleted file mode 100644 index e193cc2..0000000 Binary files a/.pic/Labs/lab_04_cybercobra/ppd_3.drawio.png and /dev/null differ diff --git a/.pic/Labs/lab_04_cybercobra/ppd_3.drawio.svg b/.pic/Labs/lab_04_cybercobra/ppd_3.drawio.svg new file mode 100644 index 0000000..724a3ab --- /dev/null +++ b/.pic/Labs/lab_04_cybercobra/ppd_3.drawio.svg @@ -0,0 +1,4 @@ + + + +
Register
File
RD1
RD2
WE
clk_i
RA1
RA2
WA
WD
32'd4
ALU
32
32
32
5
5
5
32
32
32
5
clk_i
rst_i
sw_i
,
,
— входы модуля
out_o
— выход модуля
SE
— знаковое расширение
out_o
32
+
1'b1
[22:18]
[17:13]
[4:0]
[27:23]
2
1
23
32
0
sw_i
SE
32
16
SE
3
2
32'd0
[27:5]
[29:28]
Instruction memory
32
read_data_o
addr_i
PC
clk_i
rst_i
\ No newline at end of file diff --git a/.pic/Labs/lab_04_cybercobra/ppd_4.drawio.png b/.pic/Labs/lab_04_cybercobra/ppd_4.drawio.png deleted file mode 100644 index 52cd283..0000000 Binary files a/.pic/Labs/lab_04_cybercobra/ppd_4.drawio.png and /dev/null differ diff --git a/.pic/Labs/lab_04_cybercobra/ppd_4.drawio.svg b/.pic/Labs/lab_04_cybercobra/ppd_4.drawio.svg new file mode 100644 index 0000000..2a77a4d --- /dev/null +++ b/.pic/Labs/lab_04_cybercobra/ppd_4.drawio.svg @@ -0,0 +1,4 @@ + + + +
Register
File
RD1
RD2
WE
clk_i
RA1
RA2
WA
WD
32'd4
ALU
32
32
32
5
5
5
32
32
32
5
0
1
32
10
{[12:5],2'b0}
clk_i
rst_i
sw_i
,
,
— входы модуля
out_o
— выход модуля
SE
— знаковое расширение
{[12:5],00}
— объединение 8 бит инструкции с
     двумя нулевыми битами
out_o
32
SE
+
[22:18]
[17:13]
[4:0]
[27:23]
[30]
2
1
23
32
0
sw_i
SE
32
16
SE
3
2
32'd0
[27:5]
[29:28]
[30]
flag
Instruction memory
32
read_data_o
addr_i
PC
clk_i
rst_i
\ No newline at end of file diff --git a/.pic/Labs/lab_04_cybercobra/ppd_5.drawio.png b/.pic/Labs/lab_04_cybercobra/ppd_5.drawio.png deleted file mode 100644 index 3d097c7..0000000 Binary files a/.pic/Labs/lab_04_cybercobra/ppd_5.drawio.png and /dev/null differ diff --git a/.pic/Labs/lab_04_cybercobra/ppd_5.drawio.svg b/.pic/Labs/lab_04_cybercobra/ppd_5.drawio.svg new file mode 100644 index 0000000..bfb405b --- /dev/null +++ b/.pic/Labs/lab_04_cybercobra/ppd_5.drawio.svg @@ -0,0 +1,4 @@ + + + +
Register
File
RD1
RD2
WE
clk_i
RA1
RA2
WA
WD
32'd4
ALU
32
32
32
5
5
5
32
32
32
5
2
1
23
32
0
sw_i
0
1
[30]
[31]
flag
32
10
{[12:5],2'b0}
SE
32
16
SE
clk_i
rst_i
sw_i
,
,
— входы модуля
out_o
— выход модуля
SE
— знаковое расширение
{[12:5],00}
— объединение 8 бит инструкции с
     двумя нулевыми битами
3
2
32'd0
out_o
32
SE
+
[22:18]
[17:13]
[4:0]
[27:23]
[27:5]
[29:28]
[30]
[31]
Instruction memory
32
read_data_o
addr_i
PC
clk_i
rst_i
\ No newline at end of file diff --git a/.pic/Labs/lab_04_cybercobra/ppd_6.drawio.png b/.pic/Labs/lab_04_cybercobra/ppd_6.drawio.png deleted file mode 100644 index 79cdc7e..0000000 Binary files a/.pic/Labs/lab_04_cybercobra/ppd_6.drawio.png and /dev/null differ diff --git a/Labs/04. Primitive programmable device/README.md b/Labs/04. Primitive programmable device/README.md index a1e9712..814ba3f 100644 --- a/Labs/04. Primitive programmable device/README.md +++ b/Labs/04. Primitive programmable device/README.md @@ -28,6 +28,8 @@ 6. Написать программу для процессора и на модели убедиться в корректности ее выполнения ([#задание по разработке программы](#задание-по-проверке-процессора)) +> Для того, чтобы номера таблиц и рисунков лучше соотносились друг с другом и сопутствующим текстом, первая схема разрабатываемой микроархитектуры будет обозначена как Рисунок 0. Все последующие схемы будут совпадать по нумерации с таблицами, обозначающими способ кодирования инструкций. + ## Теория про программируемое устройство В обобщенном виде, процессор включает в себя память, АЛУ, устройство управления и интерфейсную логику для организации ввода/вывода. Также, в процессоре есть специальный регистр `PC` (**Program Counter** – счетчик команд), который хранит в себе число – адрес ячейки памяти, в которой лежит инструкция, которую нужно выполнить. Инструкция тоже представляет собой число, в котором закодировано `что нужно сделать` и `с чем это нужно сделать`. @@ -79,9 +81,11 @@ Каждый раз, когда будет происходить тактовый импульс (переключение `clk_i` из 0 в 1), значение `PC` будет увеличиваться на `4`, тем самым указывая на следующую инструкцию. Последовательное считывание программы из памяти готово. -Так как операции будут выполняться только над данными в регистровом файле, то его можно сразу подключить к АЛУ, соединив порты чтения `read_data1_o` и `read_data2_o` со входами операндов АЛУ, а результат операции АЛУ подключив к порту на запись `write_data_i`. Полученный результат изображен на картинке ниже. +Так как операции будут выполняться только над данными в регистровом файле, то его можно сразу подключить к АЛУ, соединив порты чтения `read_data1_o` и `read_data2_o` со входами операндов АЛУ, а результат операции АЛУ подключив к порту на запись `write_data_i`. Полученный результат изображен на _рис. 0_. -![../../.pic/Labs/lab_04_cybercobra/ppd_1.drawio.png](../../.pic/Labs/lab_04_cybercobra/ppd_1.drawio.png) +![../../.pic/Labs/lab_04_cybercobra/ppd_0.drawio.svg](../../.pic/Labs/lab_04_cybercobra/ppd_0.drawio.svg) + +_Рисунок 0. Размещение на схеме основных блоков._ Для компактности схемы, названия портов регистрового файла сокращены (`RA1` обозначает `read_addr1_i` и т.п.). @@ -93,10 +97,12 @@ 2. по какому адресу будет сохранен результат? 3. какая операция должна быть выполнена? -Для этого в инструкции были выбраны следующие поля: 5 бит (`[27:23]`) для кодирования операции на АЛУ, два раза по 5 бит для кодирования адресов операндов в регистровом файле (`[22:18]` и `[17:13]`) и 5 бит для кодирования адреса результата (`[4:0]`). Ниже демонстрируется деление 32-битной инструкции на поля `alu_op`, `RA1`, `RA2` и `WA`. +Для этого в инструкции были выбраны следующие поля: 5 бит (`[27:23]`) для кодирования операции на АЛУ, два раза по 5 бит для кодирования адресов операндов в регистровом файле (`[22:18]` и `[17:13]`) и 5 бит для кодирования адреса результата (`[4:0]`). _Таблица 1_ демонстрируется деление 32-битной инструкции на поля `alu_op`, `RA1`, `RA2` и `WA`. ![../../.pic/Labs/lab_04_cybercobra/ppd_code_1.png](../../.pic/Labs/lab_04_cybercobra/ppd_code_1.png) +_Таблица 1. Кодирование вычислительных инструкций в архитектуре CYBERcobra 3000 Pro v2.1._ + ``` C reg_file[WA] ← reg_file[RA1] {alu_op} reg_file[RA2] ``` @@ -112,9 +118,11 @@ |alu_op| RA1 | RA2 | | WA ``` -будет выполнена операция `reg_file[28] = reg_file[4] | reg_file[8]`, потому что `alu_op = 00111`, что соответствует операции **логического ИЛИ**, `WA = 11100`, то есть 28-ой регистр, `RA1 = 00100` (4-ый регистр) и `RA2 = 01000` (8-ой регистр). Ниже иллюстрируется фрагмент микроархитектуры, поддерживающий вычислительные операции на АЛУ. Так как пока что другие инструкции не поддерживаются, то вход `WE` регистрового файла всегда равен `1` (это временно). +будет выполнена операция `reg_file[28] = reg_file[4] | reg_file[8]`, потому что `alu_op = 00111`, что соответствует операции **логического ИЛИ**, `WA = 11100`, то есть 28-ой регистр, `RA1 = 00100` (4-ый регистр) и `RA2 = 01000` (8-ой регистр). _Рис. 1_ иллюстрирует фрагмент микроархитектуры, поддерживающий вычислительные операции на АЛУ. Так как пока что другие инструкции не поддерживаются, то вход `WE` регистрового файла всегда равен `1` (это временно). -![../../.pic/Labs/lab_04_cybercobra/ppd_2.drawio.png](../../.pic/Labs/lab_04_cybercobra/ppd_2.drawio.png) +![../../.pic/Labs/lab_04_cybercobra/ppd_1.drawio.svg](../../.pic/Labs/lab_04_cybercobra/ppd_1.drawio.svg) + +_Рисунок 1. Подключение АЛУ и регистрового файла для реализации вычислительных инструкций._ ### Реализация загрузки константы в регистровый файл @@ -136,10 +144,12 @@ (если бы старший бит был равен нулю, то константа заполнилась бы слева нулями, а не единицами). -Нет ничего страшного в том, что биты константы попадают на те же поля, что и `alu_op`, `RA1` и `RA2` — когда выполняется инструкция загрузки константы не важно что будет выдавать АЛУ в этот момент (ведь благодаря мультиплексору на вход регистрового файла приходит константа). А значит не важно и что приходит в этот момент на АЛУ в качестве операндов и кода операции. Ниже демонстрируется деление 32-битной инструкции на поля `alu_op`, `RA1`, `RA2`, `WA`, `WS` и `const`, **с перекрытием полей**. +Нет ничего страшного в том, что биты константы попадают на те же поля, что и `alu_op`, `RA1` и `RA2` — когда выполняется инструкция загрузки константы не важно что будет выдавать АЛУ в этот момент (ведь благодаря мультиплексору на вход регистрового файла приходит константа). А значит не важно и что приходит в этот момент на АЛУ в качестве операндов и кода операции. _Таблица 2_ демонстрирует деление 32-битной инструкции на поля `alu_op`, `RA1`, `RA2`, `WA`, `WS` и `const`, **с перекрытием полей**. ![../../.pic/Labs/lab_04_cybercobra/ppd_code_2.png](../../.pic/Labs/lab_04_cybercobra/ppd_code_2.png) +_Таблица 2. Добавление кодирования источника записи и 23-битной константы._ + ``` C reg_file[WA] ← const ``` @@ -153,9 +163,11 @@ |WS| RF_const | WA | ``` -Далее приводится фрагмент микроархитектуры, поддерживающий вычислительные операции на АЛУ и загрузку констант из инструкции в регистровый файл. +На _рис. 2_ приводится фрагмент микроархитектуры, поддерживающий вычислительные операции на АЛУ и загрузку констант из инструкции в регистровый файл. -![../../.pic/Labs/lab_04_cybercobra/ppd_3.drawio.png](../../.pic/Labs/lab_04_cybercobra/ppd_3.drawio.png) +![../../.pic/Labs/lab_04_cybercobra/ppd_2.drawio.svg](../../.pic/Labs/lab_04_cybercobra/ppd_2.drawio.svg) + +_Рисунок 2. Добавление константы из инструкции в качестве источников записи в регистровый файл._ ### Реализация загрузки в регистровый файл данных с внешних устройств @@ -163,15 +175,19 @@ ![../../.pic/Labs/lab_04_cybercobra/ppd_code_3.png](../../.pic/Labs/lab_04_cybercobra/ppd_code_3.png) +_Таблица 3. Кодирование в инструкции большего числа источников записи._ + ``` C reg_file[WA] ← sw_i ``` По аналогии с загрузкой констант увеличиваем входной мультиплексор до 4 входов и подключаем к нему управляющие сигналы – `[29:28]` биты инструкции. Последний вход используется, чтобы разрешить неопределенность на выходе при `WS == 3`(`default`-вход, см. [мультиплексор](../../Basic%20Verilog%20structures/Multiplexors.md)). -Выход OUT подключается к первому порту на чтение регистрового файла. Значение на выходе OUT будет определяться содержимым ячейки памяти по адресу `RA1`. Ниже приводится фрагмент микроархитектуры, поддерживающий вычислительные операции на АЛУ, загрузку констант из инструкции в регистровый файл и загрузку данных с внешних устройств. +Выход OUT подключается к первому порту на чтение регистрового файла. Значение на выходе OUT будет определяться содержимым ячейки памяти по адресу `RA1`. На _рис. 3_ приводится фрагмент микроархитектуры, поддерживающий вычислительные операции на АЛУ, загрузку констант из инструкции в регистровый файл и загрузку данных с внешних устройств. -![../../.pic/Labs/lab_04_cybercobra/ppd_4.drawio.png](../../.pic/Labs/lab_04_cybercobra/ppd_4.drawio.png) +![../../.pic/Labs/lab_04_cybercobra/ppd_3.drawio.svg](../../.pic/Labs/lab_04_cybercobra/ppd_3.drawio.svg) + +_Рисунок 3. Подключение к схеме источников ввода и вывода._ ### Реализация условного перехода @@ -179,6 +195,8 @@ ![../../.pic/Labs/lab_04_cybercobra/ppd_code_4.png](../../.pic/Labs/lab_04_cybercobra/ppd_code_4.png) +_Таблица 4.Кодирование условного перехода._ + Для вычисления результата условного перехода, нам необходимо выполнить операцию на АЛУ и посмотреть на сигнал `flag`. Если он равен 1, переход выполняется, в противном случае — не выполняется. А значит, нам нужны операнды `A`, `B`, и `alu_op`. Кроме того, нам необходимо указать насколько мы сместимся относительно текущего значения `PC` (константу смещения, `offset`). Для передачи этой константы лучше всего подойдут незадействованные биты инструкции `[12:5]`. Обратим внимание на то, что `PC` 32-битный и должен быть всегда кратен четырем (`PC` не может указывать кроме как в начало инструкции, а каждая инструкция длиной в 32 бита). Чтобы константа смещения указывала на число инструкций, а не число байт, необходимо увеличить её в 4 раза. Это можно сделать, если приклеить к ней справа два нулевых бита (так же как в десятичной системе можно умножить число на 102=100 если дописать справа от него два нуля). Кроме того, чтобы разрядность константы совпадала с разрядностью `PC`, необходимо знакорасширить её до 32 бит. @@ -196,14 +214,16 @@ Сигнальные линии, которые управляют АЛУ и подают на его входы операнды уже существуют. Поэтому на схему необходимо добавить только логику управления мультиплексором на входе сумматора счетчика команд так. Эта логика работает следующим образом: -1. Если сейчас инструкция условного перехода -2. И если условие перехода выполнилось +1. если сейчас инструкция условного перехода +2. и если условие перехода выполнилось, то к `PC` прибавляется знакорасширенная константа, умноженная на 4. В противном случае, к `PC` прибавляется 4. -Так как теперь не любая инструкция приводит к записи в регистровый файл, появляется необходимость управлять входом `WE` так, чтобы при операциях условного перехода запись в регистровый файл не производилась. Это можно сделать, подав на WE значение `!B` (запись происходит, если сейчас **не операция условного перехода**) +Так как теперь не любая инструкция приводит к записи в регистровый файл, появляется необходимость управлять входом `WE` так, чтобы при операциях условного перехода запись в регистровый файл не производилась. Это можно сделать, подав на WE значение `!B` (запись происходит, если сейчас **не операция условного перехода**). -![../../.pic/Labs/lab_04_cybercobra/ppd_5.drawio.png](../../.pic/Labs/lab_04_cybercobra/ppd_5.drawio.png) +![../../.pic/Labs/lab_04_cybercobra/ppd_4.drawio.svg](../../.pic/Labs/lab_04_cybercobra/ppd_4.drawio.svg) + +_Рисунок 4. Реализация условного перехода._ ### Реализация безусловного перехода @@ -211,6 +231,8 @@ ![../../.pic/Labs/lab_04_cybercobra/ppd_code_5.png](../../.pic/Labs/lab_04_cybercobra/ppd_code_5.png) +_Таблица 5. Кодирование безусловного перехода._ + ``` C PC ← PC + const*4 ``` @@ -223,9 +245,11 @@ Кроме того, при безусловном переходе в регистровый файл так же ничего не пишется. А значит, необходимо обновить логику работы сигнала разрешения записи `WE`, который будет равен 0 если сейчас инструкция условного или безусловного перехода. -Ниже приводится итоговый вариант микроархитектуры процессора `CYBERcobra 3000 Pro 2.1` +На _рис. 5_ приводится итоговый вариант микроархитектуры процессора `CYBERcobra 3000 Pro 2.1`. -![../../.pic/Labs/lab_04_cybercobra/ppd_6.drawio.png](../../.pic/Labs/lab_04_cybercobra/ppd_6.drawio.png) +![../../.pic/Labs/lab_04_cybercobra/ppd_5.drawio.svg](../../.pic/Labs/lab_04_cybercobra/ppd_5.drawio.svg) + +_Рисунок 5. Реализация безусловного перехода._ ### Финальный обзор @@ -241,7 +265,7 @@ - J – однобитный сигнал, указывающий на выполнение безусловного перехода; - B – однобитный сигнал, указывающий на выполнение условного перехода; -- WS – двухбитный сигнал, указывающий источник данных для записи в регистровый файл: +- WS – двухбитный сигнал, указывающий источник данных для записи в регистровый файл: - 0 – константа из инструкции; - 1 – результат с АЛУ; - 2 – внешние данные; @@ -291,7 +315,7 @@ ## Задание по реализации процессора -Разработать процессор `CYBERcobra`, объединив ранее разработанные модули: +Разработать процессор `CYBERcobra` (см. [_рис. 5_](../../.pic/Labs/lab_04_cybercobra/ppd_5.drawio.svg)), объединив ранее разработанные модули: - Память инструкций (проинициализированную в двоичном формате файлом [`example.mem`](example.mem)) - Регистровый файл @@ -313,8 +337,6 @@ module CYВЕRcоbrа ( endmodule ``` -![../../.pic/Labs/lab_04_cybercobra/ppd_6.drawio.png](../../.pic/Labs/lab_04_cybercobra/ppd_6.drawio.png) - ## Порядок выполнения задания 1. Внимательно ознакомьтесь с [заданием](#задание-по-реализации-процессора). В случае возникновения вопросов, проконсультируйтесь с преподавателем.