diff --git a/.github/SUMMARY.md b/.github/SUMMARY.md index 0dd04dd..2b0a269 100644 --- a/.github/SUMMARY.md +++ b/.github/SUMMARY.md @@ -27,6 +27,7 @@ - [Лабораторная №9. Интеграция LSU](Labs/09.%20LSU%20Integration/README.md) - [Лабораторная №10. Подсистема прерываний](Labs/10.%20Interrupt%20subsystem/README.md) - [Лабораторная №11. Интеграция подсистемы прерываний](Labs/11.%20Interrupt%20integration/README.md) +- [Лабораторная №12. Дейзи-цепочка](Labs/12.%20Daisy%20chain/README.md) - [Лабораторная №12. Периферийные устройства](Labs/12.%20Peripheral%20units/README.md) - [Лабораторная №13. Программирование](Labs/13.%20Programming/README.md) - [Лабораторная №14. Программатор](Labs/14.%20Programming%20device/README.md) diff --git a/.pic/Labs/lab_12_daisy_chain/fig_01.png b/.pic/Labs/lab_12_daisy_chain/fig_01.png new file mode 100644 index 0000000..442c67b Binary files /dev/null and b/.pic/Labs/lab_12_daisy_chain/fig_01.png differ diff --git a/.pic/Labs/lab_12_daisy_chain/fig_02.drawio.svg b/.pic/Labs/lab_12_daisy_chain/fig_02.drawio.svg new file mode 100644 index 0000000..f8d6780 --- /dev/null +++ b/.pic/Labs/lab_12_daisy_chain/fig_02.drawio.svg @@ -0,0 +1,4 @@ + + + +
ready_i
irq_o
...
cause[15]
cause[1]
cause[0]
masked_irq_i[0]
masked_irq_i[1]
masked_irq_i[15]
16
16
32
— побитовая свертка по ИЛИ
masked_irq_i
ready_i
irq_ret_i

clk_i

rst_i
masked_irq_i
— входные сигналы
irq_ret_o
mcause_o
irq_o
— выходные сигналы

clk_i

rst_i
en
cause
16
1
0
16'd0
irq_ret_i
irq_ret_o
16
16
irq_cause_o
{12'h800,mcause,0000}
32
cause
— внутренний сигнал
irq_o
\ No newline at end of file diff --git a/.pic/Labs/lab_12_daisy_chain/fig_03.drawio.svg b/.pic/Labs/lab_12_daisy_chain/fig_03.drawio.svg new file mode 100644 index 0000000..fbe0bda --- /dev/null +++ b/.pic/Labs/lab_12_daisy_chain/fig_03.drawio.svg @@ -0,0 +1,4 @@ + + + +
irq_h
D
Q
RST
exc_h
D
Q
RST
reset
set
reset
set
mret_i
irq_req_i
mie_i
exception_i
irq_o
irq_ret_o
irq_cause_o
clk_i
rst_i
clk_i
rst_i
Daisy
chain
16
16
16
masked_irq_i
ready_i
irq_ret_i
irq_o
irq_ret_o
irq_cause_o
rst_i
clk_i
rst_i
16
32
\ No newline at end of file diff --git a/Labs/10. Interrupt subsystem/README.md b/Labs/10. Interrupt subsystem/README.md index de17b96..49919b9 100644 --- a/Labs/10. Interrupt subsystem/README.md +++ b/Labs/10. Interrupt subsystem/README.md @@ -145,7 +145,7 @@ _Таблица 4. Список регистров, подлежащих реа _Таблица 5. Кодирование причины перехвата в регистре `mcause`._ -Нас интересуют части, выделенные красным. В первую очередь то, как кодируется старший бит регистра `mcause`. Он зависит от типа причины перехвата (`1` в случае прерывания, `0` в случае исключения). Оставшиеся 31 бит регистра отводятся под коды различных причин. Поскольку мы создаем учебный процессор, который не будет использован в реальной жизни, он не будет поддерживать большую часть прерываний/исключений (таких как невыровненный доступ к памяти, таймеры и т.п.). В рамках данного курса мы должны поддерживать исключение по нелегальной инструкции (код 0x02) и должны уметь поддерживать прерывания периферийных устройств (под которые зарезервированы коды начиная с 16-го). В рамках данной лабораторной работы процессор будет поддерживать только один источник прерывания, поэтому для кодирования причины прерывания нам потребуется только первый код из диапазона _"Designated for platform use"_. +Нас интересуют части, выделенные красным. В первую очередь то, как кодируется старший бит регистра `mcause`. Он зависит от типа причины перехвата (`1` в случае прерывания, `0` в случае исключения). Оставшиеся 31 бит регистра отводятся под коды различных причин. Поскольку мы создаем учебный процессор, который не будет использован в реальной жизни, он не будет поддерживать большую часть прерываний/исключений (таких как невыровненный доступ к памяти, таймеры и т.п.). В рамках данного курса мы должны поддерживать исключение по нелегальной инструкции (код 0x02) и должны уметь поддерживать прерывания периферийных устройств (под которые зарезервированы коды начиная с 16-го). В рамках данной лабораторной работы процессор будет поддерживать только один источник прерывания, поэтому для кодирования причины прерывания нам потребуется только первый код из диапазона _"Designated for platform use"_. В случае, если вы захотите расширить количество источников прерываний, вы можете выполнить вспомогательную [лабораторную работу №12](../12.%20Daisy%20chain). Таким образом: в случае если произошло исключение (в связи с нелегальной инструкцией), значение `mcause` должно быть `0x00000002`. Если произошло прерывание, значение `mcause` должно быть `0x80000010`. diff --git a/Labs/11. Interrupt integration/README.md b/Labs/11. Interrupt integration/README.md index 32026ac..332eae0 100644 --- a/Labs/11. Interrupt integration/README.md +++ b/Labs/11. Interrupt integration/README.md @@ -18,10 +18,12 @@ _Рисунок 1. Схема без выделения новых частей Интегрировать модули `csr_controller` и `irq_controller` в модуль `riscv_core`. +В случае, если вы захотите расширить количество источников прерываний, вы можете выполнить вспомогательную [лабораторную работу №12](../12.%20Daisy%20chain). + ## Порядок выполнения работы 1. Интегрируйте модули `csr_controller` и `irq_controller` в модуль `riscv_core`. 1. Обратите внимание, что что в модуле `riscv_core` появились новые входные и выходные сигналы: `irq_req_i` и `irq_ret_o`. Эти сигналы должны быть использованы при подключении `riscv_core` в модуле `riscv_unit`. 1. Ко входу `irq_req_i` должен быть подключен провод `irq_req`, другой конец которого пока не будет ни к чему подключен (в следующей лабораторной это будет изменено). 2. К выходу `irq_ret_o` необходимо подключить провод `irq_ret`, который также пока не будет использован. -2. После интеграции модулей, проверьте процессорную систему с помощью [программы](irq_program.mem), текст которой [был представлен](../10.%20Interrupt%20subsystem#пример-обработки-перехвата) в ЛР10 с помощью предоставленного [тестбенча](tb_irq_unit.sv). +2. После интеграции модулей, проверьте процессорную систему с помощью [программы](irq_program.mem), текст которой [был представлен](../10.%20Interrupt%20subsystem#пример-обработки-перехвата) в ЛР10 с помощью предоставленного [тестбенча](tb_irq_unit.sv). \ No newline at end of file diff --git a/Labs/12. Daisy chain/README.md b/Labs/12. Daisy chain/README.md new file mode 100644 index 0000000..0c9e51b --- /dev/null +++ b/Labs/12. Daisy chain/README.md @@ -0,0 +1,67 @@ +# Лабораторная работа 12 "Увеличение количества источников прерываний с помощью дейзи-цепочки" + +В базовом варианте лабораторных работ вам было предложено реализовать процессорную систему с одним источником прерываний. Этого достаточно для выполнения лабораторных работ, однако, в случае если вы захотите увеличить количество периферийных устройств, поддержка только одного источника прерываний станет источником проблем. В данной лабораторной работе вы реализуете блок приоритетных прерываний и интегрируете его в контроллер прерываний, увеличив число источников прерываний до 16. + +## Цель + +1. Разработать блок приоритетных прерываний (БПП), построенный по схеме дейзи-цепочки. +2. Интегрировать БПП в контроллер прерываний. + +## Теория + +В случае, если в процессорной системе более одного источника прерываний, необходимо разобраться с тем, что делать, если произойдет коллизия (наложения) нескольких источников прерываний. Необходимо организовать приоритет прерываний. Со схемотехнической точки зрения, проще всего реализовать схему со статическим приоритетом. Одной из таких схем является дейзи-цепочка. Пример такой схемы вы можете увидеть на _рис. 1_. + +![../../.pic/Labs/lab_12_daisy_chain/fig_01.png](../../.pic/Labs/lab_12_daisy_chain/fig_01.png) + +_Рисунок 1. Структурная схема daisy-цепочки._ + +Дейзи-цепочка состоит из двух массивов элементов И. Первый массив (верхний ряд элементов) формирует многоразрядный сигнал (назовем его для определенности `ready`, на _рис. 1_ он обозначен как "_Приоритет_"), который перемножается с запросами с помощью массива элементов И нижнего ряда, формируя многоразрядный сигнал `y`. Обратите внимание на то, что результат операции И на очередном элементе нижнего массива влияет на результат И на следующем за ним элемента верхнего массива и наоборот (`readyₙ₊₁` зависит от `yₙ`, в то время как `yₙ` зависит от `readyₙ`). Как только на одном из разрядов `y` появится значение `1`, оно сразу же распространится в виде `0` по всем оставшимся последующим разрядам `ready`, обнуляя их. А обнулившись, разряды `ready` обнулят соответствующие разряды `y` (нулевые разряды `ready` запрещают генерацию прерывания для соответствующих разрядов `y`). + +Для описания верхнего ряда элементов И на языке SystemVerilog будет удобно воспользоваться конструкцией `generate for`, о которой рассказывалось в [ЛР 1 "Сумматор"](../01.%20Adder#Задание) (необходимо сделать непрерывное присваивание `readyₙ & !yₙ` для `n+1`-ого бита `ready`). + +Нижний массив элементов И можно описать через непрерывное присваивание побитового И между `ready` и сигналом запросов на прерывание. + +## Практика + +Рассмотрим реализацию нашего контроллера прерываний: + +![../../.pic/Labs/lab_12_daisy_chain/fig_02.drawio.svg](../../.pic/Labs/lab_12_daisy_chain/fig_02.drawio.svg) + +_Рисунок 2. Структурная схема блока приоритетных прерываний._ + +Помимо портов `clk_i` и `rst_i`, модуль `daisy_chain` будет иметь 3 входа и три выхода: + +- `masked_irq_i` — 16-разрядный вход маскированного запроса на прерывания (т.е. источник прерывание уже прошел маскирование сигналом CS-регистра `mie`). +- `irq_ret_i` — сигнал о возврате управления основному потоку инструкций (выход из обработчика прерываний) +- `ready_i` — сигнал о готовности процессора к перехвату (т.е. прямо сейчас процессор не находится в обработчике перехвата). Это нулевой бит сигнала `ready` в дейзи-цепочке. Пока `ready_i` равен нулю, дейзи-цепочка не будет генерировать сигналы прерываний. +- `irq_o` — сигнал о начале обработки прерываний +- `irq_cause_o` — причина прерывания. +- `irq_ret_o` — сигнал о завершении обработки запроса на прерывания. Будет соответствовать `cause_o` в момент появления сигнала `mret_i`. + +Внутренний сигнал `cause` является сигналом `y` с _рис. 1_. Как пояснялось выше, этот сигнал может содержать только одну единицу, она будет соответствовать прошедшему запросу на прерывание. А значит этот результат можно использовать в качестве сигнала для идентификации причины прерывания. При этом, свертка по ИЛИ этого сигнала даст итоговый запрос на прерывание. + +Однако, как упоминалось в ЛР10, спецификация RISC-V накладывает определенные требования на кодирование кода `mcause` для причины прерывания. В частности, необходимо выставить старший бит в единицу, а значение на оставшихся битах должно быть больше 16. Схемотехнически это проще реализовать выполнив склейку `{12'h800, cause, 4'b0000}` — в этом случае старший разряд будет равен единице, и если хоть один разряд `cause` будет равен единице (а именно это и является критерием появления прерывания), младшие 31 бит `mcause` будут старше 16. + +Регистр на _рис. 2_ хранит значение внутреннего сигнала `cause`, чтобы по завершению прерывания выставить единицу на соответствующем разряде сигнала `irq_ret_o`, который сообщит устройству, чье прерывание обрабатывалось ранее, что его обработка завершена. + +## Задание + +- Реализовать модуль `daisy_chain`. +- Интегрировать `daisy_chain` в модуль `irq_controller` по схеме, представленной на _рис. 3_. +- Отразить изменения в прототипе сигнала `irq_controller` в модулях `riscv_core` и `riscv_unit`. + +![../../.pic/Labs/lab_12_daisy_chain/fig_03.drawio.svg](../../.pic/Labs/lab_12_daisy_chain/fig_03.drawio.svg) + +_Рисунок 3. Структурная схема блока приоритетных прерываний._ + +Разрядность сигналов `irq_req_i`, `mie_i`, `irq_ret_o` изменилась. Теперь это 16-разрядные сигналы. Сигнал, который ранее шел на выход к `irq_ret_o` теперь идет на вход `irq_ret_i` модуля `daisy_chain`. Формирование кода причины прерывания `irq_cause_o` перенесено в модуль `daisy_chain`. + +## Порядок выполнения работы + +1. Опишите модуль `daisy_chain`. + 1. При формировании верхнего массива элементов И с _рис. 2_, вам необходимо воспользоваться сформировать 16 непрерывных присваиваний через блок `generate for`. + 2. Формирование нижнего массива элементов И можно сделать с помощью одного непрерывного присваивания посредством операции побитовое И. + 3. Проверьте модуль `daisy_chain` с помощью модуля [`tb_daisy_chain`](tb_daisy_chain.sv). +2. Интегрируйте модуль `daisy_chain` в модуль `irq_controller` по схеме, представленной на _рис. 3_. + 1. Не забудьте обновить разрядность сигналов `irq_req_i`, `mie_i`, `irq_ret_o`. + 2. Также не забудьте обновить разрядность сигналов `irq_req_i`, `irq_ret_o` в `riscv_core` и `riscv_unit`, также использовать младшие 16 бит сигнала `mie` вместо одного при подключении модуля `irq_controller`. diff --git a/Labs/12. Daisy chain/tb_daisy_chain.sv b/Labs/12. Daisy chain/tb_daisy_chain.sv new file mode 100644 index 0000000..c34df2b --- /dev/null +++ b/Labs/12. Daisy chain/tb_daisy_chain.sv @@ -0,0 +1,82 @@ +module tb_daisy_chain(); + +logic clk_i, rst_i, ready_i, irq_ret_i; +logic [15:0] masked_irq_i; +logic irq_o; +logic [15:0] irq_ret_o; +logic [31:0] irq_cause_o; + +daisy_chain DUT(.*); + +initial clk_i = 0; +always #5 clk_i = !clk_i; + +initial begin + rst_i <= 1'b1; + @(posedge clk_i); + rst_i <= 1'b0; + mcause_onehot_test(); + random_test(); + $finish(); +end + +task mcause_onehot_test(); + ready_i <= 1'b1; + masked_irq_i <= 0; + repeat (2**16) begin + @(posedge clk_i); + masked_irq_i <= masked_irq_i + 1'b1; + end +endtask + +task random_test(); + repeat(2**16) begin + @(posedge clk_i); + ready_i <= $urandom_range(1); + irq_ret_i <= $urandom_range(1); + masked_irq_i <= $urandom_range(2**16); + end +endtask + +logic [15:0] cause; + +always_ff @(posedge clk_i) begin + if(rst_i) begin + cause <= '0; + end + else if(irq_o) begin + cause <= irq_cause_o[19:4]; + end +end + +irq_ret_o_is_not_0: assert property ( + @(posedge clk_i) disable iff ( rst_i ) + !irq_ret_i |-> irq_ret_o === '0 +)else $error("irq_ret_o are not equal 0"); + +irq_ret_o_is_incorrect: assert property ( + @(posedge clk_i) disable iff ( rst_i ) + irq_ret_i |-> irq_ret_o === cause +)else $error("irq_ret_o are incorrect: %08h", irq_ret_o); + +irq_o_is_not_1: assert property ( + @(posedge clk_i) disable iff ( rst_i ) + ready_i & masked_irq_i |-> irq_o +)else $error("irq_o are not equal 1"); + +irq_o_is_not_0: assert property ( + @(posedge clk_i) disable iff ( rst_i ) + !ready_i |-> !irq_o +)else $error("irq_o are not equal 0"); + +irq_cause_o_mcause: assert property ( + @(posedge clk_i) disable iff ( rst_i ) + irq_o |-> $onehot0(irq_cause_o[19:4]) +)else $error("error value on irq_cause_o: %08h, should be onehot", irq_cause_o[20:5]); + +irq_cause_o_borders: assert property ( + @(posedge clk_i) disable iff ( rst_i ) + irq_o |-> (irq_cause_o[31:20] === 12'h800) && (irq_cause_o[3:0] == 4'h0) +)else $error("irq_cause_o borders are incorrect: %08h", irq_cause_o); + +endmodule \ No newline at end of file diff --git a/Labs/README.md b/Labs/README.md index cb1de49..8caccda 100644 --- a/Labs/README.md +++ b/Labs/README.md @@ -21,6 +21,7 @@ - [9 Интеграция LSU](#9-интеграция-lsu) - [10. Подсистема прерывания (IC)](#10-подсистема-прерывания-ic) - [11. Интеграция подсистемы прерывания](#11-интеграция-подсистемы-прерывания) + - [12. Увеличение количества источников прерываний с помощью дейзи-цепочки](#12-увеличение-количества-источников-прерываний-с-помощью-дейзи-цепочки) - [12. Периферийные устройства (PU)](#12-периферийные-устройства-pu) - [13. Программирование на языке высокого уровня](#13-программирование-на-языке-высокого-уровня) - [14. Программатор](#14-программатор) @@ -79,7 +80,7 @@ ![../.pic/Labs/labs.png](../.pic/Labs/labs.png) -Курс *Архитектур процессорных систем* включает в себя цикл из 15 лабораторных работ (10 основных + 5 вспомогательных), в течение которых используя язык описания аппаратуры **SystemVerilog** на основе **FPGA** (ПЛИС, программируемая логическая интегральная схема), с нуля, последовательно, создается система, под управлением процессора с архитектурой **RISC-V**, управляющего периферийными устройствами и программируемого на языке высокого уровня **C++**. +Курс *Архитектур процессорных систем* включает в себя цикл из 16 лабораторных работ (10 основных + 6 вспомогательных), в течение которых используя язык описания аппаратуры **SystemVerilog** на основе **FPGA** (ПЛИС, программируемая логическая интегральная схема), с нуля, последовательно, создается система, под управлением процессора с архитектурой **RISC-V**, управляющего периферийными устройствами и программируемого на языке высокого уровня **C++**. Создаваемая система на ПЛИС состоит из: процессора, памяти, контроллера прерываний и контроллеров периферийных устройств. @@ -163,6 +164,12 @@ ![../.pic/Labs/l9.png](../.pic/Labs/lab_11_irq_integration.drawio.svg) +## 12. Увеличение количества источников прерываний с помощью дейзи-цепочки + +В базовом варианте лабораторных работ вам было предложено реализовать процессорную систему с одним источником прерываний. Этого достаточно для выполнения лабораторных работ, однако, в случае если вы захотите увеличить количество периферийных устройств, поддержка только одного источника прерываний станет источником проблем. В данной лабораторной работе вы реализуете блок приоритетных прерываний и интегрируете его в контроллер прерываний, увеличив число источников прерываний до 16. + +![../.pic/Labs/lab_12_daisy_chain/fig_02.drawio.svg](../.pic/Labs/lab_12_daisy_chain/fig_02.drawio.svg) + ## 12. Периферийные устройства (PU) ![../.pic/Labs/l9.png](../.pic/Labs/lab_12_peripheral_units.drawio.svg)